编译 Qt with Openssl for IOS

时间:2021-06-17 13:12:47

前提:  最新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 QNetworkAccessManagers 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即可.