Load JSON without AFNetworking
If your app only needs to load some public JSON files, AFNetworking with CocoaPods is not the nimble solution you're looking for (it adds about 600KB to your compiled app). So, here is a minimal service to help you out:
Shortcut to the Gist: https://gist.github.com/widescape/10466762
Use JSONFromConnection
JSONFromConnection
is a combination of NSURLConnection sendAsynchronousRequest
and NSJSONSerialization JSONObjectWithData
that will do the magic for you while responding with either your perfect data object – or an error message. Just create a NSURLRequest
and pass it to JSONFromConnection sendAsynchronousRequest
along with a completion block.
// YourController.m
- (void)fetchData
{
NSString *urlAsString = [NSString stringWithFormat:@"https://api.example.com/%@/%@", apiKey, yourQuery];
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:urlAsString] cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:20];
__weak UIViewController *weakSelf = self;
[JSONFromConnection sendAsynchronousRequest:request completeWith:^(id dataFromJSON, NSError *connectionOrJSONError) {
if (connectionOrJSONError) {
// Handle the error
weakSelf.…
}
else {
// Do something with dataFromJSON (NSMutableData)
weakSelf.…
}
[weakSelf broadcastWeatherDataFor:index onQueriedLocation:queriedLocation];
}];
}
Note: The weakSelf reference helps to avoid problems when your controller was deallocated already when the block is executed.
Setup JSONFromConnection
Just copy the following 2 files into your project. First JSONFromConnection.h …
// JSONFromConnection.h
#import <Foundation/Foundation.h>
@interface JSONFromConnection : NSObject
+ (void)sendAsynchronousRequest:(NSURLRequest*)request completeWith:(void (^)(id dataFromJSON, NSError *connectionOrJSONError))complete;
@end
… and JSONFromConnection.m.
// JSONFromConnection.m
#import "JSONFromConnection.h"
@implementation JSONFromConnection
+ (void)sendAsynchronousRequest:(NSURLRequest*)request completeWith:(void (^)(id dataFromJSON, NSError *connectionOrJSONError))complete {
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
if (connectionError) {
complete(nil, connectionError);
}
else {
NSError *jsonError = nil;
NSMutableData *unserializedData = [NSJSONSerialization JSONObjectWithData: data options:NSJSONReadingMutableContainers error:&jsonError];
if (jsonError) {
complete(data, jsonError);
}
else {
complete(unserializedData, nil);
}
}
}];
}
@end
Tip: Always enable caching
In the example above you'll notice that the request is created using the cachePolicy NSURLRequestUseProtocolCachePolicy
that will make use of your apps shared cache. So make sure you set it up:
// AppDelegate.m
#import "AppDelegate.h"
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application willFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Setup URL Caching (always a good idea)
NSURLCache *URLCache = [[NSURLCache alloc] initWithMemoryCapacity:4 * 1024 * 1024
diskCapacity:20 * 1024 * 1024
diskPath:nil];
[NSURLCache setSharedURLCache:URLCache];
…
return YES;
}