Merge remote-tracking branch 'origin/4.1' into 4.2

Conflicts:
	src/plugins/ios/iostoolhandler.cpp
	src/shared/qbs
	src/tools/3rdparty/iossim/iossim.qbs
	src/tools/3rdparty/iossim_1_8_2/main.mm

Change-Id: Ied9cafec4f1ee93d9e524f095f5c6b1480b2f054
This commit is contained in:
Eike Ziller
2016-10-17 16:16:07 +02:00
45 changed files with 802 additions and 3377 deletions

View File

@@ -38,12 +38,14 @@
\title Specifying Build Settings
Different build configurations allow you to quickly switch between
different build settings. By default, \QC creates \b debug
and \b release build configurations. A debug build contains additional
different build settings. By default, \QC creates \e debug, \e release, and
\e profile build configurations. A debug build contains additional
debug symbols that you need for debugging the application but that you
can leave out from the release version. Generally, you use the debug
configuration for testing and the release configuration for creating
the final installation file.
the final installation file. A profile configuration is an optimized release
build that is delivered with separate debug information. It is best suited
for analyzing applications.
You specify build settings in the \uicontrol Projects mode.
To add a new build configuration, click \uicontrol Add and select the type of

View File

@@ -33,7 +33,8 @@ HEADERS += \
iosdeploystep.h \
iosdeploystepfactory.h \
iosdeploystepwidget.h \
iosanalyzesupport.h
iosanalyzesupport.h \
simulatorcontrol.h
SOURCES += \
@@ -61,7 +62,8 @@ SOURCES += \
iosdeploystep.cpp \
iosdeploystepfactory.cpp \
iosdeploystepwidget.cpp \
iosanalyzesupport.cpp
iosanalyzesupport.cpp \
simulatorcontrol.cpp
FORMS += \
iossettingswidget.ui \

View File

@@ -69,6 +69,8 @@ QtcPlugin {
"iossimulatorfactory.cpp",
"iossimulatorfactory.h",
"iostoolhandler.cpp",
"iostoolhandler.h"
"iostoolhandler.h",
"simulatorcontrol.cpp",
"simulatorcontrol.h"
]
}

View File

@@ -27,6 +27,7 @@
#include "iosconstants.h"
#include "iosdevice.h"
#include "iossimulator.h"
#include "simulatorcontrol.h"
#include "iosprobe.h"
#include <coreplugin/icore.h>
@@ -332,7 +333,7 @@ void IosConfigurations::updateSimulators()
dev = IDevice::ConstPtr(new IosSimulator(devId));
devManager->addDevice(dev);
}
IosSimulator::updateAvailableDevices();
SimulatorControl::updateAvailableSimulators();
}
void IosConfigurations::setDeveloperPath(const FileName &devPath)

View File

@@ -169,6 +169,8 @@ IosDebugSupport::IosDebugSupport(IosRunConfiguration *runConfig,
m_runner, &IosRunner::start);
connect(m_runControl, &RunControl::finished,
m_runner, &IosRunner::stop);
connect(m_runControl, &DebuggerRunControl::stateChanged,
m_runner, &IosRunner::debuggerStateChanged);
connect(m_runner, &IosRunner::gotServerPorts,
this, &IosDebugSupport::handleServerPorts);

View File

