From ab33d6d745e58e3e31429e9c738166ef0243bf24 Mon Sep 17 00:00:00 2001 From: VladiMihaylenko Date: Thu, 21 Apr 2016 19:12:04 +0300 Subject: [PATCH] First look refactoring. --- api/MapsWithMeAPI.h | 28 ++++---- api/MapsWithMeAPI.m | 68 +++++++++++-------- .../Capitals.xcodeproj/project.pbxproj | 6 +- .../Capitals/CityDetailViewController.m | 8 +-- .../Capitals/MasterViewController.m | 10 +-- 5 files changed, 66 insertions(+), 54 deletions(-) diff --git a/api/MapsWithMeAPI.h b/api/MapsWithMeAPI.h index 6cadb88..6a6cf3b 100644 --- a/api/MapsWithMeAPI.h +++ b/api/MapsWithMeAPI.h @@ -28,22 +28,26 @@ #import -#if __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_5_0 - #error "MapsWithMe supports iOS >= 5.0 only" +#if __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_7_0 + #error "maps.me supports iOS >= 7.0 only" #endif // Wrapper for a pin on a map @interface MWMPin : NSObject /// [required] pin latitude -@property (nonatomic, assign) double lat; +@property (nonatomic) CGFloat lat; /// [required] pin longitude -@property (nonatomic, assign) double lon; +@property (nonatomic) CGFloat lon; /// [optional] pin title -@property (nonatomic, retain) NSString * title; +@property (nullable, copy, nonatomic) NSString * title; /// [optional] passed back to the app when pin is clicked, OR, if it's a valid url, /// it will be opened from MapsWithMe after selecting "More Details..." for the pin -@property (nonatomic, retain) NSString * idOrUrl; -- (id)initWithLat:(double)lat lon:(double)lon title:(NSString *)title andId:(NSString *)idOrUrl; +@property (nullable, copy, nonatomic) NSString * idOrUrl; + +- (nullable instancetype)initWithLat:(CGFloat)lat + lon:(CGFloat)lon + title:(nullable NSString *)title + idOrUrl:(nullable NSString *)idOrUrl; @end @@ -52,20 +56,20 @@ @interface MWMApi : NSObject /// returns YES if url is received from MapsWithMe and can be parsed -+ (BOOL)isMapsWithMeUrl:(NSURL *)url; ++ (BOOL)isMapsWithMeUrl:(nonnull NSURL *)url; /// returns nil if user didn't select any pin and simply pressed "Back" button -+ (MWMPin *)pinFromUrl:(NSURL *)url; ++ (nullable MWMPin *)pinFromUrl:(nonnull NSURL *)url; /// returns NO if MapsWithMe is not installed or outdated version doesn't support API calls + (BOOL)isApiSupported; /// Simply opens MapsWithMe app + (BOOL)showMap; /// Displays given point on a map, title and id are optional. /// If id contains valid url, it will be opened from MapsWithMe after selecting "More Details..." for the pin -+ (BOOL)showLat:(double)lat lon:(double)lon title:(NSString *)title andId:(NSString *)idOrUrl; ++ (BOOL)showLat:(CGFloat)lat lon:(CGFloat)lon title:(nullable NSString *)title idOrUrl:(nullable NSString *)idOrUrl; /// The same as above but using pin wrapper -+ (BOOL)showPin:(MWMPin *)pin; ++ (BOOL)showPin:(nullable MWMPin *)pin; /// Displays any number of pins -+ (BOOL)showPins:(NSArray *)pins; ++ (BOOL)showPins:(nonnull NSArray *)pins; // + (void)showMapsWithMeIsNotInstalledDialog; /// Set value = YES if you want to open pin URL on balloon click, default value is NO diff --git a/api/MapsWithMeAPI.m b/api/MapsWithMeAPI.m index cc892bb..ea168bb 100644 --- a/api/MapsWithMeAPI.m +++ b/api/MapsWithMeAPI.m @@ -30,29 +30,34 @@ #define MAPSWITHME_API_VERSION 1.1 -static NSString * MWMUrlScheme = @"mapswithme://"; -static BOOL openUrlOnBalloonClick = NO; +static NSString * const kMWMUrlScheme = @"mapswithme://"; +static BOOL kOpenUrlOnBalloonClick = NO; @implementation MWMPin -- (id)init +- (nullable instancetype)init { - if ((self = [super init])) + self = [super init]; + if (self) { - self.lat = INFINITY; - self.lon = INFINITY; + _lat = INFINITY; + _lon = INFINITY; } return self; } -- (id)initWithLat:(double)lat lon:(double)lon title:(NSString *)title andId:(NSString *)idOrUrl +- (nullable instancetype)initWithLat:(CGFloat)lat + lon:(CGFloat)lon + title:(nullable NSString *)title + idOrUrl:(nullable NSString *)idOrUrl { - if ((self = [super init])) + self = [super init]; + if (self) { - self.lat = lat; - self.lon = lon; - self.title = title; - self.idOrUrl = idOrUrl; + _lat = lat; + _lon = lon; + _title = title; + _idOrUrl = idOrUrl; } return self; } @@ -67,7 +72,7 @@ static BOOL openUrlOnBalloonClick = NO; @implementation MWMNViewController // HTML page for users who didn't install MapsWithMe -static NSString * mapsWithMeIsNotInstalledPage = +static NSString * const mapsWithMeIsNotInstalledPage = @"" \ "" \ "Please install MAPS.ME - offline maps of the World" \ @@ -109,13 +114,13 @@ static NSString * mapsWithMeIsNotInstalledPage = return (__bridge_transfer NSString *)CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, (CFStringRef)str, NULL, CFSTR("!$&'()*+,-./:;=?@_~"), kCFStringEncodingUTF8); } -+ (BOOL)isMapsWithMeUrl:(NSURL *)url ++ (BOOL)isMapsWithMeUrl:(nonnull NSURL *)url { NSString * appScheme = [MWMApi detectBackUrlScheme]; return appScheme && [url.scheme isEqualToString:appScheme]; } -+ (MWMPin *)pinFromUrl:(NSURL *)url ++ (nullable MWMPin *)pinFromUrl:(nonnull NSURL *)url { if (![MWMApi isMapsWithMeUrl:url]) return nil; @@ -126,13 +131,13 @@ static NSString * mapsWithMeIsNotInstalledPage = pin = [[MWMPin alloc] init]; for (NSString * param in [url.query componentsSeparatedByString:@"&"]) { - NSArray * values = [param componentsSeparatedByString:@"="]; + NSArray * values = [param componentsSeparatedByString:@"="]; if ([values count] == 2) { NSString * key = values[0]; if ([key isEqualToString:@"ll"]) { - NSArray * coords = [values[1] componentsSeparatedByString:@","]; + NSArray * coords = [values[1] componentsSeparatedByString:@","]; if ([coords count] == 2) { pin.lat = [[NSDecimalNumber decimalNumberWithString:coords[0]] doubleValue]; @@ -156,26 +161,26 @@ static NSString * mapsWithMeIsNotInstalledPage = + (BOOL)isApiSupported { - return [[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:MWMUrlScheme]]; + return [[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:kMWMUrlScheme]]; } + (BOOL)showMap { - return [[UIApplication sharedApplication] openURL:[NSURL URLWithString:[MWMUrlScheme stringByAppendingFormat:@"map?v=%f", MAPSWITHME_API_VERSION]]]; + return [[UIApplication sharedApplication] openURL:[NSURL URLWithString:[kMWMUrlScheme stringByAppendingFormat:@"map?v=%f", MAPSWITHME_API_VERSION]]]; } -+ (BOOL)showLat:(double)lat lon:(double)lon title:(NSString *)title andId:(NSString *)idOrUrl ++ (BOOL)showLat:(CGFloat)lat lon:(CGFloat)lon title:(nullable NSString *)title idOrUrl:(nullable NSString *)idOrUrl { - MWMPin * pin = [[MWMPin alloc] initWithLat:lat lon:lon title:title andId:idOrUrl]; + MWMPin * pin = [[MWMPin alloc] initWithLat:lat lon:lon title:title idOrUrl:idOrUrl]; return [MWMApi showPin:pin]; } -+ (BOOL)showPin:(MWMPin *)pin ++ (BOOL)showPin:(nullable MWMPin *)pin { - return [MWMApi showPins:@[pin]]; + return pin ? [MWMApi showPins:@[pin]] : NO; } -+ (BOOL)showPins:(NSArray *)pins ++ (BOOL)showPins:(nonnull NSArray *)pins { // Automatic check that MapsWithMe is installed if (![MWMApi isApiSupported]) @@ -186,10 +191,13 @@ static NSString * mapsWithMeIsNotInstalledPage = } NSString * appName = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleDisplayName"]; - NSMutableString * str = [[NSMutableString alloc] initWithFormat:@"%@map?v=%f&appname=%@&", MWMUrlScheme, MAPSWITHME_API_VERSION, - [self urlEncode:appName]]; + NSMutableString * str = [NSMutableString stringWithFormat:@"%@map?v=%f&appname=%@&", + kMWMUrlScheme, + MAPSWITHME_API_VERSION, + [self urlEncode:appName]]; NSString * backUrlScheme = [MWMApi detectBackUrlScheme]; + if (backUrlScheme) [str appendFormat:@"backurl=%@&", [self urlEncode:backUrlScheme]]; @@ -205,8 +213,8 @@ static NSString * mapsWithMeIsNotInstalledPage = } } - if (openUrlOnBalloonClick) - [str appendString:@"&balloonAction=openUrlOnBalloonClick"]; + if (kOpenUrlOnBalloonClick) + [str appendString:@"&balloonAction=kOpenUrlOnBalloonClick"]; NSURL * url = [NSURL URLWithString:str]; BOOL const result = [[UIApplication sharedApplication] openURL:url]; @@ -243,12 +251,12 @@ static NSString * mapsWithMeIsNotInstalledPage = navController.navigationBar.topItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"Close" style:UIBarButtonItemStyleDone target:webController action:@selector(onCloseButtonClicked:)]; UIWindow * window = [[UIApplication sharedApplication].windows firstObject]; - [window.rootViewController presentModalViewController:navController animated:YES]; + [window.rootViewController presentViewController:navController animated:YES completion:nil]; } + (void)setOpenUrlOnBalloonClick:(BOOL)value { - openUrlOnBalloonClick = value; + kOpenUrlOnBalloonClick = value; } @end diff --git a/capitals-example/Capitals.xcodeproj/project.pbxproj b/capitals-example/Capitals.xcodeproj/project.pbxproj index 83766be..eacbe14 100644 --- a/capitals-example/Capitals.xcodeproj/project.pbxproj +++ b/capitals-example/Capitals.xcodeproj/project.pbxproj @@ -270,7 +270,7 @@ GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "Capitals/Capitals-Prefix.pch"; INFOPLIST_FILE = "Capitals/Capitals-Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 5.0; + IPHONEOS_DEPLOYMENT_TARGET = 7.0; PRODUCT_BUNDLE_IDENTIFIER = com.mapswithme.api.example.Capitals; PRODUCT_NAME = "World Capitals"; WRAPPER_EXTENSION = app; @@ -339,7 +339,7 @@ GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "Capitals/Capitals-Prefix.pch"; INFOPLIST_FILE = "Capitals/Capitals-Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 5.0; + IPHONEOS_DEPLOYMENT_TARGET = 7.0; PRODUCT_BUNDLE_IDENTIFIER = com.mapswithme.api.example.Capitals; PRODUCT_NAME = "World Capitals"; WRAPPER_EXTENSION = app; @@ -353,7 +353,7 @@ GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "Capitals/Capitals-Prefix.pch"; INFOPLIST_FILE = "Capitals/Capitals-Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 5.0; + IPHONEOS_DEPLOYMENT_TARGET = 7.0; PRODUCT_BUNDLE_IDENTIFIER = com.mapswithme.api.example.Capitals; PRODUCT_NAME = "World Capitals"; WRAPPER_EXTENSION = app; diff --git a/capitals-example/Capitals/CityDetailViewController.m b/capitals-example/Capitals/CityDetailViewController.m index a74d803..64e2fc3 100644 --- a/capitals-example/Capitals/CityDetailViewController.m +++ b/capitals-example/Capitals/CityDetailViewController.m @@ -50,8 +50,8 @@ if (withLink) pinId = [NSString stringWithFormat:@"http://en.wikipedia.org/wiki/%@", [self urlEncode:self.city[@"name"]]]; else - pinId = [NSString stringWithFormat:@"%i", _cityIndex]; - [MWMApi showLat:[self.city[@"lat"] doubleValue] lon:[self.city[@"lon"] doubleValue] title:self.city[@"name"] andId:pinId]; + pinId = [NSString stringWithFormat:@"%@", @(_cityIndex)]; + [MWMApi showLat:[self.city[@"lat"] doubleValue] lon:[self.city[@"lon"] doubleValue] title:self.city[@"name"] idOrUrl:pinId]; } - (void)setCityIndex:(NSInteger)newCityIndex @@ -93,7 +93,7 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { - NSString * cellId = [NSString stringWithFormat:@"%d%d", indexPath.section, indexPath.row]; + NSString * cellId = [NSString stringWithFormat:@"%@%@", @(indexPath.section), @(indexPath.row)]; UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:cellId]; if (cell == nil) { @@ -114,7 +114,7 @@ else { cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellId]; - cell.textLabel.textAlignment = UITextAlignmentCenter; + cell.textLabel.textAlignment = NSTextAlignmentCenter; if (indexPath.section == 1) cell.textLabel.text = @"Show map and come back"; else diff --git a/capitals-example/Capitals/MasterViewController.m b/capitals-example/Capitals/MasterViewController.m index d3000a8..9b179e6 100644 --- a/capitals-example/Capitals/MasterViewController.m +++ b/capitals-example/Capitals/MasterViewController.m @@ -52,14 +52,14 @@ - (void)showAllCitiesOnTheMap:(id)sender { - NSMutableArray * array = [[NSMutableArray alloc] initWithCapacity:[self.capitals count]]; + NSMutableArray * array = [[NSMutableArray alloc] initWithCapacity:[self.capitals count]]; for (NSInteger i = 0; i < [self.capitals count]; ++i) { - NSString * pinId = [[NSString alloc] initWithFormat:@"%i", i]; + NSString * pinId = [NSString stringWithFormat:@"%@", @(i)]; // Note that url is empty - it means "More details" button for a pin in MapsWithMe will lead back to this example app NSDictionary * city = self.capitals[i]; - MWMPin * pin = [[MWMPin alloc] initWithLat:[city[@"lat"] doubleValue] lon:[city[@"lon"] doubleValue] title:city[@"name"] andId:pinId]; + MWMPin * pin = [[MWMPin alloc] initWithLat:[city[@"lat"] doubleValue] lon:[city[@"lon"] doubleValue] title:city[@"name"] idOrUrl:pinId]; [array addObject:pin]; } // Your should hide any top view objects like UIPopoverController before calling +showPins: @@ -78,7 +78,7 @@ if ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad) { self.clearsSelectionOnViewWillAppear = NO; - self.contentSizeForViewInPopover = CGSizeMake(320.0, 600.0); + self.preferredContentSize = CGSizeMake(320.0, 600.0); } } return self; @@ -108,7 +108,7 @@ { UILabel * label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 240, tableView.rowHeight)]; label.text = [MWMApi isApiSupported] ? @"MapsWithMe is installed" : @"MapsWithMe is not installed"; - label.textAlignment = UITextAlignmentCenter; + label.textAlignment = NSTextAlignmentCenter; label.backgroundColor = [UIColor clearColor]; return label; }