Permalink
Browse files

Change BNRConnection and RSSChannel to support JSON

  • Loading branch information...
1 parent 23ddf24 commit f9a1c9de66caf4138a03827300c0eeba0f6c6516 Ryan Blunden committed Jan 19, 2013
@@ -6,6 +6,7 @@
#import <Foundation/Foundation.h>
+#import "JSONSerializable.h"
@interface BNRConnection : NSObject <NSURLConnectionDelegate, NSURLConnectionDataDelegate> {
@@ -18,6 +19,7 @@
@property(nonatomic, copy) NSURLRequest *request;
@property(nonatomic, copy) void (^completionBlock)(id obj, NSError *err);
@property(nonatomic, strong) id <NSXMLParserDelegate> xmlRootObject;
+@property(nonatomic, strong) id <JSONSerializable> jsonRootObject;
- (void)start;
@@ -44,20 +44,34 @@ - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
+ id rootObject = nil;
+
// IF there is "root object"
if ([self xmlRootObject]) {
// Create a parser with the incoming data and let the root object parse its contents
NSXMLParser *parser = [[NSXMLParser alloc] initWithData:container];
[parser setDelegate:[self xmlRootObject]];
[parser parse];
+
+ rootObject = [self xmlRootObject];
+ }
+ else if ([self jsonRootObject]) {
+ // Turn JSON data into basic model objects
+ NSDictionary *d = [NSJSONSerialization JSONObjectWithData:container options:0
+ error:nil];
+
+ // Have the root object construct itself from basic model objects
+ [[self jsonRootObject] readFromJSONDictionary:d];
+
+ rootObject = [self jsonRootObject];
}
// Then pass the root object to the completion block - remember, this is the block that the controller supplied
if ([self completionBlock]) {
- [self completionBlock]([self xmlRootObject], nil);
+ [self completionBlock](rootObject, nil);
}
- // now, destory the connection
+ // now, destroy the connection
[sharedConnectionList removeObject:self];
}
@@ -47,9 +47,9 @@ - (void)fetchRSSFeedWithCompletion:(void (^)(RSSChannel *, NSError *))block {
}
- (void)fetchTopSongs:(int)count withCompletion:(void (^)(RSSChannel *, NSError *))block {
- // Prepare a request URL, including the argument from the controler
+ // Prepare a request URL, including the argument from the controller
NSString *requestString = [NSString stringWithFormat:
- @"http://itunes.apple.com/us/rss/topsongs/limit=%d/xml", count];
+ @"http://itunes.apple.com/us/rss/topsongs/limit=%d/json", count];
NSURL *url = [NSURL URLWithString:requestString];
@@ -59,7 +59,7 @@ - (void)fetchTopSongs:(int)count withCompletion:(void (^)(RSSChannel *, NSError
BNRConnection *connection = [[BNRConnection alloc] initWithRequest:req];
[connection setCompletionBlock:block];
- [connection setXmlRootObject:channel];
+ [connection setJsonRootObject:channel];
[connection start];
}
@@ -0,0 +1,17 @@
+//
+// Created by rblunden on 1/18/13.
+//
+// To change the template use AppCode | Preferences | File Templates.
+//
+
+
+#import <Foundation/Foundation.h>
+
+@interface JSONSerializable : NSObject
+@end
+
+@protocol JSONSerializable <NSObject>
+
+- (void)readFromJSONDictionary:(NSDictionary *)d;
+
+@end
@@ -0,0 +1,14 @@
+//
+// Created by rblunden on 1/18/13.
+//
+// To change the template use AppCode | Preferences | File Templates.
+//
+
+
+#import "JSONSerializable.h"
+
+
+@implementation JSONSerializable {
+
+}
+@end
@@ -6,9 +6,10 @@
#import <Foundation/Foundation.h>
+#import "JSONSerializable.h"
-@interface RSSChannel : NSObject <NSXMLParserDelegate>
+@interface RSSChannel : NSObject <NSXMLParserDelegate, JSONSerializable>
@property(nonatomic, weak) id parentParserDelegate;
@@ -32,7 +32,7 @@ - (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName nam
currentString = [[NSMutableString alloc] init];
[self setInfoString:currentString];
}
- else if([elementName isEqual:@"item"] || [elementName isEqual:@"entry"]) {
+ else if ([elementName isEqual:@"item"] || [elementName isEqual:@"entry"]) {
// When we find an item, create an instance of an RSSItem
RSSItem *entry = [[RSSItem alloc] init];
@@ -62,5 +62,22 @@ - (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName names
}
}
+- (void)readFromJSONDictionary:(NSDictionary *)d {
+ // The top-level object contains a "feed: obhect which is the channel
+ NSDictionary *feed = d[@"feed"];
+
+ // The feed has a title property, make this the title of our channel
+ [self setTitle:feed[@"feed"]];
+
+ // The feed also has an array of entries, for each one, make a new RSSItem.
+ NSArray *entries = feed[@"entry"];
+ for (NSDictionary *entry in entries) {
+ RSSItem *i = [[RSSItem alloc] init];
+
+ // Pass the entry dictionary to the item so it can grab its ivars
+ [i readFromJSONDictionary:entry];
+ }
+}
+
@end
@@ -6,9 +6,10 @@
#import <Foundation/Foundation.h>
+#import "JSONSerializable.h"
-@interface RSSItem : NSObject <NSXMLParserDelegate> {
+@interface RSSItem : NSObject <NSXMLParserDelegate, JSONSerializable> {
NSMutableString *currentString;
}
@@ -35,4 +35,18 @@ - (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName names
[parser setDelegate:_parentParserDelegate];
}
}
+
+- (void)readFromJSONDictionary:(NSDictionary *)d {
+ [self setTitle:d[@"title"][@"label"]];
+
+ // Inside each entry is an array of links, each has an attribute object
+ NSArray *links = d[@"link"];
+ if ([links count] > 1) {
+ NSDictionary *sampleDict = links[1][@"attributes"];
+
+ // The href of an attribute object is the URK for the sample audio file
+ [self setLink:sampleDict[@"href"]];
+ }
+}
+
@end

0 comments on commit f9a1c9d

Please sign in to comment.