├── English.lproj └── InfoPlist.strings ├── .gitignore ├── NSMutableDictionary+REST_Prefix.pch ├── Info.plist ├── NSMutableDictionary+REST.h ├── NSMutableDictionaryRESTParser.h ├── main.m ├── Readme.mkdn ├── NSMutableDictionary+REST.m ├── NSMutableDictionaryRESTParser.m └── NSMutableDictionary+REST.xcodeproj └── project.pbxproj /English.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /NSMutableDictionary+REST.xcodeproj/*.mode1v3 2 | /NSMutableDictionary+REST.xcodeproj/*.pbxuser 3 | build 4 | -------------------------------------------------------------------------------- /NSMutableDictionary+REST_Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header for all source files of the 'NSMutableDictionary+REST' target in the 'NSMutableDictionary+REST' project. 3 | // 4 | 5 | #ifdef __OBJC__ 6 | #import 7 | #endif 8 | -------------------------------------------------------------------------------- /Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | English 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | com.yourcompany.${PRODUCT_NAME:rfc1034Identifier} 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | ${PRODUCT_NAME} 17 | CFBundlePackageType 18 | FMWK 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1 25 | NSPrincipalClass 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /NSMutableDictionary+REST.h: -------------------------------------------------------------------------------- 1 | // © 2010 Mirek Rusin 2 | // Released under the Apache License, Version 2.0 3 | // http://www.apache.org/licenses/LICENSE-2.0 4 | 5 | #import 6 | #import "NSMutableDictionaryRESTParser.h" 7 | 8 | @interface NSMutableDictionary (REST) 9 | 10 | + (NSMutableDictionary *) dictionaryWithRESTContentsOfURL: (NSURL *) url; 11 | + (NSMutableDictionary *) dictionaryWithRESTContentsOfURL: (NSURL *) url delegate: (id) delegate; 12 | 13 | - (NSData *) postRESTWithURL: (NSString *) urlString; 14 | - (NSData *) putRESTWithURL: (NSString *) urlString; 15 | 16 | - (NSData *) sendRESTWithURL: (NSString *) urlString 17 | method: (NSString *) method 18 | encoding: (NSString *) encoding 19 | response: (NSURLResponse **) urlResponse 20 | error: (NSError **) error; 21 | 22 | // @private 23 | 24 | - (NSMutableArray *) RESTArrayHTTPPostData; 25 | - (NSString *) RESTURLEncodedHTTPPostData; 26 | - (NSString *) RESTMultipartHTTPPostDataWithBoundary: (NSString *) boundary; 27 | 28 | @end 29 | -------------------------------------------------------------------------------- /NSMutableDictionaryRESTParser.h: -------------------------------------------------------------------------------- 1 | // © 2010 Mirek Rusin 2 | // Released under the Apache License, Version 2.0 3 | // http://www.apache.org/licenses/LICENSE-2.0 4 | 5 | #import 6 | #import 7 | 8 | typedef enum { 9 | NSMutableDictionaryRESTParserElementTypeNil, 10 | NSMutableDictionaryRESTParserElementTypeStringOrDictionary, 11 | NSMutableDictionaryRESTParserElementTypeArray, 12 | NSMutableDictionaryRESTParserElementTypeFloat, 13 | NSMutableDictionaryRESTParserElementTypeInteger 14 | } NSMutableDictionaryRESTParserElementType; 15 | 16 | @interface NSMutableDictionaryRESTParser : NSObject { 17 | 18 | @private 19 | 20 | xmlParserCtxtPtr context; 21 | 22 | NSURLConnection *urlConnection; 23 | 24 | BOOL processing; 25 | 26 | NSAutoreleasePool *pool; 27 | 28 | NSMutableArray *stack; 29 | NSMutableArray *typeStack; 30 | NSMutableArray *nameStack; 31 | NSMutableData *data; 32 | 33 | id delegate; 34 | } 35 | 36 | @property (nonatomic, retain) NSMutableDictionary *tree; 37 | 38 | @property (nonatomic, retain) NSMutableArray *stack; 39 | @property (nonatomic, retain) NSMutableArray *typeStack; 40 | @property (nonatomic, retain) NSMutableArray *nameStack; 41 | 42 | @property (nonatomic, retain) NSMutableData *data; 43 | 44 | @property (nonatomic, retain) id delegate; 45 | 46 | @property BOOL processing; 47 | 48 | @property (nonatomic, retain) NSURLConnection *urlConnection; 49 | 50 | @property (nonatomic, assign) NSAutoreleasePool *pool; 51 | 52 | - (void) parseWithURL: (NSURL *) url; 53 | 54 | @end 55 | -------------------------------------------------------------------------------- /main.m: -------------------------------------------------------------------------------- 1 | // © 2010 Mirek Rusin 2 | // Released under the Apache License, Version 2.0 3 | // http://www.apache.org/licenses/LICENSE-2.0 4 | 5 | #import 6 | #import "NSMutableDictionary+REST.h" 7 | 8 | @interface UserPrinter : NSObject 9 | @end 10 | 11 | @implementation UserPrinter 12 | 13 | - (void) didFinishElement: (id) element withPath: (NSString *) path { 14 | if ([path isEqualToString: @"/users/user"]) { 15 | NSDictionary *user = (NSDictionary *)element; 16 | printf("- %s (%s)\n", [[user objectForKey: @"fullname"] UTF8String], 17 | [[user objectForKey: @"username"] UTF8String]); 18 | } 19 | } 20 | 21 | @end 22 | 23 | int main(int argc, char** argv) { 24 | NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 25 | 26 | NSString *stringUrl = @"http://github.com/api/v2/xml/user/search/mirek"; 27 | NSURL *url = [NSURL URLWithString: stringUrl]; 28 | 29 | // Delegate gets objects asynchronously and the method returns synchronously 30 | NSMutableDictionary *users = [NSMutableDictionary dictionaryWithRESTContentsOfURL: url 31 | delegate: [[UserPrinter alloc] init]]; 32 | 33 | printf("Total users: %i\n", (int)[[users objectForKey: @"users"] count]); 34 | 35 | id user = [[users objectForKey: @"users"] objectAtIndex: 0]; 36 | 37 | NSData *responseData = [user postRESTWithURL: @"http://localhost:3100/raw_post"]; 38 | 39 | printf("%s\n", [[[NSString alloc] initWithData: responseData 40 | encoding: NSUTF8StringEncoding] UTF8String]), 41 | 42 | [pool drain]; 43 | return 0; 44 | } 45 | -------------------------------------------------------------------------------- /Readme.mkdn: -------------------------------------------------------------------------------- 1 | # NSMutableDictionary+REST.framework 2 | 3 | REST support for Objective-C `NSMutableDictionary` (libxml2 SAX2 based - yes it works with iPhone/iPad). 4 | 5 | This project is a part of [Safari Books Online Learn Something New Team Challenge](http://safaribooksonline.wordpress.com/2010/06/08/learn-something-new-team-challenge-gitpad-by-mirek-rusin/). 6 | Feel free to contribute to become a team member, and who knows we may [win an iPad for you](http://www.safaribooksonline.com/Corporate/learnteamchallenge/?cid=2010_06_blog_learnsomethingnewteamchallenge). 7 | 8 | Easy to use a/synchronous interface: 9 | 10 | // Example usage: 11 | NSString *stringUrl = @"http://github.com/api/v2/xml/user/search/chacon"; 12 | NSURL *url = [NSURL URLWithString: stringUrl]; 13 | NSLog(@"%@", [NSMutableDictionary dictionaryWithRESTContentsOfURL: url]); 14 | 15 | // ...will output something like this: 16 | { 17 | users = ( 18 | { 19 | created = "2008-04-26T15:37:59Z"; 20 | followers = 1; 21 | fullname = "Mirek Rusin"; 22 | id = "user-8561"; 23 | language = "C++"; 24 | location = London; 25 | name = mirek; 26 | pushed = "2010-05-23T21:16:50.272Z"; 27 | repos = 8; 28 | score = "15.604"; 29 | type = user; 30 | username = mirek; 31 | }, 32 | { 33 | created = "2009-10-16T16:38:48Z"; 34 | followers = 0; 35 | fullname = "Mirek Rusin"; 36 | id = "user-140734"; 37 | language = Ruby; 38 | location = London; 39 | name = mirekrusin; 40 | pushed = "2010-05-24T02:16:19.737Z"; 41 | repos = 1; 42 | score = "2.978005"; 43 | type = user; 44 | username = mirekrusin; 45 | }, 46 | { 47 | created = "2010-04-22T14:28:13Z"; 48 | followers = 0; 49 | fullname = "Mirek Mencel"; 50 | id = "user-249912"; 51 | language = ""; 52 | location = "Wroc\U0142aw"; 53 | name = mirekm; 54 | pushed = "2010-05-25T02:20:23.464Z"; 55 | repos = 0; 56 | score = "2.978005"; 57 | type = user; 58 | username = mirekm; 59 | } 60 | ); 61 | } 62 | 63 | Can you spot rails'ish conversion style? The XML looks like this: 64 | 65 | 66 | 67 | mirek 68 | London 69 | 1 70 | Mirek Rusin 71 | C++ 72 | mirek 73 | user-8561 74 | 8 75 | user 76 | 2010-05-23T21:16:50.272Z 77 | 15.603998 78 | 2008-04-26T15:37:59Z 79 | 80 | 81 | mirekrusin 82 | London 83 | 0 84 | Mirek Rusin 85 | Ruby 86 | mirekrusin 87 | user-140734 88 | 1 89 | user 90 | 2010-05-24T02:16:19.737Z 91 | 2.9780054 92 | 2009-10-16T16:38:48Z 93 | 94 | 95 | mirekm 96 | Wrocław 97 | 0 98 | Mirek Mencel 99 | 100 | mirekm 101 | user-249912 102 | 0 103 | user 104 | 2010-05-25T02:20:23.464Z 105 | 2.9780054 106 | 2010-04-22T14:28:13Z 107 | 108 | 109 | 110 | ## Async and sync at the same time? 111 | 112 | Yes, look at this code: 113 | 114 | NSString *stringUrl = @"http://github.com/api/v2/xml/user/search/mirek"; 115 | NSURL *url = [NSURL URLWithString: stringUrl]; 116 | 117 | // Delegate gets objects asynchronously and constructor returns synchronously 118 | NSDictionary *users = [NSMutableDictionary dictionaryWithRESTContentsOfURL: url 119 | delegate: [[UserPrinter alloc] init]]; 120 | 121 | // Above method returned synchronously 122 | printf("Total users: %i\n", (int)[[users objectForKey: @"users"] count]); 123 | 124 | ...where a `delegate` object is defined as: 125 | 126 | @interface UserPrinter : NSObject 127 | @end 128 | 129 | @implementation UserPrinter 130 | 131 | - (void) didFinishElement: (id) element withPath: (NSString *) path { 132 | if ([path isEqualToString: @"/users/user"]) { 133 | 134 | // Yielding users asynchronously 135 | NSDictionary *user = (NSDictionary *)element; 136 | printf("- %s (%s)\n", [[user objectForKey: @"fullname"] UTF8String], 137 | [[user objectForKey: @"username"] UTF8String]); 138 | } 139 | } 140 | 141 | @end 142 | 143 | The method returns synchronously and delegate receives messages asynchronously. 144 | 145 | ## POST support 146 | 147 | To POST the first user you could write something like this: 148 | 149 | id user = [[users objectForKey: @"users"] objectAtIndex: 0]; 150 | [user postRESTWithURL: @"http://localhost:3100/raw_post"]; 151 | 152 | `localhost:3100` runs included `restapp` example/test application. 153 | 154 | Default encoding type is `multipart/form-data` so you can send images etc (as `NSData` objects): 155 | 156 | NSURL *url = [NSURL URLWithString: @"http://www.google.co.uk//intl/en_com/images/srpr/logo1w.png"]; 157 | NSData *image = [NSData dataWithContentsOfURL: url]; 158 | id post = [NSMutableDictionary dictionaryWithObject: image 159 | forKey: @"uploaded_data"]; 160 | [post postRESTWithURL: @"http://localhost:3100/raw_post"]; 161 | 162 | Refer to the source code on how to set `application/x-www-form-urlencoded` and `multipart/form-data` encoding types explicitly. 163 | 164 | ## License 165 | 166 | © 2010 Mirek Rusin, Released under the Apache License, Version 2.0 167 | http://www.apache.org/licenses/LICENSE-2.0 168 | 169 | ## Authors 170 | 171 | * Mirek Rusin 172 | -------------------------------------------------------------------------------- /NSMutableDictionary+REST.m: -------------------------------------------------------------------------------- 1 | // © 2010 Mirek Rusin 2 | // Released under the Apache License, Version 2.0 3 | // http://www.apache.org/licenses/LICENSE-2.0 4 | 5 | #import "NSMutableDictionary+REST.h" 6 | 7 | @implementation NSMutableDictionary (REST) 8 | 9 | + (NSMutableDictionary *) dictionaryWithRESTContentsOfURL: (NSURL *) url { 10 | NSMutableDictionaryRESTParser *parser = [[NSMutableDictionaryRESTParser alloc] init]; 11 | [parser parseWithURL: url]; 12 | return parser.tree; 13 | } 14 | 15 | + (NSMutableDictionary *) dictionaryWithRESTContentsOfURL: (NSURL *) url delegate: (id) delegate { 16 | NSMutableDictionaryRESTParser *parser = [[NSMutableDictionaryRESTParser alloc] init]; 17 | parser.delegate = delegate; 18 | [parser parseWithURL: url]; 19 | return parser.tree; 20 | } 21 | 22 | /// Generate HTTP post data body from the dictionary 23 | // 24 | // Returns: HTTP post data 25 | - (NSString *) RESTURLEncodedHTTPPostData { 26 | NSMutableArray *lines = [NSMutableArray array]; 27 | for (NSArray *pair in [self RESTArrayHTTPPostData]) { 28 | NSMutableArray *escapedPair = [NSMutableArray arrayWithCapacity: 2]; 29 | for (id element in pair) 30 | [escapedPair addObject: (NSString *)CFURLCreateStringByAddingPercentEscapes(NULL, 31 | (CFStringRef)[NSString stringWithFormat: @"%@", element], 32 | NULL, 33 | (CFStringRef)@"!*'();:@&=+$,/?%#[]", 34 | kCFStringEncodingUTF8)]; 35 | [lines addObject: [escapedPair componentsJoinedByString: @"="]]; 36 | } 37 | return [lines componentsJoinedByString: @"&"]; 38 | } 39 | 40 | - (NSString *) RESTMultipartHTTPPostDataWithBoundary: (NSString *) boundary { 41 | NSMutableArray *lines = [NSMutableArray array]; 42 | for (NSArray *pair in [self RESTArrayHTTPPostData]) { 43 | [lines addObject: [NSString stringWithFormat: @"--%@", boundary]]; 44 | [lines addObject: [NSString stringWithFormat: @"Content-Disposition: form-data; name=\"%@\"", [pair objectAtIndex: 0]]]; 45 | [lines addObject: @""]; 46 | [lines addObject: [NSString stringWithFormat: @"%@", [pair lastObject]]]; 47 | } 48 | [lines addObject: [NSString stringWithFormat: @"--%@--", boundary]]; 49 | NSString *r = [lines componentsJoinedByString: @"\r\n"]; 50 | return r; 51 | } 52 | 53 | /// HTTP post data (flattened) lines 54 | // 55 | // Returns: HTTP post data key-value pairs, keys are []'ed 56 | - (NSMutableArray *) RESTArrayHTTPPostData { 57 | 58 | // Flatten the dictionary 59 | NSMutableArray *flattened = [NSMutableArray array]; 60 | NSMutableArray *objects = [NSMutableArray arrayWithObject: self]; 61 | NSMutableArray *paths = [NSMutableArray arrayWithObject: [NSMutableArray array]]; 62 | while ([objects count] > 0) { 63 | id object = [objects lastObject]; 64 | [objects removeLastObject]; 65 | NSMutableArray *path = [paths lastObject]; 66 | [paths removeLastObject]; 67 | if ([object isKindOfClass: NSClassFromString(@"NSDictionary")]) { 68 | for (NSString *key in [object allKeys]) { 69 | NSMutableArray *pathWithKey = [NSMutableArray arrayWithArray: path]; 70 | 71 | // We can be at the root and we need a key without []'thingys 72 | if ([pathWithKey count] == 0) 73 | [pathWithKey addObject: [NSString stringWithFormat: @"%@", key]]; 74 | else 75 | [pathWithKey addObject: [NSString stringWithFormat: @"[%@]", key]]; 76 | [paths addObject: pathWithKey]; 77 | [objects addObject: [object objectForKey: key]]; 78 | } 79 | } else if ([object isKindOfClass: NSClassFromString(@"NSArray")]) { 80 | for (int i = 0; i < [object count]; i++) { 81 | NSMutableArray *pathWithKey = [NSMutableArray arrayWithArray: path]; 82 | [pathWithKey addObject: [NSString stringWithFormat: @"[%i]", i]]; 83 | [paths addObject: pathWithKey]; 84 | [objects addObject: [object objectAtIndex: i]]; 85 | } 86 | } else { 87 | [flattened insertObject: [NSArray arrayWithObjects: 88 | [path componentsJoinedByString: @""], 89 | object, 90 | nil] 91 | atIndex: 0]; 92 | } 93 | } 94 | return flattened; 95 | } 96 | 97 | - (NSData *) postRESTWithURL: (NSString *) urlString { 98 | return [self sendRESTWithURL: urlString 99 | method: @"POST" 100 | encoding: @"multipart/form-data" 101 | response: nil 102 | error: nil]; 103 | } 104 | 105 | - (NSData *) putRESTWithURL: (NSString *) urlString { 106 | return [self sendRESTWithURL: urlString 107 | method: @"PUT" 108 | encoding: @"multipart/form-data" 109 | response: nil 110 | error: nil]; 111 | } 112 | 113 | - (NSData *) sendRESTWithURL: (NSString *) urlString 114 | method: (NSString *) method 115 | encoding: (NSString *) encoding 116 | response: (NSURLResponse **) urlResponse 117 | error: (NSError **) error 118 | { 119 | NSMutableURLRequest *request = [[[NSMutableURLRequest alloc] initWithURL: [NSURL URLWithString: urlString] 120 | cachePolicy: NSURLRequestReloadIgnoringCacheData 121 | timeoutInterval: 60.0] autorelease]; 122 | 123 | [request setHTTPMethod: method]; 124 | 125 | if ([encoding isEqualToString: @"multipart/form-data"]) { 126 | 127 | // multipart/form-data encoding, let's get a random boundary string 128 | NSString *boundary = [NSString stringWithFormat:@"----boundary%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c", 129 | (char)(65 + (arc4random() % 25)), (char)(65 + (arc4random() % 25)), 130 | (char)(65 + (arc4random() % 25)), (char)(65 + (arc4random() % 25)), 131 | (char)(65 + (arc4random() % 25)), (char)(65 + (arc4random() % 25)), 132 | (char)(65 + (arc4random() % 25)), (char)(65 + (arc4random() % 25)), 133 | (char)(65 + (arc4random() % 25)), (char)(65 + (arc4random() % 25)), 134 | (char)(65 + (arc4random() % 25)), (char)(65 + (arc4random() % 25)), 135 | (char)(65 + (arc4random() % 25)), (char)(65 + (arc4random() % 25)), 136 | (char)(65 + (arc4random() % 25)), (char)(65 + (arc4random() % 25))]; 137 | 138 | [request setHTTPBody: [[self RESTMultipartHTTPPostDataWithBoundary: boundary] dataUsingEncoding: NSASCIIStringEncoding]]; 139 | [request setValue: [NSString stringWithFormat: @"multipart/form-data; boundary=%@", boundary] forHTTPHeaderField: @"Content-Type"]; 140 | 141 | } else if ([encoding isEqualToString: @"application/x-www-form-urlencoded"]) { 142 | 143 | // application/x-www-form-urlencoded encoding 144 | [request setHTTPBody: [[self RESTURLEncodedHTTPPostData] dataUsingEncoding: NSASCIIStringEncoding]]; 145 | [request setValue: @"application/x-www-form-urlencoded" forHTTPHeaderField: @"Content-Type"]; 146 | 147 | } else { 148 | 149 | // Unknown encoding type 150 | assert(NO); 151 | } 152 | 153 | // TODO: Async post 154 | // NSURLConnection *conn = [[[NSURLConnection alloc] initWithRequest: request delegate: nil] autorelease]; 155 | // while (![conn isFinished]) { 156 | // [[NSRunLoop currentRunLoop] runMode: NSDefaultRunLoopMode 157 | // beforeDate: [NSDate distantFuture]]; 158 | // } 159 | 160 | return [NSURLConnection sendSynchronousRequest: request 161 | returningResponse: urlResponse 162 | error: error]; 163 | } 164 | 165 | @end 166 | -------------------------------------------------------------------------------- /NSMutableDictionaryRESTParser.m: -------------------------------------------------------------------------------- 1 | // © 2010 Mirek Rusin 2 | // Released under the Apache License, Version 2.0 3 | // http://www.apache.org/licenses/LICENSE-2.0 4 | // 5 | // Based on Apple XMLPerformance example: 6 | // http://developer.apple.com/iphone/library/samplecode/XMLPerformance/Listings/ReadMe_txt.html#//apple_ref/doc/uid/DTS40008094-ReadMe_txt-DontLinkElementID_23 7 | 8 | #import "NSMutableDictionaryRESTParser.h" 9 | 10 | // Declaration for SAX callbacks and structure 11 | static void NSMutableDictionaryRESTParserElementStart(void *ctx, const xmlChar *localname, const xmlChar *prefix, const xmlChar *URI, int nb_namespaces, const xmlChar **namespaces, int nb_attributes, int nb_defaulted, const xmlChar **attributes); 12 | static void NSMutableDictionaryRESTParserElementEnd(void *ctx, const xmlChar *localname, const xmlChar *prefix, const xmlChar *URI); 13 | static void NSMutableDictionaryRESTParserCharactersFound(void * ctx, const xmlChar * ch, int len); 14 | static void NSMutableDictionaryRESTParserErrorEncountered(void * ctx, const char * msg, ...); 15 | static xmlSAXHandler NSMutableDictionaryRESTParserHandlerStruct; 16 | 17 | @implementation NSMutableDictionaryRESTParser 18 | 19 | @synthesize tree; 20 | @synthesize stack; 21 | @synthesize typeStack; 22 | @synthesize nameStack; 23 | @synthesize data; 24 | 25 | @synthesize delegate; 26 | @synthesize urlConnection; 27 | @synthesize processing; 28 | @synthesize pool; 29 | 30 | - (void) parseWithURL: (NSURL *) url { 31 | self.pool = [[NSAutoreleasePool alloc] init]; 32 | 33 | self.processing = YES; 34 | 35 | self.tree = [NSMutableDictionary dictionary]; 36 | self.stack = [NSMutableArray arrayWithObject: self.tree]; 37 | self.typeStack = [NSMutableArray arrayWithObject: [NSNumber numberWithInt: NSMutableDictionaryRESTParserElementTypeStringOrDictionary]]; 38 | self.nameStack = [NSMutableArray arrayWithObject: @""]; 39 | 40 | [[NSURLCache sharedURLCache] removeAllCachedResponses]; 41 | NSURLRequest *urlRequest = [NSURLRequest requestWithURL: url]; 42 | urlConnection = [[NSURLConnection alloc] initWithRequest: urlRequest delegate: self]; 43 | context = xmlCreatePushParserCtxt(&NSMutableDictionaryRESTParserHandlerStruct, self, NULL, 0, NULL); 44 | 45 | // [self performSelectorOnMainThread: @selector(downloadStarted) withObject: nil waitUntilDone: NO]; 46 | 47 | if (urlConnection != nil) { 48 | do { 49 | [[NSRunLoop currentRunLoop] runMode: NSDefaultRunLoopMode 50 | beforeDate: [NSDate distantFuture]]; 51 | } while (processing); 52 | } 53 | 54 | // Release resources used only in this thread 55 | xmlFreeParserCtxt(context); 56 | 57 | self.urlConnection = nil; 58 | 59 | [pool drain]; 60 | self.pool = nil; 61 | } 62 | 63 | #pragma mark NSURLConnection delegate methods 64 | 65 | // Disable caching 66 | - (NSCachedURLResponse *) connection: (NSURLConnection *) connection willCacheResponse: (NSCachedURLResponse *) cachedResponse { 67 | return nil; 68 | } 69 | 70 | // Forward errors to the delegate 71 | - (void) connection: (NSURLConnection *) connection didFailWithError: (NSError *) error { 72 | self.processing = NO; 73 | [self performSelectorOnMainThread: @selector(parseError:) withObject: error waitUntilDone: NO]; 74 | } 75 | 76 | - (void) connection: (NSURLConnection *) connection didReceiveData: (NSData *) receivedData { 77 | xmlParseChunk(context, (const char *)[receivedData bytes], [receivedData length], NO); 78 | } 79 | 80 | - (void) connectionDidFinishLoading: (NSURLConnection *) connection { 81 | xmlParseChunk(context, NULL, 0, YES); 82 | self.processing = NO; 83 | // if ([delegate respondsToSelector: @selector(parseEnded)]) 84 | // [delegate performSelectorOnMainThread: @selector(parseEnded) withObject: self waitUntilDone: NO]; 85 | } 86 | 87 | @end 88 | 89 | #pragma mark SAX Stuff 90 | 91 | static void NSMutableDictionaryRESTParserElementStart(void *ctx, 92 | const xmlChar *localname, 93 | const xmlChar *prefix, 94 | const xmlChar *URI, 95 | int nb_namespaces, 96 | const xmlChar **namespaces, 97 | int nb_attributes, 98 | int nb_defaulted, 99 | const xmlChar **attributes) 100 | { 101 | NSMutableDictionaryRESTParser *parser = (NSMutableDictionaryRESTParser *)ctx; 102 | 103 | id new = [NSMutableDictionary dictionary]; 104 | NSMutableDictionaryRESTParserElementType newType = NSMutableDictionaryRESTParserElementTypeStringOrDictionary; 105 | parser.data = [NSMutableData data]; 106 | 107 | if (nb_attributes > 0) { 108 | int i, j; 109 | for (j = 0, i = 0; i < nb_attributes; i++, j += 5) { 110 | 111 | // We're interested in type attribute only 112 | if (!xmlStrcmp((const xmlChar *)"type", attributes[j])) { 113 | if (!xmlStrncmp((const xmlChar *)"array", attributes[j+3], strlen("array"))) { 114 | newType = NSMutableDictionaryRESTParserElementTypeArray; 115 | new = [NSMutableArray array]; 116 | break; 117 | } else if (!xmlStrncmp((const xmlChar *)"float", attributes[j+3], strlen("float"))) { 118 | newType = NSMutableDictionaryRESTParserElementTypeFloat; 119 | break; 120 | } else if (!xmlStrncmp((const xmlChar *)"integer", attributes[j+3], strlen("integer"))) { 121 | newType = NSMutableDictionaryRESTParserElementTypeInteger; 122 | break; 123 | } 124 | } 125 | } 126 | } 127 | 128 | // Push new element to the stack 129 | [parser.stack addObject: new]; 130 | [parser.typeStack addObject: [NSNumber numberWithInt: newType]]; 131 | [parser.nameStack addObject: [NSString stringWithUTF8String: (const char *)localname]]; 132 | } 133 | 134 | static void NSMutableDictionaryRESTParserElementEnd(void *ctx, const xmlChar *localname, const xmlChar *prefix, const xmlChar *URI) { 135 | NSMutableDictionaryRESTParser *parser = (NSMutableDictionaryRESTParser *)ctx; 136 | 137 | // Let's get the current element 138 | id last = [parser.stack lastObject]; 139 | NSMutableDictionaryRESTParserElementType lastType = (NSMutableDictionaryRESTParserElementType)[[parser.typeStack lastObject] intValue]; 140 | NSString *lastName = [parser.nameStack lastObject]; 141 | 142 | // Current string value 143 | NSString *string = [[NSString alloc] initWithData: parser.data encoding: NSUTF8StringEncoding]; 144 | 145 | // Depending on the type we can mutate to the proper class 146 | id new; 147 | switch (lastType) { 148 | case NSMutableDictionaryRESTParserElementTypeArray: 149 | new = last; 150 | break; 151 | 152 | case NSMutableDictionaryRESTParserElementTypeFloat: 153 | new = [NSNumber numberWithFloat: [string floatValue]]; 154 | break; 155 | 156 | case NSMutableDictionaryRESTParserElementTypeInteger: 157 | new = [NSNumber numberWithInteger: [string intValue]]; 158 | break; 159 | 160 | case NSMutableDictionaryRESTParserElementTypeStringOrDictionary: 161 | if ([last count] > 0) 162 | // Current element is a dictionary 163 | new = last; 164 | else 165 | // Current element is just plain value (doesn't have any children elements) 166 | new = string; 167 | break; 168 | } 169 | 170 | // Let's notify delgate about the new object before removing it's name from the stack 171 | if ([parser.delegate respondsToSelector: @selector(didFinishElement:withPath:)]) 172 | [parser.delegate performSelector: @selector(didFinishElement:withPath:) withObject: new withObject: [parser.nameStack componentsJoinedByString: @"/"]]; 173 | 174 | // Now we can remove element from the stack 175 | [parser.stack removeLastObject]; 176 | [parser.typeStack removeLastObject]; 177 | [parser.nameStack removeLastObject]; 178 | 179 | // We'll need current element's parent to assign new (mutated or not) element 180 | id parent = [parser.stack lastObject]; 181 | NSMutableDictionaryRESTParserElementType parentType = (NSMutableDictionaryRESTParserElementType)[[parser.typeStack lastObject] intValue]; 182 | 183 | // Parent had to be one of container types 184 | switch (parentType) { 185 | case NSMutableDictionaryRESTParserElementTypeArray: [parent addObject: new]; break; 186 | case NSMutableDictionaryRESTParserElementTypeStringOrDictionary: [parent setObject: new forKey: lastName]; break; 187 | } 188 | 189 | //[new release]; 190 | } 191 | 192 | static void NSMutableDictionaryRESTParserCharactersFound(void *ctx, const xmlChar *ch, int len) { 193 | NSMutableDictionaryRESTParser *parser = (NSMutableDictionaryRESTParser *)ctx; 194 | [parser.data appendBytes: ch length: len]; 195 | } 196 | 197 | static void NSMutableDictionaryRESTParserErrorEncountered(void *ctx, const char *msg, ...) { 198 | NSCAssert(NO, @"Unhandled error encountered during SAX parse."); 199 | } 200 | 201 | static xmlSAXHandler NSMutableDictionaryRESTParserHandlerStruct = { 202 | NULL, // internalSubset 203 | NULL, // isStandalone 204 | NULL, // hasInternalSubset 205 | NULL, // hasExternalSubset 206 | NULL, // resolveEntity 207 | NULL, // getEntity 208 | NULL, // entityDecl 209 | NULL, // notationDecl 210 | NULL, // attributeDecl 211 | NULL, // elementDecl 212 | NULL, // unparsedEntityDecl 213 | NULL, // setDocumentLocator 214 | NULL, // startDocument 215 | NULL, // endDocument 216 | NULL, // startElement*/ 217 | NULL, // endElement 218 | NULL, // reference 219 | NSMutableDictionaryRESTParserCharactersFound, // characters 220 | NULL, // ignorableWhitespace 221 | NULL, // processingInstruction 222 | NULL, // comment 223 | NULL, // warning 224 | NSMutableDictionaryRESTParserErrorEncountered, // error 225 | NULL, // fatalError //: unused error() get all the errors 226 | NULL, // getParameterEntity 227 | NULL, // cdataBlock 228 | NULL, // externalSubset 229 | XML_SAX2_MAGIC, // 230 | NULL, // 231 | NSMutableDictionaryRESTParserElementStart, // startElementNs 232 | NSMutableDictionaryRESTParserElementEnd, // endElementNs 233 | NULL, // serror 234 | }; 235 | -------------------------------------------------------------------------------- /NSMutableDictionary+REST.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 45; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 8DC2EF530486A6940098B216 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 089C1666FE841158C02AAC07 /* InfoPlist.strings */; }; 11 | EB21C02911BC4F9100C57605 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0867D69BFE84028FC02AAC07 /* Foundation.framework */; }; 12 | EB21C02C11BC4FA200C57605 /* libxml2.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = EB21C02B11BC4FA200C57605 /* libxml2.dylib */; }; 13 | EB21C03111BC501600C57605 /* NSMutableDictionary+REST.h in Headers */ = {isa = PBXBuildFile; fileRef = EB21C02D11BC501600C57605 /* NSMutableDictionary+REST.h */; }; 14 | EB21C03211BC501600C57605 /* NSMutableDictionary+REST.m in Sources */ = {isa = PBXBuildFile; fileRef = EB21C02E11BC501600C57605 /* NSMutableDictionary+REST.m */; }; 15 | EB21C03311BC501600C57605 /* NSMutableDictionaryRESTParser.h in Headers */ = {isa = PBXBuildFile; fileRef = EB21C02F11BC501600C57605 /* NSMutableDictionaryRESTParser.h */; }; 16 | EB21C03411BC501600C57605 /* NSMutableDictionaryRESTParser.m in Sources */ = {isa = PBXBuildFile; fileRef = EB21C03011BC501600C57605 /* NSMutableDictionaryRESTParser.m */; }; 17 | EB21C06711BC55E300C57605 /* NSMutableDictionary+REST.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8DC2EF5B0486A6940098B216 /* NSMutableDictionary+REST.framework */; }; 18 | EB21C06C11BC560600C57605 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = EB21C06911BC55FA00C57605 /* main.m */; }; 19 | EB21C0A511BC5CF800C57605 /* Readme.mkdn in Resources */ = {isa = PBXBuildFile; fileRef = EB21C0A411BC5CF800C57605 /* Readme.mkdn */; }; 20 | /* End PBXBuildFile section */ 21 | 22 | /* Begin PBXContainerItemProxy section */ 23 | EB21C06511BC55DF00C57605 /* PBXContainerItemProxy */ = { 24 | isa = PBXContainerItemProxy; 25 | containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; 26 | proxyType = 1; 27 | remoteGlobalIDString = 8DC2EF4F0486A6940098B216; 28 | remoteInfo = "NSMutableDictionary+REST"; 29 | }; 30 | /* End PBXContainerItemProxy section */ 31 | 32 | /* Begin PBXFileReference section */ 33 | 0867D69BFE84028FC02AAC07 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = ""; }; 34 | 0867D6A5FE840307C02AAC07 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = /System/Library/Frameworks/AppKit.framework; sourceTree = ""; }; 35 | 089C1667FE841158C02AAC07 /* English */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/InfoPlist.strings; sourceTree = ""; }; 36 | 32DBCF5E0370ADEE00C91783 /* NSMutableDictionary+REST_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSMutableDictionary+REST_Prefix.pch"; sourceTree = ""; }; 37 | 8DC2EF5A0486A6940098B216 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 38 | 8DC2EF5B0486A6940098B216 /* NSMutableDictionary+REST.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = "NSMutableDictionary+REST.framework"; sourceTree = BUILT_PRODUCTS_DIR; }; 39 | D2F7E79907B2D74100F64583 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = /System/Library/Frameworks/CoreData.framework; sourceTree = ""; }; 40 | EB21C02B11BC4FA200C57605 /* libxml2.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libxml2.dylib; path = usr/lib/libxml2.dylib; sourceTree = SDKROOT; }; 41 | EB21C02D11BC501600C57605 /* NSMutableDictionary+REST.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSMutableDictionary+REST.h"; sourceTree = ""; }; 42 | EB21C02E11BC501600C57605 /* NSMutableDictionary+REST.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSMutableDictionary+REST.m"; sourceTree = ""; }; 43 | EB21C02F11BC501600C57605 /* NSMutableDictionaryRESTParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NSMutableDictionaryRESTParser.h; sourceTree = ""; }; 44 | EB21C03011BC501600C57605 /* NSMutableDictionaryRESTParser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NSMutableDictionaryRESTParser.m; sourceTree = ""; }; 45 | EB21C06111BC55D600C57605 /* rest-console */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "rest-console"; sourceTree = BUILT_PRODUCTS_DIR; }; 46 | EB21C06911BC55FA00C57605 /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 47 | EB21C0A411BC5CF800C57605 /* Readme.mkdn */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Readme.mkdn; sourceTree = ""; }; 48 | /* End PBXFileReference section */ 49 | 50 | /* Begin PBXFrameworksBuildPhase section */ 51 | 8DC2EF560486A6940098B216 /* Frameworks */ = { 52 | isa = PBXFrameworksBuildPhase; 53 | buildActionMask = 2147483647; 54 | files = ( 55 | EB21C02911BC4F9100C57605 /* Foundation.framework in Frameworks */, 56 | EB21C02C11BC4FA200C57605 /* libxml2.dylib in Frameworks */, 57 | ); 58 | runOnlyForDeploymentPostprocessing = 0; 59 | }; 60 | EB21C05F11BC55D600C57605 /* Frameworks */ = { 61 | isa = PBXFrameworksBuildPhase; 62 | buildActionMask = 2147483647; 63 | files = ( 64 | EB21C06711BC55E300C57605 /* NSMutableDictionary+REST.framework in Frameworks */, 65 | ); 66 | runOnlyForDeploymentPostprocessing = 0; 67 | }; 68 | /* End PBXFrameworksBuildPhase section */ 69 | 70 | /* Begin PBXGroup section */ 71 | 034768DFFF38A50411DB9C8B /* Products */ = { 72 | isa = PBXGroup; 73 | children = ( 74 | 8DC2EF5B0486A6940098B216 /* NSMutableDictionary+REST.framework */, 75 | EB21C06111BC55D600C57605 /* rest-console */, 76 | ); 77 | name = Products; 78 | sourceTree = ""; 79 | }; 80 | 0867D691FE84028FC02AAC07 /* NSMutableDictionary+REST */ = { 81 | isa = PBXGroup; 82 | children = ( 83 | EB21C05D11BC55BA00C57605 /* rest-console */, 84 | 08FB77AEFE84172EC02AAC07 /* Classes */, 85 | 32C88DFF0371C24200C91783 /* Other Sources */, 86 | 089C1665FE841158C02AAC07 /* Resources */, 87 | 0867D69AFE84028FC02AAC07 /* External Frameworks and Libraries */, 88 | 034768DFFF38A50411DB9C8B /* Products */, 89 | ); 90 | name = "NSMutableDictionary+REST"; 91 | sourceTree = ""; 92 | }; 93 | 0867D69AFE84028FC02AAC07 /* External Frameworks and Libraries */ = { 94 | isa = PBXGroup; 95 | children = ( 96 | 1058C7B0FEA5585E11CA2CBB /* Linked Frameworks */, 97 | 1058C7B2FEA5585E11CA2CBB /* Other Frameworks */, 98 | ); 99 | name = "External Frameworks and Libraries"; 100 | sourceTree = ""; 101 | }; 102 | 089C1665FE841158C02AAC07 /* Resources */ = { 103 | isa = PBXGroup; 104 | children = ( 105 | 8DC2EF5A0486A6940098B216 /* Info.plist */, 106 | 089C1666FE841158C02AAC07 /* InfoPlist.strings */, 107 | ); 108 | name = Resources; 109 | sourceTree = ""; 110 | }; 111 | 08FB77AEFE84172EC02AAC07 /* Classes */ = { 112 | isa = PBXGroup; 113 | children = ( 114 | EB21C02D11BC501600C57605 /* NSMutableDictionary+REST.h */, 115 | EB21C02E11BC501600C57605 /* NSMutableDictionary+REST.m */, 116 | EB21C02F11BC501600C57605 /* NSMutableDictionaryRESTParser.h */, 117 | EB21C03011BC501600C57605 /* NSMutableDictionaryRESTParser.m */, 118 | ); 119 | name = Classes; 120 | sourceTree = ""; 121 | }; 122 | 1058C7B0FEA5585E11CA2CBB /* Linked Frameworks */ = { 123 | isa = PBXGroup; 124 | children = ( 125 | EB21C02B11BC4FA200C57605 /* libxml2.dylib */, 126 | ); 127 | name = "Linked Frameworks"; 128 | sourceTree = ""; 129 | }; 130 | 1058C7B2FEA5585E11CA2CBB /* Other Frameworks */ = { 131 | isa = PBXGroup; 132 | children = ( 133 | 0867D6A5FE840307C02AAC07 /* AppKit.framework */, 134 | D2F7E79907B2D74100F64583 /* CoreData.framework */, 135 | 0867D69BFE84028FC02AAC07 /* Foundation.framework */, 136 | ); 137 | name = "Other Frameworks"; 138 | sourceTree = ""; 139 | }; 140 | 32C88DFF0371C24200C91783 /* Other Sources */ = { 141 | isa = PBXGroup; 142 | children = ( 143 | EB21C0A411BC5CF800C57605 /* Readme.mkdn */, 144 | 32DBCF5E0370ADEE00C91783 /* NSMutableDictionary+REST_Prefix.pch */, 145 | ); 146 | name = "Other Sources"; 147 | sourceTree = ""; 148 | }; 149 | EB21C05D11BC55BA00C57605 /* rest-console */ = { 150 | isa = PBXGroup; 151 | children = ( 152 | EB21C06911BC55FA00C57605 /* main.m */, 153 | ); 154 | name = "rest-console"; 155 | sourceTree = ""; 156 | }; 157 | /* End PBXGroup section */ 158 | 159 | /* Begin PBXHeadersBuildPhase section */ 160 | 8DC2EF500486A6940098B216 /* Headers */ = { 161 | isa = PBXHeadersBuildPhase; 162 | buildActionMask = 2147483647; 163 | files = ( 164 | EB21C03111BC501600C57605 /* NSMutableDictionary+REST.h in Headers */, 165 | EB21C03311BC501600C57605 /* NSMutableDictionaryRESTParser.h in Headers */, 166 | ); 167 | runOnlyForDeploymentPostprocessing = 0; 168 | }; 169 | /* End PBXHeadersBuildPhase section */ 170 | 171 | /* Begin PBXNativeTarget section */ 172 | 8DC2EF4F0486A6940098B216 /* NSMutableDictionary+REST */ = { 173 | isa = PBXNativeTarget; 174 | buildConfigurationList = 1DEB91AD08733DA50010E9CD /* Build configuration list for PBXNativeTarget "NSMutableDictionary+REST" */; 175 | buildPhases = ( 176 | 8DC2EF500486A6940098B216 /* Headers */, 177 | 8DC2EF520486A6940098B216 /* Resources */, 178 | 8DC2EF540486A6940098B216 /* Sources */, 179 | 8DC2EF560486A6940098B216 /* Frameworks */, 180 | ); 181 | buildRules = ( 182 | ); 183 | dependencies = ( 184 | ); 185 | name = "NSMutableDictionary+REST"; 186 | productInstallPath = "$(HOME)/Library/Frameworks"; 187 | productName = "NSMutableDictionary+REST"; 188 | productReference = 8DC2EF5B0486A6940098B216 /* NSMutableDictionary+REST.framework */; 189 | productType = "com.apple.product-type.framework"; 190 | }; 191 | EB21C06011BC55D600C57605 /* rest-console */ = { 192 | isa = PBXNativeTarget; 193 | buildConfigurationList = EB21C06B11BC55FB00C57605 /* Build configuration list for PBXNativeTarget "rest-console" */; 194 | buildPhases = ( 195 | EB21C05E11BC55D600C57605 /* Sources */, 196 | EB21C05F11BC55D600C57605 /* Frameworks */, 197 | ); 198 | buildRules = ( 199 | ); 200 | dependencies = ( 201 | EB21C06611BC55DF00C57605 /* PBXTargetDependency */, 202 | ); 203 | name = "rest-console"; 204 | productName = "rest-console"; 205 | productReference = EB21C06111BC55D600C57605 /* rest-console */; 206 | productType = "com.apple.product-type.tool"; 207 | }; 208 | /* End PBXNativeTarget section */ 209 | 210 | /* Begin PBXProject section */ 211 | 0867D690FE84028FC02AAC07 /* Project object */ = { 212 | isa = PBXProject; 213 | buildConfigurationList = 1DEB91B108733DA50010E9CD /* Build configuration list for PBXProject "NSMutableDictionary+REST" */; 214 | compatibilityVersion = "Xcode 3.1"; 215 | hasScannedForEncodings = 1; 216 | mainGroup = 0867D691FE84028FC02AAC07 /* NSMutableDictionary+REST */; 217 | productRefGroup = 034768DFFF38A50411DB9C8B /* Products */; 218 | projectDirPath = ""; 219 | projectRoot = ""; 220 | targets = ( 221 | 8DC2EF4F0486A6940098B216 /* NSMutableDictionary+REST */, 222 | EB21C06011BC55D600C57605 /* rest-console */, 223 | ); 224 | }; 225 | /* End PBXProject section */ 226 | 227 | /* Begin PBXResourcesBuildPhase section */ 228 | 8DC2EF520486A6940098B216 /* Resources */ = { 229 | isa = PBXResourcesBuildPhase; 230 | buildActionMask = 2147483647; 231 | files = ( 232 | 8DC2EF530486A6940098B216 /* InfoPlist.strings in Resources */, 233 | EB21C0A511BC5CF800C57605 /* Readme.mkdn in Resources */, 234 | ); 235 | runOnlyForDeploymentPostprocessing = 0; 236 | }; 237 | /* End PBXResourcesBuildPhase section */ 238 | 239 | /* Begin PBXSourcesBuildPhase section */ 240 | 8DC2EF540486A6940098B216 /* Sources */ = { 241 | isa = PBXSourcesBuildPhase; 242 | buildActionMask = 2147483647; 243 | files = ( 244 | EB21C03211BC501600C57605 /* NSMutableDictionary+REST.m in Sources */, 245 | EB21C03411BC501600C57605 /* NSMutableDictionaryRESTParser.m in Sources */, 246 | ); 247 | runOnlyForDeploymentPostprocessing = 0; 248 | }; 249 | EB21C05E11BC55D600C57605 /* Sources */ = { 250 | isa = PBXSourcesBuildPhase; 251 | buildActionMask = 2147483647; 252 | files = ( 253 | EB21C06C11BC560600C57605 /* main.m in Sources */, 254 | ); 255 | runOnlyForDeploymentPostprocessing = 0; 256 | }; 257 | /* End PBXSourcesBuildPhase section */ 258 | 259 | /* Begin PBXTargetDependency section */ 260 | EB21C06611BC55DF00C57605 /* PBXTargetDependency */ = { 261 | isa = PBXTargetDependency; 262 | target = 8DC2EF4F0486A6940098B216 /* NSMutableDictionary+REST */; 263 | targetProxy = EB21C06511BC55DF00C57605 /* PBXContainerItemProxy */; 264 | }; 265 | /* End PBXTargetDependency section */ 266 | 267 | /* Begin PBXVariantGroup section */ 268 | 089C1666FE841158C02AAC07 /* InfoPlist.strings */ = { 269 | isa = PBXVariantGroup; 270 | children = ( 271 | 089C1667FE841158C02AAC07 /* English */, 272 | ); 273 | name = InfoPlist.strings; 274 | sourceTree = ""; 275 | }; 276 | /* End PBXVariantGroup section */ 277 | 278 | /* Begin XCBuildConfiguration section */ 279 | 1DEB91AE08733DA50010E9CD /* Debug */ = { 280 | isa = XCBuildConfiguration; 281 | buildSettings = { 282 | ALWAYS_SEARCH_USER_PATHS = NO; 283 | COPY_PHASE_STRIP = NO; 284 | DYLIB_COMPATIBILITY_VERSION = 1; 285 | DYLIB_CURRENT_VERSION = 1; 286 | FRAMEWORK_VERSION = A; 287 | GCC_DYNAMIC_NO_PIC = NO; 288 | GCC_ENABLE_FIX_AND_CONTINUE = YES; 289 | GCC_MODEL_TUNING = G5; 290 | GCC_OPTIMIZATION_LEVEL = 0; 291 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 292 | GCC_PREFIX_HEADER = "NSMutableDictionary+REST_Prefix.pch"; 293 | INFOPLIST_FILE = Info.plist; 294 | INSTALL_PATH = "$(HOME)/Library/Frameworks"; 295 | PRODUCT_NAME = "NSMutableDictionary+REST"; 296 | WRAPPER_EXTENSION = framework; 297 | }; 298 | name = Debug; 299 | }; 300 | 1DEB91AF08733DA50010E9CD /* Release */ = { 301 | isa = XCBuildConfiguration; 302 | buildSettings = { 303 | ALWAYS_SEARCH_USER_PATHS = NO; 304 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 305 | DYLIB_COMPATIBILITY_VERSION = 1; 306 | DYLIB_CURRENT_VERSION = 1; 307 | FRAMEWORK_VERSION = A; 308 | GCC_MODEL_TUNING = G5; 309 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 310 | GCC_PREFIX_HEADER = "NSMutableDictionary+REST_Prefix.pch"; 311 | INFOPLIST_FILE = Info.plist; 312 | INSTALL_PATH = "$(HOME)/Library/Frameworks"; 313 | PRODUCT_NAME = "NSMutableDictionary+REST"; 314 | WRAPPER_EXTENSION = framework; 315 | }; 316 | name = Release; 317 | }; 318 | 1DEB91B208733DA50010E9CD /* Debug */ = { 319 | isa = XCBuildConfiguration; 320 | buildSettings = { 321 | ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; 322 | FRAMEWORK_SEARCH_PATHS = ""; 323 | GCC_C_LANGUAGE_STANDARD = gnu99; 324 | GCC_OPTIMIZATION_LEVEL = 0; 325 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 326 | GCC_WARN_UNUSED_VARIABLE = YES; 327 | HEADER_SEARCH_PATHS = $SDKROOT/usr/include/libxml2; 328 | ONLY_ACTIVE_ARCH = YES; 329 | PREBINDING = NO; 330 | SDKROOT = macosx10.6; 331 | USER_HEADER_SEARCH_PATHS = ""; 332 | }; 333 | name = Debug; 334 | }; 335 | 1DEB91B308733DA50010E9CD /* Release */ = { 336 | isa = XCBuildConfiguration; 337 | buildSettings = { 338 | ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; 339 | FRAMEWORK_SEARCH_PATHS = ""; 340 | GCC_C_LANGUAGE_STANDARD = gnu99; 341 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 342 | GCC_WARN_UNUSED_VARIABLE = YES; 343 | HEADER_SEARCH_PATHS = $SDKROOT/usr/include/libxml2; 344 | PREBINDING = NO; 345 | SDKROOT = macosx10.6; 346 | USER_HEADER_SEARCH_PATHS = ""; 347 | }; 348 | name = Release; 349 | }; 350 | EB21C06311BC55D600C57605 /* Debug */ = { 351 | isa = XCBuildConfiguration; 352 | buildSettings = { 353 | ALWAYS_SEARCH_USER_PATHS = NO; 354 | COPY_PHASE_STRIP = NO; 355 | GCC_DYNAMIC_NO_PIC = NO; 356 | GCC_ENABLE_FIX_AND_CONTINUE = YES; 357 | GCC_MODEL_TUNING = G5; 358 | GCC_OPTIMIZATION_LEVEL = 0; 359 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 360 | GCC_PREFIX_HEADER = "$(SYSTEM_LIBRARY_DIR)/Frameworks/AppKit.framework/Headers/AppKit.h"; 361 | INSTALL_PATH = /usr/local/bin; 362 | OTHER_LDFLAGS = ( 363 | "-framework", 364 | Foundation, 365 | "-framework", 366 | AppKit, 367 | ); 368 | PREBINDING = NO; 369 | PRODUCT_NAME = "rest-console"; 370 | }; 371 | name = Debug; 372 | }; 373 | EB21C06411BC55D600C57605 /* Release */ = { 374 | isa = XCBuildConfiguration; 375 | buildSettings = { 376 | ALWAYS_SEARCH_USER_PATHS = NO; 377 | COPY_PHASE_STRIP = YES; 378 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 379 | GCC_ENABLE_FIX_AND_CONTINUE = NO; 380 | GCC_MODEL_TUNING = G5; 381 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 382 | GCC_PREFIX_HEADER = "$(SYSTEM_LIBRARY_DIR)/Frameworks/AppKit.framework/Headers/AppKit.h"; 383 | INSTALL_PATH = /usr/local/bin; 384 | OTHER_LDFLAGS = ( 385 | "-framework", 386 | Foundation, 387 | "-framework", 388 | AppKit, 389 | ); 390 | PREBINDING = NO; 391 | PRODUCT_NAME = "rest-console"; 392 | ZERO_LINK = NO; 393 | }; 394 | name = Release; 395 | }; 396 | /* End XCBuildConfiguration section */ 397 | 398 | /* Begin XCConfigurationList section */ 399 | 1DEB91AD08733DA50010E9CD /* Build configuration list for PBXNativeTarget "NSMutableDictionary+REST" */ = { 400 | isa = XCConfigurationList; 401 | buildConfigurations = ( 402 | 1DEB91AE08733DA50010E9CD /* Debug */, 403 | 1DEB91AF08733DA50010E9CD /* Release */, 404 | ); 405 | defaultConfigurationIsVisible = 0; 406 | defaultConfigurationName = Release; 407 | }; 408 | 1DEB91B108733DA50010E9CD /* Build configuration list for PBXProject "NSMutableDictionary+REST" */ = { 409 | isa = XCConfigurationList; 410 | buildConfigurations = ( 411 | 1DEB91B208733DA50010E9CD /* Debug */, 412 | 1DEB91B308733DA50010E9CD /* Release */, 413 | ); 414 | defaultConfigurationIsVisible = 0; 415 | defaultConfigurationName = Release; 416 | }; 417 | EB21C06B11BC55FB00C57605 /* Build configuration list for PBXNativeTarget "rest-console" */ = { 418 | isa = XCConfigurationList; 419 | buildConfigurations = ( 420 | EB21C06311BC55D600C57605 /* Debug */, 421 | EB21C06411BC55D600C57605 /* Release */, 422 | ); 423 | defaultConfigurationIsVisible = 0; 424 | defaultConfigurationName = Release; 425 | }; 426 | /* End XCConfigurationList section */ 427 | }; 428 | rootObject = 0867D690FE84028FC02AAC07 /* Project object */; 429 | } 430 | --------------------------------------------------------------------------------