前提: 最新xcode , git ,
在编译之前最好已经安装 ios developer program开发者证书等.
一,下载编译openssl for ios,并设置环境环境变量
$ cd work/qt_ios
$ git clone https://github.com/x2on/OpenSSL-for-iPhone.git
$ cd OpenSSL-for-iPhone/
$ ./build-libssl.sh
编译完成后,设置环境变量 : EXPORT OPENSSL_LIBS = /Users/dynavin/work/qt_ios/OpenSSL_for_iPhone
二,下载编译qt with Openssl
$ cd work/qt_ios
$ git clone git://gitorious.org/qt/qt5.git qt5
$ cd qt5
$ git checkout 5.4 //我编译的是qt5.4
$ ./init-repository --no-webkit //用不到webkit.如需要重新执行此命令那个 ./init-repository --no-webkit -f 等待下载完成
$ ./configure -xplatform macx-ios-clang -developer-build -opensource -release -nomake examples -nomake tests -confirm-license -openssl-linked -I/Users/dynavin/work/qt_ios/OpenSSL-for-iPhone/include/ -L/Users/dynavin/work/qt_ios/OpenSSL-for-iPhone/lib -lcrypto -lssl -sdk iphoneos
//配置的时候如果不指定sdk的话默认包括simulator和 device 库,但是qmake的时候不能指定多个库,所有如果需要用到simulator和device这两个库的话,建议分开编译两次,最好选择sdk iphoneos 或者 iphonesimulator.
$ make -j4
make的时候可能会出现一些Codesign Error之类的错误,找到指定的xcodeproject文件重新配置一下,或者在xcode中删掉以前的证书等,全部重新生成,然后在编译.
使用SSL 到工程中
在项目工程pro文件中加入
ios {
LIBS += -L/Users/hugo/tmp/OpenSSL-for-iPhone/lib/ -lssl -lcrypto
}
在用QNetworkAccessManager的时候出现
SSL handshake failed
如果在qml中出现此问题
To handle SSL errors like this, I need to provide a custom class to theQQmlApplicationEngine
that derives from QQmlNetworkAccessManagerFactory
and override the create
method to provide the QNetworkAccessManager
s that are used in QML. On these QNetworkAccessManager
instances, SSL errors can be handled by providing the ignoreSSLErrors
slot. For example, to ignore all SSL errors:
加入代码:
class SSLSafeNetworkAccessManager : public QNetworkAccessManager { Q_OBJECT public: SSLSafeNetworkAccessManager(QObject *parent = 0); public slots: void ignoreSSLErrors(QNetworkReply* reply,QList errors); }; SSLSafeNetworkAccessManager::SSLSafeNetworkAccessManager(QObject *parent) : QNetworkAccessManager(parent) { QObject::connect(this,SIGNAL(sslErrors(QNetworkReply*,QList)), this,SLOT(ignoreSSLErrors(QNetworkReply*,QList))); } void SSLSafeNetworkAccessManager::ignoreSSLErrors(QNetworkReply* reply,QList errors) { reply->ignoreSslErrors(errors); }
class SSLSafeNetworkFactory : public QObject, public QQmlNetworkAccessManagerFactory { Q_OBJECT public: virtual QNetworkAccessManager *create(QObject *parent); }; QNetworkAccessManager* SSLSafeNetworkFactory::create(QObject *parent) { SSLSafeNetworkAccessManager* manager = new SSLSafeNetworkAccessManager(parent); return manager; }
Finally, I need to instruct my QQmlApplicationEngine
to use this factory class. This must be done before loading any QML:
QQmlApplicationEngine engine {}; engine.setNetworkAccessManagerFactory(new SSLSafeNetworkFactory);
在C++中出现问题
class SslNetworkAccessManager : public QNetworkAccessManager { Q_OBJECT public: SslNetworkAccessManager(); protected: QNetworkReply* createRequest(Operation op, const QNetworkRequest & req, QIODevice * outgoingData = 0); }; And the implementation: SslNetworkAccessManager::SslNetworkAccessManager() { } QNetworkReply* SslNetworkAccessManager::createRequest(Operation op, const QNetworkRequest& req, QIODevice* outgoingData) { QNetworkReply* reply = QNetworkAccessManager::createRequest(op, req, outgoingData); reply->ignoreSslErrors(); return reply; }
用SslNetworkAccessManager替代QNetworkAccessManager即可.