@@ -101,7 +101,12 @@ bool IosDeployStep::init(QList<const BuildStep *> &earlierSteps)
this->target()->activeRunConfiguration());
QTC_ASSERT(runConfig, return false);
m_bundlePath = runConfig->bundleDirectory().toString();
if (m_device.isNull()) {
if (iosdevice()) {
m_deviceType = IosDeviceType(IosDeviceType::IosDevice, deviceId());
} else if (iossimulator()) {
m_deviceType = runConfig->deviceType();
} else {
emit addOutput(tr("Error: no device available, deploy failed."),
BuildStep::ErrorMessageOutput);
return false;
@@ -113,17 +118,15 @@ void IosDeployStep::run(QFutureInterface<bool> &fi)
{
m_futureInterface = fi;
QTC_CHECK(m_transferStatus == NoTransfer);
if (iosdevice().isNull()) {
if (iossimulator().isNull())
TaskHub::addTask(Task::Error, tr("Deployment failed. No iOS device found."),
ProjectExplorer::Constants::TASK_CATEGORY_DEPLOYMENT);
if (device().isNull()) {
TaskHub::addTask(Task::Error, tr("Deployment failed. No iOS device found."),
ProjectExplorer::Constants::TASK_CATEGORY_DEPLOYMENT);
reportRunResult(m_futureInterface, !iossimulator().isNull());
cleanup();
return;
}
m_toolHandler = new IosToolHandler(m_deviceType, this);
m_transferStatus = TransferInProgress;
QTC_CHECK(m_toolHandler == 0);
m_toolHandler = new IosToolHandler(IosDeviceType(IosDeviceType::IosDevice), this);
m_futureInterface.setProgressRange(0, 200);
m_futureInterface.setProgressValueAndText(0, QLatin1String("Transferring application"));
m_futureInterface.reportStarted();
@@ -136,7 +139,7 @@ void IosDeployStep::run(QFutureInterface<bool> &fi)
connect(m_toolHandler, &IosToolHandler::errorMsg,
this, &IosDeployStep::handleErrorMsg);
checkProvisioningProfile();
m_toolHandler->requestTransferApp(appBundle(), deviceId());
m_toolHandler->requestTransferApp(appBundle(), m_deviceType.identifier);
}
void IosDeployStep::cancel()
@@ -150,7 +153,7 @@ void IosDeployStep::cleanup()
QTC_CHECK(m_transferStatus != TransferInProgress);
m_transferStatus = NoTransfer;
m_device.clear();
m_toolHandler = 0;
m_toolHandler = nullptr;
m_expectFail = false;
}

View File

@@ -101,6 +101,7 @@ private:
QFutureInterface<bool> m_futureInterface;
ProjectExplorer::IDevice::ConstPtr m_device;
QString m_bundlePath;
IosDeviceType m_deviceType;
static const Core::Id Id;
bool m_expectFail;
};

View File

@@ -27,6 +27,7 @@
#include "iosconstants.h"
#include "iosmanager.h"
#include "iosdeploystep.h"
#include "simulatorcontrol.h"
#include <projectexplorer/kitinformation.h>
#include <projectexplorer/target.h>
@@ -346,7 +347,7 @@ IosDeviceType IosRunConfiguration::deviceType() const
{
QList<IosDeviceType> availableSimulators;
if (m_deviceType.type == IosDeviceType::SimulatedDevice)
availableSimulators = IosSimulator::availableDevices();
availableSimulators = SimulatorControl::availableSimulators();
if (!availableSimulators.isEmpty()) {
QList<IosDeviceType> elegibleDevices;
QString devname = m_deviceType.identifier.split(QLatin1Char(',')).value(0);
@@ -417,7 +418,7 @@ void IosRunConfigurationWidget::updateValues()
m_deviceTypeLabel->setVisible(showDeviceSelector);
m_deviceTypeComboBox->setVisible(showDeviceSelector);
if (showDeviceSelector && m_deviceTypeModel.rowCount() == 0) {
foreach (const IosDeviceType &dType, IosSimulator::availableDevices()) {
foreach (const IosDeviceType &dType, SimulatorControl::availableSimulators()) {
QStandardItem *item = new QStandardItem(dType.displayName);
QVariant v;
v.setValue(dType);

View File

@@ -168,6 +168,12 @@ void IosRunner::stop()
}
}
void IosRunner::debuggerStateChanged(Debugger::DebuggerState state)
{
if (m_toolHandler)
m_toolHandler->debuggerStateChanged(state);
}
void IosRunner::handleDidStartApp(IosToolHandler *handler, const QString &bundlePath,
const QString &deviceId, IosToolHandler::OpStatus status)
{

View File

@@ -29,6 +29,7 @@
#include "iostoolhandler.h"
#include "iossimulator.h"
#include <debugger/debuggerconstants.h>
#include <projectexplorer/devicesupport/idevice.h>
#include <qmldebug/qmldebugcommandlinearguments.h>
@@ -64,6 +65,9 @@ public:
void start();
void stop();
public slots:
void debuggerStateChanged(Debugger::DebuggerState state);
signals:
void didStartApp(Ios::IosToolHandler::OpStatus status);
void gotServerPorts(Utils::Port gdbPort, Utils::Port qmlPort);

View File

@@ -45,9 +45,6 @@ static const QLatin1String iosDeviceTypeDisplayNameKey = QLatin1String("displayN
static const QLatin1String iosDeviceTypeTypeKey = QLatin1String("type");
static const QLatin1String iosDeviceTypeIdentifierKey = QLatin1String("identifier");
QMutex IosSimulator::_mutex;
QList<IosDeviceType> IosSimulator::_availableDevices;
IosSimulator::IosSimulator(Core::Id id)
: IDevice(Core::Id(Constants::IOS_SIMULATOR_TYPE),
IDevice::AutoDetected,
@@ -124,48 +121,6 @@ IDevice::Ptr IosSimulator::clone() const
return IDevice::Ptr(new IosSimulator(*this));
}
QList<IosDeviceType> IosSimulator::availableDevices()
{
QMutexLocker l(&_mutex);
return _availableDevices;
}
void IosSimulator::setAvailableDevices(QList<IosDeviceType> value)
{
QMutexLocker l(&_mutex);
_availableDevices = value;
}
namespace {
void handleDeviceInfo(Ios::IosToolHandler *handler, const QString &deviceId,
const Ios::IosToolHandler::Dict &info)
{
Q_UNUSED(deviceId);
QList<IosDeviceType> res;
QMapIterator<QString, QString> i(info);
while (i.hasNext()) {
i.next();
IosDeviceType simulatorType(IosDeviceType::SimulatedDevice);
simulatorType.displayName = i.value();
simulatorType.identifier = i.key();
QStringList ids = i.key().split(QLatin1Char(','));
if (ids.length() > 1)
simulatorType.displayName += QLatin1String(", iOS ") + ids.last().trimmed();
res.append(simulatorType);
}
handler->deleteLater();
std::stable_sort(res.begin(), res.end());
IosSimulator::setAvailableDevices(res);
}
}
void IosSimulator::updateAvailableDevices()
{
IosToolHandler *toolHandler = new IosToolHandler(IosDeviceType(IosDeviceType::SimulatedDevice));
QObject::connect(toolHandler, &IosToolHandler::deviceInfo, &handleDeviceInfo);
toolHandler->requestDeviceInfo(QString());
}
void IosSimulator::fromMap(const QVariantMap &map)
{
IDevice::fromMap(map);

View File

@@ -67,10 +67,6 @@ public:
typedef QSharedPointer<IosSimulator> Ptr;
ProjectExplorer::IDevice::DeviceInfo deviceInformation() const override;
static QList<IosDeviceType> availableDevices();
static void setAvailableDevices(QList<IosDeviceType> value);
static void updateAvailableDevices();
QString displayType() const override;
ProjectExplorer::IDeviceWidget *createWidget() override;
QList<Core::Id> actionIds() const override;
@@ -91,8 +87,6 @@ protected:
IosSimulator(const IosSimulator &other);
private:
mutable quint16 m_lastPort;
static QMutex _mutex;
static QList<IosDeviceType> _availableDevices;
};
namespace IosKitInformation {

View File

@@ -27,13 +27,18 @@
#include "iosconfigurations.h"
#include "iosconstants.h"
#include "iossimulator.h"
#include "simulatorcontrol.h"
#include "debugger/debuggerconstants.h"
#include <coreplugin/icore.h>
#include <utils/qtcassert.h>
#include <utils/fileutils.h>
#include <QCoreApplication>
#include <QFileInfo>
#include <QJsonArray>
#include <QJsonDocument>
#include <QJsonObject>
#include <QList>
#include <QLoggingCategory>
#include <QProcess>
@@ -52,6 +57,8 @@ namespace Ios {
namespace Internal {
using namespace std::placeholders;
struct ParserState {
enum Kind {
Msg,
@@ -132,7 +139,8 @@ public:
virtual void requestDeviceInfo(const QString &deviceId, int timeout = 1000) = 0;
bool isRunning();
void start(const QString &exe, const QStringList &args);
void stop(int errorCode);
virtual void stop(int errorCode) = 0;
virtual void debuggerStateChanged(Debugger::DebuggerState state) { Q_UNUSED(state); }
// signals
void isTransferringApp(const QString &bundlePath, const QString &deviceId, int progress,
@@ -148,15 +156,12 @@ public:
void appOutput(const QString &output);
void errorMsg(const QString &msg);
void toolExited(int code);
// slots
void subprocessError(QProcess::ProcessError error);
void subprocessFinished(int exitCode, QProcess::ExitStatus exitStatus);
void subprocessHasData();
void killProcess();
virtual bool expectsFileDescriptor() = 0;
protected:
void processXml();
protected:
void killProcess();
protected:
IosToolHandler *q;
QProcess *process;
QTimer killTimer;
@@ -176,34 +181,56 @@ class IosDeviceToolHandlerPrivate : public IosToolHandlerPrivate
{
public:
explicit IosDeviceToolHandlerPrivate(const IosDeviceType &devType, IosToolHandler *q);
virtual void requestTransferApp(const QString &bundlePath, const QString &deviceId,
int timeout = 1000);
virtual void requestRunApp(const QString &bundlePath, const QStringList &extraArgs,
IosToolHandler::RunKind runKind,
const QString &deviceId, int timeout = 1000);
virtual void requestDeviceInfo(const QString &deviceId, int timeout = 1000);
virtual bool expectsFileDescriptor();
// IosToolHandlerPrivate overrides
public:
void requestTransferApp(const QString &bundlePath, const QString &deviceId,
int timeout = 1000) override;
void requestRunApp(const QString &bundlePath, const QStringList &extraArgs,
IosToolHandler::RunKind runKind,
const QString &deviceId, int timeout = 1000) override;
void requestDeviceInfo(const QString &deviceId, int timeout = 1000) override;
void stop(int errorCode) override;
private:
void subprocessError(QProcess::ProcessError error);
void subprocessFinished(int exitCode, QProcess::ExitStatus exitStatus);
void subprocessHasData();
void processXml();
};
class IosSimulatorToolHandlerPrivate : public IosToolHandlerPrivate
{
public:
explicit IosSimulatorToolHandlerPrivate(const IosDeviceType &devType, IosToolHandler *q);
virtual void requestTransferApp(const QString &bundlePath, const QString &deviceId,
int timeout = 1000);
virtual void requestRunApp(const QString &bundlePath, const QStringList &extraArgs,
IosToolHandler::RunKind runKind,
const QString &deviceId, int timeout = 1000);
virtual void requestDeviceInfo(const QString &deviceId, int timeout = 1000);
virtual bool expectsFileDescriptor();
// IosToolHandlerPrivate overrides
public:
void requestTransferApp(const QString &bundlePath, const QString &deviceIdentifier,
int timeout = 1000) override;
void requestRunApp(const QString &bundlePath, const QStringList &extraArgs,
IosToolHandler::RunKind runKind,
const QString &deviceIdentifier, int timeout = 1000) override;
void requestDeviceInfo(const QString &deviceId, int timeout = 1000) override;
void stop(int errorCode) override;
void debuggerStateChanged(Debugger::DebuggerState state) override;
private:
void addDeviceArguments(QStringList &args) const;
void simAppProcessError(QProcess::ProcessError error);
void simAppProcessFinished(int exitCode, QProcess::ExitStatus exitStatus);
void simAppProcessHasData();
void simAppProcessHasErrorOutput();
void launchAppOnSimulator();
private:
qint64 appPId = -1;
bool appLaunched = false;
};
IosToolHandlerPrivate::IosToolHandlerPrivate(const IosDeviceType &devType,
Ios::IosToolHandler *q) :
q(q),
process(new QProcess),
process(nullptr),
state(NonStarted),
devType(devType),
iBegin(0),
@@ -211,34 +238,6 @@ IosToolHandlerPrivate::IosToolHandlerPrivate(const IosDeviceType &devType,
gdbSocket(-1)
{
killTimer.setSingleShot(true);
QProcessEnvironment env(QProcessEnvironment::systemEnvironment());
foreach (const QString &k, env.keys())
if (k.startsWith(QLatin1String("DYLD_")))
env.remove(k);
QStringList frameworkPaths;
Utils::FileName xcPath = IosConfigurations::developerPath();
QString privateFPath = xcPath.appendPath(QLatin1String("Platforms/iPhoneSimulator.platform/Developer/Library/PrivateFrameworks")).toFileInfo().canonicalFilePath();
if (!privateFPath.isEmpty())
frameworkPaths << privateFPath;
QString otherFPath = xcPath.appendPath(QLatin1String("../OtherFrameworks")).toFileInfo().canonicalFilePath();
if (!otherFPath.isEmpty())
frameworkPaths << otherFPath;
QString sharedFPath = xcPath.appendPath(QLatin1String("../SharedFrameworks")).toFileInfo().canonicalFilePath();
if (!sharedFPath.isEmpty())
frameworkPaths << sharedFPath;
frameworkPaths << QLatin1String("/System/Library/Frameworks")
<< QLatin1String("/System/Library/PrivateFrameworks");
env.insert(QLatin1String("DYLD_FALLBACK_FRAMEWORK_PATH"), frameworkPaths.join(QLatin1Char(':')));
qCDebug(toolHandlerLog) << "IosToolHandler runEnv:" << env.toStringList();
process->setProcessEnvironment(env);
QObject::connect(process, &QProcess::readyReadStandardOutput,
q, &IosToolHandler::subprocessHasData);
QObject::connect(process,
static_cast<void (QProcess::*)(int, QProcess::ExitStatus)>(&QProcess::finished),
q, &IosToolHandler::subprocessFinished);
QObject::connect(process, &QProcess::errorOccurred, q, &IosToolHandler::subprocessError);
QObject::connect(&killTimer, &QTimer::timeout,
q, &IosToolHandler::killProcess);
}
IosToolHandlerPrivate::~IosToolHandlerPrivate()
@@ -258,6 +257,7 @@ bool IosToolHandlerPrivate::isRunning()
void IosToolHandlerPrivate::start(const QString &exe, const QStringList &args)
{
Q_ASSERT(process);
QTC_CHECK(state == NonStarted);
state = Starting;
qCDebug(toolHandlerLog) << "running " << exe << args;
@@ -265,44 +265,6 @@ void IosToolHandlerPrivate::start(const QString &exe, const QStringList &args)
state = StartedInferior;
}
void IosToolHandlerPrivate::stop(int errorCode)
{
qCDebug(toolHandlerLog) << "IosToolHandlerPrivate::stop";
State oldState = state;
state = Stopped;
switch (oldState) {
case NonStarted:
qCWarning(toolHandlerLog) << "IosToolHandler::stop() when state was NonStarted";
// pass
case Starting:
switch (op){
case OpNone:
qCWarning(toolHandlerLog) << "IosToolHandler::stop() when op was OpNone";
break;
case OpAppTransfer:
didTransferApp(bundlePath, deviceId, IosToolHandler::Failure);
break;
case OpAppRun:
didStartApp(bundlePath, deviceId, IosToolHandler::Failure);
break;
case OpDeviceInfo:
break;
}
// pass
case StartedInferior:
case XmlEndProcessed:
toolExited(errorCode);
break;
case Stopped:
return;
}
if (isRunning()) {
process->write("k\n\r");
process->closeWriteChannel();
killTimer.start(1500);
}
}
// signals
void IosToolHandlerPrivate::isTransferringApp(const QString &bundlePath, const QString &deviceId,
int progress, int maxProgress, const QString &info)
@@ -355,7 +317,7 @@ void IosToolHandlerPrivate::toolExited(int code)
emit q->toolExited(q, code);
}
void IosToolHandlerPrivate::subprocessError(QProcess::ProcessError error)
void IosDeviceToolHandlerPrivate::subprocessError(QProcess::ProcessError error)
{
if (state != Stopped)
errorMsg(IosToolHandler::tr("iOS tool Error %1").arg(error));
@@ -366,7 +328,7 @@ void IosToolHandlerPrivate::subprocessError(QProcess::ProcessError error)
}
}
void IosToolHandlerPrivate::subprocessFinished(int exitCode, QProcess::ExitStatus exitStatus)
void IosDeviceToolHandlerPrivate::subprocessFinished(int exitCode, QProcess::ExitStatus exitStatus)
{
stop((exitStatus == QProcess::NormalExit) ? exitCode : -1 );
qCDebug(toolHandlerLog) << "IosToolHandler::finished(" << this << ")";
@@ -374,7 +336,7 @@ void IosToolHandlerPrivate::subprocessFinished(int exitCode, QProcess::ExitStatu
emit q->finished(q);
}
void IosToolHandlerPrivate::processXml()
void IosDeviceToolHandlerPrivate::processXml()
{
while (!outputParser.atEnd()) {
QXmlStreamReader::TokenType tt = outputParser.readNext();
@@ -556,7 +518,7 @@ void IosToolHandlerPrivate::processXml()
}
}
void IosToolHandlerPrivate::subprocessHasData()
void IosDeviceToolHandlerPrivate::subprocessHasData()
{
qCDebug(toolHandlerLog) << "subprocessHasData, state:" << state;
while (true) {
@@ -596,7 +558,42 @@ void IosToolHandlerPrivate::subprocessHasData()
IosDeviceToolHandlerPrivate::IosDeviceToolHandlerPrivate(const IosDeviceType &devType,
IosToolHandler *q)
: IosToolHandlerPrivate(devType, q)
{ }
{
process = new QProcess;
// Prepare & set process Environment.
QProcessEnvironment env(QProcessEnvironment::systemEnvironment());
foreach (const QString &k, env.keys())
if (k.startsWith(QLatin1String("DYLD_")))
env.remove(k);
QStringList frameworkPaths;
Utils::FileName xcPath = IosConfigurations::developerPath();
QString privateFPath = xcPath.appendPath(QLatin1String("Platforms/iPhoneSimulator.platform/Developer/Library/PrivateFrameworks")).toFileInfo().canonicalFilePath();
if (!privateFPath.isEmpty())
frameworkPaths << privateFPath;
QString otherFPath = xcPath.appendPath(QLatin1String("../OtherFrameworks")).toFileInfo().canonicalFilePath();
if (!otherFPath.isEmpty())
frameworkPaths << otherFPath;
QString sharedFPath = xcPath.appendPath(QLatin1String("../SharedFrameworks")).toFileInfo().canonicalFilePath();
if (!sharedFPath.isEmpty())
frameworkPaths << sharedFPath;
frameworkPaths << QLatin1String("/System/Library/Frameworks")
<< QLatin1String("/System/Library/PrivateFrameworks");
env.insert(QLatin1String("DYLD_FALLBACK_FRAMEWORK_PATH"), frameworkPaths.join(QLatin1Char(':')));
qCDebug(toolHandlerLog) << "IosToolHandler runEnv:" << env.toStringList();
process->setProcessEnvironment(env);
QObject::connect(process, &QProcess::readyReadStandardOutput,
std::bind(&IosDeviceToolHandlerPrivate::subprocessHasData,this));
QObject::connect(process, static_cast<void (QProcess::*)(int, QProcess::ExitStatus)>(&QProcess::finished),
std::bind(&IosDeviceToolHandlerPrivate::subprocessFinished,this, _1,_2));
QObject::connect(process, static_cast<void (QProcess::*)(QProcess::ProcessError)>(&QProcess::error),
std::bind(&IosDeviceToolHandlerPrivate::subprocessError, this, _1));
QObject::connect(&killTimer, &QTimer::timeout, std::bind(&IosDeviceToolHandlerPrivate::killProcess, this));
}
void IosDeviceToolHandlerPrivate::requestTransferApp(const QString &bundlePath,
const QString &deviceId, int timeout)
@@ -644,11 +641,46 @@ void IosDeviceToolHandlerPrivate::requestDeviceInfo(const QString &deviceId, int
start(IosToolHandler::iosDeviceToolPath(), args);
}
bool IosDeviceToolHandlerPrivate::expectsFileDescriptor()
void IosDeviceToolHandlerPrivate::stop(int errorCode)
{
return op == OpAppRun && runKind == IosToolHandler::DebugRun;
qCDebug(toolHandlerLog) << "IosToolHandlerPrivate::stop";
State oldState = state;
state = Stopped;
switch (oldState) {
case NonStarted:
qCWarning(toolHandlerLog) << "IosToolHandler::stop() when state was NonStarted";
// pass
case Starting:
switch (op){
case OpNone:
qCWarning(toolHandlerLog) << "IosToolHandler::stop() when op was OpNone";
break;
case OpAppTransfer:
didTransferApp(bundlePath, deviceId, IosToolHandler::Failure);
break;
case OpAppRun:
didStartApp(bundlePath, deviceId, IosToolHandler::Failure);
break;
case OpDeviceInfo:
break;
}
// pass
case StartedInferior:
case XmlEndProcessed:
toolExited(errorCode);
break;
case Stopped:
return;
}
if (isRunning()) {
process->write("k\n\r");
process->closeWriteChannel();
killTimer.start(1500);
}
}
// IosSimulatorToolHandlerPrivate
IosSimulatorToolHandlerPrivate::IosSimulatorToolHandlerPrivate(const IosDeviceType &devType,
@@ -657,64 +689,159 @@ IosSimulatorToolHandlerPrivate::IosSimulatorToolHandlerPrivate(const IosDeviceTy
{ }
void IosSimulatorToolHandlerPrivate::requestTransferApp(const QString &bundlePath,
const QString &deviceId, int timeout)
const QString &deviceIdentifier, int timeout)
{
Q_UNUSED(timeout);
this->bundlePath = bundlePath;
this->deviceId = deviceId;
emit didTransferApp(bundlePath, deviceId, IosToolHandler::Success);
this->deviceId = deviceIdentifier;
isTransferringApp(bundlePath, deviceId, 0, 100, "");
if (SimulatorControl::startSimulator(deviceId)) {
isTransferringApp(bundlePath, deviceId, 20, 100, "");
QByteArray cmdOutput;
if (SimulatorControl::installApp(deviceId, Utils::FileName::fromString(bundlePath), cmdOutput)) {
isTransferringApp(bundlePath, deviceId, 100, 100, "");
didTransferApp(bundlePath, deviceId, IosToolHandler::Success);
} else {
errorMsg(IosToolHandler::tr("Application install on Simulator failed. %1").arg(QString::fromLocal8Bit(cmdOutput)));
didTransferApp(bundlePath, deviceId, IosToolHandler::Failure);
}
} else {
errorMsg(IosToolHandler::tr("Application install on Simulator failed. Simulator not running."));
didTransferApp(bundlePath, deviceId, IosToolHandler::Failure);
}
emit q->finished(q);
}
void IosSimulatorToolHandlerPrivate::requestRunApp(const QString &bundlePath,
const QStringList &extraArgs,
IosToolHandler::RunKind runType,
const QString &deviceId, int timeout)
const QString &deviceIdentifier, int timeout)
{
Q_UNUSED(timeout);
Q_UNUSED(deviceIdentifier);
this->bundlePath = bundlePath;
this->deviceId = deviceId;
this->deviceId = devType.identifier;
this->runKind = runType;
QStringList args;
args << QLatin1String("launch") << bundlePath;
Utils::FileName devPath = IosConfigurations::developerPath();
if (!devPath.isEmpty())
args << QLatin1String("--developer-path") << devPath.toString();
addDeviceArguments(args);
switch (runType) {
case IosToolHandler::NormalRun:
break;
case IosToolHandler::DebugRun:
args << QLatin1String("--wait-for-debugger");
break;
}
args << QLatin1String("--args") << extraArgs;
op = OpAppRun;
start(IosToolHandler::iosSimulatorToolPath(), args);
Utils::FileName appBundle = Utils::FileName::fromString(bundlePath);
if (!appBundle.exists()) {
errorMsg(IosToolHandler::tr("Application launch on Simulator failed. Invalid Bundle path %1")
.arg(bundlePath));
didStartApp(bundlePath, deviceId, Ios::IosToolHandler::Failure);
return;
}
if (SimulatorControl::startSimulator(deviceId)) {
qint64 pId = -1;
bool debugRun = runType == IosToolHandler::DebugRun;
QProcess* controlProcess = SimulatorControl::spawnAppProcess(deviceId, appBundle, pId, debugRun, extraArgs);
if (controlProcess) {
Q_ASSERT(!process || !isRunning());
if (process) {
delete process;
process = nullptr;
}
process = controlProcess;
QObject::connect(process, &QProcess::readyReadStandardOutput,
std::bind(&IosSimulatorToolHandlerPrivate::simAppProcessHasData,this));
QObject::connect(process, &QProcess::readyReadStandardError,
std::bind(&IosSimulatorToolHandlerPrivate::simAppProcessHasErrorOutput,this));
QObject::connect(process, static_cast<void (QProcess::*)(int, QProcess::ExitStatus)>(&QProcess::finished),
std::bind(&IosSimulatorToolHandlerPrivate::simAppProcessFinished,this, _1,_2));
QObject::connect(process, static_cast<void (QProcess::*)(QProcess::ProcessError)>(&QProcess::error),
std::bind(&IosSimulatorToolHandlerPrivate::simAppProcessError, this, _1));
appPId = pId;
gotInferiorPid(bundlePath,deviceId,pId);
// For debug run, wait for the debugger to attach and then launch the app.
if (!debugRun) {
launchAppOnSimulator();
}
} else {
errorMsg(IosToolHandler::tr("Spawning the Application process on Simulator failed."));
didStartApp(bundlePath, deviceId, Ios::IosToolHandler::Failure);
}
} else {
errorMsg(IosToolHandler::tr("Application launch on Simulator failed. Simulator not running.")
.arg(bundlePath));
didStartApp(bundlePath, deviceId, Ios::IosToolHandler::Failure);
}
}
void IosSimulatorToolHandlerPrivate::launchAppOnSimulator()
{
// Wait for the app to reach a state when we can launch it on the simulator.
if (appPId != -1 && SimulatorControl::waitForProcessSpawn(appPId)) {
QByteArray commandOutput;
Utils::FileName appBundle = Utils::FileName::fromString(bundlePath);
if (SimulatorControl::launchApp(deviceId, SimulatorControl::bundleIdentifier(appBundle), &commandOutput) != -1) {
appLaunched = true;
didStartApp(bundlePath, deviceId, Ios::IosToolHandler::Success);
} else {
errorMsg(IosToolHandler::tr("Application launch on Simulator failed. %1")
.arg(QString::fromLocal8Bit(commandOutput)));
didStartApp(bundlePath, deviceId, Ios::IosToolHandler::Failure);
}
} else {
errorMsg(IosToolHandler::tr("Spawning the Application process on Simulator failed. Spawning timed out."));
didStartApp(bundlePath, deviceId, Ios::IosToolHandler::Failure);
}
}
void IosSimulatorToolHandlerPrivate::requestDeviceInfo(const QString &deviceId, int timeout)
{
Q_UNUSED(timeout);
this->deviceId = deviceId;
QStringList args;
args << QLatin1String("showdevicetypes");
op = OpDeviceInfo;
start(IosToolHandler::iosSimulatorToolPath(), args);
Q_UNUSED(deviceId);
}
bool IosSimulatorToolHandlerPrivate::expectsFileDescriptor()
void IosSimulatorToolHandlerPrivate::stop(int errorCode)
{
return false;
}
void IosSimulatorToolHandlerPrivate::addDeviceArguments(QStringList &args) const
{
if (devType.type != IosDeviceType::SimulatedDevice) {
qCWarning(toolHandlerLog) << "IosSimulatorToolHandlerPrivate device type is not SimulatedDevice";
return;
if (process) {
if (isRunning()) {
process->terminate();
if (!process->waitForFinished(1000))
process->kill();
}
process->deleteLater();
process = nullptr;
appPId = -1;
appLaunched = false;
}
args << QLatin1String("--devicetypeid") << devType.identifier;
toolExited(errorCode);
}
void IosSimulatorToolHandlerPrivate::debuggerStateChanged(Debugger::DebuggerState state)
{
if (!appLaunched && state == Debugger::DebuggerState::InferiorRunOk) {
// Debugger attached. Launch it on the simulator.
launchAppOnSimulator();
}
}
void IosSimulatorToolHandlerPrivate::simAppProcessError(QProcess::ProcessError error)
{
errorMsg(IosToolHandler::tr("Simulator application process error %1").arg(error));
}
void IosSimulatorToolHandlerPrivate::simAppProcessFinished(int exitCode, QProcess::ExitStatus exitStatus)
{
stop((exitStatus == QProcess::NormalExit) ? exitCode : -1 );
qCDebug(toolHandlerLog) << "IosToolHandler::finished(" << this << ")";
q->finished(q);
}
void IosSimulatorToolHandlerPrivate::simAppProcessHasData()
{
appOutput(QString::fromLocal8Bit(process->readAllStandardOutput()));
}
void IosSimulatorToolHandlerPrivate::simAppProcessHasErrorOutput()
{
errorMsg(QString::fromLocal8Bit(process->readAllStandardError()));
}
void IosToolHandlerPrivate::killProcess()
@@ -731,18 +858,6 @@ QString IosToolHandler::iosDeviceToolPath()
return res;
}
QString IosToolHandler::iosSimulatorToolPath()
{
Utils::FileName devPath = Internal::IosConfigurations::developerPath();
bool version182 = devPath.appendPath(QLatin1String(
"Platforms/iPhoneSimulator.platform/Developer/Library/PrivateFrameworks/iPhoneSimulatorRemoteClient.framework"))
.exists();
QString res = Core::ICore::libexecPath() + QLatin1String("/ios/iossim");
if (version182)
res = res.append(QLatin1String("_1_8_2"));
return res;
}
IosToolHandler::IosToolHandler(const Internal::IosDeviceType &devType, QObject *parent) :
QObject(parent)
{
@@ -762,6 +877,11 @@ void IosToolHandler::stop()
d->stop(-1);
}
void IosToolHandler::debuggerStateChanged(int state)
{
d->debuggerStateChanged((Debugger::DebuggerState)state);
}
void IosToolHandler::requestTransferApp(const QString &bundlePath, const QString &deviceId,
int timeout)
{
@@ -784,24 +904,4 @@ bool IosToolHandler::isRunning()
return d->isRunning();
}
void IosToolHandler::subprocessError(QProcess::ProcessError error)
{
d->subprocessError(error);
}
void IosToolHandler::subprocessFinished(int exitCode, QProcess::ExitStatus exitStatus)
{
d->subprocessFinished(exitCode, exitStatus);
}
void IosToolHandler::subprocessHasData()
{
d->subprocessHasData();
}
void IosToolHandler::killProcess()
{
d->killProcess();
}
} // namespace Ios

View File

@@ -33,7 +33,6 @@
#include <QStringList>
#include <QProcess>
namespace Ios {
namespace Internal {
class IosToolHandlerPrivate;
@@ -56,7 +55,6 @@ public:
};
static QString iosDeviceToolPath();
static QString iosSimulatorToolPath();
explicit IosToolHandler(const Internal::IosDeviceType &type, QObject *parent = 0);
~IosToolHandler();
@@ -66,6 +64,7 @@ public:
void requestDeviceInfo(const QString &deviceId, int timeout = 1000);
bool isRunning();
void stop();
void debuggerStateChanged(int state);
signals:
void isTransferringApp(Ios::IosToolHandler *handler, const QString &bundlePath,
@@ -85,11 +84,10 @@ signals:
void errorMsg(Ios::IosToolHandler *handler, const QString &msg);
void toolExited(Ios::IosToolHandler *handler, int code);
void finished(Ios::IosToolHandler *handler);
private:
void subprocessError(QProcess::ProcessError error);
void subprocessFinished(int exitCode, QProcess::ExitStatus exitStatus);
void subprocessHasData();
protected:
void killProcess();
private:
friend class Ios::Internal::IosToolHandlerPrivate;
Ios::Internal::IosToolHandlerPrivate *d;

View File

@@ -0,0 +1,422 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#include "simulatorcontrol.h"
#include "iossimulator.h"
#include "iosconfigurations.h"
#ifdef Q_OS_MAC
#include <CoreFoundation/CoreFoundation.h>
#endif
#include <chrono>
#include <QJsonArray>
#include <QJsonDocument>
#include <QJsonObject>
#include <QLoggingCategory>
#include <QMap>
#include <QProcess>
#include <QReadLocker>
#include <QReadWriteLock>
#include <QTime>
#include <QUrl>
#include <QWriteLocker>
namespace {
Q_LOGGING_CATEGORY(simulatorLog, "qtc.ios.simulator")
}
namespace Ios {
namespace Internal {
static int COMMAND_TIMEOUT = 10000;
static int SIMULATOR_TIMEOUT = 60000;
static bool checkForTimeout(const std::chrono::time_point< std::chrono::high_resolution_clock, std::chrono::nanoseconds> &start, int msecs = COMMAND_TIMEOUT)
{
bool timedOut = false;
auto end = std::chrono::high_resolution_clock::now();
if (std::chrono::duration_cast<std::chrono::milliseconds>(end-start).count() > msecs)
timedOut = true;
return timedOut;
}
class SimulatorControlPrivate :QObject {
Q_OBJECT
private:
struct SimDeviceInfo {
bool isBooted() const { return state.compare(QStringLiteral("Booted")) == 0; }
bool isAvailable() const { return !availability.contains(QStringLiteral("unavailable")); }
QString name;
QString udid;
QString availability;
QString state;
QString sdk;
};
SimulatorControlPrivate(QObject *parent = nullptr);
~SimulatorControlPrivate();
QByteArray runSimCtlCommand(QStringList args) const;
SimDeviceInfo deviceInfo(const QString &simUdid) const;
bool runCommand(QString command, const QStringList &args, QByteArray *output = nullptr);
QHash<QString, QProcess*> simulatorProcesses;
QReadWriteLock processDataLock;
QList<IosDeviceType> availableDevices;
QReadWriteLock deviceDataLock;
friend class SimulatorControl;
};
SimulatorControlPrivate *SimulatorControl::d = new SimulatorControlPrivate;
SimulatorControl::SimulatorControl()
{
}
QList<Ios::Internal::IosDeviceType> SimulatorControl::availableSimulators()
{
QReadLocker locer(&d->deviceDataLock);
return d->availableDevices;
}
void SimulatorControl::updateAvailableSimulators()
{
const QByteArray output = d->runSimCtlCommand({QLatin1String("list"), QLatin1String("-j"), QLatin1String("devices")});
QJsonDocument doc = QJsonDocument::fromJson(output);
if (!doc.isNull()) {
QList<IosDeviceType> availableDevices;
const QJsonObject buildInfo = doc.object().value("devices").toObject();
foreach (const QString &buildVersion, buildInfo.keys()) {
QJsonArray devices = buildInfo.value(buildVersion).toArray();
foreach (const QJsonValue device, devices) {
QJsonObject deviceInfo = device.toObject();
QString deviceName = QString("%1, %2")
.arg(deviceInfo.value("name").toString("Unknown"))
.arg(buildVersion);
QString deviceUdid = deviceInfo.value("udid").toString("Unknown");
if (!deviceInfo.value("availability").toString().contains("unavailable")) {
IosDeviceType iOSDevice(IosDeviceType::SimulatedDevice, deviceUdid, deviceName);
availableDevices.append(iOSDevice);
}
}
}
std::stable_sort(availableDevices.begin(), availableDevices.end());
{
QWriteLocker locker(&d->deviceDataLock);
d->availableDevices = availableDevices;
}
} else {
qCDebug(simulatorLog) << "Error parsing json output from simctl. Output:" << output;
}
}
// Blocks until simulators reaches "Booted" state.
bool SimulatorControl::startSimulator(const QString &simUdid)
{
QWriteLocker locker(&d->processDataLock);
bool simulatorRunning = isSimulatorRunning(simUdid);
if (!simulatorRunning && d->deviceInfo(simUdid).isAvailable()) {
// Simulator is not running but it's available. Start the simulator.
QProcess *p = new QProcess;
QObject::connect(p, static_cast<void(QProcess::*)(int)>(&QProcess::finished), [simUdid]() {
QWriteLocker locker(&d->processDataLock);
d->simulatorProcesses[simUdid]->deleteLater();
d->simulatorProcesses.remove(simUdid);
});
const QString cmd = IosConfigurations::developerPath().appendPath(QStringLiteral("/Applications/Simulator.app")).toString();
const QStringList args({QStringLiteral("--args"), QStringLiteral("-CurrentDeviceUDID"), simUdid});
p->start(cmd, args);
if (p->waitForStarted()) {
d->simulatorProcesses[simUdid] = p;
// At this point the sim device exists, available and was not running.
// So the simulator is started and we'll wait for it to reach to a state
// where we can interact with it.
auto start = std::chrono::high_resolution_clock::now();
SimulatorControlPrivate::SimDeviceInfo info;
do {
info = d->deviceInfo(simUdid);
} while (!info.isBooted()
&& p->state() == QProcess::Running
&& !checkForTimeout(start, SIMULATOR_TIMEOUT));
simulatorRunning = info.isBooted();
} else {
qCDebug(simulatorLog) << "Error starting simulator." << p->errorString();
delete p;
}
}
return simulatorRunning;
}
bool SimulatorControl::isSimulatorRunning(const QString &simUdid)
{
if (simUdid.isEmpty())
return false;
return d->deviceInfo(simUdid).isBooted();
}
bool SimulatorControl::installApp(const QString &simUdid, const Utils::FileName &bundlePath, QByteArray &commandOutput)
{
bool installed = false;
if (isSimulatorRunning(simUdid)) {
commandOutput = d->runSimCtlCommand(QStringList() << QStringLiteral("install") << simUdid << bundlePath.toString());
installed = commandOutput.isEmpty();
} else {
commandOutput = "Simulator device not running.";
}
return installed;
}
qint64 SimulatorControl::launchApp(const QString &simUdid, const QString &bundleIdentifier, QByteArray* commandOutput)
{
qint64 pId = -1;
pId = -1;
if (!bundleIdentifier.isEmpty() && isSimulatorRunning(simUdid)) {
const QStringList args({QStringLiteral("launch"), simUdid , bundleIdentifier});
const QByteArray output = d->runSimCtlCommand(args);
const QByteArray pIdStr = output.trimmed().split(' ').last().trimmed();
bool validInt = false;
pId = pIdStr.toLongLong(&validInt);
if (!validInt) {
// Launch Failed.
qCDebug(simulatorLog) << "Launch app failed. Process id returned is not valid. PID =" << pIdStr;
pId = -1;
if (commandOutput)
*commandOutput = output;
}
}
return pId;
}
QString SimulatorControl::bundleIdentifier(const Utils::FileName &bundlePath)
{
QString bundleID;
#ifdef Q_OS_MAC
if (bundlePath.exists()) {
CFStringRef cFBundlePath = bundlePath.toString().toCFString();
CFURLRef bundle_url = CFURLCreateWithFileSystemPath (kCFAllocatorDefault, cFBundlePath, kCFURLPOSIXPathStyle, true);
CFRelease(cFBundlePath);
CFBundleRef bundle = CFBundleCreate (kCFAllocatorDefault, bundle_url);
CFRelease(bundle_url);
CFStringRef cFBundleID = CFBundleGetIdentifier(bundle);
bundleID = QString::fromCFString(cFBundleID).trimmed();
CFRelease(bundle);
}
#else
Q_UNUSED(bundlePath)
#endif
return bundleID;
}
QString SimulatorControl::bundleExecutable(const Utils::FileName &bundlePath)
{
QString executable;
#ifdef Q_OS_MAC
if (bundlePath.exists()) {
CFStringRef cFBundlePath = bundlePath.toString().toCFString();
CFURLRef bundle_url = CFURLCreateWithFileSystemPath (kCFAllocatorDefault, cFBundlePath, kCFURLPOSIXPathStyle, true);
CFRelease(cFBundlePath);
CFBundleRef bundle = CFBundleCreate (kCFAllocatorDefault, bundle_url);
CFStringRef cFStrExecutableName = (CFStringRef)CFBundleGetValueForInfoDictionaryKey(bundle, kCFBundleExecutableKey);
executable = QString::fromCFString(cFStrExecutableName).trimmed();
CFRelease(bundle);
}
#else
Q_UNUSED(bundlePath)
#endif
return executable;
}
SimulatorControlPrivate::SimulatorControlPrivate(QObject *parent):
QObject(parent),
processDataLock(QReadWriteLock::Recursive)
{
}
SimulatorControlPrivate::~SimulatorControlPrivate()
{
}
QByteArray SimulatorControlPrivate::runSimCtlCommand(QStringList args) const
{
QProcess simCtlProcess;
args.prepend(QStringLiteral("simctl"));
simCtlProcess.start(QStringLiteral("xcrun"), args, QProcess::ReadOnly);
if (!simCtlProcess.waitForFinished())
qCDebug(simulatorLog) << "simctl command failed." << simCtlProcess.errorString();
return simCtlProcess.readAll();
}
// The simctl spawns the process and returns the pId but the application process might not have started, at least in a state where you can interrupt it.
// Use SimulatorControl::waitForProcessSpawn to be sure.
QProcess *SimulatorControl::spawnAppProcess(const QString &simUdid, const Utils::FileName &bundlePath, qint64 &pId, bool waitForDebugger, const QStringList &extraArgs)
{
QProcess *simCtlProcess = nullptr;
if (isSimulatorRunning(simUdid)) {
QString bundleId = bundleIdentifier(bundlePath);
QString executableName = bundleExecutable(bundlePath);
QByteArray appPath = d->runSimCtlCommand(QStringList() << QStringLiteral("get_app_container") << simUdid << bundleId).trimmed();
if (!appPath.isEmpty() && !executableName.isEmpty()) {
// Spawn the app. The spawned app is started in suspended mode.
appPath.append('/' + executableName.toLocal8Bit());
simCtlProcess = new QProcess;
QStringList args;
args << QStringLiteral("simctl");
args << QStringLiteral("spawn");
if (waitForDebugger)
args << QStringLiteral("-w");
args << simUdid;
args << QString::fromLocal8Bit(appPath);
args << extraArgs;
simCtlProcess->start(QStringLiteral("xcrun"), args);
if (!simCtlProcess->waitForStarted()){
// Spawn command failed.
qCDebug(simulatorLog) << "Spawning the app failed." << simCtlProcess->errorString();
delete simCtlProcess;
simCtlProcess = nullptr;
}
// Find the process id of the the app process.
if (simCtlProcess) {
qint64 simctlPId = simCtlProcess->processId();
pId = -1;
QByteArray commandOutput;
QStringList pGrepArgs;
pGrepArgs << QStringLiteral("-f") << QString::fromLocal8Bit(appPath);
auto begin = std::chrono::high_resolution_clock::now();
// Find the pid of the spawned app.
while (pId == -1 && d->runCommand(QStringLiteral("pgrep"), pGrepArgs, &commandOutput)) {
foreach (auto pidStr, commandOutput.trimmed().split('\n')) {
qint64 parsedPId = pidStr.toLongLong();
if (parsedPId != simctlPId)
pId = parsedPId;
}
if (checkForTimeout(begin)) {
qCDebug(simulatorLog) << "Spawning the app failed. Process timed out";
break;
}
}
}
if (pId == -1) {
// App process id can't be found.
qCDebug(simulatorLog) << "Spawning the app failed. PID not found.";
delete simCtlProcess;
simCtlProcess = nullptr;
}
} else {
qCDebug(simulatorLog) << "Spawning the app failed. Check installed app." << appPath;
}
} else {
qCDebug(simulatorLog) << "Spawning the app failed. Simulator not running." << simUdid;
}
return simCtlProcess;
}
bool SimulatorControl::waitForProcessSpawn(qint64 processPId)
{
bool success = true;
if (processPId != -1) {
// Wait for app to reach intruptible sleep state.
QByteArray wqStr;
QStringList args;
int wqCount = -1;
args << QStringLiteral("-p") << QString::number(processPId) << QStringLiteral("-o") << QStringLiteral("wq=");
auto begin = std::chrono::high_resolution_clock::now();
do {
if (!d->runCommand(QStringLiteral("ps"), args, &wqStr)) {
success = false;
break;
}
bool validInt = false;
wqCount = wqStr.toInt(&validInt);
if (!validInt) {
wqCount = -1;
}
} while (wqCount < 0 && !checkForTimeout(begin));
success = wqCount >= 0;
} else {
qCDebug(simulatorLog) << "Wait for spawned failed. Invalid Process ID." << processPId;
}
return success;
}
SimulatorControlPrivate::SimDeviceInfo SimulatorControlPrivate::deviceInfo(const QString &simUdid) const
{
SimDeviceInfo info;
bool found = false;
if (!simUdid.isEmpty()) {
// It might happend that the simulator is not started by SimControl.
// Check of intances started externally.
const QByteArray output = runSimCtlCommand({QLatin1String("list"), QLatin1String("-j"), QLatin1String("devices")});
QJsonDocument doc = QJsonDocument::fromJson(output);
if (!doc.isNull()) {
const QJsonObject buildInfo = doc.object().value(QStringLiteral("devices")).toObject();
foreach (const QString &buildVersion, buildInfo.keys()) {
QJsonArray devices = buildInfo.value(buildVersion).toArray();
foreach (const QJsonValue device, devices) {
QJsonObject deviceInfo = device.toObject();
QString deviceUdid = deviceInfo.value(QStringLiteral("udid")).toString();
if (deviceUdid.compare(simUdid) == 0) {
found = true;
info.name = deviceInfo.value(QStringLiteral("name")).toString();
info.udid = deviceUdid;
info.state = deviceInfo.value(QStringLiteral("state")).toString();
info.sdk = buildVersion;
info.availability = deviceInfo.value(QStringLiteral("availability")).toString();
break;
}
}
if (found)
break;
}
} else {
qCDebug(simulatorLog) << "Cannot find device info. Error parsing json output from simctl. Output:" << output;
}
} else {
qCDebug(simulatorLog) << "Cannot find device info. Invalid UDID.";
}
return info;
}
bool SimulatorControlPrivate::runCommand(QString command, const QStringList &args, QByteArray *output)
{
bool success = false;
QProcess process;
process.start(command, args);
success = process.waitForFinished();
if (output)
*output = process.readAll().trimmed();
return success;
}
} // namespace Internal
} // namespace Ios
#include "simulatorcontrol.moc"

View File

@@ -0,0 +1,64 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#ifndef SIMULATORCONTROL_H
#define SIMULATORCONTROL_H
#include <QHash>
#include "utils/fileutils.h"
class QProcess;
namespace Ios {
namespace Internal {
class IosDeviceType;
class SimulatorControlPrivate;
class SimulatorControl
{
explicit SimulatorControl();
public:
static QList<IosDeviceType> availableSimulators();
static void updateAvailableSimulators();
static bool startSimulator(const QString &simUdid);
static bool isSimulatorRunning(const QString &simUdid);
static bool installApp(const QString &simUdid, const Utils::FileName &bundlePath, QByteArray &commandOutput);
static QProcess* spawnAppProcess(const QString &simUdid, const Utils::FileName &bundlePath, qint64 &pId,
bool waitForDebugger, const QStringList &extraArgs);
static qint64 launchApp(const QString &simUdid, const QString &bundleIdentifier, QByteArray *commandOutput = nullptr);
static QString bundleIdentifier(const Utils::FileName &bundlePath);
static QString bundleExecutable(const Utils::FileName &bundlePath);
static bool waitForProcessSpawn(qint64 processPId);
private:
static SimulatorControlPrivate *d;
};
} // namespace Internal
} // namespace Ios
#endif // SIMULATORCONTROL_H

View File

@@ -1,10 +1,3 @@
TEMPLATE = subdirs
mac {
SUBDIRS += \
iossim \
iossim_1_8_2
}
isEmpty(BUILD_CPLUSPLUS_TOOLS):BUILD_CPLUSPLUS_TOOLS=$$(BUILD_CPLUSPLUS_TOOLS)
!isEmpty(BUILD_CPLUSPLUS_TOOLS): SUBDIRS += cplusplus-keywordgen

View File

@@ -1,31 +0,0 @@
Author: Landon Fuller <landonf@plausiblelabs.com>
Copyright (c) 2008-2011 Plausible Labs Cooperative, Inc.
All rights reserved.
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
Modifications made by the following entities are licensed as above:
- Jeff Haynie, Appcelerator, Inc.
- https://github.com/hborders
- http://pivotallabs.com/users/scoward/blog
- Eloy Duran, Fingertips <eloy@fngtps.com>
- Fawzi Mohamed, digia <fawzi.mohamed@digia.com>

View File

@@ -1,16 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleExecutable</key>
<string>iossim</string>
<key>CFBundleIdentifier</key>
<string>org.qt-project.qt-creator.iossim</string>
<key>LSUIElement</key>
<string>1</string>
</dict>
</plist>

View File

@@ -1,450 +0,0 @@
//
// Generated by class-dump 3.5 (64 bit).
//
// class-dump is Copyright (C) 1997-1998, 2000-2001, 2004-2013 by Steve Nygard.
//
#pragma mark Function Pointers and Blocks
typedef void (*CDUnknownFunctionPointerType)(void); // return type and parameters are unknown
typedef void (^CDUnknownBlockType)(void); // return type and parameters are unknown
#pragma mark Named Structures
/*struct CGSize {
double width;
double height;
};*/
#pragma mark -
//
// File: $(DEVELOPER_DIR)/Library/PrivateFrameworks/CoreSimulator.framework/Versions/A/CoreSimulator
// UUID: C7A40E7B-B10C-3CB4-85F5-42071E2E5C4C
//
// Arch: x86_64
// Current version: 84.0.0
// Compatibility version: 1.0.0
// Source version: 84.0.0.0.0
// Minimum Mac OS X version: 10.9.0
// SDK version: 10.9.0
//
// Objective-C Garbage Collection: Unsupported
//
@protocol OS_dispatch_queue;
@protocol OS_xpc_object;
@protocol SimBridge;
@class SimDevice;
@class SimDeviceSet;
@class SimDeviceType;
@class SimRuntime;
@class SimDeviceNotificationManager;
@class SimServiceConnectionManager;
@protocol SimDeviceNotifier
- (BOOL)unregisterNotificationHandler:(unsigned long long)arg1 error:(id *)arg2;
- (unsigned long long)registerNotificationHandlerOnQueue:(NSObject<OS_dispatch_queue> *)arg1 handler:(void (^)(NSDictionary *))arg2;
- (unsigned long long)registerNotificationHandler:(void (^)(NSDictionary *))arg1;
@end
@interface NSArray (argv)
- (void)freeArgv:(char **)arg1;
- (char **)argv;
@end
@interface NSDictionary (envp)
- (void)freeEnvp:(char **)arg1;
- (char **)envp;
@end
@interface NSError (SimError)
+ (id)errorFromXPCDict:(id)arg1;
+ (id)errorWithSimErrno:(int)arg1 localizedDescription:(id)arg2;
+ (id)errorWithSimErrno:(int)arg1 userInfo:(id)arg2;
+ (id)errorWithSimErrno:(int)arg1;
- (id)xpcDict;
@end
@interface NSString (cputype)
+ (id)stringForCPUType:(int)arg1;
- (int)cputype;
@end
@interface NSUserDefaults (SimDefaults)
+ (id)simulatorDefaults;
@end
@interface SimDevice : NSObject <SimDeviceNotifier>
{
unsigned long long _state;
NSString *_name;
NSDictionary *_uiWindowProperties;
SimDeviceType *_deviceType;
SimRuntime *_runtime;
NSUUID *_UDID;
SimDeviceSet *_deviceSet;
SimServiceConnectionManager *_connectionManager;
NSString *_setPath;
SimDeviceNotificationManager *_notificationManager;
NSObject<OS_dispatch_queue> *_bootstrapQueue;
NSMutableDictionary *_registeredServices;
NSObject<OS_dispatch_queue> *_stateVariableQueue;
NSMachPort *_deathTriggerPort;
NSMachPort *_hostSupportPort;
NSMachPort *_simBridgePort;
NSDistantObject<SimBridge> *_simBridgeDistantObject;
}
+ (id)simDevice:(id)arg1 UDID:(id)arg2 deviceType:(id)arg3 runtime:(id)arg4 state:(unsigned long long)arg5 connectionManager:(id)arg6 setPath:(id)arg7;
+ (id)simDeviceAtPath:(id)arg1;
+ (id)createDeviceWithName:(id)arg1 setPath:(id)arg2 deviceType:(id)arg3 runtime:(id)arg4;
+ (BOOL)isValidState:(unsigned long long)arg1;
@property(retain, nonatomic) NSDistantObject<SimBridge> *simBridgeDistantObject; // @synthesize simBridgeDistantObject=_simBridgeDistantObject;
@property(retain, nonatomic) NSMachPort *simBridgePort; // @synthesize simBridgePort=_simBridgePort;
@property(retain, nonatomic) NSMachPort *hostSupportPort; // @synthesize hostSupportPort=_hostSupportPort;
@property(retain) NSMachPort *deathTriggerPort; // @synthesize deathTriggerPort=_deathTriggerPort;
@property(retain) NSObject<OS_dispatch_queue> *stateVariableQueue; // @synthesize stateVariableQueue=_stateVariableQueue;
@property(retain) NSMutableDictionary *registeredServices; // @synthesize registeredServices=_registeredServices;
@property(retain) NSObject<OS_dispatch_queue> *bootstrapQueue; // @synthesize bootstrapQueue=_bootstrapQueue;
@property(retain) SimDeviceNotificationManager *notificationManager; // @synthesize notificationManager=_notificationManager;
@property(copy) NSString *setPath; // @synthesize setPath=_setPath;
@property(retain) SimServiceConnectionManager *connectionManager; // @synthesize connectionManager=_connectionManager;
@property(readonly) SimDeviceSet *deviceSet; // @synthesize deviceSet=_deviceSet;
@property(copy) NSUUID *UDID; // @synthesize UDID=_UDID;
@property(retain) SimRuntime *runtime; // @synthesize runtime=_runtime;
@property(retain) SimDeviceType *deviceType; // @synthesize deviceType=_deviceType;
//- (void).cxx_destruct;
- (BOOL)isAvailableWithError:(id *)arg1;
@property(readonly) BOOL available;
- (int)launchApplicationWithID:(id)arg1 options:(id)arg2 error:(id *)arg3;
- (void)launchApplicationAsyncWithID:(id)arg1 options:(id)arg2 completionHandler:(CDUnknownBlockType)arg3;
- (id)installedAppsWithError:(id *)arg1;
- (BOOL)applicationIsInstalled:(id)arg1 type:(id *)arg2 error:(id *)arg3;
- (BOOL)uninstallApplication:(id)arg1 withOptions:(id)arg2 error:(id *)arg3;
- (BOOL)installApplication:(id)arg1 withOptions:(id)arg2 error:(id *)arg3;
- (BOOL)setKeyboardLanguage:(id)arg1 error:(id *)arg2;
- (BOOL)addPhoto:(id)arg1 error:(id *)arg2;
- (BOOL)openURL:(id)arg1 error:(id *)arg2;
- (void)simBridgeSync:(CDUnknownBlockType)arg1;
- (void)simBridgeAsync:(CDUnknownBlockType)arg1;
- (void)simBridgeCommon:(CDUnknownBlockType)arg1;
- (long long)compare:(id)arg1;
- (id)newDeviceNotification;
- (id)createXPCNotification:(const char *)arg1;
- (id)createXPCRequest:(const char *)arg1;
- (void)handleXPCRequestSpawn:(id)arg1 peer:(id)arg2;
- (void)handleXPCRequestGetenv:(id)arg1 peer:(id)arg2;
- (void)handleXPCRequestLookup:(id)arg1 peer:(id)arg2;
- (void)handleXPCRequestRegister:(id)arg1 peer:(id)arg2;
- (void)handleXPCRequestRestore:(id)arg1 peer:(id)arg2;
- (void)handleXPCRequestUpdateUIWindow:(id)arg1 peer:(id)arg2;
- (void)handleXPCRequestErase:(id)arg1 peer:(id)arg2;
- (void)handleXPCRequestUpgrade:(id)arg1 peer:(id)arg2;
- (void)handleXPCRequestShutdown:(id)arg1 peer:(id)arg2;
- (void)handleXPCRequestBoot:(id)arg1 peer:(id)arg2;
- (void)handleXPCRequestRename:(id)arg1 peer:(id)arg2;
- (void)handleXPCRequest:(id)arg1 peer:(id)arg2;
- (void)handleXPCNotificationDeviceUIWindowPropertiesChanged:(id)arg1;
- (void)handleXPCNotificationDeviceRenamed:(id)arg1;
- (void)handleXPCNotificationDeviceStateChanged:(id)arg1;
- (void)handleXPCNotification:(id)arg1;
@property(copy) NSDictionary *uiWindowProperties;
@property(copy) NSString *name;
@property unsigned long long state;
- (id)stateString;
- (BOOL)unregisterNotificationHandler:(unsigned long long)arg1 error:(id *)arg2;
- (unsigned long long)registerNotificationHandlerOnQueue:(id)arg1 handler:(CDUnknownBlockType)arg2;
- (unsigned long long)registerNotificationHandler:(CDUnknownBlockType)arg1;
- (void)simulateMemoryWarning;
- (id)memoryWarningFilePath;
@property(readonly, copy) NSString *logPath;
- (id)dataPath;
- (id)devicePath;
- (id)environment;
- (int)_spawnFromSelfWithPath:(id)arg1 options:(id)arg2 terminationHandler:(CDUnknownBlockType)arg3 error:(id *)arg4;
- (int)_spawnFromLaunchdWithPath:(id)arg1 options:(id)arg2 terminationHandler:(CDUnknownBlockType)arg3 error:(id *)arg4;
- (int)spawnWithPath:(id)arg1 options:(id)arg2 terminationHandler:(CDUnknownBlockType)arg3 error:(id *)arg4;
- (void)spawnAsyncWithPath:(id)arg1 options:(id)arg2 terminationHandler:(CDUnknownBlockType)arg3 completionHandler:(CDUnknownBlockType)arg4;
- (BOOL)registerPort:(unsigned int)arg1 service:(id)arg2 error:(id *)arg3;
- (unsigned int)lookup:(id)arg1 error:(id *)arg2;
- (unsigned int)_lookup:(id)arg1 error:(id *)arg2;
- (id)getenv:(id)arg1 error:(id *)arg2;
- (BOOL)restoreContentsAndSettingsFromDevice:(id)arg1 error:(id *)arg2;
- (void)restoreContentsAndSettingsAsyncFromDevice:(id)arg1 completionHandler:(CDUnknownBlockType)arg2;
- (BOOL)updateUIWindowProperties:(id)arg1 error:(id *)arg2;
- (void)updateAsyncUIWindowProperties:(id)arg1 completionHandler:(CDUnknownBlockType)arg2;
- (void)_sendUIWindowPropertiesToDevice;
- (BOOL)eraseContentsAndSettingsWithError:(id *)arg1;
- (void)eraseContentsAndSettingsAsyncWithCompletionHandler:(CDUnknownBlockType)arg1;
- (BOOL)upgradeToRuntime:(id)arg1 error:(id *)arg2;
- (void)upgradeAsyncToRuntime:(id)arg1 completionHandler:(CDUnknownBlockType)arg2;
- (BOOL)rename:(id)arg1 error:(id *)arg2;
- (void)renameAsync:(id)arg1 completionHandler:(CDUnknownBlockType)arg2;
- (BOOL)shutdownWithError:(id *)arg1;
- (BOOL)_shutdownWithError:(id *)arg1;
- (void)shutdownAsyncWithCompletionHandler:(CDUnknownBlockType)arg1;
- (BOOL)bootWithOptions:(id)arg1 error:(id *)arg2;
- (void)bootAsyncWithOptions:(id)arg1 completionHandler:(CDUnknownBlockType)arg2;
- (void)launchdDeathHandlerWithDeathPort:(id)arg1;
- (BOOL)startLaunchdWithDeathPort:(id)arg1 deathHandler:(CDUnknownBlockType)arg2 error:(id *)arg3;
- (void)registerPortsWithLaunchd;
@property(readonly) NSArray *launchDaemonsPaths;
- (BOOL)removeLaunchdJobWithError:(id *)arg1;
- (BOOL)createLaunchdJobWithError:(id *)arg1 extraEnvironment:(id)arg2;
- (BOOL)clearTmpWithError:(id *)arg1;
- (BOOL)ensureLogPathsWithError:(id *)arg1;
- (BOOL)supportsFeature:(id)arg1;
@property(readonly, copy) NSString *launchdJobName;
- (void)saveToDisk;
- (id)saveStateDict;
- (void)validateAndFixState;
@property(readonly, copy) NSString *descriptiveName;
- (id)description;
- (void)dealloc;
- (id)initDevice:(id)arg1 UDID:(id)arg2 deviceType:(id)arg3 runtime:(id)arg4 state:(unsigned long long)arg5 connectionManager:(id)arg6 setPath:(id)arg7;
@end
@interface SimDeviceNotificationManager : NSObject <SimDeviceNotifier>
{
NSObject<OS_dispatch_queue> *_handlersQueue;
NSMutableDictionary *_handlers;
unsigned long long _next_regID;
NSObject<OS_dispatch_queue> *_sendQueue;
}
@property(retain) NSObject<OS_dispatch_queue> *sendQueue; // @synthesize sendQueue=_sendQueue;
@property unsigned long long next_regID; // @synthesize next_regID=_next_regID;
@property(retain) NSMutableDictionary *handlers; // @synthesize handlers=_handlers;
@property(retain) NSObject<OS_dispatch_queue> *handlersQueue; // @synthesize handlersQueue=_handlersQueue;
//- (void).cxx_destruct;
- (void)sendNotification:(id)arg1;
- (BOOL)unregisterNotificationHandler:(unsigned long long)arg1 error:(id *)arg2;
- (unsigned long long)registerNotificationHandlerOnQueue:(id)arg1 handler:(CDUnknownBlockType)arg2;
- (unsigned long long)registerNotificationHandler:(CDUnknownBlockType)arg1;
- (void)dealloc;
- (id)init;
@end
@interface SimDeviceSet : NSObject <SimDeviceNotifier>
{
NSString *_setPath;
NSObject<OS_dispatch_queue> *_devicesQueue;
NSMutableDictionary *__devicesByUDID;
NSMutableDictionary *_devicesNotificationRegIDs;
SimServiceConnectionManager *_connectionManager;
SimDeviceNotificationManager *_notificationManager;
}
+ (id)setForSetPath:(id)arg1;
+ (id)defaultSet;
+ (id)defaultSetPath;
@property(retain) SimDeviceNotificationManager *notificationManager; // @synthesize notificationManager=_notificationManager;
@property(retain) SimServiceConnectionManager *connectionManager; // @synthesize connectionManager=_connectionManager;
@property(retain) NSMutableDictionary *devicesNotificationRegIDs; // @synthesize devicesNotificationRegIDs=_devicesNotificationRegIDs;
@property(retain) NSMutableDictionary *_devicesByUDID; // @synthesize _devicesByUDID=__devicesByUDID;
@property(retain) NSObject<OS_dispatch_queue> *devicesQueue; // @synthesize devicesQueue=_devicesQueue;
@property(copy) NSString *setPath; // @synthesize setPath=_setPath;
//- (void).cxx_destruct;
- (void)handleXPCRequestDeleteDevice:(id)arg1 peer:(id)arg2 device:(id)arg3;
- (void)handleXPCRequestCreateDevice:(id)arg1 peer:(id)arg2;
- (void)handleXPCRequest:(id)arg1 peer:(id)arg2;
- (void)handleXPCNotificationDeviceRemoved:(id)arg1;
- (void)handleXPCNotificationDeviceAdded:(id)arg1;
- (void)handleXPCNotification:(id)arg1;
- (BOOL)deleteDevice:(id)arg1 error:(id *)arg2;
- (void)deleteDeviceAsync:(id)arg1 completionHandler:(CDUnknownBlockType)arg2;
- (id)createDeviceWithType:(id)arg1 runtime:(id)arg2 name:(id)arg3 error:(id *)arg4;
- (void)createDeviceAsyncWithType:(id)arg1 runtime:(id)arg2 name:(id)arg3 completionHandler:(CDUnknownBlockType)arg4;
- (BOOL)unregisterNotificationHandler:(unsigned long long)arg1 error:(id *)arg2;
- (unsigned long long)registerNotificationHandlerOnQueue:(id)arg1 handler:(CDUnknownBlockType)arg2;
- (unsigned long long)registerNotificationHandler:(CDUnknownBlockType)arg1;
- (void)removeDeviceAsync:(id)arg1;
- (void)addDevice:(id)arg1;
- (void)addDeviceAsync:(id)arg1;
- (void)updateDefaultDevices;
- (id)defaultCreatedPlistPath;
@property(readonly, copy) NSArray *availableDevices;
@property(readonly, copy) NSArray *devices;
@property(readonly, copy) NSDictionary *devicesByUDID;
- (id)description;
- (void)dealloc;
- (id)initWithSetPath:(id)arg1;
@end
@interface SimDeviceType : NSObject
{
float _mainScreenScale;
unsigned int _minRuntimeVersion;
unsigned int _maxRuntimeVersion;
NSString *_name;
NSString *_identifier;
NSString *_modelIdentifier;
NSBundle *_bundle;
NSArray *_supportedArchs;
NSArray *_supportedProductFamilyIDs;
NSDictionary *_capabilities;
NSString *_springBoardConfigName;
NSString *_productClass;
NSDictionary *_environment_extra;
NSDictionary *_aliases;
NSDictionary *_supportedFeatures;
NSDictionary *_supportedFeaturesConditionalOnRuntime;
struct CGSize _mainScreenSize;
struct CGSize _mainScreenDPI;
}
+ (id)supportedDeviceTypesByName;
+ (id)supportedDeviceTypesByAlias;
+ (id)supportedDeviceTypesByIdentifier;
+ (id)supportedDeviceTypes;
+ (id)supportedDevices;
@property(copy) NSDictionary *supportedFeaturesConditionalOnRuntime; // @synthesize supportedFeaturesConditionalOnRuntime=_supportedFeaturesConditionalOnRuntime;
@property(copy) NSDictionary *supportedFeatures; // @synthesize supportedFeatures=_supportedFeatures;
@property(copy) NSDictionary *aliases; // @synthesize aliases=_aliases;
@property(copy) NSDictionary *environment_extra; // @synthesize environment_extra=_environment_extra;
@property(copy) NSString *productClass; // @synthesize productClass=_productClass;
@property(copy) NSString *springBoardConfigName; // @synthesize springBoardConfigName=_springBoardConfigName;
@property unsigned int maxRuntimeVersion; // @synthesize maxRuntimeVersion=_maxRuntimeVersion;
@property unsigned int minRuntimeVersion; // @synthesize minRuntimeVersion=_minRuntimeVersion;
@property struct CGSize mainScreenDPI; // @synthesize mainScreenDPI=_mainScreenDPI;
@property struct CGSize mainScreenSize; // @synthesize mainScreenSize=_mainScreenSize;
@property(copy) NSDictionary *capabilities; // @synthesize capabilities=_capabilities;
@property float mainScreenScale; // @synthesize mainScreenScale=_mainScreenScale;
@property(copy) NSArray *supportedProductFamilyIDs; // @synthesize supportedProductFamilyIDs=_supportedProductFamilyIDs;
@property(copy) NSArray *supportedArchs; // @synthesize supportedArchs=_supportedArchs;
@property(retain) NSBundle *bundle; // @synthesize bundle=_bundle;
@property(copy) NSString *modelIdentifier; // @synthesize modelIdentifier=_modelIdentifier;
@property(copy) NSString *identifier; // @synthesize identifier=_identifier;
@property(copy) NSString *name; // @synthesize name=_name;
//- (void).cxx_destruct;
- (Class)deviceClass;
- (long long)compare:(id)arg1;
- (BOOL)supportsFeatureConditionally:(id)arg1;
- (BOOL)supportsFeature:(id)arg1;
- (id)environmentForRuntime:(id)arg1;
- (id)environment;
@property(readonly, copy) NSString *productFamily;
@property(readonly) int productFamilyID;
- (id)description;
- (void)dealloc;
- (id)initWithBundle:(id)arg1;
- (id)initWithPath:(id)arg1;
- (id)init;
@end
@interface SimRuntime : NSObject
{
unsigned int _version;
unsigned int _minHostVersion;
unsigned int _maxHostVersion;
NSString *_name;
NSString *_identifier;
NSBundle *_bundle;
NSString *_root;
NSString *_versionString;
NSString *_buildVersionString;
NSDictionary *_supportedFeatures;
NSDictionary *_supportedFeaturesConditionalOnDeviceType;
NSDictionary *_requiredHostServices;
NSString *_platformPath;
NSArray *_supportedProductFamilyIDs;
NSDictionary *_environment_extra;
void *_libLaunchHostHandle;
NSDictionary *_aliases;
}
+ (id)supportedRuntimesByAlias;
+ (id)supportedRuntimesByIdentifier;
+ (id)supportedRuntimes;
@property unsigned int maxHostVersion; // @synthesize maxHostVersion=_maxHostVersion;
@property unsigned int minHostVersion; // @synthesize minHostVersion=_minHostVersion;
@property(copy) NSDictionary *aliases; // @synthesize aliases=_aliases;
@property(nonatomic) void *libLaunchHostHandle; // @synthesize libLaunchHostHandle=_libLaunchHostHandle;
@property(copy) NSDictionary *environment_extra; // @synthesize environment_extra=_environment_extra;
@property(copy) NSArray *supportedProductFamilyIDs; // @synthesize supportedProductFamilyIDs=_supportedProductFamilyIDs;
@property(copy) NSString *platformPath; // @synthesize platformPath=_platformPath;
@property(copy) NSDictionary *requiredHostServices; // @synthesize requiredHostServices=_requiredHostServices;
@property(copy) NSDictionary *supportedFeaturesConditionalOnDeviceType; // @synthesize supportedFeaturesConditionalOnDeviceType=_supportedFeaturesConditionalOnDeviceType;
@property(copy) NSDictionary *supportedFeatures; // @synthesize supportedFeatures=_supportedFeatures;
@property unsigned int version; // @synthesize version=_version;
@property(copy) NSString *buildVersionString; // @synthesize buildVersionString=_buildVersionString;
@property(copy) NSString *versionString; // @synthesize versionString=_versionString;
@property(copy) NSString *root; // @synthesize root=_root;
@property(retain) NSBundle *bundle; // @synthesize bundle=_bundle;
@property(copy) NSString *identifier; // @synthesize identifier=_identifier;
@property(copy) NSString *name; // @synthesize name=_name;
//- (void).cxx_destruct;
- (id)platformRuntimeOverlay;
- (CDUnknownFunctionPointerType)launch_sim_set_death_handler;
- (CDUnknownFunctionPointerType)launch_sim_waitpid;
- (CDUnknownFunctionPointerType)launch_sim_spawn;
- (CDUnknownFunctionPointerType)launch_sim_getenv;
- (CDUnknownFunctionPointerType)launch_sim_bind_session_to_port;
- (CDUnknownFunctionPointerType)launch_sim_find_endpoint;
- (CDUnknownFunctionPointerType)launch_sim_register_endpoint;
- (BOOL)isAvailableWithError:(id *)arg1;
@property(readonly) BOOL available;
- (BOOL)verifyRuntime;
- (id)dyld_simPath;
- (BOOL)createInitialContentPath:(id)arg1 error:(id *)arg2;
- (void)createInitialContentPath:(id)arg1;
- (id)sampleContentPath;
- (long long)compare:(id)arg1;
- (BOOL)supportsFeatureConditionally:(id)arg1;
- (BOOL)supportsFeature:(id)arg1;
- (BOOL)supportsDeviceType:(id)arg1;
- (BOOL)supportsDevice:(id)arg1;
- (id)environment;
- (id)description;
- (void)dealloc;
- (id)initWithBundle:(id)arg1;
- (id)initWithPath:(id)arg1;
- (id)init;
@end
@interface SimServiceConnectionManager : NSObject
{
NSObject<OS_xpc_object> *_serviceConnection;
NSObject<OS_dispatch_queue> *_serviceConnectionQueue;
NSDate *_lastConnectionTime;
}
+ (void)useService:(BOOL)arg1;
+ (id)sharedConnectionManager;
@property(retain) NSDate *lastConnectionTime; // @synthesize lastConnectionTime=_lastConnectionTime;
@property(retain) NSObject<OS_dispatch_queue> *serviceConnectionQueue; // @synthesize serviceConnectionQueue=_serviceConnectionQueue;
@property(retain) NSObject<OS_xpc_object> *serviceConnection; // @synthesize serviceConnection=_serviceConnection;
//- (void).cxx_destruct;
- (void)handleXPCEvent:(id)arg1;
- (void)dealloc;
- (BOOL)connect;
- (id)init;
@end
@interface SimVerifier : NSObject
{
NSObject<OS_xpc_object> *_serviceConnection;
NSObject<OS_dispatch_queue> *_serviceConnectionQueue;
}
+ (id)verificationError:(int)arg1;
+ (id)connectionError;
+ (id)sharedVerifier;
@property(retain) NSObject<OS_dispatch_queue> *serviceConnectionQueue; // @synthesize serviceConnectionQueue=_serviceConnectionQueue;
@property(retain) NSObject<OS_xpc_object> *serviceConnection; // @synthesize serviceConnection=_serviceConnection;
//- (void).cxx_destruct;
- (id)verifyDyldSim:(id)arg1;
- (id)verifyAll;
- (BOOL)verifyAllWithError:(id *)arg1;
- (void)dealloc;
- (id)init;
@end

View File

@@ -1,295 +0,0 @@
#import "../coresimulator/coresimulator.h"
//
// Generated by class-dump 3.5 (64 bit).
//
// class-dump is Copyright (C) 1997-1998, 2000-2001, 2004-2013 by Steve Nygard.
//
#pragma mark Blocks
typedef void (^CDUnknownBlockType)(void); // return type and parameters are unknown
#pragma mark -
//
// File: $(DEVELOPER_DIR)/Platforms/iPhoneSimulator.platform/Developer/Library/PrivateFrameworks/DVTiPhoneSimulatorRemoteClient.framework/Versions/A/DVTiPhoneSimulatorRemoteClient
//
// Arch: x86_64
// Current version: 12.0.0
// Compatibility version: 1.0.0
// Source version: 5037.3.0.0.0
// Minimum Mac OS X version: 10.8.0
// SDK version: 10.9.0
//
// Objective-C Garbage Collection: Unsupported
//
// Run path: @loader_path/../../../../PrivateFrameworks/
// = $(DEVELOPER_DIR)/Platforms/iPhoneSimulator.platform/Developer/Library/PrivateFrameworks
//
@class DTiPhoneSimulatorApplicationSpecifier;
@class DTiPhoneSimulatorSession;
@class DTiPhoneSimulatorSessionConfig;
@class DTiPhoneSimulatorSystemRoot;
@class DVTiPhoneSimulatorMessenger;
@protocol DTiPhoneSimulatorSessionDelegate
- (void) session: (DTiPhoneSimulatorSession *) session didEndWithError: (NSError *) error;
- (void) session: (DTiPhoneSimulatorSession *) session didStart: (BOOL) started withError: (NSError *) error;
@end
@protocol OS_dispatch_source
@end
@protocol OS_dispatch_queue
@end
@class DVTDispatchLock;
@class DVTConfinementServiceConnection;
@class DVTTask;
@interface DVTiPhoneSimulatorMessenger : NSObject
{
DTiPhoneSimulatorSession *_session;
CDUnknownBlockType _readyMessageHandler;
CDUnknownBlockType _runningMessageHandler;
CDUnknownBlockType _appDidLaunchMessageHandler;
CDUnknownBlockType _appDidQuitMessageHandler;
CDUnknownBlockType _appPIDExitedMessageHandler;
CDUnknownBlockType _toolDidLaunchMessageHandler;
}
+ (id)messengerForSession:(id)arg1 withConnection:(id)arg2;
+ (id)messengerForSession:(id)arg1;
@property(copy, nonatomic) CDUnknownBlockType toolDidLaunchMessageHandler; // @synthesize toolDidLaunchMessageHandler=_toolDidLaunchMessageHandler;
@property(copy, nonatomic) CDUnknownBlockType appPIDExitedMessageHandler; // @synthesize appPIDExitedMessageHandler=_appPIDExitedMessageHandler;
@property(copy, nonatomic) CDUnknownBlockType appDidQuitMessageHandler; // @synthesize appDidQuitMessageHandler=_appDidQuitMessageHandler;
@property(copy, nonatomic) CDUnknownBlockType appDidLaunchMessageHandler; // @synthesize appDidLaunchMessageHandler=_appDidLaunchMessageHandler;
@property(copy, nonatomic) CDUnknownBlockType runningMessageHandler; // @synthesize runningMessageHandler=_runningMessageHandler;
@property(copy, nonatomic) CDUnknownBlockType readyMessageHandler; // @synthesize readyMessageHandler=_readyMessageHandler;
@property(readonly) DTiPhoneSimulatorSession *session; // @synthesize session=_session;
- (void)doUbiquityFetchEvent;
- (void)doFetchEventForPID:(int)arg1;
- (void)backgroundAllApps:(int)arg1;
- (void)startSimulatorToolSessionWithParameters:(id)arg1;
- (void)stopSimulatingLocation;
- (void)startSimulatingLocationWithLatitude:(id)arg1 longitute:(id)arg2;
- (void)endSimulatorSessionWithPID:(int)arg1;
- (void)startSimulatorSessionWithRequestInfo:(id)arg1;
- (void)clearAllMessageHandlers;
- (void)waitPID:(int)arg1 withAppPIDExitedMessagedHandler:(CDUnknownBlockType)arg2;
- (void)disconnectFromService;
- (BOOL)connectToServiceWithSessionOnLaunch:(BOOL)arg1 simulatorPID:(int *)arg2 error:(id *)arg3;
- (id)initWithSession:(id)arg1;
@end
@interface DVTiPhoneSimulatorLocalMessenger : DVTiPhoneSimulatorMessenger
{
BOOL _appTerminationMessageSent;
NSObject<OS_dispatch_source> *_pidDispatchSource;
DVTTask *_simTask;
}
- (void)doUbiquityFetchEvent;
- (void)doFetchEventForPID:(int)arg1;
- (void)backgroundAllApps:(int)arg1;
- (void)_handleSimulatorToolDidLaunchMessage:(id)arg1;
- (void)setToolDidLaunchMessageHandler:(CDUnknownBlockType)arg1;
- (void)waitPID:(int)arg1 withAppPIDExitedMessagedHandler:(CDUnknownBlockType)arg2;
- (void)_handleSimulatorAppDidQuitMessage:(id)arg1;
- (void)setAppDidQuitMessageHandler:(CDUnknownBlockType)arg1;
- (void)_handleSimulatorAppDidLaunchMessage:(id)arg1;
- (void)setAppDidLaunchMessageHandler:(CDUnknownBlockType)arg1;
- (void)_handleSimulatorRunningMessage:(id)arg1;
- (void)setRunningMessageHandler:(CDUnknownBlockType)arg1;
- (void)_handleSimulatorReadyMessage:(id)arg1;
- (void)setReadyMessageHandler:(CDUnknownBlockType)arg1;
- (void)startSimulatorToolSessionWithParameters:(id)arg1;
- (void)stopSimulatingLocation;
- (void)startSimulatingLocationWithLatitude:(id)arg1 longitute:(id)arg2;
- (void)endSimulatorSessionWithPID:(int)arg1;
- (void)startSimulatorSessionWithRequestInfo:(id)arg1;
- (void)clearAllMessageHandlers;
- (void)disconnectFromService;
- (BOOL)connectToServiceWithSessionOnLaunch:(BOOL)arg1 simulatorPID:(int *)arg2 error:(id *)arg3;
- (void)_enableObserver:(BOOL)arg1 forName:(id)arg2 selector:(SEL)arg3;
@end
@interface DVTiPhoneSimulatorRemoteMessenger : DVTiPhoneSimulatorMessenger
{
unsigned long long _commandTag;
NSObject<OS_dispatch_queue> *_responseQueue;
DVTDispatchLock *_awaitingLock;
NSMutableDictionary *_awaitingSemaphores;
NSMutableDictionary *_awaitingResponses;
NSMutableSet *_waitingAppPIDs;
DVTConfinementServiceConnection *_connection;
}
@property(readonly) DVTConfinementServiceConnection *connection; // @synthesize connection=_connection;
- (void)handleNotificationResponse:(id)arg1;
- (void)waitPID:(int)arg1 withAppPIDExitedMessagedHandler:(CDUnknownBlockType)arg2;
- (void)startSimulatorToolSessionWithParameters:(id)arg1;
- (void)stopSimulatingLocation;
- (void)startSimulatingLocationWithLatitude:(id)arg1 longitute:(id)arg2;
- (void)endSimulatorSessionWithPID:(int)arg1;
- (void)startSimulatorSessionWithRequestInfo:(id)arg1;
- (void)disconnectFromService;
- (BOOL)connectToServiceWithSessionOnLaunch:(BOOL)arg1 simulatorPID:(int *)arg2 error:(id *)arg3;
- (BOOL)sendTaggedRequest:(id)arg1 awaitingResponse:(id *)arg2 error:(id *)arg3;
- (id)nextCommandTag;
- (id)awaitResponseWithTag:(id)arg1 error:(id *)arg2;
- (void)enqueueResponse:(id)arg1 withTag:(id)arg2 error:(id)arg3;
- (BOOL)sendRequest:(id)arg1 withTag:(id)arg2 error:(id *)arg3;
- (id)initWithSession:(id)arg1 connection:(id)arg2;
@end
@interface DTiPhoneSimulatorSession : NSObject
{
int _simulatedApplicationPID;
int _simulatorPID;
NSString *_uuid;
id <DTiPhoneSimulatorSessionDelegate> _delegate;
NSString *_simulatedAppPath;
long long _sessionLifecycleProgress;
NSTimer *_timeoutTimer;
DTiPhoneSimulatorSessionConfig *_sessionConfig;
DVTiPhoneSimulatorMessenger *_messenger;
}
@property(retain) DVTiPhoneSimulatorMessenger *messenger; // @synthesize messenger=_messenger;
@property(copy, nonatomic) DTiPhoneSimulatorSessionConfig *sessionConfig; // @synthesize sessionConfig=_sessionConfig;
@property(retain, nonatomic) NSTimer *timeoutTimer; // @synthesize timeoutTimer=_timeoutTimer;
@property(nonatomic) long long sessionLifecycleProgress; // @synthesize sessionLifecycleProgress=_sessionLifecycleProgress;
@property int simulatorPID; // @synthesize simulatorPID=_simulatorPID;
@property(copy) NSString *simulatedAppPath; // @synthesize simulatedAppPath=_simulatedAppPath;
@property int simulatedApplicationPID; // @synthesize simulatedApplicationPID=_simulatedApplicationPID;
@property(retain, nonatomic) id <DTiPhoneSimulatorSessionDelegate> delegate; // @synthesize delegate=_delegate;
@property(copy, nonatomic) NSString *uuid; // @synthesize uuid=_uuid;
- (void)doUbiquityFetchEvent;
- (void)doFetchEventForPID:(int)arg1;
- (void)backgroundAllApps:(int)arg1;
- (id)_invalidConfigError;
- (void)_endSimulatorSession;
- (void)_callDelegateResponseFromSessionEndedInfo:(id)arg1;
- (void)_callDelegateResponseFromSessionStartedInfo:(id)arg1;
- (id)_sessionStartRequestInfoFromConfig:(id)arg1 withError:(id *)arg2;
- (BOOL)_startToolSessionInSimulatorWithError:(id *)arg1;
- (BOOL)_startApplicationSessionInSimulatorWithError:(id *)arg1;
- (BOOL)_startBasicSessionInSimulatorWithError:(id *)arg1;
- (BOOL)_startSessionInSimulatorWithError:(id *)arg1;
- (BOOL)_handleSessionEndedInSimulator:(id)arg1 notification:(id)arg2;
- (void)_handleSessionStartedWithSim:(id)arg1;
- (void)_handleSessionStartedInSimulator:(id)arg1;
- (void)_handleSimulatorReadyMessage:(id)arg1;
- (void)_timeoutElapsed:(id)arg1;
- (BOOL)attachedToTargetWithConfig:(id)arg1 error:(id *)arg2;
- (void)stopLocationSimulation;
- (void)simulateLocationWithLatitude:(id)arg1 longitude:(id)arg2;
- (void)requestEndWithTimeout:(double)arg1;
- (BOOL)requestStartWithConfig:(id)arg1 timeout:(double)arg2 error:(id *)arg3;
- (BOOL)_setUpSimulatorMessengerWithConfig:(id)arg1 error:(id *)arg2;
- (id)description;
- (void)dealloc;
- (id)init;
@end
@interface DTiPhoneSimulatorSessionConfig : NSObject <NSCopying>
{
BOOL _launchForBackgroundFetch;
BOOL _simulatedApplicationShouldWaitForDebugger;
NSString *_localizedClientName;
DTiPhoneSimulatorSystemRoot *_simulatedSystemRoot;
NSString *_simulatedDeviceInfoName;
NSNumber *_simulatedDeviceFamily;
NSString *_simulatedArchitecture;
NSNumber *_simulatedDisplayHeight;
NSNumber *_simulatedDisplayScale;
DTiPhoneSimulatorApplicationSpecifier *_applicationToSimulateOnStart;
NSNumber *_pid;
NSArray *_simulatedApplicationLaunchArgs;
NSDictionary *_simulatedApplicationLaunchEnvironment;
NSString *_simulatedApplicationStdOutPath;
NSString *_simulatedApplicationStdErrPath;
NSFileHandle *_stdinFileHandle;
NSFileHandle *_stdoutFileHandle;
NSFileHandle *_stderrFileHandle;
id _confinementService;
}
+ (id)displayNameForDeviceFamily:(id)arg1;
@property(retain) id confinementService; // @synthesize confinementService=_confinementService;
@property(retain) NSFileHandle *stderrFileHandle; // @synthesize stderrFileHandle=_stderrFileHandle;
@property(retain) NSFileHandle *stdoutFileHandle; // @synthesize stdoutFileHandle=_stdoutFileHandle;
@property(retain) NSFileHandle *stdinFileHandle; // @synthesize stdinFileHandle=_stdinFileHandle;
@property(copy) NSString *simulatedApplicationStdErrPath; // @synthesize simulatedApplicationStdErrPath=_simulatedApplicationStdErrPath;
@property(copy) NSString *simulatedApplicationStdOutPath; // @synthesize simulatedApplicationStdOutPath=_simulatedApplicationStdOutPath;
@property BOOL simulatedApplicationShouldWaitForDebugger; // @synthesize simulatedApplicationShouldWaitForDebugger=_simulatedApplicationShouldWaitForDebugger;
@property(copy) NSDictionary *simulatedApplicationLaunchEnvironment; // @synthesize simulatedApplicationLaunchEnvironment=_simulatedApplicationLaunchEnvironment;
@property(copy) NSArray *simulatedApplicationLaunchArgs; // @synthesize simulatedApplicationLaunchArgs=_simulatedApplicationLaunchArgs;
@property(copy) NSNumber *pid; // @synthesize pid=_pid;
@property(copy) DTiPhoneSimulatorApplicationSpecifier *applicationToSimulateOnStart; // @synthesize applicationToSimulateOnStart=_applicationToSimulateOnStart;
@property(copy) NSNumber *simulatedDisplayScale; // @synthesize simulatedDisplayScale=_simulatedDisplayScale;
@property(copy) NSNumber *simulatedDisplayHeight; // @synthesize simulatedDisplayHeight=_simulatedDisplayHeight;
@property(copy) NSString *simulatedArchitecture; // @synthesize simulatedArchitecture=_simulatedArchitecture;
@property(copy) NSNumber *simulatedDeviceFamily; // @synthesize simulatedDeviceFamily=_simulatedDeviceFamily;
@property(retain) NSString *simulatedDeviceInfoName; // @synthesize simulatedDeviceInfoName=_simulatedDeviceInfoName;
@property(copy) DTiPhoneSimulatorSystemRoot *simulatedSystemRoot; // @synthesize simulatedSystemRoot=_simulatedSystemRoot;
@property(copy) NSString *localizedClientName; // @synthesize localizedClientName=_localizedClientName;
@property BOOL launchForBackgroundFetch; // @synthesize launchForBackgroundFetch=_launchForBackgroundFetch;
@property(retain) SimDevice *device; // @synthesize device=_device;
@property(retain) SimRuntime *runtime; // @synthesize runtime=_runtime;
- (id)description;
- (id)copyWithZone:(struct _NSZone *)arg1;
- (id)init;
@end
@interface DTiPhoneSimulatorSystemRoot : NSObject <NSCopying>
{
NSString *sdkRootPath;
NSString *sdkVersion;
NSString *sdkDisplayName;
}
+ (id)rootWithSDKVersion:(id)arg1;
+ (id)rootWithSDKPath:(id)arg1;
+ (id)defaultRoot;
+ (id)knownRoots;
+ (void)initialize;
@property(copy) NSString *sdkDisplayName; // @synthesize sdkDisplayName;
@property(copy) NSString *sdkVersion; // @synthesize sdkVersion;
@property(copy) NSString *sdkRootPath; // @synthesize sdkRootPath;
@property(readonly) SimRuntime *runtime; // @synthesize runtime=_runtime;
- (id)description;
- (long long)compare:(id)arg1;
- (id)copyWithZone:(struct _NSZone *)arg1;
- (BOOL)isEqual:(id)arg1;
- (id)initWithSDKPath:(id)arg1;
@end
@interface DTiPhoneSimulatorApplicationSpecifier : NSObject <NSCopying>
{
NSString *appPath;
NSString *bundleID;
NSString *toolPath;
}
+ (id)specifierWithToolPath:(id)arg1;
+ (id)specifierWithApplicationBundleIdentifier:(id)arg1;
+ (id)specifierWithApplicationPath:(id)arg1;
@property(copy, nonatomic) NSString *toolPath; // @synthesize toolPath;
@property(copy, nonatomic) NSString *bundleID; // @synthesize bundleID;
@property(copy, nonatomic) NSString *appPath; // @synthesize appPath;
- (id)description;
- (id)copyWithZone:(struct _NSZone *)arg1;
@end

View File

@@ -1,60 +0,0 @@
CONFIG += console
QT -= core
QT -= gui
QT -= test
CONFIG -= app_bundle
include(../../../../qtcreator.pri)
# Prevent from popping up in the dock when launched.
# We embed the Info.plist file, so the application doesn't need to
# be a bundle.
QMAKE_LFLAGS += -Wl,-sectcreate,__TEXT,__info_plist,\"$$PWD/Info.plist\"
-fobjc-link-runtime
LIBS += \
-framework Foundation \
-framework CoreServices \
-framework ApplicationServices \
-framework CoreFoundation \
-F/System/Library/PrivateFrameworks \
-framework IOKit -framework AppKit
iPhoneSimulatorRemoteClientDirectLinking {
LIBS += \
-F/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/Library/PrivateFrameworks \
-F/Applications/Xcode.app/Contents/OtherFrameworks
LIBS += \
-framework DTViPhoneSimulatorRemoteClient
QMAKE_RPATHDIR += /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/Library/PrivateFrameworks \
/Applications/Xcode.app/Contents/OtherFrameworks \
/System/Library/PrivateFrameworks
}
TEMPLATE = app
# put into a subdir, so we can deploy a separate qt.conf for it
DESTDIR = $$IDE_LIBEXEC_PATH/ios
include(../../../rpath.pri)
OBJECTIVE_SOURCES += \
main.mm \
nsprintf.mm \
nsstringexpandpath.mm \
iphonesimulator.mm
HEADERS += \
iphonesimulator.h \
nsprintf.h \
nsstringexpandpath.h \
version.h \
dvtiphonesimulatorremoteclient/dvtiphonesimulatorremoteclient.h \
coresimulator/coresimulator.h
DISTFILES = IOSSIM_LICENSE \
Info.plist
target.path = $$INSTALL_LIBEXEC_PATH/ios
INSTALLS += target

View File

@@ -1,30 +0,0 @@
import qbs 1.0
QtcTool {
name: "iossim"
condition: qbs.targetOS.contains("macos")
Depends { name: "bundle" }
Depends { name: "Qt"; submodules: ["widgets"] }
Depends { name: "app_version_header" }
files: [
"main.mm",
"nsprintf.mm",
"nsstringexpandpath.mm",
"iphonesimulator.mm",
"iphonesimulator.h",
"nsprintf.h",
"nsstringexpandpath.h",
"version.h",
"dvtiphonesimulatorremoteclient/dvtiphonesimulatorremoteclient.h"
]
cpp.includePaths: ["."]
cpp.driverFlags: base.concat(["-fobjc-link-runtime"])
cpp.frameworks: base.concat(["Foundation", "CoreServices", "ApplicationServices", "IOKit",
"AppKit"])
cpp.frameworkPaths: base.concat("/System/Library/PrivateFrameworks")
bundle.infoPlistFile: "Info.plist"
installDir: qtc.ide_libexec_path + "/ios"
}

View File

@@ -1,46 +0,0 @@
/* Author: Landon Fuller <landonf@plausiblelabs.com>
* Copyright (c) 2008-2011 Plausible Labs Cooperative, Inc.
* All rights reserved.
*
* See the IOSSIM_LICENSE file in this directory for the license on the source code in this file.
*/
#import <Foundation/Foundation.h>
#import "dvtiphonesimulatorremoteclient/dvtiphonesimulatorremoteclient.h"
#import "version.h"
@interface iPhoneSimulator : NSObject <DTiPhoneSimulatorSessionDelegate> {
@private
DTiPhoneSimulatorSystemRoot *sdkRoot;
NSFileHandle *stdoutFileHandle;
NSFileHandle *stderrFileHandle;
DTiPhoneSimulatorSession *mySession;
BOOL startOnly;
BOOL exitOnStartup;
BOOL shouldWaitDebugger;
BOOL shouldStartDebugger;
BOOL useGDB;
BOOL verbose;
BOOL alreadyPrintedData;
BOOL retinaDevice;
BOOL tallDevice;
BOOL is64BitDevice;
NSString *deviceTypeId;
NSString *m_stderrPath;
NSString *m_stdoutPath;
NSString *dataPath;
int xcodeVersionInt;
}
- (id)init;
- (void)dealloc;
- (void)runWithArgc:(int)argc argv:(char **)argv;
- (void)createStdioFIFO:(NSFileHandle **)fileHandle ofType:(NSString *)type atPath:(NSString **)path;
- (void)removeStdioFIFO:(NSFileHandle *)fileHandle atPath:(NSString *)path;
- (void)stop;
- (void)doExit:(int)errorCode;
- (SimDevice*) findDeviceWithFamily:(NSString *)family retina:(BOOL)retina isTallDevice:(BOOL)isTallDevice is64Bit:(BOOL)is64Bit;
- (NSString*)changeDeviceType:(NSString *)family retina:(BOOL)retina isTallDevice:(BOOL)isTallDevice is64Bit:(BOOL)is64Bit;
@end

View File

@@ -1,974 +0,0 @@
/* Author: Landon Fuller <landonf@plausiblelabs.com>
* Copyright (c) 2008-2011 Plausible Labs Cooperative, Inc.
* All rights reserved.
*
* See the IOSSIM_LICENSE file in this directory for the license on the source code in this file.
*/
#import "iphonesimulator.h"
#import "nsstringexpandpath.h"
#import "nsprintf.h"
#import <sys/types.h>
#import <sys/stat.h>
#import <Foundation/NSTask.h>
#import <Foundation/NSFileManager.h>
@class DTiPhoneSimulatorSystemRoot;
NSString *simulatorPrefrencesName = @"com.apple.iphonesimulator";
NSString *deviceProperty = @"SimulateDevice";
NSString *deviceIphoneRetina3_5Inch = @"iPhone Retina (3.5-inch)";
NSString *deviceIphoneRetina4_0Inch = @"iPhone Retina (4-inch)";
NSString *deviceIphoneRetina4_0Inch_64bit = @"iPhone Retina (4-inch 64-bit)";
NSString *deviceIphone = @"iPhone";
NSString *deviceIpad = @"iPad";
NSString *deviceIpadRetina = @"iPad Retina";
NSString *deviceIpadRetina_64bit = @"iPad Retina (64-bit)";
NSString* deviceTypeIdIphone4s = @"com.apple.CoreSimulator.SimDeviceType.iPhone-4s";
NSString* deviceTypeIdIphone5 = @"com.apple.CoreSimulator.SimDeviceType.iPhone-5";
NSString* deviceTypeIdIphone5s = @"com.apple.CoreSimulator.SimDeviceType.iPhone-5s";
NSString* deviceTypeIdIphone6 = @"com.apple.CoreSimulator.SimDeviceType.iPhone-6";
NSString* deviceTypeIdIphone6Plus = @"com.apple.CoreSimulator.SimDeviceType.iPhone-6-Plus";
NSString* deviceTypeIdIpad2 = @"com.apple.CoreSimulator.SimDeviceType.iPad-2";
NSString* deviceTypeIdIpadRetina = @"com.apple.CoreSimulator.SimDeviceType.iPad-Retina";
NSString* deviceTypeIdIpadAir = @"com.apple.CoreSimulator.SimDeviceType.iPad-Air";
NSString* deviceTypeIdResizableIphone = @"com.apple.CoreSimulator.SimDeviceType.Resizable-iPhone";
NSString* deviceTypeIdResizeableIpad = @"com.apple.CoreSimulator.SimDeviceType.Resizable-iPad";
// The path within the developer dir of the private Simulator frameworks.
NSString* const kSimulatorFrameworkRelativePathLegacy = @"Platforms/iPhoneSimulator.platform/Developer/Library/PrivateFrameworks/DVTiPhoneSimulatorRemoteClient.framework";
NSString* const kSimulatorFrameworkRelativePath = @"../SharedFrameworks/DVTiPhoneSimulatorRemoteClient.framework";
NSString* const kDVTFoundationRelativePath = @"../SharedFrameworks/DVTFoundation.framework";
NSString* const kDevToolsFoundationRelativePath = @"../OtherFrameworks/DevToolsFoundation.framework";
//NSString* const kSimulatorRelativePath = @"Platforms/iPhoneSimulator.platform/Developer/Applications/iPhone Simulator.app";
NSString* const kCoreSimulatorRelativePath = @"Library/PrivateFrameworks/CoreSimulator.framework";
static pid_t gDebuggerProcessId = 0;
static const char *gDevDir = 0;
@interface DVTPlatform : NSObject
+ (BOOL)loadAllPlatformsReturningError:(NSError **)error;
+ (id)platformForIdentifier:(NSString *)identifier;
@end
/**
* A simple iPhoneSimulatorRemoteClient framework.
*/
@implementation iPhoneSimulator
- (id)init {
self = [super init];
deviceTypeId = 0;
m_stderrPath = 0;
m_stdoutPath = 0;
dataPath = 0;
xcodeVersionInt = 0;
mySession = nil;
return self;
}
- (void)dealloc {
[mySession release];
[super dealloc];
}
- (void)doExit:(int)errorCode {
if (stderrFileHandle != nil) {
[self removeStdioFIFO:stderrFileHandle atPath:m_stderrPath];
}
if (stdoutFileHandle != nil) {
[self removeStdioFIFO:stdoutFileHandle atPath:m_stdoutPath];
}
nsprintf(@"<exit code=\"%d\"/>", errorCode);
nsprintf(@"</query_result>");
fflush(stdout);
fflush(stderr);
exit(errorCode);
}
// Helper to find a class by name and die if it isn't found.
-(Class) FindClassByName:(NSString*) nameOfClass {
Class theClass = NSClassFromString(nameOfClass);
if (!theClass) {
nsfprintf(stderr,@"Failed to find class %@ at runtime.", nameOfClass);
[self doExit:EXIT_FAILURE];
}
return theClass;
}
// Loads the Simulator framework from the given developer dir.
-(void) LoadSimulatorFramework:(NSString*) developerDir {
// The Simulator framework depends on some of the other Xcode private
// frameworks; manually load them first so everything can be linked up.
NSString* dvtFoundationPath = [developerDir stringByAppendingPathComponent:kDVTFoundationRelativePath];
NSBundle* dvtFoundationBundle =
[NSBundle bundleWithPath:dvtFoundationPath];
if (![dvtFoundationBundle load]){
nsprintf(@"Unable to dvtFoundationBundle. Error: ");
[self doExit:EXIT_FAILURE];
return ;
}
NSString* devToolsFoundationPath = [developerDir stringByAppendingPathComponent:kDevToolsFoundationRelativePath];
NSBundle* devToolsFoundationBundle =
[NSBundle bundleWithPath:devToolsFoundationPath];
if (![devToolsFoundationBundle load]){
nsprintf(@"Unable to devToolsFoundationPath.");
return ;
}
NSString* coreSimulatorPath = [developerDir stringByAppendingPathComponent:kCoreSimulatorRelativePath];
if ([[NSFileManager defaultManager] fileExistsAtPath:coreSimulatorPath]) {
NSBundle* coreSimulatorBundle = [NSBundle bundleWithPath:coreSimulatorPath];
if (![coreSimulatorBundle load]){
nsprintf(@"Unable to coreSimulatorPath.");
return ;
}
}
NSString* simBundlePath = [developerDir stringByAppendingPathComponent:kSimulatorFrameworkRelativePathLegacy];
if (![[NSFileManager defaultManager] fileExistsAtPath:simBundlePath]){
simBundlePath = [developerDir stringByAppendingPathComponent:kSimulatorFrameworkRelativePath];
}
NSBundle* simBundle = [NSBundle bundleWithPath:simBundlePath];
if (![simBundle load]){
nsprintf(@"Unable to load simulator framework.");
return ;
}
NSError* error = 0;
// Prime DVTPlatform.
Class DVTPlatformClass = [self FindClassByName:@"DVTPlatform"];
if (![DVTPlatformClass loadAllPlatformsReturningError:&error]) {
nsprintf(@"Unable to loadAllPlatformsReturningError. Error: %@",[error localizedDescription]);
return ;
}
Class systemRootClass = [self FindClassByName:@"DTiPhoneSimulatorSystemRoot"];
// The following will fail if DVTPlatform hasn't loaded all platforms.
NSAssert(systemRootClass && [systemRootClass knownRoots] != nil,
@"DVTPlatform hasn't been initialized yet.");
// DTiPhoneSimulatorRemoteClient will make this same call, so let's assert
// that it's working.
NSAssert([DVTPlatformClass platformForIdentifier:@"com.apple.platform.iphonesimulator"] != nil,
@"DVTPlatform hasn't been initialized yet.");
return ;
}
NSString* GetXcodeVersion() {
// Go look for it via xcodebuild.
NSTask* xcodeBuildTask = [[[NSTask alloc] init] autorelease];
[xcodeBuildTask setLaunchPath:@"/usr/bin/xcodebuild"];
[xcodeBuildTask setArguments:[NSArray arrayWithObject:@"-version"]];
NSPipe* outputPipe = [NSPipe pipe];
[xcodeBuildTask setStandardOutput:outputPipe];
NSFileHandle* outputFile = [outputPipe fileHandleForReading];
[xcodeBuildTask launch];
NSData* outputData = [outputFile readDataToEndOfFile];
[xcodeBuildTask terminate];
NSString* output =
[[[NSString alloc] initWithData:outputData
encoding:NSUTF8StringEncoding] autorelease];
output = [output stringByTrimmingCharactersInSet:
[NSCharacterSet whitespaceAndNewlineCharacterSet]];
if ([output length] == 0) {
output = nil;
} else {
NSArray* parts = [output componentsSeparatedByCharactersInSet: [NSCharacterSet whitespaceAndNewlineCharacterSet]];
if ([parts count] >= 2) {
return parts[1];
}
}
return output;
}
// Finds the developer dir via xcode-select or the DEVELOPER_DIR environment
// variable.
NSString* FindDeveloperDir() {
if (gDevDir)
return [NSString stringWithCString:gDevDir encoding:NSUTF8StringEncoding];
// Check the env first.
NSDictionary* env = [[NSProcessInfo processInfo] environment];
NSString* developerDir = [env objectForKey:@"DEVELOPER_DIR"];
if ([developerDir length] > 0) {
return developerDir;
}
// Go look for it via xcode-select.
NSTask* xcodeSelectTask = [[[NSTask alloc] init] autorelease];
[xcodeSelectTask setLaunchPath:@"/usr/bin/xcode-select"];
[xcodeSelectTask setArguments:[NSArray arrayWithObject:@"-print-path"]];
NSPipe* outputPipe = [NSPipe pipe];
[xcodeSelectTask setStandardOutput:outputPipe];
NSFileHandle* outputFile = [outputPipe fileHandleForReading];
[xcodeSelectTask launch];
NSData* outputData = [outputFile readDataToEndOfFile];
[xcodeSelectTask terminate];
NSString* output =
[[[NSString alloc] initWithData:outputData
encoding:NSUTF8StringEncoding] autorelease];
output = [output stringByTrimmingCharactersInSet:
[NSCharacterSet whitespaceAndNewlineCharacterSet]];
if ([output length] == 0) {
output = nil;
}
return output;
}
- (void) printUsage {
fprintf(stdout, "<msg>Usage: ios-sim &lt;command&gt; &lt;options&gt; [--args ...]\n");
fprintf(stdout, "\n");
fprintf(stdout, "Commands:\n");
fprintf(stdout, " showsdks List the available iOS SDK versions\n");
fprintf(stdout, " showdevicetypes List the available device types (Xcode6+)\n");
fprintf(stdout, " launch &lt;application path&gt; Launch the application at the specified path on the iOS Simulator\n");
fprintf(stdout, " start Launch iOS Simulator without an app\n");
fprintf(stdout, "\n");
fprintf(stdout, "Options:\n");
fprintf(stdout, " --version Print the version of ios-sim\n");
fprintf(stdout, " --developer-path &lt;developerDir&gt; path to the developer directory (in Xcode)");
fprintf(stdout, " --help Show this help text\n");
fprintf(stdout, " --verbose Set the output level to verbose\n");
fprintf(stdout, " --exit Exit after startup\n");
fprintf(stdout, " --wait-for-debugger Wait for debugger to attach\n");
fprintf(stdout, " --debug Attach LLDB to the application on startup\n");
fprintf(stdout, " --use-gdb Use GDB instead of LLDB. (Requires --debug)\n");
fprintf(stdout, " --uuid &lt;uuid&gt; A UUID identifying the session (is that correct?)\n");
fprintf(stdout, " --env &lt;environment file path&gt; A plist file containing environment key-value pairs that should be set\n");
fprintf(stdout, " --setenv NAME=VALUE Set an environment variable\n");
fprintf(stdout, " --stdout &lt;stdout file path&gt; The path where stdout of the simulator will be redirected to (defaults to stdout of ios-sim)\n");
fprintf(stdout, " --stderr &lt;stderr file path&gt; The path where stderr of the simulator will be redirected to (defaults to stderr of ios-sim)\n");
fprintf(stdout, " --timeout &lt;seconds&gt; The timeout time to wait for a response from the Simulator. Default value: 30 seconds\n");
fprintf(stdout, " --args &lt;...&gt; All following arguments will be passed on to the application</msg>\n");
fprintf(stdout, " --devicetypeid <device type> The id of the device type that should be simulated (Xcode6+). Use 'showdevicetypes' to list devices.\n");
fprintf(stdout, " e.g \"com.apple.CoreSimulator.SimDeviceType.Resizable-iPhone6, 8.0\"\n");
fprintf(stdout, "DEPRECATED in 3.x, use devicetypeid instead:\n");
fprintf(stdout, " --sdk <sdkversion> The iOS SDK version to run the application on (defaults to the latest)\n");
fprintf(stdout, " --family <device family> The device type that should be simulated (defaults to `iphone')\n");
fprintf(stdout, " --retina Start a retina device\n");
fprintf(stdout, " --tall In combination with --retina flag, start the tall version of the retina device (e.g. iPhone 5 (4-inch))\n");
fprintf(stdout, " --64bit In combination with --retina flag and the --tall flag, start the 64bit version of the tall retina device (e.g. iPhone 5S (4-inch 64bit))\n");
fflush(stdout);
}
- (void) printDeprecation:(char*)option {
(void)option;
//fprintf(stdout, "Usage of '%s' is deprecated in 3.x. Use --devicetypeid instead.\n", option);
}
- (int) showSDKs {
Class systemRootClass = [self FindClassByName:@"DTiPhoneSimulatorSystemRoot"];
NSArray *roots = [systemRootClass knownRoots];
nsprintf(@"<device_info>");
for (NSUInteger i = 0; i < [roots count]; ++i) {
DTiPhoneSimulatorSystemRoot *root = [roots objectAtIndex:i];
nsprintf(@"<item><key>sdk%d_name</key><value>%@</value></item>", i, [root sdkDisplayName]);
nsprintf(@"<item><key>sdk%d_version</key><value>%@</value></item>", i, [root sdkVersion]);
nsprintf(@"<item><key>sdk%d_sysroot</key><value>%@</value></item>", i, [root sdkRootPath]);
}
nsprintf(@"</device_info>");
return EXIT_SUCCESS;
}
- (int) showDeviceTypes {
Class simDeviceSet = NSClassFromString(@"SimDeviceSet");
nsprintf(@"<device_info>");
bool hasDevices = false;
if (simDeviceSet) {
SimDeviceSet* deviceSet = [simDeviceSet defaultSet];
NSArray* devices = [deviceSet availableDevices];
for (SimDevice* device in devices) {
hasDevices = true;
nsfprintf(stdout, @"<item><key>%@, %@</key><value>%@</value></item>",device.deviceType.identifier, device.runtime.versionString, device.deviceType.name);
}
}
if (!hasDevices) {
// fallback devices for Xcode 5.x
nsprintf(@"<item><key>com.apple.CoreSimulator.SimDeviceType.iPhone-4s</key><value>iPhone 3.5-inch Retina Display</value></item>");
nsprintf(@"<item><key>com.apple.CoreSimulator.SimDeviceType.iPhone-5s</key><value>iPhone 4-inch Retina Display</value></item>");
nsprintf(@"<item><key>com.apple.CoreSimulator.SimDeviceType.iPad-2</key><value>iPad</value></item>");
nsprintf(@"<item><key>com.apple.CoreSimulator.SimDeviceType.iPad-Retina</key><value>iPad Retina Display</value></item>");
}
nsprintf(@"</device_info>");
return EXIT_SUCCESS;
}
- (void)session:(DTiPhoneSimulatorSession *)session didEndWithError:(NSError *)error {
(void)session;
if (verbose) {
msgprintf(@"Session did end with error %@", error);
}
if (error != nil) {
[self doExit:EXIT_FAILURE];
}
[self doExit:EXIT_SUCCESS];
}
static void IgnoreSignal(int /*arg*/) {
}
static void ChildSignal(int /*arg*/) {
int status;
waitpid(gDebuggerProcessId, &status, 0);
exit(EXIT_SUCCESS);
}
- (void)session:(DTiPhoneSimulatorSession *)session didStart:(BOOL)started withError:(NSError *)error {
if (started) {
// bring to front...
[NSTask launchedTaskWithLaunchPath:@"/usr/bin/osascript"
arguments:[NSArray arrayWithObjects:
@"-e", @"tell application \"System Events\"",
@"-e", @" set listOfProcesses to (name of every process where background only is false)",
@"-e", @"end tell",
@"-e", @"repeat with processName in listOfProcesses",
@"-e", @" if processName starts with \"iOS Simulator\" or processName starts with \"iPhone Simulator\" then",
@"-e", @" tell application processName to activate",
@"-e", @" end if",
@"-e", @"end repeat", nil]];
}
if (startOnly && session) {
msgprintf(@"Simulator started (no session)");
[self doExit:EXIT_SUCCESS];
return;
}
if (started) {
int pid = [session simulatedApplicationPID];
if (shouldStartDebugger) {
char*args[4] = { NULL, NULL, (char*)[[[NSNumber numberWithInt:pid] description] UTF8String], NULL };
if (useGDB) {
args[0] = strdup("gdb");
args[1] = strdup("program");
} else {
args[0] = strdup("lldb");
args[1] = strdup("--attach-pid");
}
// The parent process must live on to process the stdout/stderr fifos,
// so start the debugger as a child process.
pid_t child_pid = fork();
if (child_pid == 0) {
execvp(args[0], args);
} else if (child_pid < 0) {
msgprintf(@"Could not start debugger process: %d", errno);
[self doExit:EXIT_FAILURE];
return;
}
gDebuggerProcessId = child_pid;
signal(SIGINT, IgnoreSignal);
signal(SIGCHLD, ChildSignal);
}
if (verbose) {
msgprintf(@"Session started");
}
nsprintf(@"<inferior_pid>%d</inferior_pid>", pid);
fflush(stdout);
if (exitOnStartup) {
[self doExit:EXIT_SUCCESS];
return;
}
} else {
msgprintf(@"Session could not be started: %@", [error localizedDescription]);
[self doExit:EXIT_FAILURE];
}
}
- (void)stop {
if (mySession)
[mySession requestEndWithTimeout: 0.1];
}
- (void)stdioDataIsAvailable:(NSNotification *)notification {
[[notification object] readInBackgroundAndNotify];
NSData *data = [[notification userInfo] valueForKey:NSFileHandleNotificationDataItem];
NSString *str = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; /* dangerous if partially encoded data is at the boundary */
if (!alreadyPrintedData) {
if ([str length] == 0) {
return;
} else {
alreadyPrintedData = YES;
}
}
if ([notification object] == stdoutFileHandle) {
printf("<app_output>%s</app_output>\n", [escapeString(str) UTF8String]);
} else {
nsprintf(@"<app_output>%@</app_output>", escapeString(str)); // handle stderr differently?
}
fflush(stdout);
}
- (void)createStdioFIFO:(NSFileHandle **)fileHandle ofType:(NSString *)type atPath:(NSString **)path {
*path = [NSString stringWithFormat:@"%@/ios-sim-%@-pipe-%d", NSTemporaryDirectory(), type, (int)time(NULL)];
if (mkfifo([*path UTF8String], S_IRUSR | S_IWUSR) == -1) {
msgprintf(@"Unable to create %@ named pipe `%@'", type, *path);
[self doExit:EXIT_FAILURE];
} else {
if (verbose) {
msgprintf(@"Creating named pipe at `%@'", *path);
}
int fd = open([*path UTF8String], O_RDONLY | O_NDELAY);
*fileHandle = [[[NSFileHandle alloc] initWithFileDescriptor:fd] retain];
[*fileHandle readInBackgroundAndNotify];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(stdioDataIsAvailable:)
name:NSFileHandleReadCompletionNotification
object:*fileHandle];
}
}
- (void)removeStdioFIFO:(NSFileHandle *)fileHandle atPath:(NSString *)path {
if (verbose) {
msgprintf(@"Removing named pipe at `%@'", path);
}
[fileHandle closeFile];
[fileHandle release];
if (![[NSFileManager defaultManager] removeItemAtPath:path error:NULL]) {
msgprintf(@"Unable to remove named pipe `%@'", path);
}
if (dataPath && ![[NSFileManager defaultManager] removeItemAtPath:[dataPath stringByAppendingPathComponent:path] error:NULL]) {
msgprintf(@"Unable to remove simlink at `%@'", [dataPath stringByAppendingPathComponent:path]);
}
}
- (int)launchApp:(NSString *)path withFamily:(NSString *)family
uuid:(NSString *)uuid
environment:(NSDictionary *)environment
stdoutPath:(NSString *)stdoutPath
stderrPath:(NSString *)stderrPath
timeout:(NSTimeInterval)timeout
args:(NSArray *)args {
DTiPhoneSimulatorApplicationSpecifier *appSpec;
DTiPhoneSimulatorSessionConfig *config;
DTiPhoneSimulatorSession *session;
NSError *error;
NSFileManager *fileManager = [[[NSFileManager alloc] init] autorelease];
if (!startOnly && ![fileManager fileExistsAtPath:path]) {
msgprintf(@"Application path %@ doesn't exist!", path);
return EXIT_FAILURE;
}
/* Create the app specifier */
appSpec = startOnly ? nil : [[self FindClassByName:@"DTiPhoneSimulatorApplicationSpecifier"] specifierWithApplicationPath:path];
if (verbose) {
msgprintf(@"App Spec: %@\n", appSpec);
msgprintf(@"SDK Root: %@\n", sdkRoot);
msgprintf(@"SDK Version: %@\n", [sdkRoot sdkVersion]);
for (id key in environment) {
msgprintf(@"Env: %@ = %@", key, [environment objectForKey:key]);
}
}
NSString *sdkVersion = [sdkRoot sdkVersion];
NSString *appSupportDir = [NSString stringWithFormat:@"%@/Library/Application Support/iPhone Simulator/%@",
NSHomeDirectory(), sdkVersion];
NSMutableDictionary *mutableEnv = [NSMutableDictionary dictionaryWithDictionary:environment];
[mutableEnv setObject:appSupportDir forKey:@"CFFIXED_USER_HOME"];
[mutableEnv setObject:appSupportDir forKey:@"IPHONE_SHARED_RESOURCES_DIRECTORY"];
[mutableEnv setObject:appSupportDir forKey:@"HOME"];
[mutableEnv setObject:[sdkRoot sdkRootPath] forKey:@"IPHONE_SIMULATOR_ROOT"];
[mutableEnv setObject:[sdkRoot sdkRootPath] forKey:@"DYLD_ROOT_PATH"];
[mutableEnv setObject:[sdkRoot sdkRootPath] forKey:@"DYLD_FRAMEWORK_PATH"];
[mutableEnv setObject:[sdkRoot sdkRootPath] forKey:@"DYLD_LIBRARY_PATH"];
[mutableEnv setObject:@"YES" forKey:@"NSUnbufferedIO"];
environment = mutableEnv;
/* Set up the session configuration */
config = [[[[self FindClassByName:@"DTiPhoneSimulatorSessionConfig"] alloc] init] autorelease];
[config setApplicationToSimulateOnStart:appSpec];
[config setSimulatedSystemRoot:sdkRoot];
[config setSimulatedApplicationShouldWaitForDebugger:shouldWaitDebugger];
[config setSimulatedApplicationLaunchArgs:args];
[config setSimulatedApplicationLaunchEnvironment:environment];
if (stderrPath) {
stderrFileHandle = nil;
} else if (!exitOnStartup) {
[self createStdioFIFO:&stderrFileHandle ofType:@"stderr" atPath:&stderrPath];
m_stderrPath = stderrPath;
}
[config setSimulatedApplicationStdErrPath:stderrPath];
if (stdoutPath) {
stdoutFileHandle = nil;
} else if (!exitOnStartup) {
[self createStdioFIFO:&stdoutFileHandle ofType:@"stdout" atPath:&stdoutPath];
m_stdoutPath = stdoutPath;
}
[config setSimulatedApplicationStdOutPath:stdoutPath];
[config setLocalizedClientName: @"iossim"];
// this was introduced in 3.2 of SDK
if ([config respondsToSelector:@selector(setSimulatedDeviceFamily:)]) {
if (family == nil) {
family = @"iphone";
}
if (verbose) {
nsprintf(@"using device family %@",family);
}
if ([family isEqualToString:@"ipad"]) {
[config setSimulatedDeviceFamily:[NSNumber numberWithInt:2]];
} else{
[config setSimulatedDeviceFamily:[NSNumber numberWithInt:1]];
}
}
if ([config respondsToSelector:@selector(setDevice:)]) {
// Xcode6+
config.device = [self findDeviceWithFamily:family retina:retinaDevice isTallDevice:tallDevice is64Bit:is64BitDevice];
// The iOS 8 simulator treats stdout/stderr paths relative to the simulator's data directory.
// Create symbolic links in the data directory that points at the real stdout/stderr paths.
if ([config.simulatedSystemRoot.sdkVersion compare:@"8.0" options:NSNumericSearch] != NSOrderedAscending) {
dataPath = config.device.dataPath;
NSString *simlinkStdout = [dataPath stringByAppendingPathComponent:stdoutPath];
m_stdoutPath = stdoutPath;
NSString *simlinkStderr = [dataPath stringByAppendingPathComponent:stderrPath];
m_stderrPath = stderrPath;
[[NSFileManager defaultManager] createSymbolicLinkAtPath:simlinkStdout withDestinationPath:stdoutPath error:NULL];
[[NSFileManager defaultManager] createSymbolicLinkAtPath:simlinkStderr withDestinationPath:stderrPath error:NULL];
}
} else {
// Xcode5 or older
NSString* devicePropertyValue = [self changeDeviceType:family retina:retinaDevice isTallDevice:tallDevice is64Bit:is64BitDevice];
[config setSimulatedDeviceInfoName:devicePropertyValue];
}
/* Start the session */
session = [[[[self FindClassByName:@"DTiPhoneSimulatorSession"] alloc] init] autorelease];
mySession = session;
[session setDelegate:self];
if (uuid != nil){
[session setUuid:uuid];
}
if (![session requestStartWithConfig:config timeout:timeout error:&error]) {
msgprintf(@"Could not start simulator session: %@", error);
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
- (SimDevice*) findDeviceWithFamily:(NSString *)family retina:(BOOL)retina isTallDevice:(BOOL)isTallDevice is64Bit:(BOOL)is64Bit {
NSString* devTypeId = self->deviceTypeId;
if (!devTypeId) {
devTypeId = deviceTypeIdIphone5;
if (retina) {
if ([family isEqualToString:@"ipad"]) {
if (is64Bit) {
devTypeId = deviceTypeIdIpadAir;
} else {
devTypeId = deviceTypeIdIpadRetina;
}
} else {
if (isTallDevice) {
if (is64Bit) {
devTypeId = deviceTypeIdIphone5s;
} else {
devTypeId = deviceTypeIdIphone5;
}
} else {
devTypeId = deviceTypeIdIphone4s;
}
}
} else {
if ([family isEqualToString:@"ipad"]) {
devTypeId = deviceTypeIdIpad2;
} else {
devTypeId = deviceTypeIdIphone4s;
}
}
}
SimDeviceSet* deviceSet = [[self FindClassByName:@"SimDeviceSet"] defaultSet];
NSArray* devices = [deviceSet availableDevices];
NSArray* deviceTypeAndVersion = [devTypeId componentsSeparatedByString:@","];
if(deviceTypeAndVersion.count == 2) {
NSString* typeIdentifier = [[deviceTypeAndVersion objectAtIndex:0] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
NSString* versionString = [[deviceTypeAndVersion objectAtIndex:1] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];;
for (SimDevice* device in devices) {
if ([device.deviceType.identifier isEqualToString:typeIdentifier] && [device.runtime.versionString isEqualToString:versionString]) {
return device;
}
}
}
//maintain old behavior (if the device identifier doesn't have a version as part of the identifier, loop through to find the first matching)
else
{
for (SimDevice* device in devices) {
if ([device.deviceType.identifier isEqualToString:devTypeId]) {
return device;
}
}
}
// Default to whatever is the first device
return [devices count] > 0 ? [devices objectAtIndex:0] : nil;
}
- (NSString*) changeDeviceType:(NSString *)family retina:(BOOL)retina isTallDevice:(BOOL)isTallDevice is64Bit:(BOOL)is64Bit {
NSString *devicePropertyValue;
if (self->deviceTypeId) {
if ([deviceTypeIdIphone4s isEqual: deviceTypeId])
devicePropertyValue = deviceIphoneRetina3_5Inch;
else if ([deviceTypeIdIphone5s isEqual: deviceTypeId])
devicePropertyValue = deviceIphoneRetina4_0Inch;
else if ([deviceTypeIdIpad2 isEqual: deviceTypeId])
devicePropertyValue = deviceIpad;
else if ([deviceTypeIdIpadRetina isEqual: deviceTypeId])
devicePropertyValue = deviceIpadRetina;
else {
nsprintf(@"<msg>Unknown or unsupported device type: %@</msg>\n", deviceTypeId);
[self doExit:EXIT_FAILURE];
return nil;
}
} else if (retina) {
if (verbose) {
msgprintf(@"using retina");
}
if ([family isEqualToString:@"ipad"]) {
if (is64Bit) {
devicePropertyValue = deviceIpadRetina_64bit;
} else {
devicePropertyValue = deviceIpadRetina;
}
}
else {
if (isTallDevice) {
if (is64Bit) {
devicePropertyValue = deviceIphoneRetina4_0Inch_64bit;
} else {
devicePropertyValue = deviceIphoneRetina4_0Inch;
}
} else {
devicePropertyValue = deviceIphoneRetina3_5Inch;
}
}
} else {
if ([family isEqualToString:@"ipad"]) {
devicePropertyValue = deviceIpad;
} else {
devicePropertyValue = deviceIphone;
}
}
CFPreferencesSetAppValue((CFStringRef)deviceProperty, (CFPropertyListRef)devicePropertyValue, (CFStringRef)simulatorPrefrencesName);
CFPreferencesAppSynchronize((CFStringRef)simulatorPrefrencesName);
return devicePropertyValue;
}
/**
* Execute 'main'
*/
- (void)runWithArgc:(int)argc argv:(char **)argv {
if (argc < 2) {
[self printUsage];
exit(EXIT_FAILURE);
}
NSString* xcodeVersion = GetXcodeVersion();
if (!([xcodeVersion compare:@"6.0" options:NSNumericSearch] != NSOrderedAscending) && false) {
nsprintf(@"You need to have at least Xcode 6.0 installed -- you have version %@.", xcodeVersion);
nsprintf(@"Run 'xcode-select --print-path' to check which version of Xcode is enabled.");
exit(EXIT_FAILURE);
}
retinaDevice = NO;
tallDevice = NO;
is64BitDevice = NO;
exitOnStartup = NO;
alreadyPrintedData = NO;
startOnly = strcmp(argv[1], "start") == 0;
deviceTypeId = nil;
nsprintf(@"<query_result>");
for (int i = 0; i < argc; ++i) {
if (strcmp(argv[i], "--developer-path") == 0) {
++i;
if (i < argc)
gDevDir = argv[i];
}
}
NSString* developerDir = FindDeveloperDir();
if (!developerDir) {
nsprintf(@"<msg>Unable to find developer directory.</msg>");
[self doExit:EXIT_FAILURE];
}
NSString *xcodePlistPath = [developerDir stringByAppendingPathComponent:@"../Info.plist"];
NSAssert([[NSFileManager defaultManager] fileExistsAtPath:xcodePlistPath isDirectory:NULL],
@"Cannot find Xcode's plist at: %@", xcodePlistPath);
NSDictionary *infoDict = [NSDictionary dictionaryWithContentsOfFile:xcodePlistPath];
NSAssert(infoDict[@"DTXcode"], @"Cannot find the 'DTXcode' key in Xcode's Info.plist.");
NSString *DTXcode = infoDict[@"DTXcode"];
xcodeVersionInt = [DTXcode intValue];
NSString* dvtFoundationPath = [developerDir stringByAppendingPathComponent:kDVTFoundationRelativePath];
if (![[NSFileManager defaultManager] fileExistsAtPath:dvtFoundationPath]) {
// execute old version
char *argNew = new char[strlen(argv[0] + 7)];
strcpy(argNew, argv[0]);
strcat(argNew, "_1_8_2");
char **argvNew = new char *[argc + 1];
argvNew[0] = argNew;
for (int iarg = 1; iarg < argc; ++iarg)
argvNew[iarg] = argv[iarg];
argvNew[argc] = 0;
execv(argNew, argvNew);
}
if (strcmp(argv[1], "showsdks") == 0) {
[self LoadSimulatorFramework:developerDir];
[self doExit:[self showSDKs]];
} else if (strcmp(argv[1], "showdevicetypes") == 0) {
[self LoadSimulatorFramework:developerDir];
[self doExit:[self showDeviceTypes]];
} else if (strcmp(argv[1], "launch") == 0 || startOnly) {
if (strcmp(argv[1], "launch") == 0 && argc < 3) {
msgprintf(@"Missing application path argument");
[self printUsage];
[self doExit:EXIT_FAILURE];
}
NSString *appPath = nil;
int argOffset;
if (startOnly) {
argOffset = 2;
}
else {
argOffset = 3;
appPath = [[NSString stringWithUTF8String:argv[2]] expandPath];
}
NSString *family = nil;
NSString *uuid = nil;
NSString *stdoutPath = nil;
NSString *stderrPath = nil;
NSString *xctest = nil;
NSTimeInterval timeout = 60;
NSMutableDictionary *environment = [NSMutableDictionary dictionary];
int i = argOffset;
for (; i < argc; i++) {
if (strcmp(argv[i], "--version") == 0) {
printf("%s\n", IOS_SIM_VERSION);
exit(EXIT_SUCCESS);
} else if (strcmp(argv[i], "--help") == 0) {
[self printUsage];
exit(EXIT_SUCCESS);
} else if (strcmp(argv[i], "--verbose") == 0) {
verbose = YES;
} else if (strcmp(argv[i], "--exit") == 0) {
exitOnStartup = YES;
} else if (strcmp(argv[i], "--wait-for-debugger") == 0) {
shouldWaitDebugger = YES;
} else if (strcmp(argv[i], "--debug") == 0) {
shouldWaitDebugger = YES;
shouldStartDebugger = YES;
} else if (strcmp(argv[i], "--use-gdb") == 0) {
useGDB = YES;
} else if (strcmp(argv[i], "--developer-path") == 0) {
++i;
if (i == argc) {
nsprintf(@"<msg>missing arg after --developer-path</msg>");
[self doExit:EXIT_FAILURE];
return;
}
} else if (strcmp(argv[i], "--timeout") == 0) {
if (i + 1 < argc) {
timeout = [[NSString stringWithUTF8String:argv[++i]] doubleValue];
NSLog(@"Timeout: %f second(s)", timeout);
}
}
else if (strcmp(argv[i], "--sdk") == 0) {
[self printDeprecation:argv[i]];
i++;
if (i == argc) {
nsprintf(@"<msg>missing arg after --sdk</msg>");
[self doExit:EXIT_FAILURE];
return;
}
[self LoadSimulatorFramework:developerDir];
NSString* ver = [NSString stringWithCString:argv[i] encoding:NSUTF8StringEncoding];
Class systemRootClass = [self FindClassByName:@"DTiPhoneSimulatorSystemRoot"];
NSArray *roots = [systemRootClass knownRoots];
for (DTiPhoneSimulatorSystemRoot *root in roots) {
NSString *v = [root sdkVersion];
if ([v isEqualToString:ver]) {
sdkRoot = root;
break;
}
}
if (sdkRoot == nil) {
msgprintf(@"Unknown or unsupported SDK version: %s\n",argv[i]);
[self showSDKs];
exit(EXIT_FAILURE);
}
} else if (strcmp(argv[i], "--family") == 0) {
[self printDeprecation:argv[i]];
i++;
if (i == argc) {
nsprintf(@"<msg>missing arg after --sdkfamilymsg>");
[self doExit:EXIT_FAILURE];
return;
}
family = [NSString stringWithUTF8String:argv[i]];
} else if (strcmp(argv[i], "--uuid") == 0) {
i++;
if (i == argc) {
nsprintf(@"<msg>missing arg after --uuid</msg>");
[self doExit:EXIT_FAILURE];
return;
}
uuid = [NSString stringWithUTF8String:argv[i]];
} else if (strcmp(argv[i], "--devicetypeid") == 0) {
i++;
if (i == argc) {
nsprintf(@"<msg>missing arg after --devicetypeid</msg>");
[self doExit:EXIT_FAILURE];
return;
}
deviceTypeId = [NSString stringWithUTF8String:argv[i]];
} else if (strcmp(argv[i], "--setenv") == 0) {
i++;
if (i == argc) {
nsprintf(@"<msg>missing arg after --setenv</msg>");
[self doExit:EXIT_FAILURE];
return;
}
NSArray *parts = [[NSString stringWithUTF8String:argv[i]] componentsSeparatedByString:@"="];
[environment setObject:[parts objectAtIndex:1] forKey:[parts objectAtIndex:0]];
} else if (strcmp(argv[i], "--env") == 0) {
i++;
if (i == argc) {
nsprintf(@"<msg>missing arg after --env</msg>");
[self doExit:EXIT_FAILURE];
return;
}
NSString *envFilePath = [[NSString stringWithUTF8String:argv[i]] expandPath];
[environment setValuesForKeysWithDictionary:[NSDictionary dictionaryWithContentsOfFile:envFilePath]];
if (!environment) {
msgprintf(@"Could not read environment from file: %s", argv[i]);
[self printUsage];
exit(EXIT_FAILURE);
}
} else if (strcmp(argv[i], "--stdout") == 0) {
i++;
if (i == argc) {
nsprintf(@"<msg>missing arg after --stdout</msg>");
[self doExit:EXIT_FAILURE];
return;
}
stdoutPath = [[NSString stringWithUTF8String:argv[i]] expandPath];
NSLog(@"stdoutPath: %@", stdoutPath);
} else if (strcmp(argv[i], "--stderr") == 0) {
i++;
if (i == argc) {
nsprintf(@"<msg>missing arg after --stderr</msg>");
[self doExit:EXIT_FAILURE];
return;
}
stderrPath = [[NSString stringWithUTF8String:argv[i]] expandPath];
NSLog(@"stderrPath: %@", stderrPath);
} else if (strcmp(argv[i], "--xctest") == 0) {
i++;
if (i == argc) {
nsprintf(@"<msg>missing arg after --xctest</msg>");
[self doExit:EXIT_FAILURE];
return;
}
xctest = [[NSString stringWithUTF8String:argv[i]] expandPath];
NSLog(@"xctest: %@", xctest);
} else if (strcmp(argv[i], "--retina") == 0) {
[self printDeprecation:argv[i]];
retinaDevice = YES;
} else if (strcmp(argv[i], "--tall") == 0) {
[self printDeprecation:argv[i]];
tallDevice = YES;
} else if (strcmp(argv[i], "--64bit") == 0) {
[self printDeprecation:argv[i]];
is64BitDevice = YES;
} else if (strcmp(argv[i], "--args") == 0) {
i++;
break;
} else {
msgprintf(@"unrecognized argument:%s", argv[i]);
[self printUsage];
[self doExit:EXIT_FAILURE];
return;
}
}
NSMutableArray *args = [NSMutableArray arrayWithCapacity:MAX(argc - i,0)];
for (; i < argc; i++) {
[args addObject:[NSString stringWithUTF8String:argv[i]]];
}
if (sdkRoot == nil) {
[self LoadSimulatorFramework:developerDir];
Class systemRootClass = [self FindClassByName:@"DTiPhoneSimulatorSystemRoot"];
sdkRoot = [systemRootClass defaultRoot];
}
if (xctest) {
NSString *appName = [appPath lastPathComponent];
NSString *executableName = [appName stringByDeletingPathExtension];
NSString *injectionPath = @"/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/Library/PrivateFrameworks/IDEBundleInjection.framework/IDEBundleInjection";
[environment setValuesForKeysWithDictionary:[NSDictionary dictionaryWithObjectsAndKeys:
injectionPath,@"DYLD_INSERT_LIBRARIES",
xctest, @"XCInjectBundle",
[appPath stringByAppendingFormat:@"/%@", executableName],@"XCInjectBundleInto",
nil]];
}
/* Don't exit, adds to runloop */
int res = [self launchApp:appPath
withFamily:family
uuid:uuid
environment:environment
stdoutPath:stdoutPath
stderrPath:stderrPath
timeout:timeout
args:args];
nsprintf(@"<app_started status=\"%@\" />", ((res == 0) ? @"SUCCESS" : @"FAILURE"));
fflush(stdout);
fflush(stderr);
if (res != 0)
[self doExit:EXIT_FAILURE];
} else {
if (argc == 2 && strcmp(argv[1], "--help") == 0) {
[self printUsage];
[self doExit:EXIT_SUCCESS];
} else if (argc == 2 && strcmp(argv[1], "--version") == 0) {
printf("%s\n", IOS_SIM_VERSION);
[self doExit:EXIT_SUCCESS];
} else {
fprintf(stderr, "Unknown command\n");
[self printUsage];
[self doExit:EXIT_FAILURE];
}
}
}
@end

View File

@@ -1,29 +0,0 @@
/* Author: Landon Fuller <landonf@plausiblelabs.com>
* Copyright (c) 2008-2011 Plausible Labs Cooperative, Inc.
* All rights reserved.
*
* See the IOSSIM_LICENSE file in this directory for the license on the source code in this file.
*/
/* derived from https://github.com/phonegap/ios-sim */
#import <AppKit/AppKit.h>
#import <Foundation/NSFileManager.h>
#import "iphonesimulator.h"
/*
* Runs the iPhoneSimulator backed by a main runloop.
*/
int main (int argc, char *argv[]) {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
iPhoneSimulator *sim = [[iPhoneSimulator alloc] init];
/* Execute command line handler */
[sim runWithArgc: argc argv: argv];
/* Run the loop to handle added input sources, if any */
[[NSRunLoop mainRunLoop] run];
[pool release];
return 0;
}

View File

@@ -1,9 +0,0 @@
/*
* See the IOSSIM_LICENSE file in this directory for the license on the source code in this file.
*/
int nsvfprintf (FILE *stream, NSString *format, va_list args);
int nsfprintf (FILE *stream, NSString *format, ...);
int nsprintf (NSString *format, ...);
int msgvfprintf (FILE *stream, NSString *format, va_list args);
int msgprintf (NSString *format, ...);
NSString *escapeString(NSString *origString);

View File

@@ -1,75 +0,0 @@
/*
* NSLog() clone, but writes to arbitrary output stream
*
* See the IOSSIM_LICENSE file in this directory for the license on the source code in this file.
*/
#import <Foundation/Foundation.h>
#import <stdio.h>
int nsvfprintf (FILE *stream, NSString *format, va_list args) {
int retval;
NSString *str = (NSString *) CFStringCreateWithFormatAndArguments(NULL, NULL, (CFStringRef) format, args);
retval = fprintf(stream, "%s\n", [str UTF8String]);
[str release];
return retval;
}
int nsfprintf (FILE *stream, NSString *format, ...) {
va_list ap;
int retval;
va_start(ap, format);
{
retval = nsvfprintf(stream, format, ap);
}
va_end(ap);
return retval;
}
int nsprintf (NSString *format, ...) {
va_list ap;
int retval;
va_start(ap, format);
{
retval = nsvfprintf(stdout, format, ap);
}
va_end(ap);
return retval;
}
NSString *escapeString(NSString *origString)
{
return [[[[origString stringByReplacingOccurrencesOfString: @"&" withString: @"&amp;"]
stringByReplacingOccurrencesOfString: @"\"" withString: @"&quot;"]
stringByReplacingOccurrencesOfString: @">" withString: @"&gt;"]
stringByReplacingOccurrencesOfString: @"<" withString: @"&lt;"];
}
int msgvfprintf (FILE *stream, NSString *format, va_list args) {
int retval;
NSString *str = (NSString *) CFStringCreateWithFormatAndArguments(NULL, NULL, (CFStringRef) format, args);
retval = fprintf(stream, "<msg>%s</msg>\n", [escapeString(str) UTF8String]);
[str release];
return retval;
}
int msgprintf(NSString *format, ...) {
va_list ap;
int retval;
va_start(ap, format);
{
retval = msgvfprintf(stdout, format, ap);
}
va_end(ap);
return retval;
}

View File

@@ -1,11 +0,0 @@
/*
* See the IOSSIM_LICENSE file in this directory for the license on the source code in this file.
*/
#import <Foundation/Foundation.h>
@interface NSString (ExpandPath)
- (NSString *)expandPath;
@end

View File

@@ -1,18 +0,0 @@
/*
* See the LICENSE file for the license on the source code in this file.
*/
#import "nsstringexpandpath.h"
@implementation NSString (ExpandPath)
- (NSString *)expandPath {
if ([self isAbsolutePath]) {
return [self stringByStandardizingPath];
} else {
NSString *cwd = [[NSFileManager defaultManager] currentDirectoryPath];
return [[cwd stringByAppendingPathComponent:self] stringByStandardizingPath];
}
}
@end

View File

@@ -1 +0,0 @@
#define IOS_SIM_VERSION "2.0.1"

View File

@@ -1,31 +0,0 @@
Author: Landon Fuller <landonf@plausiblelabs.com>
Copyright (c) 2008-2011 Plausible Labs Cooperative, Inc.
All rights reserved.
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
Modifications made by the following entities are licensed as above:
- Jeff Haynie, Appcelerator, Inc.
- https://github.com/hborders
- http://pivotallabs.com/users/scoward/blog
- Eloy Duran, Fingertips <eloy@fngtps.com>
- Fawzi Mohamed, digia <fawzi.mohamed@digia.com>

View File

@@ -1,16 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleExecutable</key>
<string>iossim_1_8_2</string>
<key>CFBundleIdentifier</key>
<string>org.qt-project.qt-creator.iossim_1_8_2</string>
<key>LSUIElement</key>
<string>1</string>
</dict>
</plist>

View File

@@ -1,30 +0,0 @@
import qbs 1.0
import QtcTool
QtcTool {
name: "iossim"
condition: qbs.targetOS.contains("macos")
Depends { name: "Qt"; submodules: ["widgets"] }
Depends { name: "app_version_header" }
files: [
"main.mm",
"nsprintf.mm",
"nsstringexpandpath.mm",
"iphonesimulator.mm",
"iphonesimulator.h",
"nsprintf.h",
"nsstringexpandpath.h",
"version.h",
"iphonesimulatorremoteclient/iphonesimulatorremoteclient.h"
]
cpp.linkerFlags: base.concat(["-fobjc-link-runtime"])
cpp.frameworks: base.concat(["Foundation", "CoreServices", "ApplicationServices", "IOKit",
"AppKit"])
cpp.frameworkPaths: base.concat("/System/Library/PrivateFrameworks")
cpp.infoPlistFile: "Info.plist"
toolInstallDir: project.ide_libexec_path + "/ios"
}

View File

@@ -1,58 +0,0 @@
CONFIG += console
QT += core
QT += gui
CONFIG -= app_bundle
include(../../../../qtcreator.pri)
# Prevent from popping up in the dock when launched.
# We embed the Info.plist file, so the application doesn't need to
# be a bundle.
QMAKE_LFLAGS += -Wl,-sectcreate,__TEXT,__info_plist,\"$$PWD/Info.plist\" \
-fobjc-link-runtime
LIBS += \
-framework Foundation \
-framework CoreServices \
-framework ApplicationServices \
-framework CoreFoundation \
-F/System/Library/PrivateFrameworks \
-framework IOKit -framework AppKit
iPhoneSimulatorRemoteClientDirectLinking {
LIBS += \
-F/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/Library/PrivateFrameworks \
-F/Applications/Xcode.app/Contents/OtherFrameworks
LIBS += \
-framework iPhoneSimulatorRemoteClient
QMAKE_RPATHDIR += /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/Library/PrivateFrameworks \
/Applications/Xcode.app/Contents/OtherFrameworks
/System/Library/PrivateFrameworks \
}
TEMPLATE = app
# put into a subdir, so we can deploy a separate qt.conf for it
DESTDIR = $$IDE_LIBEXEC_PATH/ios
include(../../../rpath.pri)
OBJECTIVE_SOURCES += \
main.mm \
nsprintf.mm \
nsstringexpandpath.mm \
iphonesimulator.mm
HEADERS += \
iphonesimulator.h \
nsprintf.h \
nsstringexpandpath.h \
version.h \
iphonesimulatorremoteclient/iphonesimulatorremoteclient.h
DISTFILES = IOSSIM_LICENSE \
Info.plist
target.path = $$INSTALL_LIBEXEC_PATH/ios
INSTALLS += target

View File

@@ -1,41 +0,0 @@
/* Author: Landon Fuller <landonf@plausiblelabs.com>
* Copyright (c) 2008-2011 Plausible Labs Cooperative, Inc.
* All rights reserved.
*
* See the IOSSIM_LICENSE file in this directory for the license on the source code in this file.
*/
#import <Foundation/Foundation.h>
#import "iphonesimulatorremoteclient/iphonesimulatorremoteclient.h"
#import "version.h"
@interface iPhoneSimulator : NSObject <DTiPhoneSimulatorSessionDelegate> {
@private
DTiPhoneSimulatorSystemRoot *sdkRoot;
NSFileHandle *stdoutFileHandle;
NSFileHandle *stderrFileHandle;
DTiPhoneSimulatorSession *session;
NSTimer *pidCheckingTimer;
BOOL startOnly;
BOOL exitOnStartup;
BOOL shouldWaitDebugger;
BOOL shouldStartDebugger;
BOOL useGDB;
BOOL verbose;
BOOL alreadyPrintedData;
BOOL retinaDevice;
BOOL tallDevice;
}
- (id)init;
- (void)dealloc;
- (void)runWithArgc:(int)argc argv:(char **)argv;
- (void)createStdioFIFO:(NSFileHandle **)fileHandle ofType:(NSString *)type atPath:(NSString **)path;
- (void)removeStdioFIFO:(NSFileHandle *)fileHandle atPath:(NSString *)path;
- (void)stop;
- (void)checkPid:(NSTimer *)timer;
- (void)doExit:(int)errorCode;
- (void)changeDeviceType:(NSString *)family retina:(BOOL)retina isTallDevice:(BOOL)isTallDevice;
@end

View File

@@ -1,634 +0,0 @@
/* Author: Landon Fuller <landonf@plausiblelabs.com>
* Copyright (c) 2008-2011 Plausible Labs Cooperative, Inc.
* All rights reserved.
*
* See the IOSSIM_LICENSE file in this directory for the license on the source code in this file.
*/
#import "iphonesimulator.h"
#import "nsstringexpandpath.h"
#import "nsprintf.h"
#import <sys/types.h>
#import <sys/stat.h>
#import <objc/runtime.h>
#import <AppKit/NSRunningApplication.h>
NSString *simulatorPrefrencesName = @"com.apple.iphonesimulator";
NSString *deviceProperty = @"SimulateDevice";
NSString *deviceIphoneRetina3_5Inch = @"iPhone Retina (3.5-inch)";
NSString *deviceIphoneRetina4_0Inch = @"iPhone Retina (4-inch)";
NSString *deviceIphone = @"iPhone";
NSString *deviceIpad = @"iPad";
NSString *deviceIpadRetina = @"iPad (Retina)";
/**
* A simple iPhoneSimulatorRemoteClient framework.
*/
@implementation iPhoneSimulator
- (id)init {
self = [super init];
session = nil;
pidCheckingTimer = nil;
return self;
}
- (void)dealloc {
[session release];
[pidCheckingTimer release];
[super dealloc];
}
- (void)doExit:(int)errorCode {
nsprintf(@"<exit code=\"%d\"/>", errorCode);
nsprintf(@"</query_result>");
fflush(stdout);
fflush(stderr);
exit(errorCode);
}
- (void) printUsage {
fprintf(stdout, "<msg>Usage: iossim <command> <options> [--args ...]\n");
fprintf(stdout, "\n");
fprintf(stdout, "Commands:\n");
fprintf(stdout, " showsdks List the available iOS SDK versions\n");
fprintf(stdout, " launch <application path> Launch the application at the specified path on the iOS Simulator\n");
fprintf(stdout, " start Launch iOS Simulator without an app\n");
fprintf(stdout, "\n");
fprintf(stdout, "Options:\n");
fprintf(stdout, " --version Print the version of ios-sim\n");
fprintf(stdout, " --developer-path <developerDir> path to the developer directory (in Xcode)");
fprintf(stdout, " --help Show this help text\n");
fprintf(stdout, " --verbose Set the output level to verbose\n");
fprintf(stdout, " --exit Exit after startup\n");
fprintf(stdout, " --wait-for-debugger Wait for debugger to attach\n");
fprintf(stdout, " --debug Attach LLDB to the application on startup\n");
fprintf(stdout, " --use-gdb Use GDB instead of LLDB. (Requires --debug)\n");
fprintf(stdout, " --sdk <sdkversion> The iOS SDK version to run the application on (defaults to the latest)\n");
fprintf(stdout, " --family <device family> The device type that should be simulated (defaults to `iphone')\n");
fprintf(stdout, " --retina Start a retina device\n");
fprintf(stdout, " --tall In combination with --retina flag, start the tall version of the retina device (e.g. iPhone 5 (4-inch))\n");
fprintf(stdout, " --uuid <uuid> A UUID identifying the session (is that correct?)\n");
fprintf(stdout, " --env <environment file path> A plist file containing environment key-value pairs that should be set\n");
fprintf(stdout, " --setenv NAME=VALUE Set an environment variable\n");
fprintf(stdout, " --stdout <stdout file path> The path where stdout of the simulator will be redirected to (defaults to stdout of ios-sim)\n");
fprintf(stdout, " --stderr <stderr file path> The path where stderr of the simulator will be redirected to (defaults to stderr of ios-sim)\n");
fprintf(stdout, " --timeout <seconds> The timeout time to wait for a response from the Simulator. Default value: 30 seconds\n");
fprintf(stdout, " --args <...> All following arguments will be passed on to the application</msg>\n");
fflush(stdout);
}
- (int) showSDKs {
NSUInteger i;
id tClass = objc_getClass("DTiPhoneSimulatorSystemRoot");
if (tClass == nil) {
nsprintf(@"<msg>DTiPhoneSimulatorSystemRoot class is nil.</msg>");
return EXIT_FAILURE;
}
NSArray *roots = [tClass knownRoots];
nsprintf(@"<device_info>");
for (i = 0; i < [roots count]; ++i) {
DTiPhoneSimulatorSystemRoot *root = [roots objectAtIndex:i];
nsprintf(@"<item><key>sdk%d_name</key><value>%@</value></item>", i, [root sdkDisplayName]);
nsprintf(@"<item><key>sdk%d_version</key><value>%@</value></item>", i, [root sdkVersion]);
nsprintf(@"<item><key>sdk%d_sysroot</key><value>%@</value></item>", i, [root sdkRootPath]);
}
nsprintf(@"</device_info>");
return EXIT_SUCCESS;
}
- (void)session:(DTiPhoneSimulatorSession *)mySession didEndWithError:(NSError *)error {
if (verbose) {
nsprintf(@"<msg>Session did end with error %@</msg>", error);
}
if (stderrFileHandle != nil) {
NSString *stderrPath = [[mySession sessionConfig] simulatedApplicationStdErrPath];
[self removeStdioFIFO:stderrFileHandle atPath:stderrPath];
}
if (stdoutFileHandle != nil) {
NSString *stdoutPath = [[mySession sessionConfig] simulatedApplicationStdOutPath];
[self removeStdioFIFO:stdoutFileHandle atPath:stdoutPath];
}
if (error != nil)
[self doExit:EXIT_FAILURE];
else
[self doExit:EXIT_SUCCESS];
}
- (void)session:(DTiPhoneSimulatorSession *)mySession didStart:(BOOL)started withError:(NSError *)error {
if (startOnly && mySession) {
[NSTask launchedTaskWithLaunchPath:@"/usr/bin/osascript"
arguments:[NSArray arrayWithObjects:@"-e", @"tell application \"iPhone Simulator\" to activate", nil]];
nsprintf(@"<msg>Simulator started (no session)</msg>");
[self doExit:EXIT_SUCCESS];
return;
}
if (started) {
[NSTask launchedTaskWithLaunchPath:@"/usr/bin/osascript"
arguments:[NSArray arrayWithObjects:@"-e", @"tell application \"iPhone Simulator\" to activate", nil]];
if (shouldStartDebugger) {
char*args[4] = { NULL, NULL, (char*)[[[mySession simulatedApplicationPID] description] UTF8String], NULL };
if (useGDB) {
args[0] = strdup("gdb");
args[1] = strdup("program");
} else {
args[0] = strdup("lldb");
args[1] = strdup("--attach-pid");
}
// The parent process must live on to process the stdout/stderr fifos,
// so start the debugger as a child process.
pid_t child_pid = fork();
if (child_pid == 0) {
execvp(args[0], args);
} else if (child_pid < 0) {
nsprintf(@"<msg>Could not start debugger process: %@</msg>", errno);
[self doExit:EXIT_FAILURE];
return;
}
}
if (verbose) {
nsprintf(@"<msg>Session started</msg>");
}
nsprintf(@"<inferior_pid>%@</inferior_pid>", [session simulatedApplicationPID]);
fflush(stdout);
if (exitOnStartup) {
[self doExit:EXIT_SUCCESS];
return;
}
pidCheckingTimer = [[NSTimer scheduledTimerWithTimeInterval:5.0 target:self
selector:@selector(checkPid:) userInfo:nil repeats: TRUE] retain];
} else {
nsprintf(@"<msg>Session could not be started: %@</msg>", error);
[self doExit:EXIT_FAILURE];
}
}
- (void)stop {
if (session)
[session requestEndWithTimeout: 0.1];
}
- (void)checkPid:(NSTimer *)timer {
(void)timer;
if (session && [[session simulatedApplicationPID]intValue] > 0) {
if (kill((pid_t)[[session simulatedApplicationPID]intValue], 0) == -1) {
nsprintf(@"<msg>app stopped</msg>");
[self doExit:EXIT_SUCCESS];
return;
}
}
}
- (void)stdioDataIsAvailable:(NSNotification *)notification {
[[notification object] readInBackgroundAndNotify];
NSData *data = [[notification userInfo] valueForKey:NSFileHandleNotificationDataItem];
NSString *str = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; /* dangerous if partially encoded data is at the boundary */
if (!alreadyPrintedData) {
if ([str length] == 0) {
return;
} else {
alreadyPrintedData = YES;
}
}
if ([notification object] == stdoutFileHandle) {
printf("<app_output>%s</app_output>\n", [str UTF8String]);
} else {
nsprintf(@"<app_output>%@</app_output>", str); // handle stderr differently?
}
fflush(stdout);
}
- (void)createStdioFIFO:(NSFileHandle **)fileHandle ofType:(NSString *)type atPath:(NSString **)path {
*path = [NSString stringWithFormat:@"%@/ios-sim-%@-pipe-%d", NSTemporaryDirectory(), type, (int)time(NULL)];
if (mkfifo([*path UTF8String], S_IRUSR | S_IWUSR) == -1) {
nsprintf(@"<msg>Unable to create %@ named pipe `%@'</msg>", type, *path);
[self doExit:EXIT_FAILURE];
} else {
if (verbose) {
nsprintf(@"<msg>Creating named pipe at `%@'</msg>", *path);
}
int fd = open([*path UTF8String], O_RDONLY | O_NDELAY);
*fileHandle = [[[NSFileHandle alloc] initWithFileDescriptor:fd] retain];
[*fileHandle readInBackgroundAndNotify];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(stdioDataIsAvailable:)
name:NSFileHandleReadCompletionNotification
object:*fileHandle];
}
}
- (void)removeStdioFIFO:(NSFileHandle *)fileHandle atPath:(NSString *)path {
if (verbose) {
nsprintf(@"<msg>Removing named pipe at `%@'</msg>", path);
}
[fileHandle closeFile];
[fileHandle release];
if (![[NSFileManager defaultManager] removeItemAtPath:path error:NULL]) {
nsprintf(@"<msg>Unable to remove named pipe `%@'</msg>", path);
}
}
- (int)launchApp:(NSString *)path withFamily:(NSString *)family
uuid:(NSString *)uuid
environment:(NSDictionary *)environment
stdoutPath:(NSString *)stdoutPath
stderrPath:(NSString *)stderrPath
timeout:(NSTimeInterval)timeout
args:(NSArray *)args {
DTiPhoneSimulatorApplicationSpecifier *appSpec;
DTiPhoneSimulatorSessionConfig *config;
NSError *error = 0;
id tClass;
NSFileManager *fileManager = [[[NSFileManager alloc] init] autorelease];
if (!startOnly && ![fileManager fileExistsAtPath:path]) {
nsprintf(@"<msg>Application path %@ doesn't exist!</msg>", path);
return EXIT_FAILURE;
}
/* Create the app specifier */
tClass = objc_getClass("DTiPhoneSimulatorApplicationSpecifier");
if (tClass == nil) {
nsprintf(@"<msg>DTiPhoneSimulatorApplicationSpecifier class is nil.</msg>");
return EXIT_FAILURE;
}
appSpec = startOnly ? nil : [tClass specifierWithApplicationPath:path];
if (verbose) {
nsprintf(@"<msg>App Spec: %@</msg>", appSpec);
nsprintf(@"SDK Root: %@", sdkRoot);
for (id key in environment) {
nsprintf(@"<msg>Env: %@ = %@</msg>", key, [environment objectForKey:key]);
}
}
NSString *sdkVersion = [sdkRoot sdkVersion];
NSString *appSupportDir = [NSString stringWithFormat:@"%@/Library/Application Support/iPhone Simulator/%@",
NSHomeDirectory(), sdkVersion];
NSMutableDictionary *mutableEnv = [NSMutableDictionary dictionaryWithDictionary:environment];
[mutableEnv setObject:appSupportDir forKey:@"CFFIXED_USER_HOME"];
[mutableEnv setObject:appSupportDir forKey:@"IPHONE_SHARED_RESOURCES_DIRECTORY"];
[mutableEnv setObject:appSupportDir forKey:@"HOME"];
[mutableEnv setObject:[sdkRoot sdkRootPath] forKey:@"IPHONE_SIMULATOR_ROOT"];
[mutableEnv setObject:[sdkRoot sdkRootPath] forKey:@"DYLD_ROOT_PATH"];
[mutableEnv setObject:[sdkRoot sdkRootPath] forKey:@"DYLD_FRAMEWORK_PATH"];
[mutableEnv setObject:[sdkRoot sdkRootPath] forKey:@"DYLD_LIBRARY_PATH"];
[mutableEnv setObject:@"YES" forKey:@"NSUnbufferedIO"];
environment = mutableEnv;
/* Set up the session configuration */
tClass = objc_getClass("DTiPhoneSimulatorSessionConfig");
if (tClass == nil) {
nsprintf(@"<msg>DTiPhoneSimulatorApplicationSpecifier class is nil.</msg>");
return EXIT_FAILURE;
}
config = [[[tClass alloc] init] autorelease];
[config setApplicationToSimulateOnStart:appSpec];
[config setSimulatedSystemRoot:sdkRoot];
[config setSimulatedApplicationShouldWaitForDebugger:shouldWaitDebugger];
[config setSimulatedApplicationLaunchArgs:args];
[config setSimulatedApplicationLaunchEnvironment:environment];
if (stderrPath) {
stderrFileHandle = nil;
} else if (!exitOnStartup) {
[self createStdioFIFO:&stderrFileHandle ofType:@"stderr" atPath:&stderrPath];
}
[config setSimulatedApplicationStdErrPath:stderrPath];
if (stdoutPath) {
stdoutFileHandle = nil;
} else if (!exitOnStartup) {
[self createStdioFIFO:&stdoutFileHandle ofType:@"stdout" atPath:&stdoutPath];
}
[config setSimulatedApplicationStdOutPath:stdoutPath];
[config setLocalizedClientName: @"iossim"];
// this was introduced in 3.2 of SDK
if ([config respondsToSelector:@selector(setSimulatedDeviceFamily:)]) {
if (family == nil) {
family = @"iphone";
}
if (verbose) {
nsprintf(@"using device family %@",family);
}
if ([family isEqualToString:@"ipad"]) {
[config setSimulatedDeviceFamily:[NSNumber numberWithInt:2]];
} else{
[config setSimulatedDeviceFamily:[NSNumber numberWithInt:1]];
}
}
[self changeDeviceType:family retina:retinaDevice isTallDevice:tallDevice];
/* Start the session */
tClass = objc_getClass("DTiPhoneSimulatorSession");
if (tClass == nil) {
nsprintf(@"<msg>DTiPhoneSimulatorSession class is nil.</msg>");
return EXIT_FAILURE;
}
session = [[tClass alloc] init];
[session setDelegate:self];
if (uuid != nil){
[session setUuid:uuid];
}
if (![session requestStartWithConfig:config timeout:timeout error:&error]) {
nsprintf(@"<msg>Could not start simulator session: %@</msg>", error);
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
- (void) changeDeviceType:(NSString *)family retina:(BOOL)retina isTallDevice:(BOOL)isTallDevice {
NSString *devicePropertyValue;
if (retina) {
if (verbose) {
nsprintf(@"<msg>using retina</msg>");
}
if ([family isEqualToString:@"ipad"]) {
devicePropertyValue = deviceIpadRetina;
}
else {
if (isTallDevice) {
devicePropertyValue = deviceIphoneRetina4_0Inch;
} else {
devicePropertyValue = deviceIphoneRetina3_5Inch;
}
}
} else {
if ([family isEqualToString:@"ipad"]) {
devicePropertyValue = deviceIpad;
} else {
devicePropertyValue = deviceIphone;
}
}
CFPreferencesSetAppValue((CFStringRef)deviceProperty, (CFPropertyListRef)devicePropertyValue, (CFStringRef)simulatorPrefrencesName);
CFPreferencesAppSynchronize((CFStringRef)simulatorPrefrencesName);
}
/**
* Execute 'main'
*/
- (void)runWithArgc:(int)argc argv:(char **)argv {
if (argc < 2) {
[self printUsage];
exit(EXIT_FAILURE);
}
retinaDevice = NO;
tallDevice = NO;
exitOnStartup = NO;
alreadyPrintedData = NO;
startOnly = strcmp(argv[1], "start") == 0;
nsprintf(@"<query_result>");
if (strcmp(argv[1], "showdevicetypes") == 0) {
nsprintf(@"<deviceinfo>");
nsprintf(@"<item><key>com.apple.CoreSimulator.SimDeviceType.iPhone-4s</key><value>iPhone 3.5-inch Retina Display</value></item>");
nsprintf(@"<item><key>com.apple.CoreSimulator.SimDeviceType.iPhone-5s</key><value>iPhone 4-inch Retina Display</value></item>");
nsprintf(@"<item><key>com.apple.CoreSimulator.SimDeviceType.iPad-2</key><value>iPad</value></item>");
nsprintf(@"<item><key>com.apple.CoreSimulator.SimDeviceType.iPad-Retina</key><value>iPad Retina Display</value></item>");
nsprintf(@"</deviceinfo>");
[self doExit:0];
return;
} else if (strcmp(argv[1], "showsdks") == 0) {
[self doExit:[self showSDKs]];
return;
} else if (strcmp(argv[1], "launch") == 0 || startOnly) {
if (strcmp(argv[1], "launch") == 0 && argc < 3) {
nsprintf(@"<msg>Missing application path argument</msg>");
[self printUsage];
[self doExit:EXIT_FAILURE];
return;
}
NSString *appPath = nil;
int argOffset;
if (startOnly) {
argOffset = 2;
}
else {
argOffset = 3;
appPath = [[NSString stringWithUTF8String:argv[2]] expandPath];
}
NSString *family = nil;
NSString *uuid = nil;
NSString *stdoutPath = nil;
NSString *stderrPath = nil;
NSTimeInterval timeout = 60;
NSMutableDictionary *environment = [NSMutableDictionary dictionary];
int i = argOffset;
for (; i < argc; i++) {
if (strcmp(argv[i], "--version") == 0) {
printf("%s\n", IOS_SIM_VERSION);
exit(EXIT_SUCCESS);
} else if (strcmp(argv[i], "--help") == 0) {
[self printUsage];
exit(EXIT_SUCCESS);
} else if (strcmp(argv[i], "--verbose") == 0) {
verbose = YES;
} else if (strcmp(argv[i], "--exit") == 0) {
exitOnStartup = YES;
} else if (strcmp(argv[i], "--wait-for-debugger") == 0) {
shouldWaitDebugger = YES;
} else if (strcmp(argv[i], "--debug") == 0) {
shouldWaitDebugger = YES;
shouldStartDebugger = YES;
} else if (strcmp(argv[i], "--use-gdb") == 0) {
useGDB = YES;
} else if (strcmp(argv[i], "--developer-path") == 0) {
++i;
if (i == argc) {
nsprintf(@"<msg>missing arg after --developer-path</msg>");
[self doExit:EXIT_FAILURE];
return;
}
} else if (strcmp(argv[i], "--timeout") == 0) {
if (i + 1 < argc) {
timeout = [[NSString stringWithUTF8String:argv[++i]] doubleValue];
nsprintf(@"<msg>Timeout: %f second(s)</msg>", timeout);
}
}
else if (strcmp(argv[i], "--sdk") == 0) {
i++;
if (i == argc) {
nsprintf(@"<msg>missing arg after --sdk</msg>");
[self doExit:EXIT_FAILURE];
return;
}
NSString* ver = [NSString stringWithCString:argv[i] encoding:NSUTF8StringEncoding];
id tClass = objc_getClass("DTiPhoneSimulatorSystemRoot");
NSArray *roots;
if (tClass == nil) {
nsprintf(@"<msg>DTiPhoneSimulatorSystemRoot class is nil.</msg>");
[self doExit:EXIT_FAILURE];
return;
}
roots = [tClass knownRoots];
for (DTiPhoneSimulatorSystemRoot *root in roots) {
NSString *v = [root sdkVersion];
if ([v isEqualToString:ver]) {
sdkRoot = root;
break;
}
}
if (sdkRoot == nil) {
fprintf(stdout,"<msg>Unknown or unsupported SDK version: %s</msg>\n",argv[i]);
[self showSDKs];
exit(EXIT_FAILURE);
}
} else if (strcmp(argv[i], "--family") == 0) {
i++;
if (i == argc) {
nsprintf(@"<msg>missing arg after --family</msg>");
[self doExit:EXIT_FAILURE];
return;
}
family = [NSString stringWithUTF8String:argv[i]];
} else if (strcmp(argv[i], "--uuid") == 0) {
i++;
uuid = [NSString stringWithUTF8String:argv[i]];
} else if (strcmp(argv[i], "--devicetypeid") == 0) {
i++;
if (i == argc) {
nsprintf(@"<msg>missing arg after --devicetypeid</msg>");
[self doExit:EXIT_FAILURE];
return;
}
if (strcmp(argv[i], "com.apple.CoreSimulator.SimDeviceType.iPhone-4s") == 0) {
family = [NSString stringWithUTF8String:"iphone"];
retinaDevice = YES;
} else if (strcmp(argv[i], "com.apple.CoreSimulator.SimDeviceType.iPad-2") == 0) {
family = [NSString stringWithUTF8String:"ipad"];
} else if (strcmp(argv[i], "com.apple.CoreSimulator.SimDeviceType.iPhone-5s") == 0) {
family = [NSString stringWithUTF8String:"iphone"];
retinaDevice = YES;
tallDevice = YES;
} else if (strcmp(argv[i], "com.apple.CoreSimulator.SimDeviceType.iPad-Retina") == 0) {
family = [NSString stringWithUTF8String:"ipad"];
retinaDevice = YES;
} else {
fprintf(stdout,"<msg>Unknown or unsupported device type: %s</msg>\n",argv[i]);
[self doExit:EXIT_FAILURE];
return;
}
} else if (strcmp(argv[i], "--setenv") == 0) {
i++;
if (i == argc) {
nsprintf(@"<msg>missing arg after --setenv</msg>");
[self doExit:EXIT_FAILURE];
return;
}
NSArray *parts = [[NSString stringWithUTF8String:argv[i]] componentsSeparatedByString:@"="];
[environment setObject:[parts objectAtIndex:1] forKey:[parts objectAtIndex:0]];
} else if (strcmp(argv[i], "--env") == 0) {
i++;
if (i == argc) {
nsprintf(@"<msg>missing arg after --env</msg>");
[self doExit:EXIT_FAILURE];
return;
}
NSString *envFilePath = [[NSString stringWithUTF8String:argv[i]] expandPath];
environment = [NSMutableDictionary dictionaryWithContentsOfFile:envFilePath];
if (!environment) {
fprintf(stdout, "<msg>Could not read environment from file: %s</msg>\n", argv[i]);
[self printUsage];
exit(EXIT_FAILURE);
}
} else if (strcmp(argv[i], "--stdout") == 0) {
i++;
if (i == argc) {
nsprintf(@"<msg>missing arg after --stdout</msg>");
[self doExit:EXIT_FAILURE];
return;
}
stdoutPath = [[NSString stringWithUTF8String:argv[i]] expandPath];
nsprintf(@"<msg>stdoutPath: %@</msg>", stdoutPath);
} else if (strcmp(argv[i], "--stderr") == 0) {
i++;
if (i == argc) {
nsprintf(@"<msg>missing arg after --stderr</msg>");
[self doExit:EXIT_FAILURE];
return;
}
stderrPath = [[NSString stringWithUTF8String:argv[i]] expandPath];
nsprintf(@"<msg>stderrPath: %@</msg>", stderrPath);
} else if (strcmp(argv[i], "--retina") == 0) {
retinaDevice = YES;
} else if (strcmp(argv[i], "--tall") == 0) {
tallDevice = YES;
} else if (strcmp(argv[i], "--args") == 0) {
i++;
break;
} else {
printf("<msg>unrecognized argument:%s</msg>\n", argv[i]);
[self printUsage];
[self doExit:EXIT_FAILURE];
return;
}
}
NSMutableArray *args = [NSMutableArray arrayWithCapacity:MAX(argc - i,0)];
for (; i < argc; i++) {
[args addObject:[NSString stringWithUTF8String:argv[i]]];
}
if (sdkRoot == nil) {
id tClass = objc_getClass("DTiPhoneSimulatorSystemRoot");
if (tClass == nil) {
nsprintf(@"<msg>DTiPhoneSimulatorSystemRoot class is nil.</msg>");
[self doExit:EXIT_FAILURE];
return;
}
sdkRoot = [tClass defaultRoot];
}
/* Don't exit, adds to runloop */
int res = [self launchApp:appPath
withFamily:family
uuid:uuid
environment:environment
stdoutPath:stdoutPath
stderrPath:stderrPath
timeout:timeout
args:args];
nsprintf(@"<app_started status=\"%@\" />", ((res == 0) ? @"SUCCESS" : @"FAILURE"));
fflush(stdout);
fflush(stderr);
if (res != 0)
[self doExit:EXIT_FAILURE];
} else {
if (argc == 2 && strcmp(argv[1], "--help") == 0) {
[self printUsage];
[self doExit:EXIT_SUCCESS];
} else if (argc == 2 && strcmp(argv[1], "--version") == 0) {
printf("%s\n", IOS_SIM_VERSION);
[self doExit:EXIT_SUCCESS];
} else {
fprintf(stdout, "<msg>Unknown command</msg>\n");
[self printUsage];
[self doExit:EXIT_FAILURE];
}
}
}
@end

View File

@@ -1,126 +0,0 @@
#import <Cocoa/Cocoa.h>
/*
* File: /Developer/Platforms/iPhoneSimulator.platform/Developer/Library/PrivateFrameworks/iPhoneSimulatorRemoteClient.framework/Versions/A/iPhoneSimulatorRemoteClient
* Arch: Intel 80x86 (i386)
* Current version: 12.0.0, Compatibility version: 1.0.0
*
* See the IOSSIM_LICENSE file in the parent directory for the license on the source code in this file.
*/
@class DTiPhoneSimulatorSession;
@protocol DTiPhoneSimulatorSessionDelegate
- (void) session: (DTiPhoneSimulatorSession *) session didEndWithError: (NSError *) error;
- (void) session: (DTiPhoneSimulatorSession *) session didStart: (BOOL) started withError: (NSError *) error;
@end
@interface DTiPhoneSimulatorApplicationSpecifier : NSObject <NSCopying>
{
NSString *_appPath;
NSString *_bundleID;
}
+ (id) specifierWithApplicationPath: (NSString *) appPath;
+ (id) specifierWithApplicationBundleIdentifier: (NSString *) bundleID;
- (NSString *) bundleID;
- (void) setBundleID: (NSString *) bundleId;
- (NSString *) appPath;
- (void) setAppPath: (NSString *) appPath;
@end
@interface DTiPhoneSimulatorSystemRoot : NSObject <NSCopying>
{
NSString *sdkRootPath;
NSString *sdkVersion;
NSString *sdkDisplayName;
}
+ (id) defaultRoot;
+ (id)rootWithSDKPath:(id)fp8;
+ (id)rootWithSDKVersion:(id)fp8;
+ (NSArray *) knownRoots;
- (id)initWithSDKPath:(id)fp8;
- (id)sdkDisplayName;
- (void)setSdkDisplayName:(id)fp8;
- (id)sdkVersion;
- (void)setSdkVersion:(id)fp8;
- (id)sdkRootPath;
- (void)setSdkRootPath:(id)fp8;
@end
@interface DTiPhoneSimulatorSessionConfig : NSObject <NSCopying>
{
NSString *_localizedClientName;
DTiPhoneSimulatorSystemRoot *_simulatedSystemRoot;
DTiPhoneSimulatorApplicationSpecifier *_applicationToSimulateOnStart;
NSArray *_simulatedApplicationLaunchArgs;
NSDictionary *_simulatedApplicationLaunchEnvironment;
BOOL _simulatedApplicationShouldWaitForDebugger;
NSString *_simulatedApplicationStdOutPath;
NSString *_simulatedApplicationStdErrPath;
}
- (id)simulatedApplicationStdErrPath;
- (void)setSimulatedApplicationStdErrPath:(id)fp8;
- (id)simulatedApplicationStdOutPath;
- (void)setSimulatedApplicationStdOutPath:(id)fp8;
- (id)simulatedApplicationLaunchEnvironment;
- (void)setSimulatedApplicationLaunchEnvironment:(id)fp8;
- (id)simulatedApplicationLaunchArgs;
- (void)setSimulatedApplicationLaunchArgs:(id)fp8;
- (DTiPhoneSimulatorApplicationSpecifier *) applicationToSimulateOnStart;
- (void) setApplicationToSimulateOnStart: (DTiPhoneSimulatorApplicationSpecifier *) appSpec;
- (DTiPhoneSimulatorSystemRoot *) simulatedSystemRoot;
- (void) setSimulatedSystemRoot: (DTiPhoneSimulatorSystemRoot *) simulatedSystemRoot;
- (BOOL) simulatedApplicationShouldWaitForDebugger;
- (void) setSimulatedApplicationShouldWaitForDebugger: (BOOL) waitForDebugger;
- (id)localizedClientName;
- (void)setLocalizedClientName:(id)fp8;
// Added in 3.2 to support iPad/iPhone device families
- (void)setSimulatedDeviceFamily:(NSNumber*)family;
@end
@interface DTiPhoneSimulatorSession : NSObject {
NSString *_uuid;
id <DTiPhoneSimulatorSessionDelegate> _delegate;
NSNumber *_simulatedApplicationPID;
int _sessionLifecycleProgress;
NSTimer *_timeoutTimer;
DTiPhoneSimulatorSessionConfig *_sessionConfig;
struct ProcessSerialNumber _simulatorPSN;
}
- (BOOL) requestStartWithConfig: (DTiPhoneSimulatorSessionConfig *) config timeout: (NSTimeInterval) timeout error: (NSError **) outError;
- (void) requestEndWithTimeout: (NSTimeInterval) timeout;
- (id)sessionConfig;
- (void)setSessionConfig:(id)fp8;
- (id)timeoutTimer;
- (void)setTimeoutTimer:(id)fp8;
- (int)sessionLifecycleProgress;
- (void)setSessionLifecycleProgress:(int)fp8;
- (id)simulatedApplicationPID;
- (void)setSimulatedApplicationPID:(id)fp8;
- (id<DTiPhoneSimulatorSessionDelegate>) delegate;
- (void) setDelegate: (id<DTiPhoneSimulatorSessionDelegate>) delegate;
- (id)uuid;
- (void)setUuid:(id)fp8;
@end

View File

@@ -1,68 +0,0 @@
/* Author: Landon Fuller <landonf@plausiblelabs.com>
* Copyright (c) 2008-2011 Plausible Labs Cooperative, Inc.
* All rights reserved.
*
* See the IOSSIM_LICENSE file in this directory for the license on the source code in this file.
*/
/* derived from https://github.com/phonegap/ios-sim */
#import <AppKit/AppKit.h>
#import "iphonesimulator.h"
#include <QLibrary>
#include <QGuiApplication>
#include <QString>
#include <QStringList>
/* to do:
* - try to stop inferior when killed (or communicate with creator to allow killing the inferior)
* - remove unneeded functionality and streamline a bit
*/
/*
* Runs the iPhoneSimulator backed by a main runloop.
*/
int main (int argc, char *argv[]) {
int qtargc = 1;
char *qtarg = 0;
if (argc)
qtarg = argv[0];
QGuiApplication a(qtargc, &qtarg);
//NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
QString xcodePath = QLatin1String("/Applications/Xcode.app/Contents/Developer/");
for (int i = 0; i + 1 < argc; ++i) {
if (strcmp(argv[i], "--developer-path") == 0)
xcodePath = QString::fromLocal8Bit(argv[i + 1]);
}
if (!xcodePath.endsWith(QLatin1Char('/')))
xcodePath.append(QLatin1Char('/'));
/* manual loading of the private deps */
QStringList deps = QStringList()
<< QLatin1String("/System/Library/PrivateFrameworks/DebugSymbols.framework/Versions/A/DebugSymbols")
<< QLatin1String("/System/Library/PrivateFrameworks/CoreSymbolication.framework/CoreSymbolication")
<< (xcodePath + QLatin1String("../OtherFrameworks/DevToolsFoundation.framework/DevToolsFoundation"));
foreach (const QString &libPath, deps) {
QLibrary *lib = new QLibrary(libPath);
//lib->setLoadHints(QLibrary::ExportExternalSymbolsHint);
if (!lib->load())
printf("<msg>error loading %s</msg>", libPath.toUtf8().constData());
}
QLibrary *libIPhoneSimulatorRemoteClient = new QLibrary(xcodePath
+ QLatin1String("Platforms/iPhoneSimulator.platform/Developer/Library/PrivateFrameworks/iPhoneSimulatorRemoteClient.framework/iPhoneSimulatorRemoteClient"));
//libIPhoneSimulatorRemoteClient->setLoadHints(QLibrary::ResolveAllSymbolsHint|QLibrary::ExportExternalSymbolsHint);
if (!libIPhoneSimulatorRemoteClient->load())
printf("<msg>error loading iPhoneSimulatorRemoteClient</msg>");
iPhoneSimulator *sim = [[iPhoneSimulator alloc] init];
/* Execute command line handler */
[sim runWithArgc: argc argv: argv];
/* Run the loop to handle added input sources, if any */
int res = a.exec();
exit(res);
// [pool release];
return 0;
}

View File

@@ -1,6 +0,0 @@
/*
* See the IOSSIM_LICENSE file in this directory for the license on the source code in this file.
*/
int nsvfprintf (FILE *stream, NSString *format, va_list args);
int nsfprintf (FILE *stream, NSString *format, ...);
int nsprintf (NSString *format, ...);

View File

@@ -1,44 +0,0 @@
/*
* NSLog() clone, but writes to arbitrary output stream
*
* See the IOSSIM_LICENSE file in this directory for the license on the source code in this file.
*/
#import <Foundation/Foundation.h>
#import <stdio.h>
int nsvfprintf (FILE *stream, NSString *format, va_list args) {
int retval;
NSString *str = (NSString *) CFStringCreateWithFormatAndArguments(NULL, NULL, (CFStringRef) format, args);
retval = fprintf(stream, "%s\n", [str UTF8String]);
[str release];
return retval;
}
int nsfprintf (FILE *stream, NSString *format, ...) {
va_list ap;
int retval;
va_start(ap, format);
{
retval = nsvfprintf(stream, format, ap);
}
va_end(ap);
return retval;
}
int nsprintf (NSString *format, ...) {
va_list ap;
int retval;
va_start(ap, format);
{
retval = nsvfprintf(stdout, format, ap);
}
va_end(ap);
return retval;
}

View File

@@ -1,11 +0,0 @@
/*
* See the IOSSIM_LICENSE file in this directory for the license on the source code in this file.
*/
#import <Foundation/Foundation.h>
@interface NSString (ExpandPath)
- (NSString *)expandPath;
@end

View File

@@ -1,18 +0,0 @@
/*
* See the IOSSIM_LICENSE file in this directory for the license on the source code in this file.
*/
#import "nsstringexpandpath.h"
@implementation NSString (ExpandPath)
- (NSString *)expandPath {
if ([self isAbsolutePath]) {
return [self stringByStandardizingPath];
} else {
NSString *cwd = [[NSFileManager defaultManager] currentDirectoryPath];
return [[cwd stringByAppendingPathComponent:self] stringByStandardizingPath];
}
}
@end

View File

@@ -1 +0,0 @@
#define IOS_SIM_VERSION "1.8.2m"

View File

@@ -86,6 +86,8 @@ using namespace QmlDesigner;
# define SHARE_PATH "/share/qtcreator"
#endif
QT_BEGIN_NAMESPACE
//Allow comparison of QByteArray and QString. We always assume utf8 as the encoding.
namespace QTest {
bool qCompare(const QString &string, const QByteArray &array, const char *actual,
@@ -103,6 +105,8 @@ namespace QTest {
}
QT_END_NAMESPACE
QString resourcePath()
{
return QDir::cleanPath(QTCREATORDIR + QLatin1String(SHARE_PATH));