From f3029262dfc32a7cb0f98154ea3af41ffdfed416 Mon Sep 17 00:00:00 2001 From: Mattt Thompson Date: Tue, 11 Oct 2011 12:25:37 -0500 Subject: [PATCH] Initial implementation of Mac example application --- .../project.pbxproj | 90 +++-- Mac Example/Classes/AFGowallaAPIClient.h | 31 ++ Mac Example/Classes/AFGowallaAPIClient.m | 61 +++ .../Controllers/NearbySpotsController.h | 30 ++ .../Controllers/NearbySpotsController.m | 120 ++++++ Mac Example/Classes/Models/Spot.h | 43 +++ Mac Example/Classes/Models/Spot.m | 78 ++++ Mac Example/Images/placeholder-stamp.png | Bin 0 -> 3968 bytes Mac Example/en.lproj/MainMenu.xib | 349 +++++++++++++++++- .../xcschemes/AFNetworkingExample.xcscheme | 75 ++++ .../xcschemes/xcschememanagement.plist | 22 ++ iOS Example/Classes/AFGowallaAPIClient.m | 6 +- iOS Example/Classes/Models/Spot.h | 4 +- iOS Example/Classes/Models/Spot.m | 2 +- 14 files changed, 866 insertions(+), 45 deletions(-) create mode 100644 Mac Example/Classes/AFGowallaAPIClient.h create mode 100644 Mac Example/Classes/AFGowallaAPIClient.m create mode 100644 Mac Example/Classes/Controllers/NearbySpotsController.h create mode 100644 Mac Example/Classes/Controllers/NearbySpotsController.m create mode 100644 Mac Example/Classes/Models/Spot.h create mode 100644 Mac Example/Classes/Models/Spot.m create mode 100644 Mac Example/Images/placeholder-stamp.png create mode 100644 iOS Example/AFNetworking iOS Example.xcodeproj/xcuserdata/mattt.xcuserdatad/xcschemes/AFNetworkingExample.xcscheme create mode 100644 iOS Example/AFNetworking iOS Example.xcodeproj/xcuserdata/mattt.xcuserdatad/xcschemes/xcschememanagement.plist diff --git a/Mac Example/AFNetworking Mac Example.xcodeproj/project.pbxproj b/Mac Example/AFNetworking Mac Example.xcodeproj/project.pbxproj index c084ce3..4fa95be 100644 --- a/Mac Example/AFNetworking Mac Example.xcodeproj/project.pbxproj +++ b/Mac Example/AFNetworking Mac Example.xcodeproj/project.pbxproj @@ -10,6 +10,11 @@ F87A159F1444926300318955 /* AFURLConnectionOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = F87A159E1444926300318955 /* AFURLConnectionOperation.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; F87A15A21444926A00318955 /* AFXMLRequestOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = F87A15A11444926900318955 /* AFXMLRequestOperation.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; F87A15A51444927300318955 /* AFPropertyListRequestOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = F87A15A41444927300318955 /* AFPropertyListRequestOperation.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + F87A15CD1444A30800318955 /* AFGowallaAPIClient.m in Sources */ = {isa = PBXBuildFile; fileRef = F87A15C61444A30800318955 /* AFGowallaAPIClient.m */; }; + F87A15CE1444A30800318955 /* NearbySpotsController.m in Sources */ = {isa = PBXBuildFile; fileRef = F87A15C91444A30800318955 /* NearbySpotsController.m */; }; + F87A15CF1444A30800318955 /* Spot.m in Sources */ = {isa = PBXBuildFile; fileRef = F87A15CC1444A30800318955 /* Spot.m */; }; + F87A15D11444A3EB00318955 /* CoreLocation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F87A15D01444A3EB00318955 /* CoreLocation.framework */; }; + F87A15DD1444A86600318955 /* placeholder-stamp.png in Resources */ = {isa = PBXBuildFile; fileRef = F87A15DB1444A86600318955 /* placeholder-stamp.png */; }; F897DE78142CFEDC000DDD35 /* AFHTTPClient.m in Sources */ = {isa = PBXBuildFile; fileRef = F897DE6A142CFEDC000DDD35 /* AFHTTPClient.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; F897DE79142CFEDC000DDD35 /* AFHTTPRequestOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = F897DE6C142CFEDC000DDD35 /* AFHTTPRequestOperation.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; F897DE7A142CFEDC000DDD35 /* AFImageCache.m in Sources */ = {isa = PBXBuildFile; fileRef = F897DE6E142CFEDC000DDD35 /* AFImageCache.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; @@ -32,6 +37,14 @@ F87A15A11444926900318955 /* AFXMLRequestOperation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AFXMLRequestOperation.m; sourceTree = ""; }; F87A15A31444927300318955 /* AFPropertyListRequestOperation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AFPropertyListRequestOperation.h; sourceTree = ""; }; F87A15A41444927300318955 /* AFPropertyListRequestOperation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AFPropertyListRequestOperation.m; sourceTree = ""; }; + F87A15C51444A30800318955 /* AFGowallaAPIClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AFGowallaAPIClient.h; sourceTree = ""; }; + F87A15C61444A30800318955 /* AFGowallaAPIClient.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AFGowallaAPIClient.m; sourceTree = ""; }; + F87A15C81444A30800318955 /* NearbySpotsController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NearbySpotsController.h; sourceTree = ""; }; + F87A15C91444A30800318955 /* NearbySpotsController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NearbySpotsController.m; sourceTree = ""; }; + F87A15CB1444A30800318955 /* Spot.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Spot.h; sourceTree = ""; }; + F87A15CC1444A30800318955 /* Spot.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Spot.m; sourceTree = ""; }; + F87A15D01444A3EB00318955 /* CoreLocation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreLocation.framework; path = System/Library/Frameworks/CoreLocation.framework; sourceTree = SDKROOT; }; + F87A15DB1444A86600318955 /* placeholder-stamp.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "placeholder-stamp.png"; sourceTree = ""; }; F897DE69142CFEDC000DDD35 /* AFHTTPClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AFHTTPClient.h; sourceTree = ""; }; F897DE6A142CFEDC000DDD35 /* AFHTTPClient.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AFHTTPClient.m; sourceTree = ""; }; F897DE6B142CFEDC000DDD35 /* AFHTTPRequestOperation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AFHTTPRequestOperation.h; sourceTree = ""; }; @@ -68,6 +81,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + F87A15D11444A3EB00318955 /* CoreLocation.framework in Frameworks */, F8CEEB6F142CEC6E00247B03 /* Cocoa.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; @@ -75,6 +89,43 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + F87A15C41444A30800318955 /* Classes */ = { + isa = PBXGroup; + children = ( + F87A15C51444A30800318955 /* AFGowallaAPIClient.h */, + F87A15C61444A30800318955 /* AFGowallaAPIClient.m */, + F87A15C71444A30800318955 /* Controllers */, + F87A15CA1444A30800318955 /* Models */, + ); + path = Classes; + sourceTree = ""; + }; + F87A15C71444A30800318955 /* Controllers */ = { + isa = PBXGroup; + children = ( + F87A15C81444A30800318955 /* NearbySpotsController.h */, + F87A15C91444A30800318955 /* NearbySpotsController.m */, + ); + path = Controllers; + sourceTree = ""; + }; + F87A15CA1444A30800318955 /* Models */ = { + isa = PBXGroup; + children = ( + F87A15CB1444A30800318955 /* Spot.h */, + F87A15CC1444A30800318955 /* Spot.m */, + ); + path = Models; + sourceTree = ""; + }; + F87A15DA1444A86600318955 /* Images */ = { + isa = PBXGroup; + children = ( + F87A15DB1444A86600318955 /* placeholder-stamp.png */, + ); + path = Images; + sourceTree = ""; + }; F897DE68142CFEDC000DDD35 /* AFNetworking */ = { isa = PBXGroup; children = ( @@ -104,37 +155,6 @@ path = ../../AFNetworking; sourceTree = ""; }; - F8A27AB4142CFE1300F5E0D6 /* Classes */ = { - isa = PBXGroup; - children = ( - F8A27AB5142CFE1300F5E0D6 /* Controllers */, - F8A27AB6142CFE1300F5E0D6 /* Models */, - F8A27AB7142CFE1300F5E0D6 /* Views */, - ); - path = Classes; - sourceTree = ""; - }; - F8A27AB5142CFE1300F5E0D6 /* Controllers */ = { - isa = PBXGroup; - children = ( - ); - path = Controllers; - sourceTree = ""; - }; - F8A27AB6142CFE1300F5E0D6 /* Models */ = { - isa = PBXGroup; - children = ( - ); - path = Models; - sourceTree = ""; - }; - F8A27AB7142CFE1300F5E0D6 /* Views */ = { - isa = PBXGroup; - children = ( - ); - path = Views; - sourceTree = ""; - }; F8A27ABD142CFE1300F5E0D6 /* Vendor */ = { isa = PBXGroup; children = ( @@ -163,6 +183,7 @@ F8A27AC5142CFE1300F5E0D6 /* AppDelegate.h */, F8A27AB9142CFE1300F5E0D6 /* Credits.rtf */, F8A27ABB142CFE1300F5E0D6 /* MainMenu.xib */, + F87A15DA1444A86600318955 /* Images */, ); name = "Supporting Files"; sourceTree = ""; @@ -170,7 +191,7 @@ F8CEEB5F142CEC6E00247B03 = { isa = PBXGroup; children = ( - F8A27AB4142CFE1300F5E0D6 /* Classes */, + F87A15C41444A30800318955 /* Classes */, F8A27ACD142CFE3000F5E0D6 /* Supporting Files */, F8A27ABD142CFE1300F5E0D6 /* Vendor */, F8CEEB6D142CEC6E00247B03 /* Frameworks */, @@ -189,6 +210,7 @@ F8CEEB6D142CEC6E00247B03 /* Frameworks */ = { isa = PBXGroup; children = ( + F87A15D01444A3EB00318955 /* CoreLocation.framework */, F8CEEB6E142CEC6E00247B03 /* Cocoa.framework */, F8CEEB70142CEC6E00247B03 /* Other Frameworks */, ); @@ -258,6 +280,7 @@ files = ( F8A27AC9142CFE1300F5E0D6 /* Credits.rtf in Resources */, F8A27ACA142CFE1300F5E0D6 /* MainMenu.xib in Resources */, + F87A15DD1444A86600318955 /* placeholder-stamp.png in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -281,6 +304,9 @@ F87A159F1444926300318955 /* AFURLConnectionOperation.m in Sources */, F87A15A21444926A00318955 /* AFXMLRequestOperation.m in Sources */, F87A15A51444927300318955 /* AFPropertyListRequestOperation.m in Sources */, + F87A15CD1444A30800318955 /* AFGowallaAPIClient.m in Sources */, + F87A15CE1444A30800318955 /* NearbySpotsController.m in Sources */, + F87A15CF1444A30800318955 /* Spot.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/Mac Example/Classes/AFGowallaAPIClient.h b/Mac Example/Classes/AFGowallaAPIClient.h new file mode 100644 index 0000000..5fabb8c --- /dev/null +++ b/Mac Example/Classes/AFGowallaAPIClient.h @@ -0,0 +1,31 @@ +// AFGowallaAPI.h +// +// Copyright (c) 2011 Gowalla (http://gowalla.com/) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#import +#import "AFHTTPClient.h" + +extern NSString * const kAFGowallaClientID; +extern NSString * const kAFGowallaBaseURLString; + +@interface AFGowallaAPIClient : AFHTTPClient ++ (AFGowallaAPIClient *)sharedClient; +@end diff --git a/Mac Example/Classes/AFGowallaAPIClient.m b/Mac Example/Classes/AFGowallaAPIClient.m new file mode 100644 index 0000000..53c7f02 --- /dev/null +++ b/Mac Example/Classes/AFGowallaAPIClient.m @@ -0,0 +1,61 @@ +// AFGowallaAPI.m +// +// Copyright (c) 2011 Gowalla (http://gowalla.com/) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#import "AFGowallaAPIClient.h" + +#import "AFJSONRequestOperation.h" + +// Replace this with your own API Key, available at http://api.gowalla.com/api/keys/ +NSString * const kAFGowallaClientID = @"e7ccb7d3d2414eb2af4663fc91eb2793"; + +NSString * const kAFGowallaBaseURLString = @"https://api.gowalla.com/"; + +@implementation AFGowallaAPIClient + ++ (AFGowallaAPIClient *)sharedClient { + static AFGowallaAPIClient *_sharedClient = nil; + static dispatch_once_t oncePredicate; + dispatch_once(&oncePredicate, ^{ + _sharedClient = [[self alloc] initWithBaseURL:[NSURL URLWithString:kAFGowallaBaseURLString]]; + }); + + return _sharedClient; +} + +- (id)initWithBaseURL:(NSURL *)url { + self = [super initWithBaseURL:url]; + if (!self) { + return nil; + } + + [self registerHTTPOperationClass:[AFJSONRequestOperation class]]; + + // X-Gowalla-API-Key HTTP Header; see http://api.gowalla.com/api/docs + [self setDefaultHeader:@"X-Gowalla-API-Key" value:kAFGowallaClientID]; + + // X-Gowalla-API-Version HTTP Header; see http://api.gowalla.com/api/docs + [self setDefaultHeader:@"X-Gowalla-API-Version" value:@"1"]; + + return self; +} + +@end diff --git a/Mac Example/Classes/Controllers/NearbySpotsController.h b/Mac Example/Classes/Controllers/NearbySpotsController.h new file mode 100644 index 0000000..d70623f --- /dev/null +++ b/Mac Example/Classes/Controllers/NearbySpotsController.h @@ -0,0 +1,30 @@ +// NearbySpotsViewController.h +// +// Copyright (c) 2011 Gowalla (http://gowalla.com/) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#import +#import + +@interface NearbySpotsController : NSObject + +@property (strong) IBOutlet NSTableView *tableView; + +@end diff --git a/Mac Example/Classes/Controllers/NearbySpotsController.m b/Mac Example/Classes/Controllers/NearbySpotsController.m new file mode 100644 index 0000000..11dc74a --- /dev/null +++ b/Mac Example/Classes/Controllers/NearbySpotsController.m @@ -0,0 +1,120 @@ +// NearbySpotsViewController.m +// +// Copyright (c) 2011 Gowalla (http://gowalla.com/) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#import "NearbySpotsController.h" + +#import "Spot.h" + +#import "AFImageRequestOperation.h" +#import "AFImageCache.h" + +@interface NearbySpotsController () +@property (strong) NSArray *nearbySpots; +@property (strong) CLLocationManager *locationManager; +@property (strong) NSOperationQueue *imageOperationQueue; + +- (void)loadSpotsForLocation:(CLLocation *)location; +@end + +@implementation NearbySpotsController +@synthesize nearbySpots = _nearbySpots; +@synthesize locationManager = _locationManager; +@synthesize imageOperationQueue = _imageOperationQueue; +@synthesize tableView = _tableView; + +- (id)init { + self = [super init]; + if (!self) { + return nil; + } + + self.nearbySpots = [NSArray array]; + + self.locationManager = [[CLLocationManager alloc] init]; + self.locationManager.delegate = self; + self.locationManager.distanceFilter = 80.0; + + self.imageOperationQueue = [[NSOperationQueue alloc] init]; + self.imageOperationQueue.maxConcurrentOperationCount = 8; + + return self; +} + +- (void)awakeFromNib { + [self.locationManager startUpdatingLocation]; +} + +- (void)loadSpotsForLocation:(CLLocation *)location { + [Spot spotsWithURLString:@"/spots" near:location parameters:[NSDictionary dictionaryWithObject:@"128" forKey:@"per_page"] block:^(NSArray *records) { + self.nearbySpots = [records sortedArrayUsingComparator:^ NSComparisonResult(id obj1, id obj2) { + CLLocationDistance d1 = [[(Spot *)obj1 location] distanceFromLocation:location]; + CLLocationDistance d2 = [[(Spot *)obj2 location] distanceFromLocation:location]; + + if (d1 < d2) { + return NSOrderedAscending; + } else if (d1 > d2) { + return NSOrderedDescending; + } else { + return NSOrderedSame; + } + }]; + + [self.tableView reloadData]; + }]; +} + +#pragma mark - CLLocationManagerDelegate + +- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation { + [self loadSpotsForLocation:newLocation]; +} + +#pragma mark - NSTableViewDataSource + +- (NSInteger)numberOfRowsInTableView:(NSTableView *)tableView { + return [self.nearbySpots count]; +} + +- (id)tableView:(NSTableView *)tableView objectValueForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row { + Spot *spot = [self.nearbySpots objectAtIndex:row]; + + if ([[tableColumn dataCell] isMemberOfClass:[NSImageCell class]]) { + NSURL *imageURL = [NSURL URLWithString:spot.imageURLString]; + NSImage *image = [[AFImageCache sharedImageCache] cachedImageForURL:imageURL cacheName:nil]; + if (!image) { + NSURLRequest *imageRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:spot.imageURLString]]; + AFImageRequestOperation *operation = [AFImageRequestOperation imageRequestOperationWithRequest:imageRequest success:^(NSImage *image) { + + [tableView reloadDataForRowIndexes:[NSIndexSet indexSetWithIndex:row] columnIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, 2)]]; + }]; + [self.imageOperationQueue addOperation:operation]; + + image = [NSImage imageNamed:@"placeholder-stamp.png"]; + } + + return image; + } else { + return spot.name; + } +} + +@end diff --git a/Mac Example/Classes/Models/Spot.h b/Mac Example/Classes/Models/Spot.h new file mode 100644 index 0000000..e3c9954 --- /dev/null +++ b/Mac Example/Classes/Models/Spot.h @@ -0,0 +1,43 @@ +// Spot.h +// +// Copyright (c) 2011 Gowalla (http://gowalla.com/) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#import +#import + +@interface Spot : NSObject { +@private + NSString *_name; + NSString *_imageURLString; + NSNumber *_latitude; + NSNumber *_longitude; +} + +@property (strong) NSString *name; +@property (strong) NSString *imageURLString; +@property (strong) NSNumber *latitude; +@property (strong) NSNumber *longitude; +@property (readonly) CLLocation *location; + +- (id)initWithAttributes:(NSDictionary *)attributes; ++ (void)spotsWithURLString:(NSString *)urlString near:(CLLocation *)location parameters:(NSDictionary *)parameters block:(void (^)(NSArray *records))block; + +@end diff --git a/Mac Example/Classes/Models/Spot.m b/Mac Example/Classes/Models/Spot.m new file mode 100644 index 0000000..e93e70a --- /dev/null +++ b/Mac Example/Classes/Models/Spot.m @@ -0,0 +1,78 @@ +// Spot.m +// +// Copyright (c) 2011 Gowalla (http://gowalla.com/) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#import "Spot.h" + +#import "AFGowallaAPIClient.h" + +@implementation Spot +@synthesize name = _name; +@synthesize imageURLString = _imageURLString; +@synthesize latitude = _latitude; +@synthesize longitude = _longitude; +@dynamic location; + +- (id)initWithAttributes:(NSDictionary *)attributes { + self = [super init]; + if (!self) { + return nil; + } + + self.name = [attributes valueForKeyPath:@"name"]; + self.imageURLString = [attributes valueForKeyPath:@"image_url"]; + self.latitude = [attributes valueForKeyPath:@"lat"]; + self.longitude = [attributes valueForKeyPath:@"lng"]; + + return self; +} + +- (CLLocation *)location { + return [[CLLocation alloc] initWithLatitude:[self.latitude doubleValue] longitude:[self.longitude doubleValue]]; +} + ++ (void)spotsWithURLString:(NSString *)urlString near:(CLLocation *)location parameters:(NSDictionary *)parameters block:(void (^)(NSArray *records))block { + + NSLog(@"GET"); + NSDictionary *mutableParameters = [NSMutableDictionary dictionaryWithDictionary:parameters]; + if (location) { + [mutableParameters setValue:[NSString stringWithFormat:@"%1.7f", location.coordinate.latitude] forKey:@"lat"]; + [mutableParameters setValue:[NSString stringWithFormat:@"%1.7f", location.coordinate.longitude] forKey:@"lng"]; + } + + [[AFGowallaAPIClient sharedClient] getPath:urlString parameters:mutableParameters success:^(id object) { + NSMutableArray *mutableRecords = [NSMutableArray array]; + for (NSDictionary *attributes in [object valueForKeyPath:@"spots"]) { + Spot *spot = [[Spot alloc] initWithAttributes:attributes]; + [mutableRecords addObject:spot]; + } + + if (block) { + block([NSArray arrayWithArray:mutableRecords]); + } + } failure:^(NSHTTPURLResponse *response, NSError *error) { + if (block) { + block([NSArray array]); + } + }]; +} + +@end diff --git a/Mac Example/Images/placeholder-stamp.png b/Mac Example/Images/placeholder-stamp.png new file mode 100644 index 0000000000000000000000000000000000000000..7aafe3ddaac4e304926d9e84529f82b46e169569 GIT binary patch literal 3968 zcmV-`4}b89P)X+uL$Nkc;* zP;zf(X>4Tx0C)kNmUmQB*%pV-y*Itk5+Wca^cs2zAksTX6$DXM^`x7XQc?|s+0 z08spb1j2M!0f022SQPH-!CVp(%f$Br7!UytSOLJ{W@ZFO_(THK{JlMynW#v{v-a*T zfMmPdEWc1DbJqWVks>!kBnAKqMb$PuekK>?0+ds;#ThdH1j_W4DKdsJG8Ul;qO2n0 z#IJ1jr{*iW$(WZWsE0n`c;fQ!l&-AnmjxZO1uWyz`0VP>&nP`#itsL#`S=Q!g`M=rU9)45( zJ;-|dRq-b5&z?byo>|{)?5r=n76A4nTALlSzLiw~v~31J<>9PP?;rs31pu_(obw)r zY+jPY;tVGXi|p)da{-@gE-UCa`=5eu%D;v=_nFJ?`&K)q7e9d`Nfk3?MdhZarb|T3 z%nS~f&t(1g5dY)AIcd$w!z`Siz!&j_=v7hZlnI21XuE|xfmo0(WD10T)!}~_HYW!e zew}L+XmwuzeT6wtxJd`dZ#@7*BLgIEKY9Xv>st^p3dp{^Xswa2bB{85{^$B13tWnB z;Y>jyQ|9&zk7RNsqAVGs--K+z0uqo1bf5|}fi5rtEMN^BfHQCd-XH*kfJhJnmIE$G z0%<@5vOzxB0181d*a3EfYH$G5fqKvcPJ%XY23!PJzzuK<41h;K3WmW;Fah3yX$XSw z5EY_9s*o0>51B&N5F1(uc|$=^I1~fLLy3?Ol0f;;Ca4%HgQ}rJP(Ab`bQ-z{U4#0d z2hboi2K@njgb|nm(_szR0JebHusa+GN5aeCM0gdP2N%HG;Yzp`J`T6S7vUT504#-H z!jlL<$Or?`Mpy_N@kBz9SR?@vA#0H$qyni$nvf2p8@Y{0k#Xb$28W?xm>3qu8RLgp zjNxKdVb)?wFx8l2m{v>|<~C*!GlBVnrDD~wrdTJeKXwT=5u1%I#8zOBU|X=4u>;s) z>^mF|$G{ol9B_WP7+f-LHLe7=57&&lfa}8z;U@8Tyei%l?}87(bMRt(A-)QK9Dg3) zj~~XrCy)tR1Z#p1A(kK{Y$Q|=8VKhI{e%(1G*N-5Pjn)N5P8I0VkxnX*g?EW941ba z6iJ387g8iCnY4jaNopcpCOsy-A(P2EWJhusSwLP-t|XrzUnLKcKTwn?CKOLf97RIe zPB}`sKzTrUL#0v;sBY9)s+hW+T2H-1eM)^VN0T#`^Oxhvt&^*fYnAJldnHel*Ozyf zUoM{~Um<@={-*r60#U(0!Bc^wuvVc);k3d%g-J!4qLpHZVwz%!VuRu}#Ze`^l7W)9 z5>Kf>>9Eozr6C$Z)1`URxU@~QI@)F0FdauXr2Es8>BaOP=)Lp_WhG@>R;lZ?BJkMlIuMhw8ApiF&yDYW2hFJ?fJhni{?u z85&g@mo&yT8JcdI$(rSw=QPK(Xj%)k1X|@<=e1rim6`6$RAwc!i#egKuI;BS(LSWz zt39n_sIypSqfWEV6J3%nTQ@-4i zi$R;gsG*9XzhRzXqv2yCs*$VFDx+GXJH|L;wsDH_KI2;^u!)^Xl1YupO;gy^-c(?^ z&$Q1BYvyPsG^;hc$D**@Sy`+`)}T4VJji^bd7Jqw3q6Zii=7tT7GEswEK@D(EFW1Z zSp`^awCb?>!`j4}Yh7b~$A)U-W3$et-R8BesV(1jzwLcHnq9En7Q0Tn&-M=XBKs!$ zF$X<|c!#|X_tWYh)GZit z(Q)Cp9CDE^WG;+fcyOWARoj*0TI>4EP1lX*cEoMO-Pk?Z{kZ!p4@(b`M~lalr<3Oz z&kJ6Nm#vN_+kA5{dW4@^Vjg_`q%qU1ULk& z3Fr!>1V#i_2R;ij2@(Z$1jE4r!MlPVFVbHmT+|iPIq0wy5aS{>yK?9ZAjVh%SOwMWgFjair&;wpi!{CU}&@N=Eg#~ zLQ&zpEzVmGY{hI9Z0+4-0xS$$Xe-OToc?Y*V;rTcf_ zb_jRe-RZjXSeas3UfIyD;9afd%<`i0x4T#DzE)vdabOQ=k7SRuGN`h>O0Q~1)u-yD z>VX=Mn&!Rgd$;YK+Q-}1zu#?t(*cbG#Ronf6db&N$oEidtwC+YVcg-Y!_VuY>bk#Y ze_ww@?MU&F&qswvrN_dLb=5o6*Egs)ls3YRlE$&)amR1{;Ppd$6RYV^Go!iq1UMl% z@#4q$AMc(FJlT1QeX8jv{h#)>&{~RGq1N2iiMFIRX?sk2-|2wUogK~{EkB$8eDsX= znVPf8XG_nK&J~=SIiGia@9y}|z3FhX{g&gcj=lwb=lWgyFW&aLedUh- zof`v-2Kw$UzI*>(+&$@i-u=-BsSjR1%z8NeX#HdC`Hh-Z(6xI-`hmHDqv!v)W&&nrf>M(RhcN6(D;jNN*%^u_SYjF;2ng}*8Ow)d6M ztDk;%`@Lsk$;9w$(d(H%O5UixIr`T2ZRcd@y(Ol!$uqRMAs+p<2yh z-9t=6AzKfkc=DoR@KO;C6ufvS3bjI@Q0b+ZG>J)ex0~$0ncW$`Z<04`r>UFNC7G3d zF!|=qd+hvv@0+(XvoD-!noy6DNF-!cmBs{t9|Il+Ie;Jlca-Cxl|CO&Q^3Es@NBE5 zVcsz+=3FkPUyH}%T0PFs{TGo$G7(TgIwJsomKV4&o)^55Btoml12RUB>H!W-wnR+G z=klQGWhfR3plLc7Mr9L)u2sPJE(iKtJQ`0uuGC|R#FDYru-P3GMD9I75ZYC*3Vy#2 zL{S2s=WKW;!Qj}SQ8Ww_%4HqW=?vsHb5N;NvgL{~wFs-9%tU7}dwVN;5*Z&K7fzl$ z_7>0clcFT{V8PK>5T3Wr>IAQa!o&>2fI_|qD=RBd*2^ncpSXVg=9jaxvz1z(!P<8% zaw(Y@PIy(xdz&S&S9o?}XWYt?0UOy3SX)bBw#vU3jpAz;qwzb=zB|=- zB{DNJ^|IU|ek02*p8jxOT?L#_OlWc89?qjuUMrPfkHtRt-r3JtuPJin%B6FHD17Gg z`+3Sly)xhgan?zQGLuQCjY_%l&iV5fzi{@cuK%k@GWqcvlHBrDu)7P|@lx6^2?j_q zS-jL%|6T)KE4>+we)u(ObH+!CB$Jb)DDg{YSEuarb?mzY10|VE=02>it!pTAIvSn$ zjkQ(Bt*@KvBe*}Aob1Qx@Pn$V2P#2WbQRD*5(_aAn*-OXJ|se4vA!1Nsvz>gP;bwH zWuh9EWQc{Bh>aMl+iCwHkyEFSzmNBYkw_%$3JC^GGQ>n|#K?}b_`n>wd^r*Fwzc04 zg?i*xkM)Se`ne_+@&#C4UePu;vQJ#N5MO3s4`igHBk&O#%Sx-l+FcikjTniw8qUs0 z5+49Ps&BckzgNOi-N$wNx~{{$#U(wT%Y>ra51MvHJl?>&NG#zai0i#MQizq9r>CbQ#B7Q9eBEbp0yRW7 z*g#WOh&db%zG91by=|}J+NiW_9N0FD*IK`%81wNHA|(stlRGgzkLo()4=0V4LV?ngnIh3nM}s+&?q~Z^nK_F z^;zJS$iTqUKjMO8LtS1p74V-7;Hkp{KiL^Mbm+;cBS)S!X-T+I3b76i4V#h3;b~h0 zcjixwp87o8AAyCx7NJ-yy4Hu-h>=)FkH7FKu@kJlK7#u)Zdd2$Z=Shv<5w^_6PKjh zaWc7M YES - NSWindowTemplate NSView NSMenu + NSScrollView + NSWindowTemplate NSMenuItem + NSTableView + NSTextFieldCell + NSImageCell + NSTableColumn + NSScroller NSCustomObject @@ -1317,19 +1323,218 @@ 15 2 - {{335, 390}, {480, 360}} + {{50, 538}, {375, 500}} 1954021376 AFNetworking Mac Example NSWindow + {375, 1280} + {375, 200} - + 256 - {480, 360} + + YES + + + 274 + + YES + + + 2304 + + YES + + + 256 + {373, 498} + + + + _NS:1197 + YES + + + -2147483392 + {{224, 0}, {16, 17}} + _NS:1202 + + + YES + + 129.5078125 + 100 + 130 + + 75628096 + 2048 + + + LucidaGrande + 11 + 3100 + + + 3 + MC4zMzMzMzI5ODU2AA + + + 6 + System + headerTextColor + + 3 + MAA + + + + + 67239424 + 33554432 + + LucidaGrande + 13 + 1044 + + _NS:4045 + 1 + 0 + 0 + NO + + 3 + YES + YES + + + + 223 + 40 + 1000 + + 75628096 + 2048 + + + + + + + 337772032 + 0 + Text Cell + + LucidaGrande + 16 + 16 + + + + 6 + System + controlBackgroundColor + + 3 + MC42NjY2NjY2NjY3AA + + + + 6 + System + controlTextColor + + + + 3 + YES + YES + + + + 10 + 10 + + 3 + MQA + + + 6 + System + gridColor + + 3 + MC41AA + + + 60 + 373293056 + + + 4 + 15 + 0 + YES + 0 + 1 + + + {{1, 1}, {373, 498}} + + + + _NS:1195 + + + 4 + + + + -2147483392 + {{224, 17}, {15, 102}} + + + + _NS:1214 + + _doScroller: + 0.99815157116451014 + + + + -2147483392 + {{1, 526}, {374, 15}} + + + + _NS:1216 + 1 + + _doScroller: + 0.99733333333333329 + + + {375, 500} + + + + _NS:1193 + 133682 + + + + QSAAAEEgAABCjAAAQowAAA + + + {375, 500} + + + {{0, 0}, {1920, 1178}} - {10000000000000, 10000000000000} + {375, 222} + {375, 1302} YES @@ -1338,6 +1543,9 @@ NSFontManager + + NearbySpotsController + @@ -2022,6 +2230,30 @@ 535 + + + tableView + + + + 550 + + + + dataSource + + + + 551 + + + + delegate + + + + 552 + @@ -2572,6 +2804,10 @@ 372 + + YES + + @@ -3065,6 +3301,70 @@ + + 537 + + + YES + + + + + + + + 538 + + + + + 540 + + + + + 541 + + + YES + + + + + + + 542 + + + YES + + + + + + 543 + + + YES + + + + + + 544 + + + + + 546 + + + + + 549 + + + @@ -3211,6 +3511,15 @@ 516.IBPluginDependency 517.IBPluginDependency 534.IBPluginDependency + 537.IBPluginDependency + 538.IBPluginDependency + 540.IBPluginDependency + 541.IBPluginDependency + 542.IBPluginDependency + 543.IBPluginDependency + 544.IBPluginDependency + 546.IBPluginDependency + 549.IBPluginDependency 56.IBPluginDependency 57.IBPluginDependency 58.IBPluginDependency @@ -3382,6 +3691,15 @@ com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin @@ -3396,7 +3714,7 @@ - 535 + 554 @@ -3487,6 +3805,25 @@ ./Classes/NSDocument.h + + NearbySpotsController + NSObject + + tableView + NSTableView + + + tableView + + tableView + NSTableView + + + + IBProjectSource + ./Classes/NearbySpotsController.h + + 0 diff --git a/iOS Example/AFNetworking iOS Example.xcodeproj/xcuserdata/mattt.xcuserdatad/xcschemes/AFNetworkingExample.xcscheme b/iOS Example/AFNetworking iOS Example.xcodeproj/xcuserdata/mattt.xcuserdatad/xcschemes/AFNetworkingExample.xcscheme new file mode 100644 index 0000000..19af009 --- /dev/null +++ b/iOS Example/AFNetworking iOS Example.xcodeproj/xcuserdata/mattt.xcuserdatad/xcschemes/AFNetworkingExample.xcscheme @@ -0,0 +1,75 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/iOS Example/AFNetworking iOS Example.xcodeproj/xcuserdata/mattt.xcuserdatad/xcschemes/xcschememanagement.plist b/iOS Example/AFNetworking iOS Example.xcodeproj/xcuserdata/mattt.xcuserdatad/xcschemes/xcschememanagement.plist new file mode 100644 index 0000000..ab5d718 --- /dev/null +++ b/iOS Example/AFNetworking iOS Example.xcodeproj/xcuserdata/mattt.xcuserdatad/xcschemes/xcschememanagement.plist @@ -0,0 +1,22 @@ + + + + + SchemeUserState + + AFNetworkingExample.xcscheme + + orderHint + 1 + + + SuppressBuildableAutocreation + + F8E4695F1395739C00DB05C8 + + primary + + + + + diff --git a/iOS Example/Classes/AFGowallaAPIClient.m b/iOS Example/Classes/AFGowallaAPIClient.m index e83a320..4f0bb3d 100644 --- a/iOS Example/Classes/AFGowallaAPIClient.m +++ b/iOS Example/Classes/AFGowallaAPIClient.m @@ -47,6 +47,8 @@ NSString * const kAFGowallaBaseURLString = @"https://api.gowalla.com/"; return nil; } + [self registerHTTPOperationClass:[AFJSONRequestOperation class]]; + // X-Gowalla-API-Key HTTP Header; see http://api.gowalla.com/api/docs [self setDefaultHeader:@"X-Gowalla-API-Key" value:kAFGowallaClientID]; @@ -55,9 +57,7 @@ NSString * const kAFGowallaBaseURLString = @"https://api.gowalla.com/"; // X-UDID HTTP Header [self setDefaultHeader:@"X-UDID" value:[[UIDevice currentDevice] uniqueIdentifier]]; - - [self registerHTTPOperationClass:[AFJSONRequestOperation class]]; - + return self; } diff --git a/iOS Example/Classes/Models/Spot.h b/iOS Example/Classes/Models/Spot.h index 3cee711..80a5ee7 100644 --- a/iOS Example/Classes/Models/Spot.h +++ b/iOS Example/Classes/Models/Spot.h @@ -23,8 +23,6 @@ #import #import -typedef void (^AFRecordsBlock)(NSArray *records); - @interface Spot : NSObject { @private NSString *_name; @@ -40,6 +38,6 @@ typedef void (^AFRecordsBlock)(NSArray *records); @property (readonly) CLLocation *location; - (id)initWithAttributes:(NSDictionary *)attributes; -+ (void)spotsWithURLString:(NSString *)urlString near:(CLLocation *)location parameters:(NSDictionary *)parameters block:(AFRecordsBlock)block; ++ (void)spotsWithURLString:(NSString *)urlString near:(CLLocation *)location parameters:(NSDictionary *)parameters block:(void (^)(NSArray *records))block; @end diff --git a/iOS Example/Classes/Models/Spot.m b/iOS Example/Classes/Models/Spot.m index 5d9675a..bd7272a 100644 --- a/iOS Example/Classes/Models/Spot.m +++ b/iOS Example/Classes/Models/Spot.m @@ -57,7 +57,7 @@ return [[[CLLocation alloc] initWithLatitude:[self.latitude doubleValue] longitude:[self.longitude doubleValue]] autorelease]; } -+ (void)spotsWithURLString:(NSString *)urlString near:(CLLocation *)location parameters:(NSDictionary *)parameters block:(AFRecordsBlock)block { ++ (void)spotsWithURLString:(NSString *)urlString near:(CLLocation *)location parameters:(NSDictionary *)parameters block:(void (^)(NSArray *records))block { NSDictionary *mutableParameters = [NSMutableDictionary dictionaryWithDictionary:parameters]; if (location) { [mutableParameters setValue:[NSString stringWithFormat:@"%1.7f", location.coordinate.latitude] forKey:@"lat"];