Skip to content

Instantly share code, notes, and snippets.

@coolmenu
Forked from democ/iPhone开发中使用ZMQ.md
Created November 3, 2016 10:06
Show Gist options
  • Save coolmenu/d2ed0885b90a326a739e5e0f755a30f1 to your computer and use it in GitHub Desktop.
Save coolmenu/d2ed0885b90a326a739e5e0f755a30f1 to your computer and use it in GitHub Desktop.

如果你的iOS项目项目中要使用zmq,那么肯定会涉及到以下问题:

  • Compiling Libzmq as a Universal Static Library for iOS
  • Use Libzmq in project

Step 1)prepare the zeromq sources for iOS

  • download the POSIX tarball from zeromq web site

  • uncompress the tarball

  • enter the zeromq- directory and run “./configure”. We do not need to mess around with configure script parameters for architecture, static linking, … The defaults for OS X are fine.

  • Remove from the src folder everything that is not “.cpp” or “.hpp” (makefiles, *.in files, …). You can do it manually or executing "cd src ; rm -r ls | egrep -v \.cpp\$ | egrep -v \.hpp\$ .deps ; cd .."

Step 2)prepare the iOS framework

  • Create a new project
  1. File -> New -> New Project (Command-Shift-N)
  2. Select Frameworks & Libraries under iOS
  3. Select “Cocoa Touch Static Library” and click “Next”
  4. Provide a name for the library
  • Configure architectures

By default the static library is configured to only build for armv7 so we need to add armv6 and i386 to ensure that the static library is built for older devices (iPhone 3G/Original, early generation iPod Touch) and the simulator.

Alt text

ps:我在这一步的时候将Project也按上面的图片进行了设置

Step 3)import the zeromq sources in the iOS project

  • drag the folders zeromq-/src and zeromq-/include (checking the option to add the sources to the existing zeromq-framework target)

![Alt text](drag the folders zeromq-/src and zeromq-/include (checking the option to add the sources to the existing zeromq-framework target) "import the zeromq sources in the iOS project")

Step 4)Create aggregate target

An aggregate target aggregates other targets together. In effect, it wraps a number of script executables and copy file tasks in a specified order.

  1. File -> New Target
  2. Select “Other” under iOS
  3. Select “Aggregate”
  4. Give it a name ("zeromq-ios" for example)

Alt text

Step 5)Build static libaries

Under the “Build Phases” section of the aggregate target we are going to add a build phase that compiles a static library for i386 and ARM. In the next step we’ll merge the binaries into a fat binary.

  1. Select zeromq-ios target
  2. Select “Build Phases”
  3. Click “Add Build Phase” (如果你使用Xcode5 请从工具栏操作 "Editor > Add Build Phase")
  4. Select “Add Run Script Build Phase”
  5. Name it “Build Static Libs”
  6. Paste the code below to the "Build Static Libs" script

ps:如果上面的选项出现灰色无法进行操作的话,就在Project和Targets来回点击一下就行了.

        xcodebuild -project ${PROJECT_NAME}.xcodeproj -sdk iphonesimulator -target ${PROJECT_NAME} -configuration ${CONFIGURATION} clean build CONFIGURATION_BUILD_DIR=${BUILD_DIR}/${CONFIGURATION}-iphonesimulator
         
        xcodebuild -project ${PROJECT_NAME}.xcodeproj -sdk iphoneos -target ${PROJECT_NAME} -configuration ${CONFIGURATION} clean build CONFIGURATION_BUILD_DIR=${BUILD_DIR}/${CONFIGURATION}-iphoneos

Alt text

Step 6)Build universal binary

We are going to add another “Run Script” phase that builds the framework itself. The script is going to:

Create a directory structure that mimics the same directory structure seen in Apple’s dynamic frameworks:

        SIMULATOR_LIBRARY_PATH="${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/lib${PROJECT_NAME}.a" &&
        DEVICE_LIBRARY_PATH="${BUILD_DIR}/${CONFIGURATION}-iphoneos/lib${PROJECT_NAME}.a" &&
        UNIVERSAL_LIBRARY_DIR="${BUILD_DIR}/${CONFIGURATION}-iphoneuniversal" &&
        UNIVERSAL_LIBRARY_PATH="${UNIVERSAL_LIBRARY_DIR}/${PRODUCT_NAME}" &&
        FRAMEWORK="${UNIVERSAL_LIBRARY_DIR}/${PRODUCT_NAME}.framework" &&
         
        # Create framework directory structure.
        rm -rf "${FRAMEWORK}" &&
        mkdir -p "${UNIVERSAL_LIBRARY_DIR}" &&
        mkdir -p "${FRAMEWORK}/Versions/A/Headers" &&
        mkdir -p "${FRAMEWORK}/Versions/A/Resources" &&
         
        # Generate universal binary for the device and simulator.
        lipo "${SIMULATOR_LIBRARY_PATH}" "${DEVICE_LIBRARY_PATH}" -create -output "${UNIVERSAL_LIBRARY_PATH}" &&
         
        # Move files to appropriate locations in framework paths.
        cp "${UNIVERSAL_LIBRARY_PATH}" "${FRAMEWORK}/Versions/A" &&
        ln -s "A" "${FRAMEWORK}/Versions/Current" &&
        ln -s "Versions/Current/Headers" "${FRAMEWORK}/Headers" &&
        ln -s "Versions/Current/Resources" "${FRAMEWORK}/Resources" &&
        ln -s "Versions/Current/${PRODUCT_NAME}" "${FRAMEWORK}/${PRODUCT_NAME}"

