Editor’s Note
Editorial
T
he fast pace of change in iOS, and many of its associated tools for developing iOS apps, hurtles through the air at tremendous speeds for the software development practice. In an almost wild manner Apple continues to add valuable features to Xcode. Other vendors create tools that either generate Xcode, or their own code, as well as cross platform code. Some tools create web apps, mainly data centric apps, as opposed to graphical or geometry type apps. There are UIWebView apps that have few iOS controls which connect to existing web server solutions; many of these are the ones that are pathetically slow afterthought apps. Others are Web Apps that use only the iOS Safari browser on iOS devices. Often this leaves new developers floundering wondering what to choose. A book, an article or a video produced just two to four years ago can be extremely difficult for new and even some experienced developers to follow. I wondered for a long time why many of my students found patterns difficult to comprehend and put together for use in their code. I believe one culprit that causes some students to have difficulty comprehending deeper concepts and coding abilities is due to some of the newer, simpler Integrated Development Environments (IDE’s). Software companies with good intentions continue to attempt to make things easier and quicker for the developer; however, I believe this comes at a cost. I have found that there is also a strong leaning for new developers to take on a cut-and-paste mentality. So many newer developers on forums continue to make request for working code that they can just paste into their apps. It seems they feel everything should be a simple click, drag, and paste and then everything should just work. Also, some students have asked me why Xcode development cannot be as simple as the now historic Visual Basic used to be? They say all you needed to do was double click on a button you added to your application and you could start typing your code. I will never forget what my University of Waterloo computer science professor Peter Kiriakidas emphasized to our class. He said, “Remember, the more functionality you add into a language the more restrictions you create and restrictions can be both good and they can also be bad”. VB was simple, and it was not an Object Oriented Programming (OOP) language. To have less restrictions with other languages there are just more things a developer needs to take into consideration before starting to code. On the other hand, when it comes to Objective-C, it’s so nice that we can still add straight C code from the 70‘s into our new Objective-C code, and still have it compile and run today. To delegate some complexity to a valuable IDE is a great asset; however, it is also important to understand the interrogative questions of how the thing works. Today, of course a developer using Xcode can simply add a button by dragging it onto their view. They just hold down their control key on their keyboard while they drag from their graphical object (e.g. button) to the correct .h file to add methods and/ or properties related to the graphical objects they previously added to the view. They need only think a bit before they add their property and/or methods; then they can add their code. Thinking before doing is good. In these iOS articles the authors will attempt to create tutorials as well as articles covering various tools, technologies while we will try to steer away from ideologies. I myself am working on a unique education app that will provide developers with short, quick video tutorials to learn how to develop software. I truly believe deeper comprehension is needed by all those developing iOS apps. Let's see what we can do.
team Editor in Chief: Doug Panchyshyn Editorial Advisory Board: Laszlo Acs, Dawid Esterhuien Special thanks to Raul Mesa Special thanks to our Beta testers and Proofreaders who helped us with this issue. Our magazine would not exist without your assistance and expertise. Publisher: Paweł Marciniak Managing Director: Ewa Dudzic Production Director: Andrzej Kuca andrzej.kuca@sdjournal.org Art. Director: Ireneusz Pogroszewski ireneusz.pogroszewski@sdjournal.org DTP: Ireneusz Pogroszewski Marketing Director: Ewa Dudzic Publisher: Hakin9 Media SK 02-676 Warsaw, Poland Postepu 17D Phone: 1 917 338 3631 http://en.sdjournal.org/ Whilst every effort has been made to ensure the highest quality of the magazine, the editors make no warranty, expressed or implied, concerning the results of the content’s usage. All trademarks presented in the magazine were used for informative purposes only. All rights to trademarks presented in the magazine are reserved by the companies which own them.
DISCLAIMER! The techniques described in our magazine may be used in private, local networks only. The editors hold no responsibility for the misuse of the techniques presented or any data loss.
Thank you for subscribing and please visit my website at http://www.DougPan.com
4
08/2013
What do all these have in common?
They all use Nipper Studio to audit their firewalls, switches & routers Nipper Studio is an award winning configuration auditing tool which analyses vulnerabilities and security weaknesses. You can use our point and click interface or automate using scripts. Reports show: 1) Severity of the Threat & Ease of Resolution 2) Configuration Change Tracking & Analysis 3) Potential Solutions including Command Line Fixes to resolve the Issue Nipper Studio doesn’t produce any network traffic, doesn’t need to interact directly with devices and can be used in secure environments.
SME pricing from
£650 scaling to enterprise level
evaluate for free at www.titania.com
www.titania.com T: +44 (0) 1905 888785 en.sdjournal.org
5
Adding Instant Messaging to Your iOS APP
Using XMPP Framework The XMPP protocol is a popular choice for building instant messaging applications. The core XMPP specification and common XMPP extensions give you everything you need out of the box for a full featured chat application including authentication, server side contact lists, online presence and more. XMPPFramework brings the most common XMPP features to the iPhone and iPad in an easy to use and efficient modular framework.
I
nstalling and configuring a production Jabber server is outside the scope of this article however, since you will be needing a server for testing and I recommend installing ejabberd on your local machine. ejabberd is a well developed and reliable XMPP server that supports the core RFC specification as well as many commonly used XEP extensions. It’s available for download here: http://www.process-one.net/en/ejabberd/downloads/. Once you’ve downloaded the installer locate it in finder and right click to select Open. This will launch a wizard to guide you through the initial configuration. In this example we’re running ejabberd on a local machine so you’ll need to make sure you enter your computers network name when you are prompted for the ejabberd server domain. For my macbook air this is “new-host. home”. You’ll also be asked to set the administrator account name and password. Once you’ve configured ejabberd, go ahead and log into the web admin panel by navigating your browser to http://localhost:5280. Your credentials will be adminusername@yourcomputer and the password you had specified during configuration. In my case the admin Jabber ID is admin@new-host.home. Once there you’ll want to add a couple of test users. You can do this by drilling down from the Virtual Hosts page to the Users page (under the selected virtual host). From here you can add users as well as view all registered users and
their online status. For my installation I’ve created two users named auser and auser2. Before we create an iOS app let’s make sure our server is working and our test users can talk to each other. Since you’re using a mac to follow along, the quickest way to get this done is to add your test user accounts to the Messages/iChat client and have them message each other. Once you’ve opened up the Messages application, navigate to the Messages menu and select Preferences to open the preferences dialog. From here you’ll select the Accounts tab. In the lower left corner you will click the plus (+) button to add a new account. Select “Jabber” for account type, enter the Jabber ID/ password for your test account and click Done. You must enter the JID and not just the user name. The JID (Jabber ID) is like an email address and contains the user and domain separated by an @ symbol. In my example the JID is auser@new-host.home. Repeat this process for each test account you’ve created. Once you have added the accounts send a message back and forth between them. If everything seems to be in order then it’s time to create the iOS client.
What you will need...
• A mac with the latest Xcode environment • if you are adding chat to an existing project you will also need to ensure the project is using ARC (automatic reference counting) or you can direct the compiler to compile all the XMPPFramework dependencies using ARC. Figure 1. Setting up ejabberd users
6
08/2013
Adding the XMPPFramework to your project
First you’ll need to download the latest stable XMPPFramework version from get hub to a new directory. In my example I’ve created a new directory called ~/ XMPPFramework/. To get the latest run the following in Terminal: git clone https://github.com/robbiehanson/ XMPPFramework.git ~/XMPPFramework/. Note that if you are intending to create a new iOS project for a chat application then you may want to use the prebuilt Xcode project that is included in the XMPPFramework (path/to/XMPPFramework/Xcode/iPhoneXMPP/) and Listing 1. app delegate header #import <UIKit/UIKit.h>
#import “XMPPFramework.h” @class ViewController; @interface MyChatClientAppDelegate : UIResponder <UIApplicationDelegate>
{
XMPPStream *xmppStream; NSString *password;
BOOL allowSelfSignedCertificates; BOOL allowSSLHostNameMismatch; BOOL isXmppConnected;
}
@property (nonatomic, strong, readonly) XMPPStream *xmppStream;
@property (strong, nonatomic) UIWindow *window; @property (strong, nonatomic) ViewController *viewController;
- (BOOL)xmppConnect;
- (void)xmppDisconnect; @end
Listing 2. app delegate implementation @implementation MyChatClientAppDelegate @synthesize xmppStream;
- (BOOL)application:(UIApplication *)application did FinishLaunchingWithOptions:(NSDi
{
ctionary *)launchOptions // add these function calls below your
boilerplate code and before the method returns...
[self setupStream]; [self xmppConnect];
en.sdjournal.org
skip to the end of this article for the production summary. You’ll need to import some of the folders that you’ve just downloaded in to the working copy of the XMPPFramework project. Let’s make a place for them in your Xcode project by creating a new group called XMPPFramework. Now, drag and drop the folders and files below into your Xcode project. • Authentication • Categories • Core
• • • •
Extensions Utilities Vendor Sample_XMPPFramework.h
When the “Choose option for adding these files” dialog appears, select the checkbox for “Copy items into destination group’s folder (if needed)”. Once you’ve added the files to your project, you’ll need to rename the newly added Sample_XMPPFramework.h to XMPPFramework.h. This is the file that you will use
Listing 3. SetupStream method in the app delegate implementation
home/iPhoneXmppClient”]];
- (void)setupStream
password = @”poi987”;
NSAssert(xmppStream == nil, @”Method setupStream
NSError *error = nil;
{
invoked multiple times”);
if (![xmppStream connectWithTimeout:XMPPStreamTimeo utNone error:&error]) {
// Setup xmpp stream
NSLog(@”Error connecting: %@”, error);
// The XMPPStream is the base class for all
}
return YES;
//
activity.
// Everything else plugs into the xmppStream,
such as modules/extensions and delegates.
return NO;
}
xmppStream = [[XMPPStream alloc] init];
- (void)xmppDisconnect
#if !TARGET_IPHONE_SIMULATOR
xmppStream.enableBackgroundingOnSocket = YES; #endif
[xmppStream addDelegate:self
delegateQueue:dispatch_get_main_ queue()];
// You may need to alter these settings depending on the server you’re connecting to
// [xmppStream setHostName:@”new-host.home”];
// [xmppStream setHostPort:5222];
allowSelfSignedCertificates = NO;
allowSSLHostNameMismatch = NO; }
Listing 4. xmppConnect and xmppDisconect methods in the app delegate implementation - (BOOL)xmppConnect {
if (![xmppStream isDisconnected]) {
}
[xmppStream setMyJID:[XMPPJID
return YES;
8
jidWithString:@”noodle@new-host.
{ }
[xmppStream disconnect];
Listing 5. XMPPStream authentication delegate methods - (void)xmppStreamDidConnect:(XMPPStream *)sender {
isXmppConnected = YES; NSError *error = nil;
if (![[self xmppStream] authenticateWithPassword:pa ssword error:&error])
NSLog(@”Error authenticating: %@”, error); }
- (void)xmppStreamDidAuthenticate:(XMPPStream *)sender { }
[self sendTestChatMessage];
- (void)xmppStream:(XMPPStream *)sender didNotAuthenti { }
cate:(NSXMLElement *)error
NSLog(@”%s: %@”, __func__, error);
08/2013
XMPP Framework
to customize which XMPP extensions are compiled in to your app. Next you’ll need to link the library files. To do this you’ll click on your project name (in the left side project navigation), then select the build target and click on the Build Phases tab. From here let’s add the following libraries: • CFNetwork.framework • CoreData.framework • CoreLocation.framework
• • • •
libresolv.dylib Security.framework SystemConfiguration.framework Vendor/libidn/libidn.a
You’ll need to tell the compiler where to find the headers for some of the newly added dependencies. Let’s point it to /usr/include/libxml2/. Under the project settings find user header search paths and add a new row for /usr/include/libxml2/. If you are getting com-
Listing 6. Inbound message handler methods in the app delegate implementation - (void)xmppStream:(XMPPStream *)sender didReceiveMessage:(XMPPMessage *)message {
if ([message isChatMessageWithBody]) {
NSString *body = [[message elementForName:@”body”] stringValue]; if ([[UIApplication sharedApplication] applicationState] == UIApplicationStateActive) {
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@”Incoming Message” message:body
delegate:nil
cancelButtonTitle:@”Ok” [alertView show]; }
}
}
otherButtonTitles:nil];
else { }
// message is black holed since app is in background
- (void)xmppStream:(XMPPStream *)sender didReceivePresence:(XMPPPresence *)presence {} - (void)xmppStream:(XMPPStream *)sender didReceiveError:(id)error {} - (BOOL)xmppStream:(XMPPStream *)sender didReceiveIQ:(XMPPIQ *)iq { }
return YES;
Listing 7. Outbound message test method in the app delegate implementation - (void)sendTestChatMessage {
NSXMLElement *body = [NSXMLElement elementWithName:@”body”]; [body setStringValue:@”Yay, we’ve connected!”];
NSXMLElement *message = [NSXMLElement elementWithName:@”message”]; [message addAttributeWithName:@”type” stringValue:@”chat”];
[message addAttributeWithName:@”to” stringValue:@”auser2@new-host.home”]; [message addChild:body];
}
[[self xmppStream] sendElement:message];
en.sdjournal.org
9
piler errors such as “libxml/tree.h not found” ensure you’ve set Always Search User Paths under project settings, to Yes. You’ll also need to add a linking flag at the project level. Under project settings find other linker flags and add a new row for -lxml2. This should take care of basic configuration. If your project requires the use of additional XMPP extensions in your project you may need to resolve more dependencies. For further documentation, visit the XMPPFramework github project site.
Assigning a delegate
In order to hook your code in to the functionality of XMPPFramework you’ll need to specify a delegate. For simplicity we’ will assign the app delegate as the xmppStream delegate from within itself. Open up your app delegate header and add all the non-boilerplate lines from Listing 1. The XMPPStream object is where all the magic happens and we’ll be using it to assign the delegate in the app delegate implementation. Next you’ll need to synthesize the accessor methods to the XMPPStream object. To do this add @synthesize xmppStream; to the top of your implementation. We’ll also go ahead and add two new calls in application: didFinishLaunchingWithOptions: to a couple of methods that we will define in a minute, setupStream and xmppConnect. The top of your implementation should look something like the Listing 2. Now lets add the setupStream method where we will assign the XMPPStream delegate and configure some connection settings (Listing 3). Reading through the code you’ll see that there are some settings you may need to tweak if you’re not using an out of the box ejabberd installation for this walkthrough. Next we’ll add the xmppConnect method (Listing 4).
Authentication
At this point we’re ready to add a few methods that will authenticate the Jabber user and handle a success or failure case (Listing 5).
Handling an inbound message
As you can see, xmppStream takes care of configuration, establishing a connection and tearing it down. It also knows how to handle inbound messages and calls the delegates that will handle each message type (Listing 6). Here we are handling a chat message and displaying the body in an alert dialog. There are also a few empty methods that are shown for documentation purposes. When developing a more feature full app you will need to handle all message types. Figure 2. Example
10
On the Web
• https://github.com/robbiehanson/XMPPFramework/ – home of the XMPPFramework project, • http://www.process-one.net/en/ejabberd/downloads/ – ejabberd binaries download page. • http://www.turnkeylinux.org/ejabberd/ – ejabberd appliance.
Glossary
Jabber ID or JID: The Jabber ID, much like an email address, is a combination of a user and domain separated by an @ symbol. Additionally a Jabber ID may contain a resource which is most often used for specifying the user agent or device name. An example: bob@bigcompany.com/iphone XMPP: eXtensible Messaging and Presence Protocol is a suite of related protocols designed for creating message oriented middleware systems.
Creating and Sending a message
Earlier we defined the xmppStreamDidAuthenticate method which is called after a user has authenticated with the server. There we are calling our not yet defined outbound message test method. Let’s define that now (Listing 7).
Production Notes • If your messages are sensitive it’s recommended that you configure your Jabber server to only accept encrypted connections. • XMPP presence messages can be power hungry. Sending and receiving fewer of them is a good start for improving battery life. One way to do this is using the privacy lists extension (XEP-0016).
Summary
There are many uses for XMPP beyond chat applications such as push notification, API tunneling (there is a SOAP specific extension) or distributed workflow applications. Using the modular and multithreaded XMPPFramework gives you the ability to reliably deliver advanced features and applications on OSX and iOS based devices. If you are developing an application based on a more obscure XEP specification, then XMPPFramework provides a core platform for you to build from.
Alan Synnestvedt The author has been developing data driven applications for over a decade while working in Healthcare, Telecommunication and B2B Services markets. He has a current focus in mobile applications and is a founding partner of BRAVE GENIUS, where the team brings new software and technology products to market in the northeastern US.
08/2013
Find your way through the data centre maze The modern datacentre is transforming, impacted by efficiency demands, new design concepts, legislation and IT innovation, solutions that worked yesterday can soon be rendered uncompetitive or even obsolete. The Datacentre Transformation Conference sets out to help steer you through the maze of requirements and developments.
Register today to secure your place
www.dtconference.com
Sponsored by:
In Association with:
nt lle ng ! ce rki es Ex two niti u Ne ort p Op
9 July 2013 aql Conference Auditorium, Salem Church, Leeds