iPhone: Why not use NSMutableDictionary to communicate with an API?

In this “tutorial” I will show you how I use an NSMutableDictionary object on the iPhone to make calls to an PHP API I wrote.

The code is far from being ready for production, it’s more an indication of how communication between iPhone and webapplications can be done. Because Apple didn’t gave us much to do that.

Wouldn’t it be nice to just fill a NSMutableDictionary object with data and POST it to an URL, and get a NSDictionary object in return with the result of the API call?

Something like this:

1
2
3
4
5
6
NSMutableDictionary *dict   = [NSMutableDictionary dictionaryWithCapacity:3];
NSMutableDictionary *params = [NSMutableDictionary dictionaryWithCapacity:1];
[dict setValue:@"com.yourcompany.package" forKey:@"package"];
[dict setValue:@"methodToCal" forKey:@"method"];
[params setValue:[NSNumber numberWithInt:4] forKey:@"limit"];
[dict setValue:params forKey:@"params"];

The ‘dict’ object is the object we send to the server, with the APIHelper class it’s converted to plist xml data, and the PHP API parses the xml. Load the requested package, and makes the method call.

The return value of this method call is then sent back to the iPhone and the APIHelper reads it and makes a nice NSDictionary object for you.

APIHelper.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
//
//  APIHelper.h
//  APIHelperDemo
//
//  Created by Jeroen van Wissen on 10/10/08.
//  Copyright 2008 FastOne Internet Services. All rights reserved.
//

#import

#define HTTPS_API @"https://api.yourcompany.com/"

@protocol APIHelperDelegate
@required
- (void)apiCallResult:(NSDictionary *)dict;
@end

@interface APIHelper : NSObject {
id delegate;
NSMutableData *receivedData;
NSDictionary  *receivedDict;
}

@property (nonatomic, retain) NSMutableData *receivedData;
@property (nonatomic, retain) NSDictionary *receivedDict;
@property (nonatomic,assign) id  delegate;

- (void)makeAPICall:(NSMutableDictionary *)dict;
+ (APIHelper *)sharedInstance;

@end

APIHelper.m

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
//
//  APIHelper.m
//  APIHelperDemo
//
//  Created by Jeroen van Wissen on 10/10/08.
//  Copyright 2008 FastOne Internet Services. All rights reserved.
//

#import "APIHelper.h"

@implementation APIHelper
@synthesize delegate, receivedData, receivedDict;

- (void) makeAPICall:(NSMutableDictionary*)dict {
NSString *error;
NSURL *APIHost = [NSURL URLWithString: HTTPS_API];
[NSURLRequest setAllowsAnyHTTPSCertificate:YES forHost:[APIHost host]];

// Convert the NSMutableDictionary to NSData to be posted
NSData *postData = [NSPropertyListSerialization dataFromPropertyList:dict
format:kCFPropertyListXMLFormat_v1_0
errorDescription:&error];

NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL: [NSURL URLWithString: HTTPS_API]];
[request setHTTPMethod: @"POST"];
[request setHTTPBody:postData];

NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
if (connection) {
receivedData=[[NSMutableData data] retain];
} else {

}
}

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
[receivedData setLength:0];
}

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
[receivedData appendData:data];
}

- (void)connection:(NSURLConnection *)connection
didFailWithError:(NSError *)error
{
[connection release];
[receivedData release];

NSLog(@"Connection failed! Error - %@ %@",
[error localizedDescription],
[[error userInfo] objectForKey:NSErrorFailingURLStringKey]);
}

- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
NSString *plistError;
NSPropertyListFormat format;
receivedDict = [NSPropertyListSerialization propertyListFromData:receivedData
mutabilityOption:NSPropertyListImmutable
format:&format
errorDescription:&plistError];

[self.delegate apiCallResult: receivedDict];
[connection release];
[receivedData release];
}

+ (APIHelper *)sharedInstance
{
static APIHelper *instance = nil;
if (!instance)
instance = [[self alloc] init];
return instance;
}

@end

It’s just a thought I had today, and worked it out in a small prototype. Comments are welcome, leave a note if you found it usefull!

The iPhone application linked does nothing on the screen, it makes the API call, and NSLog’s the return value to the debug console of XCode. To test it, upload the PHP API to your site, and edit the HTTPS_API in APIHelper.h

If you don’t have https:// you can comment out these lines in APIHelper.m:

1
2
NSURL *APIHost = [NSURL URLWithString: HTTPS_API];
[NSURLRequest setAllowsAnyHTTPSCertificate:YES forHost:[APIHost host]];

The archive with the PHP API and the APIHelperDemo iPhone App can be downloaded below

Download APIHelper Demo

APIHelperDemo-0.1.zip

Tags: , ,

Laat een reactie achter