编译 Qt with Openssl for IOS
前提: 最新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即可.