diff --git a/src/plugins/ios/iosdebugsupport.cpp b/src/plugins/ios/iosdebugsupport.cpp
index d698c9e438a196c2772cba661d7678ab4cc6327f..86e75d4f37e1aab4282236b4b89c739e4a5491b4 100644
--- a/src/plugins/ios/iosdebugsupport.cpp
+++ b/src/plugins/ios/iosdebugsupport.cpp
@@ -119,7 +119,9 @@ RunControl *IosDebugSupport::createDebugRunControl(IosRunConfiguration *runConfi
 
     Debugger::DebuggerRunConfigurationAspect *aspect
             = runConfig->extraAspect<Debugger::DebuggerRunConfigurationAspect>();
-    if (aspect->useCppDebugger()) {
+    bool cppDebug = aspect->useCppDebugger();
+    bool qmlDebug = aspect->useQmlDebugger();
+    if (cppDebug) {
         params.languages |= CppLanguage;
         params.sysRoot = SysRootKitInformation::sysRoot(kit).toString();
         params.debuggerCommand = DebuggerKitInformation::debuggerCommand(kit).toString();
@@ -128,42 +130,36 @@ RunControl *IosDebugSupport::createDebugRunControl(IosRunConfiguration *runConfi
         params.executable = runConfig->exePath().toString();
         params.remoteChannel = QLatin1String("connect://localhost:0");
     }
-    if (aspect->useQmlDebugger()) {
+    if (qmlDebug) {
         params.languages |= QmlLanguage;
-        QTcpServer server;
-        QTC_ASSERT(server.listen(QHostAddress::LocalHost)
-                   || server.listen(QHostAddress::LocalHostIPv6), return 0);
-        params.qmlServerAddress = server.serverAddress().toString();
-        params.remoteSetupNeeded = true;
-        //TODO: Not sure if these are the right paths.
         params.projectSourceDirectory = project->projectDirectory();
         params.projectSourceFiles = project->files(QmakeProject::ExcludeGeneratedFiles);
         params.projectBuildDirectory = project->rootQmakeProjectNode()->buildDir();
+        if (!cppDebug)
+            params.startMode = AttachToRemoteServer;
     }
 
     DebuggerRunControl * const debuggerRunControl
         = DebuggerPlugin::createDebugger(params, runConfig, errorMessage);
     if (debuggerRunControl)
-        new IosDebugSupport(runConfig, debuggerRunControl);
+        new IosDebugSupport(runConfig, debuggerRunControl, cppDebug, qmlDebug);
     return debuggerRunControl;
 }
 
 IosDebugSupport::IosDebugSupport(IosRunConfiguration *runConfig,
-    DebuggerRunControl *runControl)
+    DebuggerRunControl *runControl, bool cppDebug, bool qmlDebug)
     : QObject(runControl), m_runControl(runControl),
-      m_runner(new IosRunner(this, runConfig, true)),
-      m_qmlPort(0)
+      m_runner(new IosRunner(this, runConfig, cppDebug, qmlDebug))
 {
-
     connect(m_runControl->engine(), SIGNAL(requestRemoteSetup()),
             m_runner, SLOT(start()));
     connect(m_runControl, SIGNAL(finished()),
             m_runner, SLOT(stop()));
 
-    connect(m_runner, SIGNAL(gotGdbserverPort(int)),
-        SLOT(handleGdbServerPort(int)));
-    connect(m_runner, SIGNAL(gotInferiorPid(Q_PID)),
-        SLOT(handleGotInferiorPid(Q_PID)));
+    connect(m_runner, SIGNAL(gotServerPorts(int,int)),
+        SLOT(handleServerPorts(int,int)));
+    connect(m_runner, SIGNAL(gotInferiorPid(Q_PID, int)),
+        SLOT(handleGotInferiorPid(Q_PID, int)));
     connect(m_runner, SIGNAL(finished(bool)),
         SLOT(handleRemoteProcessFinished(bool)));
 
@@ -177,22 +173,22 @@ IosDebugSupport::~IosDebugSupport()
 {
 }
 
-void IosDebugSupport::handleGdbServerPort(int gdbServerPort)
+void IosDebugSupport::handleServerPorts(int gdbServerPort, int qmlPort)
 {
-    if (gdbServerPort > 0) {
-        m_runControl->engine()->notifyEngineRemoteSetupDone(gdbServerPort, m_qmlPort);
+    if (gdbServerPort > 0 || (m_runner && !m_runner->cppDebug() && qmlPort > 0)) {
+        m_runControl->engine()->notifyEngineRemoteSetupDone(gdbServerPort, qmlPort);
     } else {
         m_runControl->engine()->notifyEngineRemoteSetupFailed(
                     tr("Could not get debug server file descriptor."));
     }
 }
 
-void IosDebugSupport::handleGotInferiorPid(Q_PID pid)
+void IosDebugSupport::handleGotInferiorPid(Q_PID pid, int qmlPort)
 {
     if (pid > 0) {
         //m_runControl->engine()->notifyInferiorPid(pid);
 #ifndef Q_OS_WIN // Q_PID might be 64 bit pointer...
-        m_runControl->engine()->notifyEngineRemoteSetupDone(int(pid), m_qmlPort);
+        m_runControl->engine()->notifyEngineRemoteSetupDone(int(pid), qmlPort);
 #endif
     } else {
         m_runControl->engine()->notifyEngineRemoteSetupFailed(
diff --git a/src/plugins/ios/iosdebugsupport.h b/src/plugins/ios/iosdebugsupport.h
index 020682557549bf33bb48066d90a2aee97e6b8023..8f038904ae356570431b9f3c599d183c087fa6af 100644
--- a/src/plugins/ios/iosdebugsupport.h
+++ b/src/plugins/ios/iosdebugsupport.h
@@ -50,12 +50,12 @@ public:
                                                               QString *errorMessage);
 
     IosDebugSupport(IosRunConfiguration *runConfig,
-        Debugger::DebuggerRunControl *runControl);
+        Debugger::DebuggerRunControl *runControl, bool cppDebug, bool qmlDebug);
     ~IosDebugSupport();
 
 private slots:
-    void handleGdbServerPort(int gdbServerFd);
-    void handleGotInferiorPid(Q_PID);
+    void handleServerPorts(int gdbServerFd, int qmlPort);
+    void handleGotInferiorPid(Q_PID, int qmlPort);
     void handleRemoteProcessFinished(bool cleanEnd);
 
     void handleRemoteOutput(const QString &output);
@@ -65,8 +65,6 @@ private:
     Debugger::DebuggerRunControl *m_runControl;
     IosRunner * const m_runner;
     const QString m_dumperLib;
-
-    int m_qmlPort;
 };
 
 } // namespace Internal
diff --git a/src/plugins/ios/iosruncontrol.cpp b/src/plugins/ios/iosruncontrol.cpp
index 5a12772cd84c0d316026de9229402bf9c7d80f54..491707e18189e6b19855a867d4dff343c53af97e 100644
--- a/src/plugins/ios/iosruncontrol.cpp
+++ b/src/plugins/ios/iosruncontrol.cpp
@@ -42,7 +42,7 @@ namespace Internal {
 
 IosRunControl::IosRunControl(IosRunConfiguration *rc)
     : RunControl(rc, NormalRunMode)
-    , m_runner(new IosRunner(this, rc, false))
+    , m_runner(new IosRunner(this, rc, false, false))
     , m_running(false)
 {
 }
diff --git a/src/plugins/ios/iosrunner.cpp b/src/plugins/ios/iosrunner.cpp
index cb958259600e1af890aa5ee421e2e98fd4067ae4..11dec23ac8e8c54fa3d138f9e5134667d88cfe96 100644
--- a/src/plugins/ios/iosrunner.cpp
+++ b/src/plugins/ios/iosrunner.cpp
@@ -40,10 +40,12 @@
 #include <projectexplorer/target.h>
 #include <projectexplorer/taskhub.h>
 #include <projectexplorer/projectexplorerconstants.h>
+#include <debugger/debuggerrunconfigurationaspect.h>
 
 #include <QDir>
 #include <QTime>
 #include <QMessageBox>
+#include <QRegExp>
 
 #include <signal.h>
 
@@ -52,11 +54,12 @@ using namespace ProjectExplorer;
 namespace Ios {
 namespace Internal {
 
-IosRunner::IosRunner(QObject *parent, IosRunConfiguration *runConfig, bool debuggingMode)
+IosRunner::IosRunner(QObject *parent, IosRunConfiguration *runConfig, bool cppDebug, bool qmlDebug)
     : QObject(parent), m_toolHandler(0), m_bundleDir(runConfig->bundleDir().toString()),
       m_arguments(runConfig->commandLineArguments()),
       m_device(ProjectExplorer::DeviceKitInformation::device(runConfig->target()->kit())),
-      m_debuggingMode(debuggingMode), m_cleanExit(false), m_pid(0)
+      m_cppDebug(cppDebug), m_qmlDebug(qmlDebug), m_cleanExit(false),
+      m_qmlPort(0), m_pid(0)
 {
 }
 
@@ -72,7 +75,10 @@ QString IosRunner::bundlePath()
 
 QStringList IosRunner::extraArgs()
 {
-    return m_arguments;
+    QStringList res = m_arguments;
+    if (m_qmlPort != 0)
+        res << QString::fromLatin1("-qmljsdebugger=port:%1,block").arg(m_qmlPort);
+    return res;
 }
 
 QString IosRunner::deviceId()
@@ -85,11 +91,21 @@ QString IosRunner::deviceId()
 
 IosToolHandler::RunKind IosRunner::runType()
 {
-    if (m_debuggingMode)
+    if (m_cppDebug)
         return IosToolHandler::DebugRun;
     return IosToolHandler::NormalRun;
 }
 
+bool IosRunner::cppDebug() const
+{
+    return m_cppDebug;
+}
+
+bool IosRunner::qmlDebug() const
+{
+    return m_qmlDebug;
+}
+
 void IosRunner::start()
 {
     if (m_toolHandler) {
@@ -97,15 +113,27 @@ void IosRunner::start()
         emit finished(m_cleanExit);
     }
     m_cleanExit = false;
+    m_qmlPort = 0;
     IosToolHandler::DeviceType devType = IosToolHandler::IosDeviceType;
-    if (m_device->type() != Ios::Constants::IOS_DEVICE_TYPE) {
+    if (m_device->type() == Ios::Constants::IOS_DEVICE_TYPE) {
+        IosDevice::ConstPtr iosDevice = m_device.dynamicCast<const IosDevice>();
+        if (m_device.isNull()) {
+            emit finished(m_cleanExit);
+            return;
+        }
+        if (m_qmlDebug)
+            m_qmlPort = iosDevice->nextPort();
+    } else {
         IosSimulator::ConstPtr sim = m_device.dynamicCast<const IosSimulator>();
         if (sim.isNull()) {
             emit finished(m_cleanExit);
             return;
         }
         devType = IosToolHandler::IosSimulatedIphoneRetina4InchType; // store type in sim?
+        if (m_qmlDebug)
+            m_qmlPort = sim->nextPort();
     }
+
     m_toolHandler = new IosToolHandler(devType, this);
     connect(m_toolHandler, SIGNAL(appOutput(Ios::IosToolHandler*,QString)),
             SLOT(handleAppOutput(Ios::IosToolHandler*,QString)));
@@ -114,8 +142,8 @@ void IosRunner::start()
             SLOT(handleDidStartApp(Ios::IosToolHandler*,QString,QString,Ios::IosToolHandler::OpStatus)));
     connect(m_toolHandler, SIGNAL(errorMsg(Ios::IosToolHandler*,QString)),
             SLOT(handleErrorMsg(Ios::IosToolHandler*,QString)));
-    connect(m_toolHandler, SIGNAL(gotGdbserverPort(Ios::IosToolHandler*,QString,QString,int)),
-            SLOT(handleGotGdbserverPort(Ios::IosToolHandler*,QString,QString,int)));
+    connect(m_toolHandler, SIGNAL(gotServerPorts(Ios::IosToolHandler*,QString,QString,int,int)),
+            SLOT(handleGotServerPorts(Ios::IosToolHandler*,QString,QString,int,int)));
     connect(m_toolHandler, SIGNAL(gotInferiorPid(Ios::IosToolHandler*,QString,QString,Q_PID)),
             SLOT(handleGotInferiorPid(Ios::IosToolHandler*,QString,QString,Q_PID)));
     connect(m_toolHandler, SIGNAL(toolExited(Ios::IosToolHandler*,int)),
@@ -144,12 +172,13 @@ void IosRunner::handleDidStartApp(IosToolHandler *handler, const QString &bundle
         emit didStartApp(status);
 }
 
-void IosRunner::handleGotGdbserverPort(IosToolHandler *handler, const QString &bundlePath,
-                                         const QString &deviceId, int gdbPort)
+void IosRunner::handleGotServerPorts(IosToolHandler *handler, const QString &bundlePath,
+                                         const QString &deviceId, int gdbPort, int qmlPort)
 {
     Q_UNUSED(bundlePath); Q_UNUSED(deviceId);
+    m_qmlPort = qmlPort;
     if (m_toolHandler == handler)
-        emit gotGdbserverPort(gdbPort);
+        emit gotServerPorts(gdbPort, qmlPort);
 }
 
 void IosRunner::handleGotInferiorPid(IosToolHandler *handler, const QString &bundlePath,
@@ -158,13 +187,18 @@ void IosRunner::handleGotInferiorPid(IosToolHandler *handler, const QString &bun
     Q_UNUSED(bundlePath); Q_UNUSED(deviceId);
     m_pid = pid;
     if (m_toolHandler == handler)
-        emit gotInferiorPid(pid);
+        emit gotInferiorPid(pid, m_qmlPort);
 }
 
 void IosRunner::handleAppOutput(IosToolHandler *handler, const QString &output)
 {
     Q_UNUSED(handler);
-    emit appOutput(output);
+    QRegExp qmlPortRe(QLatin1String("QML Debugger: Waiting for connection on port ([0-9]+)..."));
+    int index = qmlPortRe.indexIn(output);
+    QString res(output);
+    if (index != -1 && m_qmlPort)
+       res.replace(qmlPortRe.cap(1), QString::number(m_qmlPort));
+    emit appOutput(res);
 }
 
 void IosRunner::handleErrorMsg(IosToolHandler *handler, const QString &msg)
@@ -174,11 +208,16 @@ void IosRunner::handleErrorMsg(IosToolHandler *handler, const QString &msg)
         TaskHub::addTask(Task::Warning,
                          tr("Run failed. The settings in the Organizer window of Xcode might be incorrect."),
                          ProjectExplorer::Constants::TASK_CATEGORY_DEPLOYMENT);
-    else if (msg.contains(QLatin1String("Unexpected reply: ELocked (454c6f636b6564) vs OK (OK)")))
+    else if (msg.contains(QLatin1String("Unexpected reply: ELocked (454c6f636b6564) vs OK (4f4b)")))
         TaskHub::addTask(Task::Error,
                          tr("The device is locked, please unlock."),
                          ProjectExplorer::Constants::TASK_CATEGORY_DEPLOYMENT);
-    emit errorMsg(msg);
+    QRegExp qmlPortRe(QLatin1String("QML Debugger: Waiting for connection on port ([0-9]+)..."));
+    int index = qmlPortRe.indexIn(msg);
+    QString res(msg);
+    if (index != -1 && m_qmlPort)
+       res.replace(qmlPortRe.cap(1), QString::number(m_qmlPort));
+    emit errorMsg(res);
 }
 
 void IosRunner::handleToolExited(IosToolHandler *handler, int code)
diff --git a/src/plugins/ios/iosrunner.h b/src/plugins/ios/iosrunner.h
index abf971c416dffbf8c71d0886fd9246b59593599b..21b1f9a7943db897fa860a79baa64669dab6493f 100644
--- a/src/plugins/ios/iosrunner.h
+++ b/src/plugins/ios/iosrunner.h
@@ -49,7 +49,7 @@ class IosRunner : public QObject
     Q_OBJECT
 
 public:
-    IosRunner(QObject *parent, IosRunConfiguration *m_runConfig, bool m_debuggingMode);
+    IosRunner(QObject *parent, IosRunConfiguration *runConfig, bool cppDebug, bool qmlDebug);
     ~IosRunner();
 
     QString displayName() const;
@@ -58,22 +58,24 @@ public:
     QStringList extraArgs();
     QString deviceId();
     IosToolHandler::RunKind runType();
+    bool cppDebug() const;
+    bool qmlDebug() const;
 public slots:
     void start();
     void stop();
 
 signals:
     void didStartApp(Ios::IosToolHandler::OpStatus status);
-    void gotGdbserverPort(int gdbPort);
-    void gotInferiorPid(Q_PID pid);
+    void gotServerPorts(int gdbPort, int qmlPort);
+    void gotInferiorPid(Q_PID pid, int);
     void appOutput(const QString &output);
     void errorMsg(const QString &msg);
     void finished(bool cleanExit);
 private slots:
     void handleDidStartApp(Ios::IosToolHandler *handler, const QString &bundlePath,
                            const QString &deviceId, Ios::IosToolHandler::OpStatus status);
-    void handleGotGdbserverPort(Ios::IosToolHandler *handler, const QString &bundlePath,
-                                const QString &deviceId, int gdbPort);
+    void handleGotServerPorts(Ios::IosToolHandler *handler, const QString &bundlePath,
+                              const QString &deviceId, int gdbPort, int qmlPort);
     void handleGotInferiorPid(Ios::IosToolHandler *handler, const QString &bundlePath,
                               const QString &deviceId, Q_PID pid);
     void handleAppOutput(Ios::IosToolHandler *handler, const QString &output);
@@ -85,8 +87,10 @@ private:
     QString m_bundleDir;
     QStringList m_arguments;
     ProjectExplorer::IDevice::ConstPtr m_device;
-    bool m_debuggingMode;
+    bool m_cppDebug;
+    bool m_qmlDebug;
     bool m_cleanExit;
+    quint16 m_qmlPort;
     Q_PID m_pid;
 };
 
diff --git a/src/plugins/ios/iostoolhandler.cpp b/src/plugins/ios/iostoolhandler.cpp
index 26de448afbfd596b360c869c3698678803a354b2..6ceb6ede258829fdc0806884e5a638667b524c30 100644
--- a/src/plugins/ios/iostoolhandler.cpp
+++ b/src/plugins/ios/iostoolhandler.cpp
@@ -65,7 +65,7 @@ struct ParserState {
         ControlChar,
         AppStarted,
         InferiorPid,
-        GdbServerPort,
+        ServerPorts,
         Item,
         Status,
         AppTransfer,
@@ -79,6 +79,7 @@ struct ParserState {
     QString value;
     QMap<QString,QString> info;
     int progress, maxProgress;
+    int gdbPort, qmlPort;
     bool collectChars() {
         switch (kind) {
         case Msg:
@@ -87,9 +88,9 @@ struct ParserState {
         case Value:
         case Status:
         case InferiorPid:
-        case GdbServerPort:
         case AppOutput:
             return true;
+        case ServerPorts:
         case QueryResult:
         case ControlChar:
         case AppStarted:
@@ -103,7 +104,7 @@ struct ParserState {
     }
 
     ParserState(Kind kind) :
-        kind(kind) { }
+        kind(kind), gdbPort(0), qmlPort(0) { }
 };
 
 class IosToolHandlerPrivate
@@ -142,7 +143,8 @@ public:
                         IosToolHandler::OpStatus status);
     void didStartApp(const QString &bundlePath, const QString &deviceId,
                      IosToolHandler::OpStatus status);
-    void gotGdbserverPort(const QString &bundlePath, const QString &deviceId, int gdbPort);
+    void gotServerPorts(const QString &bundlePath, const QString &deviceId, int gdbPort,
+                        int qmlPort);
     void gotInferiorPid(const QString &bundlePath, const QString &deviceId, Q_PID pid);
     void deviceInfo(const QString &deviceId, const IosToolHandler::Dict &info);
     void appOutput(const QString &output);
@@ -301,10 +303,10 @@ void IosToolHandlerPrivate::didStartApp(const QString &bundlePath, const QString
     emit q->didStartApp(q, bundlePath, deviceId, status);
 }
 
-void IosToolHandlerPrivate::gotGdbserverPort(const QString &bundlePath,
-                  const QString &deviceId, int gdbPort)
+void IosToolHandlerPrivate::gotServerPorts(const QString &bundlePath,
+                                           const QString &deviceId, int gdbPort, int qmlPort)
 {
-    emit q->gotGdbserverPort(q, bundlePath, deviceId, gdbPort);
+    emit q->gotServerPorts(q, bundlePath, deviceId, gdbPort, qmlPort);
 }
 
 void IosToolHandlerPrivate::gotInferiorPid(const QString &bundlePath, const QString &deviceId,
@@ -439,8 +441,12 @@ void IosToolHandlerPrivate::processXml()
                 stack.append(ParserState(ParserState::DeviceInfo));
             } else if (elName == QLatin1String("inferior_pid")) {
                 stack.append(ParserState(ParserState::InferiorPid));
-            } else if (elName == QLatin1String("gdb_server_port")) {
-                stack.append(ParserState(ParserState::GdbServerPort));
+            } else if (elName == QLatin1String("server_ports")) {
+                stack.append(ParserState(ParserState::ServerPorts));
+                QXmlStreamAttributes attributes = outputParser.attributes();
+                int gdbServerPort = attributes.value(QLatin1String("gdb_server")).toString().toInt();
+                int qmlServerPort = attributes.value(QLatin1String("qml_server")).toString().toInt();
+                gotServerPorts(bundlePath, deviceId, gdbServerPort, qmlServerPort);
             } else {
                 qDebug() << "unexpected element " << elName;
             }
@@ -494,8 +500,7 @@ void IosToolHandlerPrivate::processXml()
             case ParserState::InferiorPid:
                 gotInferiorPid(bundlePath, deviceId, Q_PID(p.chars.toInt()));
                 break;
-            case ParserState::GdbServerPort:
-                gotGdbserverPort(bundlePath, deviceId, p.chars.toInt());
+            case ParserState::ServerPorts:
                 break;
             }
             break;
diff --git a/src/plugins/ios/iostoolhandler.h b/src/plugins/ios/iostoolhandler.h
index e8f4210a7f540082d60501a37b45731a4ada7940..8f163c02f63798b52d5d8aa0e7cceec60e030aa0 100644
--- a/src/plugins/ios/iostoolhandler.h
+++ b/src/plugins/ios/iostoolhandler.h
@@ -81,8 +81,8 @@ signals:
                         const QString &deviceId, Ios::IosToolHandler::OpStatus status);
     void didStartApp(Ios::IosToolHandler *handler, const QString &bundlePath,
                      const QString &deviceId, Ios::IosToolHandler::OpStatus status);
-    void gotGdbserverPort(Ios::IosToolHandler *handler, const QString &bundlePath,
-                            const QString &deviceId, int gdbPort);
+    void gotServerPorts(Ios::IosToolHandler *handler, const QString &bundlePath,
+                            const QString &deviceId, int gdbPort, int qmlPort);
     void gotInferiorPid(Ios::IosToolHandler *handler, const QString &bundlePath,
                         const QString &deviceId, Q_PID pid);
     void deviceInfo(Ios::IosToolHandler *handler, const QString &deviceId,