|
iPhone
How to use XMPP Framework on the iPhone
IntroductionThe default project in subversion is a normal Xcode destop project. However, the XMPP Framework is compatible with the iPhone. DetailsIt's best to work step by step. Step 1Copy AsyncSocket.h and AsyncSocket.m to your iPhone project. AsyncSocket requires CFNetwork, so if this isn't already added to your project, you'll need to do that now: In Xcode, click Project -> Add to project... Then add /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS2.X.sdk/System/Library/Frameworks/CFNetwork.framework (Where iPhoneOS2.X.sdk is whatever version you have, such as 2.1, 2.2, etc) Now check to make sure your project compiles. Step 2The iPhone does not currently come with the NSXML classes (such as NSXMLDocument, NSXMLElement, NSXMLNode, etc). To get around this problem, the XMPP framework uses the open-source KissXML project, which provides NSXML replacement classes for the iPhone. KissXML is already included in the XMPP framework code. Add the KissXML folder to your iPhone project. You may notice in the DDXML.h file that on the iPhone, the NSXML classes are defined to be their DDXML class equivalents. You are encouraged to use the NSXML names in your project. This way, if Apple ever makes the NSXML classes available on the iPhone, the transition will be seamless for you. KissXML depends on libxml, and the KissXML project provides instructions (with pictures) on how to configure Xcode. Follow the instructions on the KissXML Getting Started page. Now check to make sure your project compiles. Step 3Add all the files with filenames that start with "XMPP" to your project. Also add these files:
Do NOT add SCNotificationManager. This class is not compatible with the iPhone. Your project won't compile at this point due to LibIDN.m. Step 4In the XMPP framework there is a folder named "libidn". Add the two header files to your project:
Your project won't link at this point. Step 5Now we need to add the libidn.a library to the project. After a bit of trial and error, this section has been updated to make it easier to compile The XMPP framework includes two versions of the library, one compiled for Mac OS X, and the other compiled for the iPhone. If you simply add the desktop version of the library to your project, it will work on the simulator but not on the phone. If you simply add the iPhone version of the library to your project, it will work on the phone but not on the simulator. Follow these steps to properly add the libidn library to your iPhone project. From the XMPP framework:
Notice the spelling and capitalization of the "iphoneos" and "iphonesimulator" directories. These must be exact, because we're going to use the environment variable "${PLATFORM_NAME}" in Xcode later. Now open the Xcode project settings, select "All Configurations", and search for "other_ldflags". If you followed step 2, this should already have a "-lxml2" value in it. Add another value now for "-lidn"
Now search for "search_paths". If you followed step 2, you should already have "/usr/include/libxml2" in your "Header Search Paths". Now edit your "Library Search Paths" like so:
That value you're entering is "$(SRCROOT)/libidn/${PLATFORM_NAME}" (including the quotes). The values in ${} are environment variables that Xcode will automatically replace. When you're compiling for the simulator the ${PLATFORM_NAME} value will get replaced with iphonesimulator. And when you're compiling for the device, it will get replaced with iphoneos. Your project settings should now look something like this (note the selected options):
You should now be able to easily compile the xmpp framework for the simulator or the device. |
Sign in to add a comment
Thanks for doing this work.
However, I have trouble following your instructions. There is no KissXML in the XMPP. I did not find an idn-int.h or stringprep.h either
KissXML is a folder within the trunk: http://code.google.com/p/xmppframework/source/browse/#svn/trunk/KissXML
ind-int.h and stringprep.h are within the libidn folder: http://code.google.com/p/xmppframework/source/browse/#svn/trunk/libidn
I found it easier to just add a Run Script phase that used the PLATFORM_NAME environment var to copy one of the libs.
mv iPhone iphoneos mv MacOS iphonesimulator cat > mklibidn.sh #!/bin/sh
BASEDIR=$(dirname $0) cp -f ${BASEDIR}/${PLATFORM_NAME}/libidn.a ${BASEDIR}/libidn.a
In XCode: Add ${XMPPFRAMEWORK_PATH}/libidn/libidn.a to the target Add Run Script to the target "exec ${XMPPFRAMEWORK_PATH}/libidn/mklibidn.sh"
Hey, so it turns out that there's an even better solution for libidn linking. Make the two versions as before, but put both libidn-simulator.a and libidn-iPhone.a in one target and Xcode will figure it at link time (one will fail, but that doesn't stop the other from working).
Works for me.
I installed the XMPP files as described above, including the additions in the comments and my code compiles (with warnings noted above) and runs on the iPhone simulator, but when I compile for the iPhone Device (with the correct version of libidn.a), I get the linking errors below. It looks like stringprep isn't finding what it needs in the right place. Does anyone know how to correct this? Thanks.
Building target “Contineo” of project “Contineo” with configuration “Release” — (4 errors, 13 warnings)
ld warning: in /Users/david/Development/Contineo/XMPP/libidn/Mac/libidn.a, missing required architecture arm in file Undefined symbols:
"stringprep_nameprep", referenced from: stringprep_nameprep$non_lazy_ptr in LibIDN.o "stringprep", referenced from: "stringprep_xmpp_nodeprep", referenced from: ld: symbol(s) not found collect2: ld returned 1 exit statusHi DShaneNYC,
I just tried compiling it on my machine for the device, v2.2. It worked fine. Did you remember to add the files "idn-int.h" and "stringprep.h" to your project?
Hi ryandjohnson,
It appears some SystemConfiguration? stuff has been deprecated. You can simply remove the SCNotificationManager files from the project. They only serve one purpose - to notify XMPPClient when a network connection becomes available, in order to facilitate auto-reconnecting. There may be another way to do this on the iPhone...
Thanks for your help. I figured it out. It seems that the libidn/Mac directory is in the linker library search path before its parent: -L/Users/david/Development/Contineo/XMPP/libidn/Mac -L/Users/david/Development/Contineo/XMPP/libidn so it got chosen first. When I removed it from the project all compiled corectly.
I've updated the instructions to fix those nasty hacks for getting libidn to properly link.
For general questions about the xmpp framework, please use the XMPPFramework Mailing List.
Just a comment (two in fact): So 1: Thanks for this remarkable work 2: How can you deploy SSCrypto on iPhone ????
The XMPPFramework doesn't use SSCrypto when running on the iPhone. In this case it uses CommonCrypto?. (See the file NSDataAdditions.m) You should not include SSCrypto in your iPhone project.
In case you still have 4 errors during linking stringprep, I had confused the two libidn.a files.
As of iPhone OS3.0 the deprecated SC functions are removed from the SDK. I got the project to compile by removing SCNotificationManager from the project and by commenting out the places where it was referenced in XMPPClient. Including any references to @selector(attemptReconnect).
I guess it should still be possible to implement reachability functionalities similar to Apple's Reachability.app sample code.
during builds for OS3.0b5 devices I get the following warnings about some object files in libidn.a missing missing architecture information for armv6. Am I doing something wrong or are these OK?
warning: (armv6) /Users/ekurutepe/development/iPhone/xmppTest/libidn/iphoneos/libidn.a(stringprep.o) object file '/Users/ekurutepe/development/iPhone/xmppTest/libidn/iphoneos/libidn.a(stringprep.o)' doesn't contain architecture information for armv6. warning: (armv6) /Users/ekurutepe/development/iPhone/xmppTest/libidn/iphoneos/libidn.a(nfkc.o) object file '/Users/ekurutepe/development/iPhone/xmppTest/libidn/iphoneos/libidn.a(nfkc.o)' doesn't contain architecture information for armv6. warning: (armv6) /Users/ekurutepe/development/iPhone/xmppTest/libidn/iphoneos/libidn.a(profiles.o) object file '/Users/ekurutepe/development/iPhone/xmppTest/libidn/iphoneos/libidn.a(profiles.o)' doesn't contain architecture information for armv6. warning: (armv6) /Users/ekurutepe/development/iPhone/xmppTest/libidn/iphoneos/libidn.a(rfc3454.o) object file '/Users/ekurutepe/development/iPhone/xmppTest/libidn/iphoneos/libidn.a(rfc3454.o)' doesn't contain architecture information for armv6.
Hi ekurutepe,
The compiler is telling you that you're linking to a libidn.a, but that the file doesn't contain a library in the proper architecture. You likely got the files backwards. E.g. you're linking to the iphone-simulator libidn file when compiling for the device, or vice-versa.