Step 7) Copy header files into place

  1. Select “Add Build Phase”
  2. Click “Add Copy Files”
  3. Set “Destination” to “Absolute Path”
  4. Set subpath to ${BUILD_DIR}/${CONFIGURATION}-iphoneuniversal/${PRODUCT_NAME}.framework/Versions/A/Headers/
  5. Add header files that should be public to the list. (这里就是include文件家写的zqm.h, zmq_utils.h)

Alt text

Now you should have a universal framework containing zeromq ! But … where is it located ? It has been deployed somewhere below /Library/Developer/Xcode/DerivedData/… In order to find the just built framework, expand the “Product” group and do a right click on the product, choosing “Show in finder”. Et voilà, you have a “Release-iphoneuniversal” containing a “zeromq-ios.framework” (or whatever name you chose) that is your zeromq ios universal framework !

Alt text

Alt text

Release-iphoneuniversal下的东西就是你要的东西啦!!!

Step 8)write a ios client using the brand new zeromq framework

  1. just create a normal ios project
  2. drag the ”zeromq-ios.framework” folder in the “Release-iphoneuniversal” (check the copy checkbox)
  3. click on the project, build settings, add “-lstdc++” to “Other Linker Flags” (the C++ standard library is needed by zeromq)
  4. add the framework headers (just add “$(SRCROOT)/zeromq-ios.framework/Headers”) to the “Header Search Path”compiler directive
  5. just use normally zeromq in your application (the only note about is that you should #include ”zmq.h” instead of #include <zmq.h>)

到目前一个可以在iphone开发项目中使用的zmq静态库就算完成了.

附赠 objc-zmq: an Objective-C binding to zmq

Github code

  1. 下载上面的仓库然后解压
  2. 将 "Classes > objec-zmq"文件下的文件引入到你的项目中

下面的代码进行了reqZMQ,subZMQ

        -(void) requestZMQ
        {
            // Do any additional setup after loading the view, typically from a nib.
            //  Socket to talk to clients
            ZMQContext *ctx = [[ZMQContext alloc] initWithIOThreads:1];
            NSString *endpoint = @"tcp://officevpn.raoheng.net:10010";
            ZMQSocket *requester = [ctx socketWithType:ZMQ_REQ];
            
            BOOL didConnect = [requester connectToEndpoint:endpoint];
            if (!didConnect) {
                NSLog(@"*** Failed to connect to endpoint [%@].", endpoint);
            }
            int kMaxRequest = 10;
            NSData *request = [@"13599832991039421,user1,123,getHistory,^XAUUSD,2,1,10,4EC514F8CDA44339A3367E7ECF53BC1E" dataUsingEncoding:NSUTF8StringEncoding];
            for (int request_nbr = 0; request_nbr < kMaxRequest; ++request_nbr) {
                
                [requester sendData:request withFlags:0];
                NSLog(@"Sending request %d.", request_nbr);
                
                //            NSLog(@"Waiting for reply");
                NSData *reply = [requester receiveDataWithFlags:0];
                NSString *text = [[NSString alloc] initWithData:reply encoding:NSUTF8StringEncoding];
                NSLog(@"Received reply %d: %@", request_nbr, text);
                
                
            }
        }

        -(void) subZMQ
        {
            ZMQContext *ctx = [[ZMQContext alloc] initWithIOThreads:1];
            NSString *endpoint = @"tcp://officevpn.raoheng.net:10086";
            ZMQSocket *requester = [ctx socketWithType:ZMQ_SUB];
            BOOL didConnect = [requester connectToEndpoint:endpoint];
            BOOL didSub =  [requester subscribeAll];
            
            if (!didConnect) {
                NSLog(@"*** Failed to connect to endpoint [%@].", endpoint);
            }
            if (!didSub) {
                NSLog(@"*** Failed to subing");
            }
            while (1) {
                NSData *reply = [requester receiveDataWithFlags:0];
                NSString *text = [[NSString alloc] initWithData:reply encoding:NSUTF8StringEncoding];
                NSLog(@"Received reply %@", text);
                
            }
            
        }


        - (void)viewDidLoad
        {
            [super viewDidLoad];
        //    [self subZMQ];
            [self requestZMQ];


        }

参考资料:

  1. zmq wiki
  2. zeromq on ios
  3. [Building a Universal Framework for iOS](Building a Universal Framework for iOS)
  4. objc-zmq
  5. Creating a Static Library in iOS Tutorial

ZMQ使用相关:

  1. ZMQ:Socket
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment