Last active
December 21, 2015 16:49
-
-
Save stephenkeep/6335946 to your computer and use it in GitHub Desktop.
iOS Snips
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-(void)AppendExisting:(NSString*)val | |
{ | |
@synchronized (val) { | |
[oldValue stringByAppendingFormat:@"-%@",val]; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL | |
URLWithString:@"link"]]; AFJSONRequestOperation *operation = | |
[AFJSONRequestOperation JSONRequestOperationWithRequest:request | |
success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) | |
{ | |
NSDictionary *jsonDict = (NSDictionary *) JSON; | |
NSArray *products = [jsonDict objectForKey:@"products"]; | |
NSMutableArray *productsList = [[NSMutableArray alloc] init]; | |
Product *product = [[Product alloc] init]; | |
[products enumerateObjectsUsingBlock:^(id obj,NSUInteger idx, BOOL *stop){ | |
product.icon_url= [obj objectForKey:@"icon_url"]; | |
[productsList addObject:product]; | |
}]; | |
} failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id JSON { | |
NSLog(@"Request Failure Because %@",[error userInfo]); | |
}]; | |
[operation start]; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//Start Singleton | |
[ExploreManager sharedExploreManager]; | |
[[TopicManager sharedTopicManager] setContext:[self managedObjectContext]]; | |
//reset badge | |
application.applicationIconBadgeNumber = 0; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// ARLocationServices.h | |
// Topshop | |
// | |
// Created by Stephen Keep on 04/06/2013. | |
// Copyright (c) 2013 Red Ant Ltd. All rights reserved. | |
// | |
#import <Foundation/Foundation.h> | |
#import <MapKit/MapKit.h> | |
@interface ARLocationServices : NSObject <CLLocationManagerDelegate> { | |
CLLocationManager* _locationManager; | |
} | |
@property (strong, nonatomic) CLLocationManager* locationManager; | |
+ (void)start; | |
+ (void)getStoresForCurrentLocation:(NSArrayNSErrorBlock) block; | |
+ (void)getStoresForLocationString:(NSString *)locationString usingBlock:(NSArrayNSErrorBlock) block; | |
+ (void)getStoresForCoordinates:(CLLocationCoordinate2D)coordinates usingBlock:(NSArrayNSErrorBlock) block; | |
@end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// ARLocationServices.m | |
// Topshop | |
// | |
// Created by Stephen Keep on 04/06/2013. | |
// Copyright (c) 2013 Red Ant Ltd. All rights reserved. | |
// | |
#import "ARLocationServices.h" | |
#import "ARShopObject.h" | |
#import <AddressBook/AddressBook.h> | |
#import "SVPlacemark.h" | |
#define kNumberOfResults @"20" | |
#define kDistanceToSearch @"200" | |
#define NSNullToNil(obj) [obj isKindOfClass:[NSNull class]]?nil:obj | |
@interface ARLocationServices () { | |
} | |
@property (strong, nonatomic) NSMutableArray *stores; | |
@end | |
@implementation ARLocationServices | |
PureSingleton(ARLocationServices) | |
- (id)init { | |
self = [super init]; | |
if(self) { | |
_locationManager = [[CLLocationManager alloc] init]; | |
[_locationManager setDelegate:self]; | |
[_locationManager setDistanceFilter:kCLDistanceFilterNone]; | |
[_locationManager setHeadingFilter:kCLHeadingFilterNone]; | |
[_locationManager startUpdatingLocation]; | |
} | |
return self; | |
} | |
+ (void)start { | |
[ARLocationServices shared]; | |
} | |
+ (void)getStoresForCurrentLocation:(NSArrayNSErrorBlock) block { | |
if ([[ARLocationServices shared] locationEnabled]) { | |
float longitude = [[ARLocationServices shared] getLongitude]; | |
float latitude = [[ARLocationServices shared] getLatitude]; | |
[[ARLocationServices shared] fetchStoresForCurrentLatitude:latitude andLongitude:longitude usingBlock:^(NSArray *array, NSError *error) { | |
block(array,error); | |
}]; | |
} | |
} | |
+ (void)getStoresForLocationString:(NSString *)locationString usingBlock:(NSArrayNSErrorBlock) block { | |
[[ARLocationServices shared] getGeocodeWithLocationString:locationString usingBlock:^(NSArray *array, NSError *error) { | |
if (error) { | |
block(nil,error); | |
} else if ([array count] == 1) { | |
CLLocationCoordinate2D coordinate = ((SVPlacemark *)[array objectAtIndex:0]).coordinate; | |
float longitude = coordinate.longitude; | |
float latitude = coordinate.latitude; | |
[[ARLocationServices shared] fetchStoresForCurrentLatitude:latitude andLongitude:longitude usingBlock:^(NSArray *array, NSError *error) { | |
block(array,error); | |
}]; | |
} else { | |
block(array,[NSError errorWithDomain:@"com.redant" code:-1 userInfo:nil]); | |
} | |
}]; | |
} | |
+ (void)getStoresForCoordinates:(CLLocationCoordinate2D)coordinates usingBlock:(NSArrayNSErrorBlock) block { | |
float longitude = coordinates.longitude; | |
float latitude = coordinates.latitude; | |
[[ARLocationServices shared] fetchStoresForCurrentLatitude:latitude andLongitude:longitude usingBlock:^(NSArray *array, NSError *error) { | |
block(array,error); | |
}]; | |
} | |
-(BOOL)locationEnabled { | |
if (CLLocationManager.authorizationStatus == kCLAuthorizationStatusAuthorized) { | |
return YES; | |
} else if (CLLocationManager.authorizationStatus == kCLAuthorizationStatusDenied) { | |
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Location Service Disabled" | |
message:@"To re-enable, please go to Settings and turn on Location Service for this app." | |
delegate:nil | |
cancelButtonTitle:@"OK" | |
otherButtonTitles:nil]; | |
[alert show]; | |
return NO; | |
} | |
return NO; | |
} | |
-(float)getLongitude { | |
CLLocation *location = [self.locationManager location]; | |
return location.coordinate.longitude; | |
} | |
-(float)getLatitude { | |
CLLocation *location = [self.locationManager location]; | |
return location.coordinate.latitude; | |
} | |
- (void)fetchStoresForCurrentLatitude:(float)latitude andLongitude:(float)longitude usingBlock:(NSArrayNSErrorBlock) block { | |
NSString *sUrl = [[[[[[ARConfigServices valueForKey:@"storeFinderURL"] | |
stringByReplacingOccurrencesOfString:@"{storeId}" withString:@"12556"] | |
stringByReplacingOccurrencesOfString:@"{longitude}" withString:[NSString stringWithFormat:@"%f",longitude]] | |
stringByReplacingOccurrencesOfString:@"{latitude}" withString:[NSString stringWithFormat:@"%f",latitude]] | |
stringByReplacingOccurrencesOfString:@"{distance}" withString:kDistanceToSearch] | |
stringByReplacingOccurrencesOfString:@"{maxResults}" withString:kNumberOfResults]; | |
NSURL *url = [NSURL URLWithString:sUrl]; | |
NSURLRequest *request = [NSURLRequest requestWithURL:url]; | |
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request]; | |
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) { | |
NSString *response = [[[operation responseString] stringByReplacingOccurrencesOfString:@"jsonMethod(" withString:@""] | |
stringByReplacingOccurrencesOfString:@");" withString:@""]; | |
NSData *data = [response dataUsingEncoding:NSUTF8StringEncoding]; | |
NSArray *jsonArray = [NSJSONSerialization JSONObjectWithData:data options: NSJSONReadingMutableContainers error:nil]; | |
if (_stores) { | |
_stores = nil; | |
} | |
_stores = [[NSMutableArray alloc] initWithCapacity:0]; | |
if (!jsonArray) { | |
if (block) { | |
block(nil,[NSError errorWithDomain:@"com.redant" code:0 userInfo:nil]); | |
} | |
NSLog(@"Error parsing JSON"); | |
} else if ([jsonArray valueForKey:@"error"]) { | |
if (block) { | |
block(nil,[NSError errorWithDomain:@"com.redant" code:0 userInfo:nil]); | |
} | |
} else { | |
for(NSDictionary *item in [[jsonArray valueForKey:@"stores"] valueForKey:@"store"]) { | |
[_stores addObject:[self configureShopWithDictionary:item]]; | |
} | |
block(_stores,nil); | |
} | |
} failure:^(AFHTTPRequestOperation *operation, NSError *error) { | |
block(nil,error); | |
NSLog(@"%@", [error userInfo]); | |
}]; | |
[operation start]; | |
} | |
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error { | |
NSLog(@"%@",[error localizedDescription]); | |
} | |
- (void) getGeocodeWithLocationString:(NSString*)locationString usingBlock:(NSArrayNSErrorBlock)block { | |
NSString *sUrl = [NSString stringWithFormat:@"http://maps.googleapis.com/maps/api/geocode/json?address=%@®ion=%@&sensor=true", | |
locationString, | |
[ARConfigServices valueForKey:@"Google Map Region"]]; | |
NSURL *url = [NSURL URLWithString:sUrl]; | |
NSURLRequest *request = [NSURLRequest requestWithURL:url]; | |
AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) { | |
if ([JSON isKindOfClass:[NSDictionary class]]) { | |
NSDictionary *responseDict = JSON; | |
NSArray *resultsArray = [responseDict valueForKey:@"results"]; | |
NSMutableArray *placemarksArray = [NSMutableArray arrayWithCapacity:[resultsArray count]]; | |
if(responseDict == nil || resultsArray == nil || [resultsArray count] == 0) { | |
block(nil,[NSError errorWithDomain:@"com.redant" code:0 userInfo:nil]); | |
return; | |
} | |
for(NSDictionary *placemarkDict in resultsArray) { | |
NSDictionary *addressDict = [placemarkDict valueForKey:@"address_components"]; | |
NSDictionary *coordinateDict = [[placemarkDict valueForKey:@"geometry"] valueForKey:@"location"]; | |
float lat = [[coordinateDict valueForKey:@"lat"] floatValue]; | |
float lng = [[coordinateDict valueForKey:@"lng"] floatValue]; | |
NSMutableDictionary *formattedAddressDict = [[NSMutableDictionary alloc] init]; | |
for(NSDictionary *component in addressDict) { | |
NSArray *types = [component valueForKey:@"types"]; | |
if([types containsObject:@"street_number"]) | |
[formattedAddressDict setValue:[component valueForKey:@"long_name"] forKey:(NSString*)kABPersonAddressStreetKey]; | |
if([types containsObject:@"route"]) | |
[formattedAddressDict setValue:[[formattedAddressDict valueForKey:(NSString*)kABPersonAddressStreetKey] stringByAppendingFormat:@" %@",[component valueForKey:@"long_name"]] forKey:(NSString*)kABPersonAddressStreetKey]; | |
if([types containsObject:@"locality"]) | |
[formattedAddressDict setValue:[component valueForKey:@"long_name"] forKey:(NSString*)kABPersonAddressCityKey]; | |
if([types containsObject:@"administrative_area_level_1"]) | |
[formattedAddressDict setValue:[component valueForKey:@"long_name"] forKey:(NSString*)kABPersonAddressStateKey]; | |
if([types containsObject:@"postal_code"]) | |
[formattedAddressDict setValue:[component valueForKey:@"long_name"] forKey:(NSString*)kABPersonAddressZIPKey]; | |
if([types containsObject:@"country"]) { | |
[formattedAddressDict setValue:[component valueForKey:@"long_name"] forKey:(NSString*)kABPersonAddressCountryKey]; | |
[formattedAddressDict setValue:[component valueForKey:@"short_name"] forKey:(NSString*)kABPersonAddressCountryCodeKey]; | |
} | |
} | |
SVPlacemark *placemark = [[SVPlacemark alloc] initWithCoordinate:CLLocationCoordinate2DMake(lat, lng) addressDictionary:formattedAddressDict]; | |
placemark.formattedAddress = [placemarkDict objectForKey:@"formatted_address"]; | |
[placemarksArray addObject:placemark]; | |
} | |
block(placemarksArray,nil); | |
} else { | |
block(nil,[NSError errorWithDomain:@"com.redant" code:0 userInfo:nil]); | |
} | |
} failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id JSON) { | |
block(nil,error); | |
NSLog(@"%@", [error userInfo]); | |
}]; | |
[operation start]; | |
} | |
- (ARShopObject *) configureShopWithDictionary:(NSDictionary*)result | |
{ | |
ARShopObject *obj = [[ARShopObject alloc] init]; | |
obj.storeId = NSNullToNil([result objectForKey:@"storeId"]); | |
obj.name = NSNullToNil([result objectForKey:@"storeName"]); | |
obj.postcode = NSNullToNil([result objectForKey:@"postcode"]); | |
obj.country = NSNullToNil([result objectForKey:@"country"]); | |
obj.telephone = NSNullToNil([result objectForKey:@"telephoneNumber"]); | |
obj.latitude = [NSNullToNil([result objectForKey:@"latitude"]) floatValue]; | |
obj.longitude = [NSNullToNil([result objectForKey:@"longitude"]) floatValue]; | |
obj.distanceFromSearch = [NSNullToNil([result objectForKey:@"distance"]) doubleValue]; | |
obj.stockValue = [NSNullToNil([result objectForKey:@"stock"]) intValue]; | |
obj.stockText = NSNullToNil([result objectForKey:@"stockSymbol"]); | |
//obj.userLocation = CLLocationCoordinate2DMake(search.latitude, search.longitude); | |
obj.facebookId = NSNullToNil([result objectForKey:@"facebookId"]); | |
NSString * value = nil; | |
if ((value = NSNullToNil([result objectForKey:@"address1"]))) | |
{ | |
[obj.addressLines addObject:value]; | |
} | |
if ((value = NSNullToNil([result objectForKey:@"address2"]))) | |
{ | |
[obj.addressLines addObject:value]; | |
} | |
if ((value = NSNullToNil([result objectForKey:@"address3"]))) | |
{ | |
[obj.addressLines addObject:value]; | |
} | |
if ((value = NSNullToNil([result objectForKey:@"address4"]))) | |
{ | |
[obj.addressLines addObject:value]; | |
} | |
obj.openTimesMon = NSNullToNil([result objectForKey:@"openingMon"]); | |
obj.openTimesTue = NSNullToNil([result objectForKey:@"openingTue"]); | |
obj.openTimesWed = NSNullToNil([result objectForKey:@"openingWed"]); | |
obj.openTimesThu = NSNullToNil([result objectForKey:@"openingThu"]); | |
obj.openTimesFri = NSNullToNil([result objectForKey:@"openingFri"]); | |
obj.openTimesSat = NSNullToNil([result objectForKey:@"openingSat"]); | |
obj.openTimesSun = NSNullToNil([result objectForKey:@"openingSun"]); | |
return obj; | |
} | |
@end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// ARSplitViewController.h | |
// Topshop | |
// | |
// Created by Stephen Keep on 03/06/2013. | |
// Copyright (c) 2013 Red Ant Ltd. All rights reserved. | |
// | |
#import <UIKit/UIKit.h> | |
#import "ARNavigationController.h" | |
#import "ARViewController.h" | |
@interface ARSplitViewController : UIViewController | |
@property (nonatomic) BOOL hideNavigationBar; | |
@property (nonatomic, strong) ARNavigationController *leftPanel; | |
@property (nonatomic, strong) ARNavigationController *rightPanel; | |
- (id) initWithLeftViewController:(ARViewController *)left andRightViewController:(ARViewController *)right; | |
- (void) popViewControllerOnRightViewControllerAnimated:(BOOL)animated; | |
- (void) pushViewControllerOnRightViewController:(UIViewController *)vc animated:(BOOL)animated; | |
- (void) toggleLeftPanel; | |
@end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// ARSplitViewController.m | |
// Topshop | |
// | |
// Created by Stephen Keep on 03/06/2013. | |
// Copyright (c) 2013 Red Ant Ltd. All rights reserved. | |
// | |
#import "ARSplitViewController.h" | |
#import <QuartzCore/QuartzCore.h> | |
#define kLeftPanelWidth 320.0f | |
@interface ARSplitViewController () { | |
CGRect _leftPanelRestingFrame; | |
CGRect _rightPanelRestingFrame; | |
CGRect _leftPanelActiveFrame; | |
CGRect _rightPanelActiveFrame; | |
} | |
@property (nonatomic, strong) UIView *leftPanelContainer; | |
@property (nonatomic, strong) UIView *rightPanelContainer; | |
@property (nonatomic, strong) ARViewController *leftViewController; | |
@property (nonatomic, strong) ARViewController *rightViewController; | |
@end | |
@implementation ARSplitViewController | |
-(id)initWithLeftViewController:(ARViewController *)left andRightViewController:(ARViewController *)right { | |
self = [super init]; | |
if (self) { | |
self.leftViewController = left; | |
self.rightViewController = right; | |
} | |
return self; | |
} | |
- (void)viewDidLoad { | |
[super viewDidLoad]; | |
self.view.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth; | |
self.leftPanelContainer = [[UIView alloc] initWithFrame:CGRectMake(0,0,kLeftPanelWidth,self.view.bounds.size.height)]; | |
self.rightPanelContainer = [[UIView alloc] initWithFrame:CGRectMake(kLeftPanelWidth,0,self.view.bounds.size.width-kLeftPanelWidth,self.view.bounds.size.height)]; | |
[self.view addSubview:self.leftPanelContainer]; | |
[self.view addSubview:self.rightPanelContainer]; | |
[self.view bringSubviewToFront:self.leftPanelContainer]; | |
} | |
- (BOOL)shouldAutorotate { | |
return YES; | |
} | |
- (void)viewWillAppear:(BOOL)animated { | |
[super viewWillAppear:animated]; | |
if (!self.rightPanel && !self.leftPanel) { | |
self.navigationController.navigationBarHidden = _hideNavigationBar; | |
self.rightPanel = [[ARNavigationController alloc] initWithRootViewController:_rightViewController]; | |
[self _loadRightPanel]; | |
self.leftPanel = [[ARNavigationController alloc] initWithRootViewController:_leftViewController]; | |
[self _loadLeftPanel]; | |
if (_hideNavigationBar) { | |
_leftPanelRestingFrame = CGRectMake(-kLeftPanelWidth,0,kLeftPanelWidth,self.view.bounds.size.height+44); | |
_rightPanelRestingFrame = CGRectMake(0,0,self.view.bounds.size.width,self.view.bounds.size.height+44); | |
} else { | |
_rightPanelRestingFrame = CGRectMake(0,0,self.view.bounds.size.width,self.view.bounds.size.height); | |
_leftPanelRestingFrame = CGRectMake(-kLeftPanelWidth,0,kLeftPanelWidth,self.view.bounds.size.height); | |
} | |
[self _configureContainers]; | |
UIView *divider = [[UIView alloc] initWithFrame:CGRectMake(kLeftPanelWidth-1, 0, 1, self.view.bounds.size.height)]; | |
if (_hideNavigationBar) { | |
CGRectSetY(divider.frame, 44); | |
} | |
divider.backgroundColor = [UIColor colorWithWhite:0.9 alpha:1.0]; | |
[self.leftPanelContainer addSubview:divider]; | |
} | |
} | |
- (void)viewDidAppear:(BOOL)animated{ | |
[super viewDidAppear:animated]; | |
} | |
#pragma mark - Style | |
- (void)_configureContainers { | |
if (_hideNavigationBar) { | |
_leftPanelActiveFrame = CGRectMake(0,0,kLeftPanelWidth,self.view.bounds.size.height+44); | |
_rightPanelActiveFrame = CGRectMake(kLeftPanelWidth,0,self.view.bounds.size.width-kLeftPanelWidth,self.view.bounds.size.height+44); | |
} else { | |
_leftPanelActiveFrame = CGRectMake(0,0,kLeftPanelWidth,self.view.bounds.size.height); | |
_rightPanelActiveFrame = CGRectMake(kLeftPanelWidth,0,self.view.bounds.size.width-kLeftPanelWidth,self.view.bounds.size.height); | |
} | |
self.leftPanelContainer.frame = CGRectMake(0,0,kLeftPanelWidth,self.view.bounds.size.height); | |
self.leftPanelContainer.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleHeight; | |
_leftPanel.view.frame = self.leftPanelContainer.frame; | |
_leftPanel.view.autoresizingMask = self.view.autoresizingMask; | |
self.rightPanelContainer.frame = CGRectMake(kLeftPanelWidth,0,self.view.bounds.size.width-kLeftPanelWidth,self.view.bounds.size.height);; | |
self.rightPanelContainer.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; | |
_rightPanel.view.frame = CGRectMake(0,0,self.view.bounds.size.width-kLeftPanelWidth,self.view.bounds.size.height); | |
_rightPanel.view.autoresizingMask = self.view.autoresizingMask; | |
} | |
#pragma mark - Panels | |
- (void)setLeftPanel:(ARNavigationController *)panel { | |
_leftPanel = panel; | |
[self addChildViewController:_leftPanel]; | |
[_leftPanelContainer addSubview:_leftPanel.view]; | |
[_leftPanel didMoveToParentViewController:self]; | |
} | |
- (void)setRightPanel:(ARNavigationController *)panel { | |
_rightPanel = panel; | |
[self addChildViewController:_rightPanel]; | |
[_rightPanelContainer addSubview:_rightPanel.view]; | |
[_rightPanel didMoveToParentViewController:self]; | |
} | |
-(void)popViewControllerOnRightViewControllerAnimated:(BOOL)animated { | |
[_rightViewController.navigationController popViewControllerAnimated:animated]; | |
} | |
-(void)pushViewControllerOnRightViewController:(UIViewController *)vc animated:(BOOL)animated { | |
[_rightViewController.navigationController pushViewController:vc animated:animated]; | |
} | |
#pragma mark - Loading Panels | |
- (void)_loadLeftPanel { | |
_leftPanel.view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; | |
[self.leftPanelContainer addSubview:_leftPanel.view]; | |
} | |
- (void)_loadRightPanel { | |
_rightPanel.view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; | |
[self.rightPanelContainer addSubview:_rightPanel.view]; | |
} | |
- (void)_unloadPanels { | |
if (self.leftPanel.isViewLoaded) { | |
[self.leftPanel.view removeFromSuperview]; | |
} | |
if (self.rightPanel.isViewLoaded) { | |
[self.rightPanel.view removeFromSuperview]; | |
} | |
} | |
#pragma mark - Showing Panels | |
- (void)toggleLeftPanel { | |
if (CGRectEqualToRect(self.leftPanelContainer.frame,_leftPanelRestingFrame)) { | |
ARViewController *vc = [((UINavigationController*)self.rightViewController.parentViewController).viewControllers lastObject]; | |
if ([vc respondsToSelector:@selector(showSideBar)]) { | |
[vc performSelector:@selector(showSideBar)]; | |
} | |
} else { | |
ARViewController *vc = [((UINavigationController*)self.rightViewController.parentViewController).viewControllers lastObject]; | |
if ([vc respondsToSelector:@selector(hideSideBar)]) { | |
[vc performSelector:@selector(hideSideBar)]; | |
} | |
} | |
[UIView animateWithDuration:0.3f delay:0.0f options:UIViewAnimationOptionCurveLinear|UIViewAnimationOptionLayoutSubviews animations:^{ | |
if (CGRectEqualToRect(self.leftPanelContainer.frame,_leftPanelRestingFrame)) { | |
self.leftPanelContainer.frame = _leftPanelActiveFrame; | |
self.rightPanelContainer.frame = _rightPanelActiveFrame; | |
} else { | |
self.leftPanelContainer.frame = _leftPanelRestingFrame; | |
self.rightPanelContainer.frame = _rightPanelRestingFrame; | |
} | |
} completion:^(BOOL finished) { | |
}]; | |
} | |
@end | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// AudioManager.h | |
// lovethat | |
// | |
// Created by Stephen Keep on 07/01/2013. | |
// | |
// | |
#import <Foundation/Foundation.h> | |
#import "SynthesizeSingleton.h" | |
#import <CoreAudio/CoreAudioTypes.h> | |
#import <AVFoundation/AVFoundation.h> | |
@interface AudioManager : NSObject { | |
AVPlayer* audioPlayer; | |
NSString *artist; | |
NSString *track; | |
NSString *purchaseURL; | |
NSString *uuid; | |
} | |
@property (nonatomic,retain) AVPlayer* audioPlayer; | |
@property (nonatomic,retain) NSString *artist; | |
@property (nonatomic,retain) NSString *track; | |
@property (nonatomic,retain) NSString *purchaseURL; | |
@property (nonatomic,retain) NSString *uuid; | |
+ (AudioManager *)sharedAudioManager; | |
- (void)playFile:(NSString *)url; | |
- (void)stop; | |
- (void)download; | |
@end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// AudioManager.m | |
// lovethat | |
// | |
// Created by Stephen Keep on 07/01/2013. | |
// | |
// | |
#import "AudioManager.h" | |
@interface AudioManager () { | |
NSURL *iTunesURL; | |
} | |
@property (nonatomic, retain) NSURL *iTunesURL; | |
@end | |
@implementation AudioManager | |
SYNTHESIZE_SINGLETON_FOR_CLASS(AudioManager); | |
@synthesize audioPlayer,artist,track,purchaseURL,uuid,iTunesURL; | |
- (id)init { | |
self = [super init]; | |
if(self) { | |
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(stop) name:AVPlayerItemDidPlayToEndTimeNotification object:nil]; | |
} | |
return self; | |
} | |
-(void) stop { | |
if (audioPlayer) { | |
[audioPlayer removeObserver:self forKeyPath:@"status"]; | |
[audioPlayer pause]; | |
[audioPlayer release]; | |
audioPlayer = nil; | |
[artist release]; | |
artist = nil; | |
[track release]; | |
track = nil; | |
[purchaseURL release]; | |
purchaseURL = nil; | |
[uuid release]; | |
uuid = nil; | |
[[NSNotificationCenter defaultCenter] postNotificationName:@"stoppedPlaying" object:nil]; | |
[[NSUserDefaults standardUserDefaults] setBool:NO forKey:@"playingAudio"]; | |
[[NSUserDefaults standardUserDefaults] synchronize]; | |
} | |
} | |
-(void)play { | |
[audioPlayer play]; | |
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"playingAudio"]; | |
[[NSNotificationCenter defaultCenter] postNotificationName:@"startedPlaying" object:nil]; | |
[[NSUserDefaults standardUserDefaults] synchronize]; | |
} | |
- (void)playFile:(NSString *)url | |
{ | |
DLog(@"%@ url",url); | |
if (audioPlayer) { | |
AVPlayerItem *playerItem = [AVPlayerItem playerItemWithURL:[NSURL URLWithString:url]]; | |
[audioPlayer replaceCurrentItemWithPlayerItem:playerItem]; | |
[[NSNotificationCenter defaultCenter] postNotificationName:@"changedTrack" object:nil]; | |
} else { | |
audioPlayer = [[AVPlayer alloc] initWithURL:[NSURL URLWithString:url]]; | |
[audioPlayer addObserver:self forKeyPath:@"status" options:0 context:NULL]; | |
} | |
} | |
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { | |
if ([keyPath isEqualToString:@"status"]) { | |
if (audioPlayer.status == AVPlayerStatusReadyToPlay) { | |
[self play]; | |
} else if (audioPlayer.status == AVPlayerStatusFailed) { | |
/* An error was encountered */ | |
} | |
} | |
} | |
-(void)download { | |
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; | |
NSLocale *locale = [NSLocale currentLocale]; | |
NSString *url = [NSString stringWithFormat:@"http://itunes.loveth.at/?url=%@&id=%@&did=%@&country=%@",[purchaseURL stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding],uuid,[defaults objectForKey:@UDDeviceUuid],[[locale objectForKey:NSLocaleCountryCode] lowercaseString]]; | |
DLog(@"url: %@",url); | |
[self openReferralURL:[NSURL URLWithString:url]]; | |
} | |
// Process a LinkShare/TradeDoubler/DGM URL to something iPhone can handle | |
- (void)openReferralURL:(NSURL *)referralURL { | |
NSURLConnection *conn = [[NSURLConnection alloc] initWithRequest:[NSURLRequest requestWithURL:referralURL] delegate:self startImmediately:YES]; | |
[conn release]; | |
} | |
// Save the most recent URL in case multiple redirects occur | |
// "iTunesURL" is an NSURL property in your class declaration | |
- (NSURLRequest *)connection:(NSURLConnection *)connection willSendRequest:(NSURLRequest *)request redirectResponse:(NSURLResponse *)response { | |
self.iTunesURL = [response URL]; | |
//NSLog(@"url: %@", [self.iTunesURL absoluteString]); | |
return request; | |
} | |
// No more redirects; use the last URL saved | |
- (void)connectionDidFinishLoading:(NSURLConnection *)connection { | |
if (self.iTunesURL) { | |
[[UIApplication sharedApplication] openURL:self.iTunesURL]; | |
self.iTunesURL = nil; | |
} | |
} | |
@end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// CoreDataHelper.h | |
// lovethat | |
// | |
// Created by Stephen Keep on 14/11/2012. | |
// | |
// | |
#import "MarkupParser.h" | |
@interface NSObject (CoreDataHelper) | |
-(void)updateCommentStringForObject:(NSManagedObject *)object; | |
-(NSManagedObject *)insertOrGetEntity:(NSString *)name withValues:(NSDictionary *)values usingId:(NSString *)uniqueID withPredicate:(NSPredicate *)predicate inContext:(NSManagedObjectContext *)newContext; | |
-(void)saveContext:(NSManagedObjectContext *)context; | |
-(NSManagedObject *)getActionForId:(NSNumber *)actionId inContext:(NSManagedObjectContext *)context; | |
-(void)insertActions:(NSArray *)actions inContext:(NSManagedObjectContext *)context usingScope:(NSString *)scope; | |
-(void)deleteActionsInContext:(NSManagedObjectContext *)context; | |
-(void)deletePeopleInContext:(NSManagedObjectContext *)context; | |
-(void)deleteHashtagsInContext:(NSManagedObjectContext *)context; | |
-(void)deleteCommentsForAction:(NSManagedObject *)object inContext:(NSManagedObjectContext *)context; | |
-(NSManagedObject *)insertEntity:(NSString *)name withValues:(NSDictionary *)values inContext:(NSManagedObjectContext *)context; | |
@end | |
@implementation NSObject (CoreDataHelper) | |
-(void)saveContext:(NSManagedObjectContext *)context { | |
NSError *error; | |
if (![context save:&error]) { | |
NSLog(@"Whoops, couldn't save: %@", error); | |
} | |
} | |
-(void)updateCommentStringForObject:(NSManagedObject *)object { | |
NSMutableString *commentsString = [[NSMutableString alloc] initWithCapacity:1]; | |
NSArray *plusOnes = [[NSArray alloc] initWithArray:(NSArray *)[[object valueForKey:@"plusOnes"] allObjects]]; | |
if (plusOnes.count > 0) { | |
[commentsString appendFormat:@"<font color=\"lightGray\" strokeColor=\"none\" face=\"PTSans-Bold\">+1 "]; | |
} | |
for (NSDictionary *plusOne in plusOnes) { | |
DLog(@"%@",[plusOne valueForKey:@"lastName"]); | |
NSString *lastName; | |
if ((NSNull *)[plusOne valueForKey:@"lastName"] != [NSNull null] && ![[plusOne valueForKey:@"lastName"] isEqualToString:@"(null)"]) { | |
lastName = [plusOne valueForKey:@"lastName"]; | |
} else lastName = @""; | |
[commentsString appendFormat:@"<font color=\"aqua\" strokeColor=\"none\" face=\"PTSans-Bold\">%@ %@<person id=\"%@\" friendly=\"%@ %@\">",[plusOne valueForKey:@"firstName"],[plusOne valueForKey:@"lastName"],[plusOne valueForKey:@"userId"],[plusOne valueForKey:@"firstName"],[plusOne valueForKey:@"lastName"]]; | |
if (plusOne != [plusOnes lastObject]) [commentsString appendFormat:@", "]; | |
} | |
if (plusOnes.count > 0) { | |
[commentsString appendFormat:@"\n"]; | |
} | |
[plusOnes release]; | |
NSSortDescriptor *sortDescriptor = [[[NSSortDescriptor alloc] initWithKey:@"dateCreated" ascending:NO] autorelease]; | |
NSArray *sortDescriptors = [NSArray arrayWithObject:sortDescriptor]; | |
NSArray *comments = [[NSArray alloc] initWithArray:[[[object valueForKey:@"comments"] allObjects] sortedArrayUsingDescriptors:sortDescriptors]]; | |
for (NSDictionary *comment in comments) { | |
//DETECT URLS | |
NSString *formattedComment = [comment valueForKey:@"comment"]; | |
NSDataDetector *linkDetector = [NSDataDetector dataDetectorWithTypes:NSTextCheckingTypeLink error:nil]; | |
NSArray *matches = [linkDetector matchesInString:[comment valueForKey:@"comment"] options:0 range:NSMakeRange(0, [[comment valueForKey:@"comment"] length])]; | |
for (NSTextCheckingResult *match in matches) { | |
if ([match resultType] == NSTextCheckingTypeLink) { | |
NSURL *url = [match URL]; | |
NSString *originalURL = [[comment valueForKey:@"comment"] substringWithRange:match.range]; | |
NSString *addURL = [[NSString alloc] initWithFormat:@"<font color=\"aqua\" strokeColor=\"none\" face=\"PTSans-Bold\">%@<url link=\"%@\" friendly=\"%@\"><font color=\"lightGray\" strokeColor=\"none\" face=\"PTSans-Regular\">",originalURL,url,originalURL]; | |
formattedComment = [formattedComment stringByReplacingOccurrencesOfString:originalURL withString:addURL]; | |
[addURL release]; | |
} | |
} | |
NSString *lastName; | |
if ((NSNull *)[comment valueForKey:@"lastName"] != [NSNull null] && ![[comment valueForKey:@"lastName"] isEqualToString:@"(null)"]) { | |
lastName = [comment valueForKey:@"lastName"]; | |
} else lastName = @""; | |
[commentsString appendFormat:@"<font color=\"aqua\" strokeColor=\"none\" face=\"PTSans-Bold\">%@ %@ <person id=\"%@\" friendly=\"%@ %@\"><font color=\"lightGray\" strokeColor=\"none\" face=\"PTSans-Regular\">- %@ \n",[comment valueForKey:@"firstName"],[comment valueForKey:@"lastName"],[comment valueForKey:@"userId"],[comment valueForKey:@"firstName"],[comment valueForKey:@"lastName"],[formattedComment stringByReplacingOccurrencesOfString:@"\n" withString:@""]]; | |
} | |
[comments release]; | |
[object setValue:commentsString forKey:@"comment"]; | |
[commentsString release]; | |
} | |
-(void)insertActions:(NSArray *)actions inContext:(NSManagedObjectContext *)context usingScope:(NSString *)scope { | |
NSDateFormatter *formatter = [[NSDateFormatter alloc] init]; | |
[formatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"]; | |
for (NSDictionary *action in actions) { | |
NSString *predicateString = [NSString stringWithFormat:@"actionId_scope == $ENTITY_ID"]; | |
NSPredicate *predicate = [NSPredicate predicateWithFormat:predicateString]; | |
NSMutableDictionary *actionDict = [[NSMutableDictionary alloc] initWithDictionary:action]; | |
[actionDict setValue:[NSString stringWithFormat:@"%@_%@",[action valueForKey:@"actionId"],scope] forKey:@"actionId_scope"]; | |
NSManagedObject *object = [self insertOrGetEntity:@"Action" withValues:actionDict usingId:@"actionId_scope" withPredicate:predicate inContext:context]; | |
[actionDict release]; | |
[object setValue:scope forKey:@"scope"]; | |
NSDate *date = [formatter dateFromString:[action valueForKey:@"timestamp"]]; | |
[object setValue:date forKey:@"dateCreated"]; | |
NSString *dateFormatted = [NSString stringWithFormat:@"%@",[[object valueForKey:@"dateCreated"] humanIntervalSinceNow]]; | |
[object setValue:dateFormatted forKey:@"dateFormatted"]; | |
if ([[object valueForKey:@"kind"] isEqualToString:@"ebook"]) { | |
[object setValue:@"book" forKey:@"kind"]; | |
} else if ([[object valueForKey:@"kind"] isEqualToString:@"feature-movie"]) { | |
[object setValue:@"movie" forKey:@"kind"]; | |
} else if ([[object valueForKey:@"kind"] isEqualToString:@"software"]) { | |
[object setValue:@"app" forKey:@"kind"]; | |
} | |
NSMutableString *commentsString = [[NSMutableString alloc] initWithCapacity:1]; | |
NSArray *plusOnes = [[NSArray alloc] initWithArray:(NSArray *)[action valueForKey:@"plusOnes"]]; | |
if (plusOnes.count > 0) { | |
[commentsString appendFormat:@"<font color=\"lightGray\" strokeColor=\"none\" face=\"PTSans-Bold\">+1 "]; | |
} | |
for (NSDictionary *plusOne in plusOnes) { | |
NSManagedObject *plusOneObj = [self insertEntity:@"PlusOne" withValues:plusOne inContext:context]; | |
[plusOneObj setValue:object forKey:@"action"]; | |
[commentsString appendFormat:@"<font color=\"aqua\" strokeColor=\"none\" face=\"PTSans-Bold\">%@ %@<person id=\"%@\" friendly=\"%@ %@\">",[plusOne valueForKey:@"firstName"],[plusOne valueForKey:@"lastName"],[plusOne valueForKey:@"userId"],[plusOne valueForKey:@"firstName"],[plusOne valueForKey:@"lastName"]]; | |
if (plusOne != [plusOnes lastObject]) [commentsString appendFormat:@", "]; | |
} | |
if (plusOnes.count > 0) { | |
[commentsString appendFormat:@"\n"]; | |
} | |
[plusOnes release]; | |
NSArray *comments = [[NSArray alloc] initWithArray:(NSArray *)[action valueForKey:@"comments"]]; | |
[self deleteCommentsForAction:object inContext:context]; | |
for (NSDictionary *comment in comments) { | |
NSManagedObject *commentObj = [self insertEntity:@"Comment" withValues:comment inContext:context]; | |
[commentObj setValue:object forKey:@"action"]; | |
NSDate *date = [formatter dateFromString:[comment valueForKey:@"timestamp"]]; | |
[commentObj setValue:date forKey:@"dateCreated"]; | |
//DETECT URLS | |
NSString *formattedComment = [comment valueForKey:@"comment"]; | |
NSDataDetector *linkDetector = [NSDataDetector dataDetectorWithTypes:NSTextCheckingTypeLink error:nil]; | |
NSArray *matches = [linkDetector matchesInString:[comment valueForKey:@"comment"] options:0 range:NSMakeRange(0, [[comment valueForKey:@"comment"] length])]; | |
for (NSTextCheckingResult *match in matches) { | |
if ([match resultType] == NSTextCheckingTypeLink) { | |
NSURL *url = [match URL]; | |
NSString *originalURL = [[comment valueForKey:@"comment"] substringWithRange:match.range]; | |
NSString *addURL = [[NSString alloc] initWithFormat:@"<font color=\"aqua\" strokeColor=\"none\" face=\"PTSans-Bold\">%@<url link=\"%@\" friendly=\"%@\"><font color=\"lightGray\" strokeColor=\"none\" face=\"PTSans-Regular\">",originalURL,url,originalURL]; | |
formattedComment = [formattedComment stringByReplacingOccurrencesOfString:originalURL withString:addURL]; | |
[addURL release]; | |
} | |
} | |
[commentsString appendFormat:@"<font color=\"aqua\" strokeColor=\"none\" face=\"PTSans-Bold\">%@ %@ <person id=\"%@\" friendly=\"%@ %@\"><font color=\"lightGray\" strokeColor=\"none\" face=\"PTSans-Regular\">- %@ \n",[comment valueForKey:@"firstName"],[comment valueForKey:@"lastName"],[comment valueForKey:@"userId"],[comment valueForKey:@"firstName"],[comment valueForKey:@"lastName"],[formattedComment stringByReplacingOccurrencesOfString:@"\n" withString:@""]]; | |
} | |
[comments release]; | |
[object setValue:[NSString stringWithFormat:@"%@",commentsString] forKey:@"comment"]; | |
[commentsString release]; | |
} | |
[formatter release]; | |
} | |
-(void)deletePeopleInContext:(NSManagedObjectContext *)context { | |
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; | |
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Person" inManagedObjectContext:context]; | |
[fetchRequest setEntity:entity]; | |
[fetchRequest setIncludesPropertyValues:NO]; | |
NSArray *fetchedObjects = [context executeFetchRequest:fetchRequest error:nil]; | |
[fetchRequest release]; | |
for (NSManagedObject *object in fetchedObjects) { | |
[context deleteObject:object]; | |
} | |
} | |
-(void)deleteActionsInContext:(NSManagedObjectContext *)context { | |
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; | |
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Action" inManagedObjectContext:context]; | |
[fetchRequest setEntity:entity]; | |
[fetchRequest setIncludesPropertyValues:NO]; | |
NSArray *fetchedObjects = [context executeFetchRequest:fetchRequest error:nil]; | |
[fetchRequest release]; | |
for (NSManagedObject *object in fetchedObjects) { | |
[context deleteObject:object]; | |
} | |
} | |
-(void)deleteHashtagsInContext:(NSManagedObjectContext *)context { | |
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; | |
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Hashtag" inManagedObjectContext:context]; | |
[fetchRequest setEntity:entity]; | |
[fetchRequest setIncludesPropertyValues:NO]; | |
NSArray *fetchedObjects = [context executeFetchRequest:fetchRequest error:nil]; | |
[fetchRequest release]; | |
for (NSManagedObject *object in fetchedObjects) { | |
[context deleteObject:object]; | |
} | |
} | |
-(void)deleteCommentsForAction:(NSManagedObject *)object inContext:(NSManagedObjectContext *)context { | |
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; | |
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Comment" inManagedObjectContext:context]; | |
[fetchRequest setEntity:entity]; | |
[fetchRequest setIncludesPropertyValues:NO]; | |
//DLog(@"%@",[object valueForKey:@"actionId"]); | |
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"action.actionId == %@",[object valueForKey:@"actionId"]]; | |
fetchRequest.predicate = predicate; | |
NSError *error; | |
NSArray *fetchedObjects = [context executeFetchRequest:fetchRequest error:&error]; | |
if (fetchedObjects == nil) { | |
DLog(@"%@",[error localizedDescription]); | |
} | |
[fetchRequest release]; | |
for (NSManagedObject *object in fetchedObjects) { | |
[context deleteObject:object]; | |
} | |
} | |
-(NSManagedObject *)getActionForId:(NSNumber *)actionId inContext:(NSManagedObjectContext *)context { | |
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; | |
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Action" inManagedObjectContext:context]; | |
[fetchRequest setEntity:entity]; | |
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"actionId == %@",actionId]; | |
fetchRequest.predicate = predicate; | |
NSError *error; | |
NSArray *fetchedObjects = [context executeFetchRequest:fetchRequest error:&error]; | |
if (fetchedObjects == nil) { | |
DLog(@"%@",[error localizedDescription]); | |
} | |
[fetchRequest release]; | |
return [fetchedObjects lastObject]; | |
} | |
#pragma mark - boilerplate core data methods | |
-(NSManagedObject *)insertOrGetEntity:(NSString *)name withValues:(NSDictionary *)values usingId:(NSString *)uniqueID withPredicate:(NSPredicate *)predicate inContext:(NSManagedObjectContext *)newContext { | |
//DLog(@"get: %@", name); | |
if ([self doesEntityExist:name withValue:[values valueForKey:uniqueID] withPredicate:predicate inContext:newContext]) { | |
//DLog(@"get id: %@",[values valueForKey:@"actionId"]); | |
return [self updateID:[values valueForKey:uniqueID] withName:name usingValues:values withPredicate:predicate inContext:newContext]; | |
} else { | |
//DLog(@"insert"); | |
return [self insertEntity:name withValues:values inContext:newContext]; | |
} | |
} | |
-(BOOL)doesEntityExist:(NSString *)name withValue:(NSString *)value withPredicate:(NSPredicate *)predicate inContext:(NSManagedObjectContext *)newContext { | |
NSEntityDescription *entity = [NSEntityDescription entityForName:name inManagedObjectContext:newContext]; | |
NSFetchRequest *request = [[NSFetchRequest alloc] init]; | |
[request setEntity:entity]; | |
NSDictionary *variables = [[NSDictionary alloc] initWithObjectsAndKeys:value, @"ENTITY_ID", nil]; | |
NSPredicate *localPredicate = [predicate predicateWithSubstitutionVariables:variables]; | |
[variables release]; | |
[request setPredicate:localPredicate]; | |
NSError *error = nil; | |
NSUInteger count = [newContext countForFetchRequest:request error:&error]; | |
[request release]; | |
if (!error){ | |
return count; | |
} | |
else | |
return NO; | |
} | |
-(NSManagedObject *)updateID:(NSString *)id withName:(NSString *)name usingValues:(NSDictionary *)values withPredicate:(NSPredicate *)predicate inContext:(NSManagedObjectContext *)newContext { | |
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; | |
NSEntityDescription *entity = [NSEntityDescription entityForName:name inManagedObjectContext:newContext]; | |
[fetchRequest setEntity:entity]; | |
NSDictionary *variables = [[NSDictionary alloc] initWithObjectsAndKeys:id, @"ENTITY_ID", nil]; | |
NSPredicate *localPredicate = [predicate predicateWithSubstitutionVariables:variables]; | |
[variables release]; | |
[fetchRequest setPredicate:localPredicate]; | |
NSArray *fetchedObjects = [newContext executeFetchRequest:fetchRequest error:nil]; | |
[fetchRequest release]; | |
NSEntityDescription *entityDescription = [NSEntityDescription entityForName:name inManagedObjectContext:newContext]; | |
if (fetchedObjects.count > 0) { | |
NSManagedObject *newEntity = [fetchedObjects lastObject]; | |
for (NSAttributeDescription *attribute in [entityDescription properties]) { | |
if ((NSNull *)[values valueForKey:attribute.name] != [NSNull null]) { | |
if([attribute isKindOfClass:[NSAttributeDescription class]]) { | |
if ([values objectForKey:attribute.name] != nil) { | |
[newEntity setValue:[values valueForKey:attribute.name] forKey:attribute.name]; | |
} | |
} | |
} | |
} | |
return newEntity; | |
} | |
return nil; | |
} | |
-(NSManagedObject *)insertEntity:(NSString *)name withValues:(NSDictionary *)values inContext:(NSManagedObjectContext *)context { | |
NSManagedObject *newEntity = [NSEntityDescription insertNewObjectForEntityForName:name inManagedObjectContext:context]; | |
NSEntityDescription *entityDescription = [NSEntityDescription entityForName:name inManagedObjectContext:context]; | |
for (NSAttributeDescription *attribute in [entityDescription properties]) { | |
if ((NSNull *)[values valueForKey:attribute.name] != [NSNull null]) { | |
if([attribute isKindOfClass:[NSAttributeDescription class]]) { | |
if (attribute.attributeType == NSDateAttributeType) { | |
[newEntity setValue:[values valueForKey:attribute.name] forKey:attribute.name]; | |
} else { | |
if ([values objectForKey:attribute.name] != nil) { | |
[newEntity setValue:[values valueForKey:attribute.name] forKey:attribute.name]; | |
} | |
} | |
} | |
} | |
} | |
return newEntity; | |
} | |
-(NSUInteger)countCorrectQuestionsFrom:(NSDate*)from to:(NSDate*)to { | |
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Answered" inManagedObjectContext:context]; | |
NSFetchRequest *request = [[NSFetchRequest alloc] init]; | |
[request setEntity:entity]; | |
NSPredicate *localpredicate = [NSPredicate predicateWithFormat:@"(lastUse => %@) AND (lastUse < %@) AND (choice.correct == YES) AND (user==%@)",from,to, [UserManager user]]; | |
[request setPredicate:localpredicate]; | |
NSError *error = nil; | |
NSArray *answeredArray = [context executeFetchRequest:request error:&error]; | |
[request release]; | |
if (!error) { | |
NSMutableSet *uniqueQuestions = [NSMutableSet set]; | |
for (Answered *answered in answeredArray) { | |
[uniqueQuestions addObject:answered.choice.question]; | |
} | |
return [uniqueQuestions count]; | |
} | |
return 0; | |
} | |
@end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifdef DEBUG | |
# define DLog(...) NSLog(@"%s %@", __PRETTY_FUNCTION__, [NSString stringWithFormat:__VA_ARGS__]) | |
#else | |
# define DLog(...) /* */ | |
#endif | |
#define PureSingleton(className) \ | |
+ (className *)shared { \ | |
static className *__main; \ | |
static dispatch_once_t onceToken; \ | |
dispatch_once(&onceToken, ^{ __main = [[className alloc] init]; }); \ | |
return __main; } | |
#define IS_IPAD (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) | |
#define IS_IPHONE (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone) | |
#define IS_IPHONE_4_INCH (IS_IPHONE && [[UIScreen mainScreen] bounds].size.height > 500.0f) | |
#define IS_IPHONE_35_INCH (IS_IPHONE && [[UIScreen mainScreen] bounds].size.height < 500.0f) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
+ (void)downloadHomePageWithCompletionBlock:(NSBoolBlock)block { | |
NSString *homepage = [[ARCacheServices shared] getHomePageKey]; | |
[[ARCacheServices shared] startDownloadForFileWithKey:homepage usingBlock:^(NSString *string, NSError *error) { | |
if (block) { | |
if (error) { | |
block(NO); | |
return; | |
} else { | |
NSData *newData = [string dataUsingEncoding:NSUTF8StringEncoding]; | |
if(newData != nil && [newData length] != 0) { | |
logDebug(@"New homepage is available."); | |
NSError *error = nil; | |
HTMLParser *parser = [[HTMLParser alloc] initWithData:newData error:&error]; | |
HTMLNode *headNode = [[[parser doc] childWithTagName:@"head"] childWithId:@"topshop_homepage"]; //head - topshop_homepage | |
if(headNode == nil || error != nil) { // :@ not TS hompage. delete | |
block(NO); | |
return; | |
} | |
else { | |
block(YES); | |
return; | |
} | |
} | |
else { | |
logDebug(@"Latest homepage is nil or new homepage is not available. "); | |
block(NO); | |
return; | |
} | |
} | |
} | |
}]; | |
} | |
-(void)startDownloadForFileWithKey:(NSString *)key usingBlock:(NSStringNSErrorBlock) block { | |
if ([self validateUrl:key]) { | |
NSString *filename = [key lastPathComponent]; | |
NSString *fileCachePath = [NSString stringWithFormat:@"%@%@",_cachePath,filename]; | |
NSURL *url = [NSURL URLWithString:key]; | |
NSURLRequest *request = [NSURLRequest requestWithURL:url]; | |
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request]; | |
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) { | |
NSString *response = [operation responseString]; | |
[response writeToFile:fileCachePath atomically:YES encoding:NSUTF8StringEncoding error:nil]; | |
if (block) { | |
block(response,nil); | |
} | |
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible: NO]; | |
} failure:^(AFHTTPRequestOperation *operation, NSError *error) { | |
if (block) { | |
block(nil,error); | |
} | |
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible: NO]; | |
}]; | |
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible: YES]; | |
[operation start]; | |
} else { | |
if (block) { | |
block(nil,[NSError errorWithDomain:@"redant.com" code:0 userInfo:nil]); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
feedQueue = dispatch_queue_create("at.loveth.explorequeue", NULL); | |
DLog(@"%@",[request responseString]); | |
NSData *data = [request responseData]; | |
dispatch_async(feedQueue, ^(void) { | |
NSManagedObjectContext *backgroundContext = [[NSManagedObjectContext alloc] init]; | |
[backgroundContext setPersistentStoreCoordinator:[context persistentStoreCoordinator]]; | |
//set undo to nil reduces memory footprint | |
[backgroundContext setUndoManager:nil]; | |
[backgroundContext setMergePolicy:NSMergeByPropertyObjectTrumpMergePolicy]; | |
//JSONKit | |
NSDictionary *jsonObjects = [data objectFromJSONDataWithParseOptions:JKParseOptionLooseUnicode]; | |
NSArray *actions = [[NSArray alloc] initWithArray:(NSArray *)[jsonObjects valueForKey:@"actions"]]; | |
[self insertActions:actions inContext:backgroundContext usingScope:[NSString stringWithFormat:@"%@",userId]]; | |
[[NSNotificationCenter defaultCenter] addObserver:self | |
selector:@selector(backgroundContextDidSave:) | |
name:NSManagedObjectContextDidSaveNotification | |
object:backgroundContext]; | |
NSError *error; | |
if (![backgroundContext save:&error]) { | |
NSLog(@"Whoops, couldn't save: %@", error); | |
} | |
[[NSNotificationCenter defaultCenter] removeObserver:self name:NSManagedObjectContextDidSaveNotification object:backgroundContext]; | |
[backgroundContext release]; | |
dispatch_sync(dispatch_get_main_queue(), ^(void) { | |
if (actions.count == 0) { | |
[[NSNotificationCenter defaultCenter] postNotificationName: @"personFeedNoResults" object: nil userInfo: nil]; | |
} | |
}); | |
[actions release]; | |
}); | |
/* Save notification handler for the background context */ | |
- (void)backgroundContextDidSave:(NSNotification *)notification { | |
/* Make sure we're on the main thread when updating the main context */ | |
if (![NSThread isMainThread]) { | |
[self performSelectorOnMainThread:@selector(backgroundContextDidSave:) withObject:notification waitUntilDone:NO]; | |
return; | |
} | |
NSError *error; | |
if (![context save:&error]) { | |
DLog(@"Whoops, couldn't save: %@", error); | |
} | |
/* merge in the changes to the main context */ | |
[context mergeChangesFromContextDidSaveNotification:notification]; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//Project -> Info -> Configurations->Debug-Tests -select Pods | |
// then add libPods.a to tests target | |
//main.m | |
int main(int argc, char *argv[]) | |
{ | |
@autoreleasepool { | |
return UIApplicationMain(argc, argv, nil, @"GHUnitIOSAppDelegate"); | |
} | |
} | |
//test.m | |
#import "WeatherClient.h" | |
#import "GHUnit.h" | |
#define kNetworkTimeout 30.0f | |
@interface WeatherAPITest : GHAsyncTestCase | |
@end | |
@implementation WeatherAPITest | |
- (void)testObservation | |
{ | |
[self prepare]; | |
__block NSError *responseError = nil; | |
__block Observation *resposeObservation = nil; | |
WeatherClient *sharedClient = [WeatherClient sharedClient]; | |
// Known Location (San Francisco) | |
CLLocation *knownLocation = [[CLLocation alloc] initWithLatitude:37.7750 longitude:122.4183]; | |
[sharedClient getCurrentWeatherObservationForLocation:knownLocation completion:^(Observation *observation, NSError *error) { | |
responseError = error; | |
resposeObservation = observation; | |
[self notify:kGHUnitWaitStatusSuccess forSelector:_cmd]; | |
}]; | |
// Wait for the async activity to complete | |
[self waitForStatus:kGHUnitWaitStatusSuccess timeout:kNetworkTimeout]; | |
// Check for Observation Object & Error | |
GHAssertNil(responseError, @""); | |
GHAssertNotNil(resposeObservation, @"Response Observation is nil"); | |
// Validate (some) data | |
GHAssertNotNil(resposeObservation.location, @"Response Observation.location is nil"); | |
GHAssertNotNil(resposeObservation.timeString, @"Response Observation.timeString is nil"); | |
GHAssertNotNil(resposeObservation.temperatureDescription, @"Response Observation.temperatureDescription is nil"); | |
} | |
@end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// Location.h | |
// lovethat | |
// | |
// Created by Stephen Keep on 08/11/2012. | |
// | |
// | |
#import <Foundation/Foundation.h> | |
#import <MapKit/MapKit.h> | |
#import "SynthesizeSingleton.h" | |
@interface LocationManager : NSObject <CLLocationManagerDelegate> { | |
NSArray *places; | |
} | |
@property (nonatomic, strong) CLLocationManager* locationManager; | |
@property (nonatomic, retain) NSArray *places; | |
+ (LocationManager *)sharedLocationManager; | |
-(void)getNearbyLocations; | |
-(NSArray *)getPlaces; | |
-(void)getNearbyLocationsUsingBlock:(id (^)(NSArray *))block; | |
-(NSNumber *)getLongitude; | |
-(NSNumber *)getLatitude; | |
-(BOOL)locationEnabled; | |
@end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// Location.m | |
// lovethat | |
// | |
// Created by Stephen Keep on 08/11/2012. | |
// | |
// | |
#import "LocationManager.h" | |
#import "ASIHTTPRequest.h" | |
#import "JSONKit.h" | |
@implementation LocationManager | |
SYNTHESIZE_SINGLETON_FOR_CLASS(LocationManager); | |
@synthesize locationManager,places; | |
- (id)init { | |
self = [super init]; | |
if(self) { | |
self.locationManager = [CLLocationManager new]; | |
[self.locationManager setDelegate:self]; | |
[self.locationManager setDistanceFilter:kCLDistanceFilterNone]; | |
[self.locationManager setHeadingFilter:kCLHeadingFilterNone]; | |
[self.locationManager startUpdatingLocation]; | |
} | |
return self; | |
} | |
-(BOOL)locationEnabled { | |
if (CLLocationManager.authorizationStatus == kCLAuthorizationStatusAuthorized) { | |
return YES; | |
} else if (CLLocationManager.authorizationStatus == kCLAuthorizationStatusDenied) { | |
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Location Service Disabled" | |
message:@"To re-enable, please go to Settings and turn on Location Service for this app." | |
delegate:nil | |
cancelButtonTitle:@"OK" | |
otherButtonTitles:nil]; | |
[alert show]; | |
[alert release]; | |
return NO; | |
} | |
return NO; | |
} | |
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation { | |
/*CLLocation *location = [self.locationManager location]; | |
float longitude=location.coordinate.longitude; | |
float latitude=location.coordinate.latitude;*/ | |
//DLog(@"longitude: %f, latitude: %f",longitude,latitude); | |
} | |
- (void)locationManager:(CLLocationManager *)manager didUpdateHeading:(CLHeading *)newHeading { | |
//handle your heading updates here- I would suggest only handling the nth update, because they | |
//come in fast and furious and it takes a lot of processing power to handle all of them | |
} | |
-(void)getNearbyLocations { | |
CLLocation *location = [self.locationManager location]; | |
float longitude=location.coordinate.longitude; | |
float latitude=location.coordinate.latitude; | |
NSString *urlString = [NSString stringWithFormat:@"https://maps.googleapis.com/maps/api/place/nearbysearch/json?key=AIzaSyBdAPK6kXa49ZckhBzqIcONr_MEoao84Fs&location=%f,%f&sensor=true&rankby=distance&types=bar|amusement_park|aquarium|art_gallery|bakery|book_store|bowling_alley|cafe|campground|casino|clothing_store|department_store|electronics_store|florist|food|grocery_or_supermarket|gym|library|liquor_store|movie_theater|museum|night_club|restaurant|shoe_store|shopping_mall|spa|stadium|zoo",latitude,longitude]; | |
DLog(@"%@",urlString); | |
NSURL *url = [NSURL URLWithString:[urlString stringByReplacingOccurrencesOfString:@"|" withString:@"%7C"]]; | |
__block ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url]; | |
[request addRequestHeader:@"Accept-Encoding" value:@"gzip"]; | |
[request setRequestMethod:@"GET"]; | |
[request setCompletionBlock:^{ | |
//DLog(@"%@",[request responseString]); | |
NSData *data = [request responseData]; | |
NSDictionary *jsonObjects = [data objectFromJSONDataWithParseOptions:JKParseOptionLooseUnicode]; | |
if (places) { | |
[places release]; | |
places = nil; | |
} | |
places = [[NSArray alloc] initWithArray:(NSArray *)[jsonObjects valueForKey:@"results"]]; | |
}]; | |
[request setFailedBlock:^{ | |
DLog(@"error %i",[request responseStatusCode]); | |
}]; | |
[request startAsynchronous]; | |
} | |
-(void)getNearbyLocationsUsingBlock:(id (^)(NSArray *))block { | |
if (places) { | |
block(places); | |
} else { | |
CLLocation *location = [self.locationManager location]; | |
float longitude=location.coordinate.longitude; | |
float latitude=location.coordinate.latitude; | |
NSString *urlString = [NSString stringWithFormat:@"https://maps.googleapis.com/maps/api/place/nearbysearch/json?key=AIzaSyBdAPK6kXa49ZckhBzqIcONr_MEoao84Fs&location=%f,%f&sensor=true&rankby=distance&types=bar|amusement_park|aquarium|art_gallery|bakery|book_store|bowling_alley|cafe|campground|casino|clothing_store|department_store|electronics_store|florist|food|grocery_or_supermarket|gym|library|liquor_store|movie_theater|museum|night_club|restaurant|shoe_store|shopping_mall|spa|stadium|zoo",latitude,longitude]; | |
DLog(@"%@",urlString); | |
NSURL *url = [NSURL URLWithString:[urlString stringByReplacingOccurrencesOfString:@"|" withString:@"%7C"]]; | |
__block ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url]; | |
[request addRequestHeader:@"Accept-Encoding" value:@"gzip"]; | |
[request setRequestMethod:@"GET"]; | |
[request setCompletionBlock:^{ | |
//DLog(@"%@",[request responseString]); | |
NSData *data = [request responseData]; | |
NSDictionary *jsonObjects = [data objectFromJSONDataWithParseOptions:JKParseOptionLooseUnicode]; | |
if (places) { | |
[places release]; | |
places = nil; | |
} | |
places = [[NSArray alloc] initWithArray:(NSArray *)[jsonObjects valueForKey:@"results"]]; | |
block(places); | |
}]; | |
[request setFailedBlock:^{ | |
DLog(@"error %i",[request responseStatusCode]); | |
}]; | |
[request startAsynchronous]; | |
} | |
} | |
-(NSArray *)getPlaces { | |
return places; | |
} | |
-(NSNumber *)getLongitude { | |
CLLocation *location = [self.locationManager location]; | |
return [NSNumber numberWithFloat:location.coordinate.longitude]; | |
} | |
-(NSNumber *)getLatitude { | |
CLLocation *location = [self.locationManager location]; | |
return [NSNumber numberWithFloat:location.coordinate.latitude]; | |
} | |
@end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[[NSNotificationCenter defaultCenter] postNotificationName: @"personFeedNoResults" object: nil userInfo: nil]; | |
[[NSNotificationCenter defaultCenter] addObserver: self | |
selector: @selector(controllerDidChangeContent:) | |
name: @"personFeedNoResults" | |
object: nil]; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef RABlockAdditions_h | |
#define RABlockAdditions_h | |
typedef void (^NSNotificationBlock)(NSNotification *notification); | |
typedef void (^NSArrayBlock)(NSArray *results); | |
typedef void (^NSErrorBlock)(NSError *error); | |
typedef void (^NSBoolBlock)(BOOL success); | |
typedef void (^NSIntegerBlock)(NSInteger result); | |
typedef void (^NSDataBlock)(NSData *data); | |
typedef void (^NSVoidBlock)(void); | |
typedef void (^NSBoolArrayBlock)(BOOL success, NSArray *objects); | |
typedef void (^NSBoolDictionaryBlock)(BOOL success, NSDictionary *dictionary); | |
typedef void (^NSStringNSErrorBlock)(NSString *string, NSError *error); | |
typedef void (^NSArrayNSErrorBlock)(NSArray *array, NSError *error); | |
typedef void (^NSDictionaryNSErrorBlock)(NSDictionary *dictionary, NSError *error); | |
typedef void (^NSDataNSErrorBlock)(NSData *data, NSError *error); | |
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
- (BOOL) validateUrl: (NSString *) candidate { | |
NSString *urlRegEx = | |
@"(http|https)://((\\w)*|([0-9]*)|([-|_])*)+([\\.|/]((\\w)*|([0-9]*)|([-|_])*))+"; | |
NSPredicate *urlTest = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", urlRegEx]; | |
return [urlTest evaluateWithObject:candidate]; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#define SYNTHESIZE_SINGLETON_FOR_CLASS(classname) \ | |
\ | |
static classname *shared##classname = nil; \ | |
\ | |
+ (classname *)shared##classname \ | |
{ \ | |
@synchronized(self) \ | |
{ \ | |
if (shared##classname == nil) \ | |
{ \ | |
shared##classname = [[self alloc] init]; \ | |
} \ | |
} \ | |
\ | |
return shared##classname; \ | |
} \ | |
\ | |
+ (id)allocWithZone:(NSZone *)zone \ | |
{ \ | |
@synchronized(self) \ | |
{ \ | |
if (shared##classname == nil) \ | |
{ \ | |
shared##classname = [super allocWithZone:zone]; \ | |
return shared##classname; \ | |
} \ | |
} \ | |
\ | |
return nil; \ | |
} \ | |
\ | |
- (id)copyWithZone:(NSZone *)zone \ | |
{ \ | |
return self; \ | |
} \ | |
\ | |
- (id)retain \ | |
{ \ | |
return self; \ | |
} \ | |
\ | |
- (NSUInteger)retainCount \ | |
{ \ | |
return NSUIntegerMax; \ | |
} \ | |
\ | |
- (oneway void)release \ | |
{ \ | |
} \ | |
\ | |
- (id)autorelease \ | |
{ \ | |
return self; \ | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#import <UIKit/UIKit.h> | |
@interface UIColor (Extensions) | |
+(UIColor *) aquaColor; | |
+(UIColor *) pinkColor; | |
+(UIColor *) limeColor; | |
+(UIColor *) lemonColor; | |
+(UIColor *) shadeColor; | |
+(UIColor *) darkShadeColor; | |
@end | |
/*#407b86 rgb(64, 123, 134) | |
#a72949 rgb(167, 41, 73) | |
#959b19 rgb(149, 155, 25) | |
#6d6c69 rgb(109, 108, 105) | |
#696863 rgb(105, 104, 99)*/ | |
@implementation UIColor (Extensions) | |
+ (UIColor *)aquaColor { | |
return [UIColor colorWithRed:77/255.0f green:154/255.0f blue:174/255.0f alpha:1.0]; | |
} | |
+ (UIColor *)pinkColor { | |
return [UIColor colorWithRed:219/255.0f green:48/255.0f blue:84/255.0f alpha:0.8]; | |
} | |
+ (UIColor *)limeColor { | |
return [UIColor colorWithRed:157/255.0f green:167/255.0f blue:3/255.0f alpha:1.0]; | |
} | |
+ (UIColor *)lemonColor { | |
return [UIColor colorWithRed:200/255.0f green:195/255.0f blue:101/255.0f alpha:1.0]; | |
} | |
+ (UIColor *)shadeColor { | |
return [UIColor colorWithRed:108/255.0f green:107/255.0f blue:99/255.0f alpha:1.0]; | |
} | |
+ (UIColor *)darkShadeColor { | |
return [UIColor colorWithRed:56/255.0f green:56/255.0f blue:56/255.0f alpha:1.0]; | |
} | |
@end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
http://nscookbook.com/2013/03/recipe-18-unit-testing-with-ghunit-cocoapods/