├── .DS_Store ├── JFOpenWeatherMapManager ├── en.lproj │ └── InfoPlist.strings ├── WeatherModel │ ├── DataModels.h │ ├── Snow.h │ ├── Clouds.h │ ├── Rain.h │ ├── Coord.h │ ├── Wind.h │ ├── Sys.h │ ├── Weather.h │ ├── Main.h │ ├── Clouds.m │ ├── Rain.m │ ├── Snow.m │ ├── Coord.m │ ├── Wind.m │ ├── Sys.m │ ├── Weather.m │ └── Main.m ├── APTimeZones │ ├── Categories │ │ ├── CLLocation+APTimeZones.h │ │ ├── CLPlacemark+APTimeZones.h │ │ ├── CLLocation+APTimeZones.m │ │ └── CLPlacemark+APTimeZones.m │ ├── APTimeZones.h │ └── APTimeZones.m ├── JFAppDelegate.h ├── JFOpenWeatherMapManager-Prefix.pch ├── main.m ├── Images.xcassets │ ├── AppIcon.appiconset │ │ └── Contents.json │ └── LaunchImage.launchimage │ │ └── Contents.json ├── JFWeatherManager.h ├── JFViewController.h ├── JFOpenWeatherMapManager-Info.plist ├── AFNetworking │ ├── AFNetworking.h │ ├── AFSecurityPolicy.h │ ├── AFHTTPRequestOperation.h │ ├── AFHTTPRequestOperation.m │ ├── AFNetworkReachabilityManager.h │ ├── AFNetworkReachabilityManager.m │ ├── AFSecurityPolicy.m │ ├── AFURLResponseSerialization.h │ ├── AFHTTPRequestOperationManager.m │ ├── AFHTTPSessionManager.m │ ├── AFHTTPSessionManager.h │ └── AFURLRequestSerialization.h ├── JFAppDelegate.m ├── JFWeatherManager.m ├── JFWeatherData.h ├── JFViewController.m ├── Base.lproj │ └── Main.storyboard └── JFWeatherData.m ├── JFOpenWeatherMapManagerTests ├── en.lproj │ └── InfoPlist.strings ├── JFOpenWeatherMapManagerTests-Info.plist └── JFOpenWeatherMapManagerTests.m ├── JFOpenWeatherMapManager.xcodeproj ├── xcuserdata │ ├── Jon.xcuserdatad │ │ ├── xcdebugger │ │ │ └── Breakpoints_v2.xcbkptlist │ │ └── xcschemes │ │ │ ├── xcschememanagement.plist │ │ │ └── JFOpenWeatherMapManager.xcscheme │ └── Jonathan.xcuserdatad │ │ └── xcschemes │ │ ├── xcschememanagement.plist │ │ └── JFOpenWeatherMapManager.xcscheme └── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcuserdata │ ├── Jon.xcuserdatad │ └── UserInterfaceState.xcuserstate │ └── Jonathan.xcuserdatad │ └── UserInterfaceState.xcuserstate ├── .gitignore ├── LICENSE.md └── README.md /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jfield44/JFOpenWeatherMapManager/HEAD/.DS_Store -------------------------------------------------------------------------------- /JFOpenWeatherMapManager/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /JFOpenWeatherMapManagerTests/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /JFOpenWeatherMapManager.xcodeproj/xcuserdata/Jon.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | -------------------------------------------------------------------------------- /JFOpenWeatherMapManager.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /JFOpenWeatherMapManager.xcodeproj/project.xcworkspace/xcuserdata/Jon.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jfield44/JFOpenWeatherMapManager/HEAD/JFOpenWeatherMapManager.xcodeproj/project.xcworkspace/xcuserdata/Jon.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /JFOpenWeatherMapManager.xcodeproj/project.xcworkspace/xcuserdata/Jonathan.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jfield44/JFOpenWeatherMapManager/HEAD/JFOpenWeatherMapManager.xcodeproj/project.xcworkspace/xcuserdata/Jonathan.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | .DS_Store 3 | */build/* 4 | *.pbxuser 5 | !default.pbxuser 6 | *.mode1v3 7 | !default.mode1v3 8 | *.mode2v3 9 | !default.mode2v3 10 | *.perspectivev3 11 | !default.perspectivev3 12 | xcuserdata 13 | profile 14 | *.moved-aside 15 | DerivedData 16 | .idea/ 17 | *.hmap 18 | *.xccheckout 19 | 20 | #CocoaPods 21 | Pods 22 | -------------------------------------------------------------------------------- /JFOpenWeatherMapManager/WeatherModel/DataModels.h: -------------------------------------------------------------------------------- 1 | // 2 | // DataModels.h 3 | // 4 | // Created by Jonathan Field on 26/10/2013 5 | // Copyright (c) 2013 __MyCompanyName__. All rights reserved. 6 | // 7 | 8 | #import "Wind.h" 9 | #import "Clouds.h" 10 | #import "Coord.h" 11 | #import "Main.h" 12 | #import "Weather.h" 13 | #import "Sys.h" 14 | -------------------------------------------------------------------------------- /JFOpenWeatherMapManager/APTimeZones/Categories/CLLocation+APTimeZones.h: -------------------------------------------------------------------------------- 1 | // 2 | // CLLocation+APTimeZones.h 3 | // Example 4 | // 5 | // Created by Sergii Kryvoblotskyi on 11/11/13. 6 | // Copyright (c) 2013 Alterplay. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface CLLocation (APTimeZones) 12 | - (NSTimeZone *)timeZone; 13 | @end 14 | -------------------------------------------------------------------------------- /JFOpenWeatherMapManager/APTimeZones/Categories/CLPlacemark+APTimeZones.h: -------------------------------------------------------------------------------- 1 | // 2 | // CLPlacemark+APTimeZones.h 3 | // Example 4 | // 5 | // Created by Sergii Kryvoblotskyi on 11/11/13. 6 | // Copyright (c) 2013 Alterplay. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface CLPlacemark (APTimeZones) 12 | - (NSTimeZone *)timeZone; 13 | @end 14 | -------------------------------------------------------------------------------- /JFOpenWeatherMapManager/JFAppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // JFAppDelegate.h 3 | // JFOpenWeatherMapManager 4 | // 5 | // Created by Jonathan Field on 27/10/2013. 6 | // Copyright (c) 2013 Jonathan Field. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface JFAppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /JFOpenWeatherMapManager/JFOpenWeatherMapManager-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header 3 | // 4 | // The contents of this file are implicitly included at the beginning of every source file. 5 | // 6 | 7 | #import 8 | 9 | #ifndef __IPHONE_5_0 10 | #warning "This project uses features only available in iOS SDK 5.0 and later." 11 | #endif 12 | 13 | #ifdef __OBJC__ 14 | #import 15 | #import 16 | #endif 17 | -------------------------------------------------------------------------------- /JFOpenWeatherMapManager/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // JFOpenWeatherMapManager 4 | // 5 | // Created by Jonathan Field on 27/10/2013. 6 | // Copyright (c) 2013 Jonathan Field. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "JFAppDelegate.h" 12 | 13 | int main(int argc, char * argv[]) 14 | { 15 | @autoreleasepool { 16 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([JFAppDelegate class])); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /JFOpenWeatherMapManager/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "29x29", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "40x40", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "60x60", 16 | "scale" : "2x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /JFOpenWeatherMapManager/WeatherModel/Snow.h: -------------------------------------------------------------------------------- 1 | // 2 | // Snow.h 3 | // 4 | // Created by Jonathan Field on 31/10/2013 5 | // Copyright (c) 2013 __MyCompanyName__. All rights reserved. 6 | // 7 | 8 | #import 9 | 10 | 11 | 12 | @interface Snow : NSObject 13 | 14 | @property (nonatomic, assign) double threeHour; 15 | 16 | + (Snow *)modelObjectWithDictionary:(NSDictionary *)dict; 17 | - (instancetype)initWithDictionary:(NSDictionary *)dict; 18 | - (NSDictionary *)dictionaryRepresentation; 19 | 20 | @end 21 | -------------------------------------------------------------------------------- /JFOpenWeatherMapManager/WeatherModel/Clouds.h: -------------------------------------------------------------------------------- 1 | // 2 | // Clouds.h 3 | // 4 | // Created by Jonathan Field on 26/10/2013 5 | // Copyright (c) 2013 __MyCompanyName__. All rights reserved. 6 | // 7 | 8 | #import 9 | 10 | 11 | 12 | @interface Clouds : NSObject 13 | 14 | @property (nonatomic, assign) double all; 15 | 16 | + (Clouds *)modelObjectWithDictionary:(NSDictionary *)dict; 17 | - (instancetype)initWithDictionary:(NSDictionary *)dict; 18 | - (NSDictionary *)dictionaryRepresentation; 19 | 20 | @end 21 | -------------------------------------------------------------------------------- /JFOpenWeatherMapManager/WeatherModel/Rain.h: -------------------------------------------------------------------------------- 1 | // 2 | // JFRain.h 3 | // 4 | // Created by Jonathan Field on 27/10/2013 5 | // Copyright (c) 2013 __MyCompanyName__. All rights reserved. 6 | // 7 | 8 | #import 9 | 10 | 11 | 12 | @interface Rain : NSObject 13 | 14 | @property (nonatomic, assign) double threeHour; 15 | 16 | + (Rain *)modelObjectWithDictionary:(NSDictionary *)dict; 17 | - (instancetype)initWithDictionary:(NSDictionary *)dict; 18 | - (NSDictionary *)dictionaryRepresentation; 19 | 20 | @end 21 | -------------------------------------------------------------------------------- /JFOpenWeatherMapManager/APTimeZones/Categories/CLLocation+APTimeZones.m: -------------------------------------------------------------------------------- 1 | // 2 | // CLLocation+APTimeZones.m 3 | // Example 4 | // 5 | // Created by Sergii Kryvoblotskyi on 11/11/13. 6 | // Copyright (c) 2013 Alterplay. All rights reserved. 7 | // 8 | 9 | #import "CLLocation+APTimeZones.h" 10 | #import "APTimeZones.h" 11 | 12 | @implementation CLLocation (APTimeZones) 13 | 14 | - (NSTimeZone *)timeZone { 15 | NSTimeZone *timeZone = [[APTimeZones sharedInstance] timeZoneWithLocation:self]; 16 | return timeZone; 17 | 18 | } 19 | 20 | @end 21 | -------------------------------------------------------------------------------- /JFOpenWeatherMapManager/WeatherModel/Coord.h: -------------------------------------------------------------------------------- 1 | // 2 | // Coord.h 3 | // 4 | // Created by Jonathan Field on 26/10/2013 5 | // Copyright (c) 2013 __MyCompanyName__. All rights reserved. 6 | // 7 | 8 | #import 9 | 10 | 11 | 12 | @interface Coord : NSObject 13 | 14 | @property (nonatomic, assign) double lon; 15 | @property (nonatomic, assign) double lat; 16 | 17 | + (Coord *)modelObjectWithDictionary:(NSDictionary *)dict; 18 | - (instancetype)initWithDictionary:(NSDictionary *)dict; 19 | - (NSDictionary *)dictionaryRepresentation; 20 | 21 | @end 22 | -------------------------------------------------------------------------------- /JFOpenWeatherMapManager/WeatherModel/Wind.h: -------------------------------------------------------------------------------- 1 | // 2 | // Wind.h 3 | // 4 | // Created by Jonathan Field on 26/10/2013 5 | // Copyright (c) 2013 __MyCompanyName__. All rights reserved. 6 | // 7 | 8 | #import 9 | 10 | 11 | 12 | @interface Wind : NSObject 13 | 14 | @property (nonatomic, assign) double speed; 15 | @property (nonatomic, assign) double deg; 16 | 17 | + (Wind *)modelObjectWithDictionary:(NSDictionary *)dict; 18 | - (instancetype)initWithDictionary:(NSDictionary *)dict; 19 | - (NSDictionary *)dictionaryRepresentation; 20 | 21 | @end 22 | -------------------------------------------------------------------------------- /JFOpenWeatherMapManager/Images.xcassets/LaunchImage.launchimage/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "orientation" : "portrait", 5 | "idiom" : "iphone", 6 | "extent" : "full-screen", 7 | "minimum-system-version" : "7.0", 8 | "scale" : "2x" 9 | }, 10 | { 11 | "orientation" : "portrait", 12 | "idiom" : "iphone", 13 | "subtype" : "retina4", 14 | "extent" : "full-screen", 15 | "minimum-system-version" : "7.0", 16 | "scale" : "2x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /JFOpenWeatherMapManager/WeatherModel/Sys.h: -------------------------------------------------------------------------------- 1 | // 2 | // Sys.h 3 | // 4 | // Created by Jonathan Field on 26/10/2013 5 | // Copyright (c) 2013 __MyCompanyName__. All rights reserved. 6 | // 7 | 8 | #import 9 | 10 | 11 | 12 | @interface Sys : NSObject 13 | 14 | @property (nonatomic, strong) NSString *country; 15 | @property (nonatomic, assign) double sunrise; 16 | @property (nonatomic, assign) double sunset; 17 | 18 | + (Sys *)modelObjectWithDictionary:(NSDictionary *)dict; 19 | - (instancetype)initWithDictionary:(NSDictionary *)dict; 20 | - (NSDictionary *)dictionaryRepresentation; 21 | 22 | @end 23 | -------------------------------------------------------------------------------- /JFOpenWeatherMapManager/WeatherModel/Weather.h: -------------------------------------------------------------------------------- 1 | // 2 | // Weather.h 3 | // 4 | // Created by Jonathan Field on 26/10/2013 5 | // Copyright (c) 2013 __MyCompanyName__. All rights reserved. 6 | // 7 | 8 | #import 9 | 10 | 11 | 12 | @interface Weather : NSObject 13 | 14 | @property (nonatomic, assign) double weatherIdentifier; 15 | @property (nonatomic, strong) NSString *main; 16 | @property (nonatomic, strong) NSString *icon; 17 | @property (nonatomic, strong) NSString *weatherDescription; 18 | 19 | + (Weather *)modelObjectWithDictionary:(NSDictionary *)dict; 20 | - (instancetype)initWithDictionary:(NSDictionary *)dict; 21 | - (NSDictionary *)dictionaryRepresentation; 22 | 23 | @end 24 | -------------------------------------------------------------------------------- /JFOpenWeatherMapManager/WeatherModel/Main.h: -------------------------------------------------------------------------------- 1 | // 2 | // Main.h 3 | // 4 | // Created by Jonathan Field on 26/10/2013 5 | // Copyright (c) 2013 __MyCompanyName__. All rights reserved. 6 | // 7 | 8 | #import 9 | 10 | 11 | 12 | @interface Main : NSObject 13 | 14 | @property (nonatomic, assign) double humidity; 15 | @property (nonatomic, assign) double tempMax; 16 | @property (nonatomic, assign) double tempMin; 17 | @property (nonatomic, assign) double temp; 18 | @property (nonatomic, assign) double pressure; 19 | 20 | + (Main *)modelObjectWithDictionary:(NSDictionary *)dict; 21 | - (instancetype)initWithDictionary:(NSDictionary *)dict; 22 | - (NSDictionary *)dictionaryRepresentation; 23 | 24 | @end 25 | -------------------------------------------------------------------------------- /JFOpenWeatherMapManager/APTimeZones/Categories/CLPlacemark+APTimeZones.m: -------------------------------------------------------------------------------- 1 | // 2 | // CLPlacemark+APTimeZones.m 3 | // Example 4 | // 5 | // Created by Sergii Kryvoblotskyi on 11/11/13. 6 | // Copyright (c) 2013 Alterplay. All rights reserved. 7 | // 8 | 9 | #import "CLPlacemark+APTimeZones.h" 10 | #import "APTimeZones.h" 11 | 12 | @implementation CLPlacemark (APTimeZones) 13 | 14 | - (NSTimeZone *)timeZone { 15 | CLLocation *location = self.location; 16 | 17 | NSString *countryCode = self.addressDictionary[@"CountryCode"]; 18 | NSTimeZone *timeZone = [[APTimeZones sharedInstance] timeZoneWithLocation:location 19 | countryCode:countryCode]; 20 | return timeZone; 21 | } 22 | 23 | @end 24 | -------------------------------------------------------------------------------- /JFOpenWeatherMapManager.xcodeproj/xcuserdata/Jon.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | JFOpenWeatherMapManager.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | FC52C11F181D6F080057F940 16 | 17 | primary 18 | 19 | 20 | FC52C140181D6F080057F940 21 | 22 | primary 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /JFOpenWeatherMapManager.xcodeproj/xcuserdata/Jonathan.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | JFOpenWeatherMapManager.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | FC52C11F181D6F080057F940 16 | 17 | primary 18 | 19 | 20 | FC52C140181D6F080057F940 21 | 22 | primary 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /JFOpenWeatherMapManagerTests/JFOpenWeatherMapManagerTests-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | JonathanField.${PRODUCT_NAME:rfc1034identifier} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundlePackageType 14 | BNDL 15 | CFBundleShortVersionString 16 | 1.0 17 | CFBundleSignature 18 | ???? 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /JFOpenWeatherMapManagerTests/JFOpenWeatherMapManagerTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // JFOpenWeatherMapManagerTests.m 3 | // JFOpenWeatherMapManagerTests 4 | // 5 | // Created by Jonathan Field on 27/10/2013. 6 | // Copyright (c) 2013 Jonathan Field. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface JFOpenWeatherMapManagerTests : XCTestCase 12 | 13 | @end 14 | 15 | @implementation JFOpenWeatherMapManagerTests 16 | 17 | - (void)setUp 18 | { 19 | [super setUp]; 20 | // Put setup code here. This method is called before the invocation of each test method in the class. 21 | } 22 | 23 | - (void)tearDown 24 | { 25 | // Put teardown code here. This method is called after the invocation of each test method in the class. 26 | [super tearDown]; 27 | } 28 | 29 | - (void)testExample 30 | { 31 | XCTFail(@"No implementation for \"%s\"", __PRETTY_FUNCTION__); 32 | } 33 | 34 | @end 35 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2013 Jonathan Field 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /JFOpenWeatherMapManager/JFWeatherManager.h: -------------------------------------------------------------------------------- 1 | // 2 | // JFWeatherManager.h 3 | // JFOpenWeatherMapManager 4 | // 5 | // Created by Jonathan Field on 27/10/2013. 6 | // Copyright (c) 2013 Jonathan Field. All rights reserved. 7 | // http://jonathanfield.me 8 | // https://github.com/jfield44/JFOpenWeatherMapManager 9 | 10 | #import 11 | #import "JFWeatherData.h" 12 | #import "DataModels.h" 13 | #import "AFNetworking.h" 14 | 15 | @class JFWeatherManager; 16 | 17 | @interface JFWeatherManager : NSObject 18 | 19 | /* 20 | This function will retrieve the OpenWeatherMap API response based on the parameters provided 21 | latitude : Latitude Coordinate to retrieve weather for 22 | longitude : Longitude Coordinate to retrieve weather for 23 | apiKey : If you use an API for OpenWeatherMap API you should send this, if you do not, pass nil 24 | completitionBlock: When the API call has been completed, use the outcome of this block to manipulate WeatherData 25 | */ 26 | - (void)fetchWeatherDataForLatitude:(double)latitude andLongitude:(double)longitude withAPIKeyOrNil:(NSString *)apiKey :(void(^)(JFWeatherData *returnedWeatherData))completionBlock; 27 | 28 | 29 | @end 30 | -------------------------------------------------------------------------------- /JFOpenWeatherMapManager/JFViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // JFViewController.h 3 | // JFOpenWeatherMapManager 4 | // 5 | // Created by Jonathan Field on 27/10/2013. 6 | // Copyright (c) 2013 Jonathan Field. All rights reserved. 7 | // http://jonathanfield.me 8 | // https://github.com/jfield44/JFOpenWeatherMapManager 9 | 10 | /* 11 | This view controller provides a rough and ready example implementation of how to use JFOpenWeatherMapManager. The example consists of a mapview that on when a pin is dropped, will 12 | print out the local weather data for that latitude and latitude, once this has completed it will be displayed in the tableview below. 13 | */ 14 | 15 | #import 16 | #import 17 | #import 18 | #import "JFWeatherData.h" 19 | #import "JFWeatherManager.h" 20 | #import "DataModels.h" 21 | 22 | @interface JFViewController : UIViewController { 23 | 24 | JFWeatherManager *weatherManager; 25 | NSMutableArray *tableViewContents; 26 | 27 | } 28 | 29 | @property (weak, nonatomic) IBOutlet MKMapView *mapView; 30 | @property (weak, nonatomic) IBOutlet UITableView *tableView; 31 | 32 | - (void)addGestureRecogniserToMapView; 33 | - (void)addPinToMap:(UIGestureRecognizer *)gestureRecognizer; 34 | 35 | @end 36 | -------------------------------------------------------------------------------- /JFOpenWeatherMapManager/JFOpenWeatherMapManager-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | ${PRODUCT_NAME} 9 | CFBundleExecutable 10 | ${EXECUTABLE_NAME} 11 | CFBundleIdentifier 12 | JonathanField.${PRODUCT_NAME:rfc1034identifier} 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | ${PRODUCT_NAME} 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1.0 25 | LSRequiresIPhoneOS 26 | 27 | UIMainStoryboardFile 28 | Main 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UISupportedInterfaceOrientations 34 | 35 | UIInterfaceOrientationPortrait 36 | UIInterfaceOrientationLandscapeLeft 37 | UIInterfaceOrientationLandscapeRight 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /JFOpenWeatherMapManager/APTimeZones/APTimeZones.h: -------------------------------------------------------------------------------- 1 | // 2 | // APTimeZones.h 3 | // APTimeZones 4 | // 5 | // Created by Sergii Kryvoblotskyi on 10/17/13. 6 | // Copyright (c) 2013 Alterplay. All rights reserved. 7 | // 8 | 9 | // Permission is hereby granted, free of charge, to any person obtaining a copy 10 | // of this software and associated documentation files (the "Software"), to deal 11 | // in the Software without restriction, including without limitation the rights 12 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | // copies of the Software, and to permit persons to whom the Software is 14 | // furnished to do so, subject to the following conditions: 15 | // 16 | // The above copyright notice and this permission notice shall be included in 17 | // all copies or substantial portions of the Software. 18 | // 19 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 | // THE SOFTWARE. 26 | 27 | #import 28 | #import 29 | #import "CLLocation+APTimeZones.h" 30 | #import "CLPlacemark+APTimeZones.h" 31 | 32 | @interface APTimeZones : NSObject 33 | 34 | /* 35 | Get timezone with lat/lon and country code 36 | */ 37 | - (NSTimeZone *)timeZoneWithLocation:(CLLocation *)location; 38 | 39 | /* 40 | Get timezone with lat/lon and country code. 41 | Extremely speeds up and more carefull result. 42 | */ 43 | - (NSTimeZone *)timeZoneWithLocation:(CLLocation *)location countryCode:(NSString *)countryCode; 44 | 45 | + (APTimeZones *)sharedInstance; 46 | @end 47 | -------------------------------------------------------------------------------- /JFOpenWeatherMapManager/AFNetworking/AFNetworking.h: -------------------------------------------------------------------------------- 1 | // AFNetworking.h 2 | // 3 | // Copyright (c) 2013 AFNetworking (http://afnetworking.com/) 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | #import 24 | #import 25 | 26 | #ifndef _AFNETWORKING_ 27 | #define _AFNETWORKING_ 28 | 29 | #import "AFURLRequestSerialization.h" 30 | #import "AFURLResponseSerialization.h" 31 | #import "AFSecurityPolicy.h" 32 | #import "AFNetworkReachabilityManager.h" 33 | 34 | #import "AFURLConnectionOperation.h" 35 | #import "AFHTTPRequestOperation.h" 36 | #import "AFHTTPRequestOperationManager.h" 37 | 38 | #if ( ( defined(__MAC_OS_X_VERSION_MAX_ALLOWED) && __MAC_OS_X_VERSION_MAX_ALLOWED >= 1090) || \ 39 | ( defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 70000 ) ) 40 | #import "AFURLSessionManager.h" 41 | #import "AFHTTPSessionManager.h" 42 | #endif 43 | 44 | #endif /* _AFNETWORKING_ */ 45 | -------------------------------------------------------------------------------- /JFOpenWeatherMapManager/WeatherModel/Clouds.m: -------------------------------------------------------------------------------- 1 | // 2 | // Clouds.m 3 | // 4 | // Created by Jonathan Field on 26/10/2013 5 | // Copyright (c) 2013 __MyCompanyName__. All rights reserved. 6 | // 7 | 8 | #import "Clouds.h" 9 | 10 | 11 | NSString *const kCloudsAll = @"all"; 12 | 13 | 14 | @interface Clouds () 15 | 16 | - (id)objectOrNilForKey:(id)aKey fromDictionary:(NSDictionary *)dict; 17 | 18 | @end 19 | 20 | @implementation Clouds 21 | 22 | @synthesize all = _all; 23 | 24 | 25 | + (Clouds *)modelObjectWithDictionary:(NSDictionary *)dict 26 | { 27 | Clouds *instance = [[Clouds alloc] initWithDictionary:dict]; 28 | return instance; 29 | } 30 | 31 | - (instancetype)initWithDictionary:(NSDictionary *)dict 32 | { 33 | self = [super init]; 34 | 35 | // This check serves to make sure that a non-NSDictionary object 36 | // passed into the model class doesn't break the parsing. 37 | if(self && [dict isKindOfClass:[NSDictionary class]]) { 38 | self.all = [[self objectOrNilForKey:kCloudsAll fromDictionary:dict] doubleValue]; 39 | 40 | } 41 | 42 | return self; 43 | 44 | } 45 | 46 | - (NSDictionary *)dictionaryRepresentation 47 | { 48 | NSMutableDictionary *mutableDict = [NSMutableDictionary dictionary]; 49 | [mutableDict setValue:[NSNumber numberWithDouble:self.all] forKey:kCloudsAll]; 50 | 51 | return [NSDictionary dictionaryWithDictionary:mutableDict]; 52 | } 53 | 54 | - (NSString *)description 55 | { 56 | return [NSString stringWithFormat:@"%@", [self dictionaryRepresentation]]; 57 | } 58 | 59 | #pragma mark - Helper Method 60 | - (id)objectOrNilForKey:(id)aKey fromDictionary:(NSDictionary *)dict 61 | { 62 | id object = [dict objectForKey:aKey]; 63 | return [object isEqual:[NSNull null]] ? nil : object; 64 | } 65 | 66 | 67 | #pragma mark - NSCoding Methods 68 | 69 | - (id)initWithCoder:(NSCoder *)aDecoder 70 | { 71 | self = [super init]; 72 | 73 | self.all = [aDecoder decodeDoubleForKey:kCloudsAll]; 74 | return self; 75 | } 76 | 77 | - (void)encodeWithCoder:(NSCoder *)aCoder 78 | { 79 | 80 | [aCoder encodeDouble:_all forKey:kCloudsAll]; 81 | } 82 | 83 | 84 | @end 85 | -------------------------------------------------------------------------------- /JFOpenWeatherMapManager/WeatherModel/Rain.m: -------------------------------------------------------------------------------- 1 | // 2 | // JFRain.m 3 | // 4 | // Created by Jonathan Field on 27/10/2013 5 | // Copyright (c) 2013 __MyCompanyName__. All rights reserved. 6 | // 7 | 8 | #import "Rain.h" 9 | 10 | 11 | NSString *const kRain3h = @"3h"; 12 | 13 | 14 | @interface Rain () 15 | 16 | - (id)objectOrNilForKey:(id)aKey fromDictionary:(NSDictionary *)dict; 17 | 18 | @end 19 | 20 | @implementation Rain 21 | 22 | @synthesize threeHour = _threeHour; 23 | 24 | 25 | + (Rain *)modelObjectWithDictionary:(NSDictionary *)dict 26 | { 27 | Rain *instance = [[Rain alloc] initWithDictionary:dict]; 28 | return instance; 29 | } 30 | 31 | - (instancetype)initWithDictionary:(NSDictionary *)dict 32 | { 33 | self = [super init]; 34 | 35 | // This check serves to make sure that a non-NSDictionary object 36 | // passed into the model class doesn't break the parsing. 37 | if(self && [dict isKindOfClass:[NSDictionary class]]) { 38 | self.threeHour = [[self objectOrNilForKey:kRain3h fromDictionary:dict] doubleValue]; 39 | 40 | } 41 | 42 | return self; 43 | 44 | } 45 | 46 | - (NSDictionary *)dictionaryRepresentation 47 | { 48 | NSMutableDictionary *mutableDict = [NSMutableDictionary dictionary]; 49 | [mutableDict setValue:[NSNumber numberWithDouble:self.threeHour] forKey:kRain3h]; 50 | 51 | return [NSDictionary dictionaryWithDictionary:mutableDict]; 52 | } 53 | 54 | - (NSString *)description 55 | { 56 | return [NSString stringWithFormat:@"%@", [self dictionaryRepresentation]]; 57 | } 58 | 59 | #pragma mark - Helper Method 60 | - (id)objectOrNilForKey:(id)aKey fromDictionary:(NSDictionary *)dict 61 | { 62 | id object = [dict objectForKey:aKey]; 63 | return [object isEqual:[NSNull null]] ? nil : object; 64 | } 65 | 66 | 67 | #pragma mark - NSCoding Methods 68 | 69 | - (id)initWithCoder:(NSCoder *)aDecoder 70 | { 71 | self = [super init]; 72 | 73 | self.threeHour = [aDecoder decodeDoubleForKey:kRain3h]; 74 | return self; 75 | } 76 | 77 | - (void)encodeWithCoder:(NSCoder *)aCoder 78 | { 79 | 80 | [aCoder encodeDouble:_threeHour forKey:kRain3h]; 81 | } 82 | 83 | 84 | @end 85 | -------------------------------------------------------------------------------- /JFOpenWeatherMapManager/WeatherModel/Snow.m: -------------------------------------------------------------------------------- 1 | // 2 | // Snow.m 3 | // 4 | // Created by Jonathan Field on 31/10/2013 5 | // Copyright (c) 2013 __MyCompanyName__. All rights reserved. 6 | // 7 | 8 | #import "Snow.h" 9 | 10 | 11 | NSString *const kSnow3h = @"3h"; 12 | 13 | 14 | @interface Snow () 15 | 16 | - (id)objectOrNilForKey:(id)aKey fromDictionary:(NSDictionary *)dict; 17 | 18 | @end 19 | 20 | @implementation Snow 21 | 22 | @synthesize threeHour = _threeHour; 23 | 24 | 25 | + (Snow *)modelObjectWithDictionary:(NSDictionary *)dict 26 | { 27 | Snow *instance = [[Snow alloc] initWithDictionary:dict]; 28 | return instance; 29 | } 30 | 31 | - (instancetype)initWithDictionary:(NSDictionary *)dict 32 | { 33 | self = [super init]; 34 | 35 | // This check serves to make sure that a non-NSDictionary object 36 | // passed into the model class doesn't break the parsing. 37 | if(self && [dict isKindOfClass:[NSDictionary class]]) { 38 | self.threeHour = [[self objectOrNilForKey:kSnow3h fromDictionary:dict] doubleValue]; 39 | 40 | } 41 | 42 | return self; 43 | 44 | } 45 | 46 | - (NSDictionary *)dictionaryRepresentation 47 | { 48 | NSMutableDictionary *mutableDict = [NSMutableDictionary dictionary]; 49 | [mutableDict setValue:[NSNumber numberWithDouble:self.threeHour] forKey:kSnow3h]; 50 | 51 | return [NSDictionary dictionaryWithDictionary:mutableDict]; 52 | } 53 | 54 | - (NSString *)description 55 | { 56 | return [NSString stringWithFormat:@"%@", [self dictionaryRepresentation]]; 57 | } 58 | 59 | #pragma mark - Helper Method 60 | - (id)objectOrNilForKey:(id)aKey fromDictionary:(NSDictionary *)dict 61 | { 62 | id object = [dict objectForKey:aKey]; 63 | return [object isEqual:[NSNull null]] ? nil : object; 64 | } 65 | 66 | 67 | #pragma mark - NSCoding Methods 68 | 69 | - (id)initWithCoder:(NSCoder *)aDecoder 70 | { 71 | self = [super init]; 72 | 73 | self.threeHour = [aDecoder decodeDoubleForKey:kSnow3h]; 74 | return self; 75 | } 76 | 77 | - (void)encodeWithCoder:(NSCoder *)aCoder 78 | { 79 | 80 | [aCoder encodeDouble:_threeHour forKey:kSnow3h]; 81 | } 82 | 83 | 84 | @end 85 | -------------------------------------------------------------------------------- /JFOpenWeatherMapManager/JFAppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // JFAppDelegate.m 3 | // JFOpenWeatherMapManager 4 | // 5 | // Created by Jonathan Field on 27/10/2013. 6 | // Copyright (c) 2013 Jonathan Field. All rights reserved. 7 | // 8 | 9 | #import "JFAppDelegate.h" 10 | 11 | @implementation JFAppDelegate 12 | 13 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 14 | { 15 | // Override point for customization after application launch. 16 | return YES; 17 | } 18 | 19 | - (void)applicationWillResignActive:(UIApplication *)application 20 | { 21 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 22 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. 23 | } 24 | 25 | - (void)applicationDidEnterBackground:(UIApplication *)application 26 | { 27 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 28 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 29 | } 30 | 31 | - (void)applicationWillEnterForeground:(UIApplication *)application 32 | { 33 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. 34 | } 35 | 36 | - (void)applicationDidBecomeActive:(UIApplication *)application 37 | { 38 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 39 | } 40 | 41 | - (void)applicationWillTerminate:(UIApplication *)application 42 | { 43 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 44 | } 45 | 46 | @end 47 | -------------------------------------------------------------------------------- /JFOpenWeatherMapManager/JFWeatherManager.m: -------------------------------------------------------------------------------- 1 | // 2 | // JFWeatherManager.m 3 | // JFOpenWeatherMapManager 4 | // 5 | // Created by Jonathan Field on 27/10/2013. 6 | // Copyright (c) 2013 Jonathan Field. All rights reserved. 7 | // 8 | 9 | #import "JFWeatherManager.h" 10 | 11 | @implementation JFWeatherManager 12 | 13 | static NSString *BASE_URL = @"http://api.openweathermap.org/data/2.5/weather"; 14 | static NSString *SERVER_SIDE_ERROR = @"Request failed: server error (512)"; 15 | 16 | 17 | - (void)fetchWeatherDataForLatitude:(double)latitude andLongitude:(double)longitude withAPIKeyOrNil:(NSString *)apiKey :(void (^)(JFWeatherData *))completionBlock{ 18 | 19 | NSURL *destinationUrl; 20 | if (apiKey == nil || [apiKey isEqualToString:@"YOUR_API_KEY_HERE"]) { 21 | destinationUrl = [NSURL URLWithString:[NSString stringWithFormat:@"%@?lat=%f&lon=%f",BASE_URL,latitude,longitude]]; 22 | } 23 | else{ 24 | destinationUrl = [NSURL URLWithString:[NSString stringWithFormat:@"%@?lat=%f&lon=%f&APPID=%@",BASE_URL,latitude,longitude,apiKey]]; 25 | } 26 | 27 | NSLog(@"Calling Weather API on %@",destinationUrl); 28 | NSURLRequest *request = [NSURLRequest requestWithURL:destinationUrl]; 29 | 30 | AFHTTPRequestOperation *op = [[AFHTTPRequestOperation alloc] initWithRequest:request]; 31 | op.responseSerializer = [AFJSONResponseSerializer serializer]; 32 | [op setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) { 33 | 34 | completionBlock([JFWeatherData modelObjectWithDictionary:responseObject]); 35 | 36 | } failure:^(AFHTTPRequestOperation *operation, NSError *error) { 37 | 38 | NSLog(@"Error: %@", error); 39 | NSLog(@"Error: %ld", (long)error.code); 40 | 41 | if ([[error localizedDescription]isEqualToString:SERVER_SIDE_ERROR]) { 42 | [[[UIAlertView alloc]initWithTitle:@"Server Error" message:@"There was an server side issue with OpenWeatherMap API, consider signing up for an API Key or if you have one please try again" delegate:nil cancelButtonTitle:@"Okay" otherButtonTitles:nil]show]; 43 | } 44 | 45 | }]; 46 | [[NSOperationQueue mainQueue] addOperation:op]; 47 | 48 | } 49 | 50 | 51 | 52 | @end 53 | -------------------------------------------------------------------------------- /JFOpenWeatherMapManager/WeatherModel/Coord.m: -------------------------------------------------------------------------------- 1 | // 2 | // Coord.m 3 | // 4 | // Created by Jonathan Field on 26/10/2013 5 | // Copyright (c) 2013 __MyCompanyName__. All rights reserved. 6 | // 7 | 8 | #import "Coord.h" 9 | 10 | 11 | NSString *const kCoordLon = @"lon"; 12 | NSString *const kCoordLat = @"lat"; 13 | 14 | 15 | @interface Coord () 16 | 17 | - (id)objectOrNilForKey:(id)aKey fromDictionary:(NSDictionary *)dict; 18 | 19 | @end 20 | 21 | @implementation Coord 22 | 23 | @synthesize lon = _lon; 24 | @synthesize lat = _lat; 25 | 26 | 27 | + (Coord *)modelObjectWithDictionary:(NSDictionary *)dict 28 | { 29 | Coord *instance = [[Coord alloc] initWithDictionary:dict]; 30 | return instance; 31 | } 32 | 33 | - (instancetype)initWithDictionary:(NSDictionary *)dict 34 | { 35 | self = [super init]; 36 | 37 | // This check serves to make sure that a non-NSDictionary object 38 | // passed into the model class doesn't break the parsing. 39 | if(self && [dict isKindOfClass:[NSDictionary class]]) { 40 | self.lon = [[self objectOrNilForKey:kCoordLon fromDictionary:dict] doubleValue]; 41 | self.lat = [[self objectOrNilForKey:kCoordLat fromDictionary:dict] doubleValue]; 42 | 43 | } 44 | 45 | return self; 46 | 47 | } 48 | 49 | - (NSDictionary *)dictionaryRepresentation 50 | { 51 | NSMutableDictionary *mutableDict = [NSMutableDictionary dictionary]; 52 | [mutableDict setValue:[NSNumber numberWithDouble:self.lon] forKey:kCoordLon]; 53 | [mutableDict setValue:[NSNumber numberWithDouble:self.lat] forKey:kCoordLat]; 54 | 55 | return [NSDictionary dictionaryWithDictionary:mutableDict]; 56 | } 57 | 58 | - (NSString *)description 59 | { 60 | return [NSString stringWithFormat:@"%@", [self dictionaryRepresentation]]; 61 | } 62 | 63 | #pragma mark - Helper Method 64 | - (id)objectOrNilForKey:(id)aKey fromDictionary:(NSDictionary *)dict 65 | { 66 | id object = [dict objectForKey:aKey]; 67 | return [object isEqual:[NSNull null]] ? nil : object; 68 | } 69 | 70 | 71 | #pragma mark - NSCoding Methods 72 | 73 | - (id)initWithCoder:(NSCoder *)aDecoder 74 | { 75 | self = [super init]; 76 | 77 | self.lon = [aDecoder decodeDoubleForKey:kCoordLon]; 78 | self.lat = [aDecoder decodeDoubleForKey:kCoordLat]; 79 | return self; 80 | } 81 | 82 | - (void)encodeWithCoder:(NSCoder *)aCoder 83 | { 84 | 85 | [aCoder encodeDouble:_lon forKey:kCoordLon]; 86 | [aCoder encodeDouble:_lat forKey:kCoordLat]; 87 | } 88 | 89 | 90 | @end 91 | -------------------------------------------------------------------------------- /JFOpenWeatherMapManager/WeatherModel/Wind.m: -------------------------------------------------------------------------------- 1 | // 2 | // Wind.m 3 | // 4 | // Created by Jonathan Field on 26/10/2013 5 | // Copyright (c) 2013 __MyCompanyName__. All rights reserved. 6 | // 7 | 8 | #import "Wind.h" 9 | 10 | 11 | NSString *const kWindSpeed = @"speed"; 12 | NSString *const kWindDeg = @"deg"; 13 | 14 | 15 | @interface Wind () 16 | 17 | - (id)objectOrNilForKey:(id)aKey fromDictionary:(NSDictionary *)dict; 18 | 19 | @end 20 | 21 | @implementation Wind 22 | 23 | @synthesize speed = _speed; 24 | @synthesize deg = _deg; 25 | 26 | 27 | + (Wind *)modelObjectWithDictionary:(NSDictionary *)dict 28 | { 29 | Wind *instance = [[Wind alloc] initWithDictionary:dict]; 30 | return instance; 31 | } 32 | 33 | - (instancetype)initWithDictionary:(NSDictionary *)dict 34 | { 35 | self = [super init]; 36 | 37 | // This check serves to make sure that a non-NSDictionary object 38 | // passed into the model class doesn't break the parsing. 39 | if(self && [dict isKindOfClass:[NSDictionary class]]) { 40 | self.speed = [[self objectOrNilForKey:kWindSpeed fromDictionary:dict] doubleValue]; 41 | self.deg = [[self objectOrNilForKey:kWindDeg fromDictionary:dict] doubleValue]; 42 | 43 | } 44 | 45 | return self; 46 | 47 | } 48 | 49 | - (NSDictionary *)dictionaryRepresentation 50 | { 51 | NSMutableDictionary *mutableDict = [NSMutableDictionary dictionary]; 52 | [mutableDict setValue:[NSNumber numberWithDouble:self.speed] forKey:kWindSpeed]; 53 | [mutableDict setValue:[NSNumber numberWithDouble:self.deg] forKey:kWindDeg]; 54 | 55 | return [NSDictionary dictionaryWithDictionary:mutableDict]; 56 | } 57 | 58 | - (NSString *)description 59 | { 60 | return [NSString stringWithFormat:@"%@", [self dictionaryRepresentation]]; 61 | } 62 | 63 | #pragma mark - Helper Method 64 | - (id)objectOrNilForKey:(id)aKey fromDictionary:(NSDictionary *)dict 65 | { 66 | id object = [dict objectForKey:aKey]; 67 | return [object isEqual:[NSNull null]] ? nil : object; 68 | } 69 | 70 | 71 | #pragma mark - NSCoding Methods 72 | 73 | - (id)initWithCoder:(NSCoder *)aDecoder 74 | { 75 | self = [super init]; 76 | 77 | self.speed = [aDecoder decodeDoubleForKey:kWindSpeed]; 78 | self.deg = [aDecoder decodeDoubleForKey:kWindDeg]; 79 | return self; 80 | } 81 | 82 | - (void)encodeWithCoder:(NSCoder *)aCoder 83 | { 84 | 85 | [aCoder encodeDouble:_speed forKey:kWindSpeed]; 86 | [aCoder encodeDouble:_deg forKey:kWindDeg]; 87 | } 88 | 89 | 90 | @end 91 | -------------------------------------------------------------------------------- /JFOpenWeatherMapManager/WeatherModel/Sys.m: -------------------------------------------------------------------------------- 1 | // 2 | // Sys.m 3 | // 4 | // Created by Jonathan Field on 26/10/2013 5 | // Copyright (c) 2013 __MyCompanyName__. All rights reserved. 6 | // 7 | 8 | #import "Sys.h" 9 | 10 | 11 | NSString *const kSysCountry = @"country"; 12 | NSString *const kSysSunrise = @"sunrise"; 13 | NSString *const kSysSunset = @"sunset"; 14 | 15 | 16 | @interface Sys () 17 | 18 | - (id)objectOrNilForKey:(id)aKey fromDictionary:(NSDictionary *)dict; 19 | 20 | @end 21 | 22 | @implementation Sys 23 | 24 | @synthesize country = _country; 25 | @synthesize sunrise = _sunrise; 26 | @synthesize sunset = _sunset; 27 | 28 | 29 | + (Sys *)modelObjectWithDictionary:(NSDictionary *)dict 30 | { 31 | Sys *instance = [[Sys alloc] initWithDictionary:dict]; 32 | return instance; 33 | } 34 | 35 | - (instancetype)initWithDictionary:(NSDictionary *)dict 36 | { 37 | self = [super init]; 38 | 39 | // This check serves to make sure that a non-NSDictionary object 40 | // passed into the model class doesn't break the parsing. 41 | if(self && [dict isKindOfClass:[NSDictionary class]]) { 42 | self.country = [self objectOrNilForKey:kSysCountry fromDictionary:dict]; 43 | self.sunrise = [[self objectOrNilForKey:kSysSunrise fromDictionary:dict] doubleValue]; 44 | self.sunset = [[self objectOrNilForKey:kSysSunset fromDictionary:dict] doubleValue]; 45 | 46 | } 47 | 48 | return self; 49 | 50 | } 51 | 52 | - (NSDictionary *)dictionaryRepresentation 53 | { 54 | NSMutableDictionary *mutableDict = [NSMutableDictionary dictionary]; 55 | [mutableDict setValue:self.country forKey:kSysCountry]; 56 | [mutableDict setValue:[NSNumber numberWithDouble:self.sunrise] forKey:kSysSunrise]; 57 | [mutableDict setValue:[NSNumber numberWithDouble:self.sunset] forKey:kSysSunset]; 58 | 59 | return [NSDictionary dictionaryWithDictionary:mutableDict]; 60 | } 61 | 62 | - (NSString *)description 63 | { 64 | return [NSString stringWithFormat:@"%@", [self dictionaryRepresentation]]; 65 | } 66 | 67 | #pragma mark - Helper Method 68 | - (id)objectOrNilForKey:(id)aKey fromDictionary:(NSDictionary *)dict 69 | { 70 | id object = [dict objectForKey:aKey]; 71 | return [object isEqual:[NSNull null]] ? nil : object; 72 | } 73 | 74 | 75 | #pragma mark - NSCoding Methods 76 | 77 | - (id)initWithCoder:(NSCoder *)aDecoder 78 | { 79 | self = [super init]; 80 | 81 | self.country = [aDecoder decodeObjectForKey:kSysCountry]; 82 | self.sunrise = [aDecoder decodeDoubleForKey:kSysSunrise]; 83 | self.sunset = [aDecoder decodeDoubleForKey:kSysSunset]; 84 | return self; 85 | } 86 | 87 | - (void)encodeWithCoder:(NSCoder *)aCoder 88 | { 89 | 90 | [aCoder encodeObject:_country forKey:kSysCountry]; 91 | [aCoder encodeDouble:_sunrise forKey:kSysSunrise]; 92 | [aCoder encodeDouble:_sunset forKey:kSysSunset]; 93 | } 94 | 95 | 96 | @end 97 | -------------------------------------------------------------------------------- /JFOpenWeatherMapManager/JFWeatherData.h: -------------------------------------------------------------------------------- 1 | // 2 | // JFWeatherData.h 3 | // 4 | // Created by Jonathan Field on 27/10/2013 5 | // Copyright (c) 2013 __MyCompanyName__. All rights reserved. 6 | // http://jonathanfield.me 7 | // https://github.com/jfield44/JFOpenWeatherMapManager 8 | 9 | #import 10 | #import "Main.h" 11 | #import "Wind.h" 12 | #import "Coord.h" 13 | #import "Sys.h" 14 | #import "Weather.h" 15 | #import "Clouds.h" 16 | #import "Rain.h" 17 | #import "Snow.h" 18 | #import "APTimeZones.h" 19 | 20 | @class Main, Wind, Coord, Sys, Clouds, Rain, Snow; 21 | 22 | typedef enum temperatureUnits {kTemperatureKelvin, kTemperatureCelcius, kTemperatureFarenheit} TemperatureUnit; 23 | typedef enum pressureUnits {kPressureHectopascal, kPressurePascal} PressureUnit; 24 | typedef enum windSpeedUnits {kWindSpeedMPS, kWindSpeedMPH, kWindSpeedKPH} WindSpeedUnit; 25 | 26 | @interface JFWeatherData : NSObject 27 | 28 | @property (nonatomic, strong) NSString *base; 29 | @property (nonatomic, assign) double internalBaseClassIdentifier; 30 | @property (nonatomic, assign) double dt; 31 | @property (nonatomic, strong) Main *main; 32 | @property (nonatomic, strong) Wind *wind; 33 | @property (nonatomic, strong) Coord *coord; 34 | @property (nonatomic, strong) Sys *sys; 35 | @property (nonatomic, strong) NSArray *weather; 36 | @property (nonatomic, strong) Clouds *clouds; 37 | @property (nonatomic, assign) double cod; 38 | @property (nonatomic, strong) NSString *name; 39 | @property (nonatomic, strong) Rain *rain; 40 | @property (nonatomic, strong) Snow *snow; 41 | 42 | + (JFWeatherData *)modelObjectWithDictionary:(NSDictionary *)dict; //Create object from API Dictionary Response 43 | - (instancetype)initWithDictionary:(NSDictionary *)dict; //** 44 | - (NSDictionary *)dictionaryRepresentation; 45 | 46 | - (NSString *)currentConditionsTextualDescription; //E.g. Broken Clouds 47 | - (double)temperatureInUnitFormat:(TemperatureUnit)temperatureUnit; //Temperature with format specified as param 48 | - (double)pressureInUnitFormat:(PressureUnit)pressureUnit; //Pressure with format specificed as param 49 | - (NSString *)sunriseTime; //Time of SunRise (GMT only at the moment) 50 | - (NSString *)sunsetTime; //Time of SunSet (GMT only at the moment) 51 | - (NSString *)dayLightHours; //Hours and minutes of Daylight HH:mm 52 | - (NSString *)humidityPercentage; //Humidty as a percentage 53 | - (NSString *)cloudCovergePercentage; //Cloud coverage as a percentage 54 | - (double)windSpeedInUnitFormat:(WindSpeedUnit)windSpeedUnit; //Wind Speed with format specified as param 55 | - (double)windDirectionInDegrees; //Wind Direction in degrees 56 | - (NSString *)windDirectionInGeographicalDirection; //Wind Direction as N/NE/E/SE 57 | - (double)rainFallVolumeOver3HoursInMillimeters; //Amount of Rain Precipitation over next 3 hours in mm 58 | - (double)snowFallVolumeOver3HoursInMillimeters; //Amount of Snow Precipitation over next 3 hours in mm 59 | - (double)latitudeCoordinateOfRequest; //Latitude of Request 60 | - (double)longitudeCoordinateOfRequest; //Longitude of Request 61 | - (NSString *)countryCode; // E.g. GB / US / DE 62 | 63 | @end 64 | -------------------------------------------------------------------------------- /JFOpenWeatherMapManager/WeatherModel/Weather.m: -------------------------------------------------------------------------------- 1 | // 2 | // Weather.m 3 | // 4 | // Created by Jonathan Field on 26/10/2013 5 | // Copyright (c) 2013 __MyCompanyName__. All rights reserved. 6 | // 7 | 8 | #import "Weather.h" 9 | 10 | 11 | NSString *const kWeatherId = @"id"; 12 | NSString *const kWeatherMain = @"main"; 13 | NSString *const kWeatherIcon = @"icon"; 14 | NSString *const kWeatherDescription = @"description"; 15 | 16 | 17 | @interface Weather () 18 | 19 | - (id)objectOrNilForKey:(id)aKey fromDictionary:(NSDictionary *)dict; 20 | 21 | @end 22 | 23 | @implementation Weather 24 | 25 | @synthesize weatherIdentifier = _weatherIdentifier; 26 | @synthesize main = _main; 27 | @synthesize icon = _icon; 28 | @synthesize weatherDescription = _weatherDescription; 29 | 30 | 31 | + (Weather *)modelObjectWithDictionary:(NSDictionary *)dict 32 | { 33 | Weather *instance = [[Weather alloc] initWithDictionary:dict]; 34 | return instance; 35 | } 36 | 37 | - (instancetype)initWithDictionary:(NSDictionary *)dict 38 | { 39 | self = [super init]; 40 | 41 | // This check serves to make sure that a non-NSDictionary object 42 | // passed into the model class doesn't break the parsing. 43 | if(self && [dict isKindOfClass:[NSDictionary class]]) { 44 | self.weatherIdentifier = [[self objectOrNilForKey:kWeatherId fromDictionary:dict] doubleValue]; 45 | self.main = [self objectOrNilForKey:kWeatherMain fromDictionary:dict]; 46 | self.icon = [self objectOrNilForKey:kWeatherIcon fromDictionary:dict]; 47 | self.weatherDescription = [self objectOrNilForKey:kWeatherDescription fromDictionary:dict]; 48 | 49 | } 50 | 51 | return self; 52 | 53 | } 54 | 55 | - (NSDictionary *)dictionaryRepresentation 56 | { 57 | NSMutableDictionary *mutableDict = [NSMutableDictionary dictionary]; 58 | [mutableDict setValue:[NSNumber numberWithDouble:self.weatherIdentifier] forKey:kWeatherId]; 59 | [mutableDict setValue:self.main forKey:kWeatherMain]; 60 | [mutableDict setValue:self.icon forKey:kWeatherIcon]; 61 | [mutableDict setValue:self.weatherDescription forKey:kWeatherDescription]; 62 | 63 | return [NSDictionary dictionaryWithDictionary:mutableDict]; 64 | } 65 | 66 | - (NSString *)description 67 | { 68 | return [NSString stringWithFormat:@"%@", [self dictionaryRepresentation]]; 69 | } 70 | 71 | #pragma mark - Helper Method 72 | - (id)objectOrNilForKey:(id)aKey fromDictionary:(NSDictionary *)dict 73 | { 74 | id object = [dict objectForKey:aKey]; 75 | return [object isEqual:[NSNull null]] ? nil : object; 76 | } 77 | 78 | 79 | #pragma mark - NSCoding Methods 80 | 81 | - (id)initWithCoder:(NSCoder *)aDecoder 82 | { 83 | self = [super init]; 84 | 85 | self.weatherIdentifier = [aDecoder decodeDoubleForKey:kWeatherId]; 86 | self.main = [aDecoder decodeObjectForKey:kWeatherMain]; 87 | self.icon = [aDecoder decodeObjectForKey:kWeatherIcon]; 88 | self.weatherDescription = [aDecoder decodeObjectForKey:kWeatherDescription]; 89 | return self; 90 | } 91 | 92 | - (void)encodeWithCoder:(NSCoder *)aCoder 93 | { 94 | 95 | [aCoder encodeDouble:_weatherIdentifier forKey:kWeatherId]; 96 | [aCoder encodeObject:_main forKey:kWeatherMain]; 97 | [aCoder encodeObject:_icon forKey:kWeatherIcon]; 98 | [aCoder encodeObject:_weatherDescription forKey:kWeatherDescription]; 99 | } 100 | 101 | 102 | @end 103 | -------------------------------------------------------------------------------- /JFOpenWeatherMapManager/WeatherModel/Main.m: -------------------------------------------------------------------------------- 1 | // 2 | // Main.m 3 | // 4 | // Created by Jonathan Field on 26/10/2013 5 | // Copyright (c) 2013 __MyCompanyName__. All rights reserved. 6 | // 7 | 8 | #import "Main.h" 9 | 10 | 11 | NSString *const kMainHumidity = @"humidity"; 12 | NSString *const kMainTempMax = @"temp_max"; 13 | NSString *const kMainTempMin = @"temp_min"; 14 | NSString *const kMainTemp = @"temp"; 15 | NSString *const kMainPressure = @"pressure"; 16 | 17 | 18 | @interface Main () 19 | 20 | - (id)objectOrNilForKey:(id)aKey fromDictionary:(NSDictionary *)dict; 21 | 22 | @end 23 | 24 | @implementation Main 25 | 26 | @synthesize humidity = _humidity; 27 | @synthesize tempMax = _tempMax; 28 | @synthesize tempMin = _tempMin; 29 | @synthesize temp = _temp; 30 | @synthesize pressure = _pressure; 31 | 32 | 33 | + (Main *)modelObjectWithDictionary:(NSDictionary *)dict 34 | { 35 | Main *instance = [[Main alloc] initWithDictionary:dict]; 36 | return instance; 37 | } 38 | 39 | - (instancetype)initWithDictionary:(NSDictionary *)dict 40 | { 41 | self = [super init]; 42 | 43 | // This check serves to make sure that a non-NSDictionary object 44 | // passed into the model class doesn't break the parsing. 45 | if(self && [dict isKindOfClass:[NSDictionary class]]) { 46 | self.humidity = [[self objectOrNilForKey:kMainHumidity fromDictionary:dict] doubleValue]; 47 | self.tempMax = [[self objectOrNilForKey:kMainTempMax fromDictionary:dict] doubleValue]; 48 | self.tempMin = [[self objectOrNilForKey:kMainTempMin fromDictionary:dict] doubleValue]; 49 | self.temp = [[self objectOrNilForKey:kMainTemp fromDictionary:dict] doubleValue]; 50 | self.pressure = [[self objectOrNilForKey:kMainPressure fromDictionary:dict] doubleValue]; 51 | 52 | } 53 | 54 | return self; 55 | 56 | } 57 | 58 | - (NSDictionary *)dictionaryRepresentation 59 | { 60 | NSMutableDictionary *mutableDict = [NSMutableDictionary dictionary]; 61 | [mutableDict setValue:[NSNumber numberWithDouble:self.humidity] forKey:kMainHumidity]; 62 | [mutableDict setValue:[NSNumber numberWithDouble:self.tempMax] forKey:kMainTempMax]; 63 | [mutableDict setValue:[NSNumber numberWithDouble:self.tempMin] forKey:kMainTempMin]; 64 | [mutableDict setValue:[NSNumber numberWithDouble:self.temp] forKey:kMainTemp]; 65 | [mutableDict setValue:[NSNumber numberWithDouble:self.pressure] forKey:kMainPressure]; 66 | 67 | return [NSDictionary dictionaryWithDictionary:mutableDict]; 68 | } 69 | 70 | - (NSString *)description 71 | { 72 | return [NSString stringWithFormat:@"%@", [self dictionaryRepresentation]]; 73 | } 74 | 75 | #pragma mark - Helper Method 76 | - (id)objectOrNilForKey:(id)aKey fromDictionary:(NSDictionary *)dict 77 | { 78 | id object = [dict objectForKey:aKey]; 79 | return [object isEqual:[NSNull null]] ? nil : object; 80 | } 81 | 82 | 83 | #pragma mark - NSCoding Methods 84 | 85 | - (id)initWithCoder:(NSCoder *)aDecoder 86 | { 87 | self = [super init]; 88 | 89 | self.humidity = [aDecoder decodeDoubleForKey:kMainHumidity]; 90 | self.tempMax = [aDecoder decodeDoubleForKey:kMainTempMax]; 91 | self.tempMin = [aDecoder decodeDoubleForKey:kMainTempMin]; 92 | self.temp = [aDecoder decodeDoubleForKey:kMainTemp]; 93 | self.pressure = [aDecoder decodeDoubleForKey:kMainPressure]; 94 | return self; 95 | } 96 | 97 | - (void)encodeWithCoder:(NSCoder *)aCoder 98 | { 99 | 100 | [aCoder encodeDouble:_humidity forKey:kMainHumidity]; 101 | [aCoder encodeDouble:_tempMax forKey:kMainTempMax]; 102 | [aCoder encodeDouble:_tempMin forKey:kMainTempMin]; 103 | [aCoder encodeDouble:_temp forKey:kMainTemp]; 104 | [aCoder encodeDouble:_pressure forKey:kMainPressure]; 105 | } 106 | 107 | 108 | @end 109 | -------------------------------------------------------------------------------- /JFOpenWeatherMapManager.xcodeproj/xcuserdata/Jon.xcuserdatad/xcschemes/JFOpenWeatherMapManager.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 33 | 39 | 40 | 41 | 42 | 43 | 49 | 50 | 51 | 52 | 61 | 62 | 68 | 69 | 70 | 71 | 72 | 73 | 79 | 80 | 86 | 87 | 88 | 89 | 91 | 92 | 95 | 96 | 97 | -------------------------------------------------------------------------------- /JFOpenWeatherMapManager.xcodeproj/xcuserdata/Jonathan.xcuserdatad/xcschemes/JFOpenWeatherMapManager.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 33 | 39 | 40 | 41 | 42 | 43 | 49 | 50 | 51 | 52 | 61 | 62 | 68 | 69 | 70 | 71 | 72 | 73 | 79 | 80 | 86 | 87 | 88 | 89 | 91 | 92 | 95 | 96 | 97 | -------------------------------------------------------------------------------- /JFOpenWeatherMapManager/AFNetworking/AFSecurityPolicy.h: -------------------------------------------------------------------------------- 1 | // AFSecurity.h 2 | // 3 | // Copyright (c) 2013 AFNetworking (http://afnetworking.com) 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | #import 24 | #import 25 | 26 | typedef NS_ENUM(NSUInteger, AFSSLPinningMode) { 27 | AFSSLPinningModeNone, 28 | AFSSLPinningModePublicKey, 29 | AFSSLPinningModeCertificate, 30 | }; 31 | 32 | /** 33 | `AFSecurityPolicy` evaluates server trust against pinned X.509 certificates and public keys over secure connections. 34 | 35 | Adding pinned SSL certificates to your app helps prevent man-in-the-middle attacks and other vulnerabilities. Applications dealing with sensitive customer data or financial information are strongly encouraged to route all communication over an HTTPS connection with SSL pinning configured and enabled. 36 | */ 37 | @interface AFSecurityPolicy : NSObject 38 | 39 | /** 40 | The criteria by which server trust should be evaluated against the pinned SSL certificates. Defaults to `AFSSLPinningModeNone`. 41 | */ 42 | @property (nonatomic, assign) AFSSLPinningMode SSLPinningMode; 43 | 44 | /** 45 | The certificates used to evaluate server trust according to the SSL pinning mode. By default, this property is set to any (`.cer`) certificates included in the app bundle. 46 | */ 47 | @property (nonatomic, strong) NSArray *pinnedCertificates; 48 | 49 | /** 50 | Whether or not to trust servers with an invalid or expired SSL certificates. Defaults to `NO`. 51 | */ 52 | @property (nonatomic, assign) BOOL allowInvalidCertificates; 53 | 54 | ///----------------------------------------- 55 | /// @name Getting Specific Security Policies 56 | ///----------------------------------------- 57 | 58 | /** 59 | Returns the shared default security policy, which does not accept invalid certificates, and does not validate against pinned certificates or public keys. 60 | 61 | @return The default security policy. 62 | */ 63 | + (instancetype)defaultPolicy; 64 | 65 | ///--------------------- 66 | /// @name Initialization 67 | ///--------------------- 68 | 69 | /** 70 | Creates and returns a security policy with the specified pinning mode. 71 | 72 | @param pinningMode The SSL pinning mode. 73 | 74 | @return A new security policy. 75 | */ 76 | + (instancetype)policyWithPinningMode:(AFSSLPinningMode)pinningMode; 77 | 78 | ///------------------------------ 79 | /// @name Evaluating Server Trust 80 | ///------------------------------ 81 | 82 | /** 83 | Whether or not the specified server trust should be accepted, based on the security policy. 84 | 85 | This method should be used when responding to an authentication challenge from a server. 86 | 87 | @param serverTrust The X.509 certificate trust of the server. 88 | 89 | @return Whether or not to trust the server. 90 | */ 91 | - (BOOL)evaluateServerTrust:(SecTrustRef)serverTrust; 92 | 93 | @end 94 | 95 | ///---------------- 96 | /// @name Constants 97 | ///---------------- 98 | 99 | /** 100 | ## SSL Pinning Modes 101 | 102 | The following constants are provided by `AFSSLPinningMode` as possible SSL pinning modes. 103 | 104 | enum { 105 | AFSSLPinningModeNone, 106 | AFSSLPinningModePublicKey, 107 | AFSSLPinningModeCertificate, 108 | } 109 | 110 | `AFSSLPinningModeNone` 111 | Do not validate servers against pinned certificates. 112 | 113 | `AFSSLPinningModePublicKey` 114 | Validate host certificates against public keys of pinned certificates. 115 | 116 | `AFSSLPinningModeCertificate` 117 | Validate host certificates against pinned certificates. 118 | */ 119 | -------------------------------------------------------------------------------- /JFOpenWeatherMapManager/AFNetworking/AFHTTPRequestOperation.h: -------------------------------------------------------------------------------- 1 | // AFHTTPRequestOperation.h 2 | // 3 | // Copyright (c) 2013 AFNetworking (http://afnetworking.com) 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | #import 24 | #import "AFURLConnectionOperation.h" 25 | #import "AFURLResponseSerialization.h" 26 | 27 | /** 28 | `AFHTTPRequestOperation` is a subclass of `AFURLConnectionOperation` for requests using the HTTP or HTTPS protocols. It encapsulates the concept of acceptable status codes and content types, which determine the success or failure of a request. 29 | */ 30 | @interface AFHTTPRequestOperation : AFURLConnectionOperation 31 | 32 | ///------------------------------------------------ 33 | /// @name Getting HTTP URL Connection Information 34 | ///------------------------------------------------ 35 | 36 | /** 37 | The last HTTP response received by the operation's connection. 38 | */ 39 | @property (readonly, nonatomic, strong) NSHTTPURLResponse *response; 40 | 41 | /** 42 | Responses sent from the server in data tasks created with `dataTaskWithRequest:success:failure:` and run using the `GET` / `POST` / et al. convenience methods are automatically validated and serialized by the response serializer. By default, this property is set to an AFHTTPResoinse serializer, which uses the raw data as its response object. The serializer validates the status code to be in the `2XX` range, denoting success. If the response serializer generates an error in `-responseObjectForResponse:data:error:`, the `failure` callback of the session task or request operation will be executed; otherwise, the `success` callback will be executed. 43 | 44 | @warning `responseSerializer` must not be `nil`. Setting a response serializer will clear out any cached value 45 | */ 46 | @property (nonatomic, strong) AFHTTPResponseSerializer * responseSerializer; 47 | 48 | /** 49 | An object constructed by the `responseSerializer` from the response and response data. Returns `nil` unless the operation `isFinished`, has a `response`, and has `responseData` with non-zero content length. If an error occurs during serialization, `nil` will be returned, and the `error` property will be populated with the serialization error. 50 | */ 51 | @property (readonly, nonatomic, strong) id responseObject; 52 | 53 | ///----------------------------------------------------------- 54 | /// @name Setting Completion Block Success / Failure Callbacks 55 | ///----------------------------------------------------------- 56 | 57 | /** 58 | Sets the `completionBlock` property with a block that executes either the specified success or failure block, depending on the state of the request on completion. If `error` returns a value, which can be caused by an unacceptable status code or content type, then `failure` is executed. Otherwise, `success` is executed. 59 | 60 | This method should be overridden in subclasses in order to specify the response object passed into the success block. 61 | 62 | @param success The block to be executed on the completion of a successful request. This block has no return value and takes two arguments: the receiver operation and the object constructed from the response data of the request. 63 | @param failure The block to be executed on the completion of an unsuccessful request. This block has no return value and takes two arguments: the receiver operation and the error that occurred during the request. 64 | */ 65 | - (void)setCompletionBlockWithSuccess:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success 66 | failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure; 67 | 68 | @end 69 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | JFOpenWeatherMapManager 2 | ======================= 3 | 4 | Objective-C iOS / Mac OS X Wrapper to allow easy manipulation of the Open Weather Map API 5 | 6 | Wrapper for Open Weather Map API + MapView example, add a pin to the map to retrieve the current weather data for that location 7 | 8 | Add JFWeatherMapManager to your project 9 | 10 | Import the following Header files 11 | ```Objective-C 12 | #import "JFWeatherData.h" 13 | #import "JFWeatherManager.h" 14 | #import "DataModels.h" 15 | ``` 16 | 17 | If you are using the example project, be sure to set your API key in the View Controller, this is not mandatory and if you choose not to use an API key, simply pass nil to the fetch command later on 18 | ```Objective-C 19 | static NSString *API_KEY = @"YOUR_API_KEY_HERE"; 20 | ``` 21 | 22 | Create a Reference to a JFWeatherManager object and call the fetch function 23 | ```Objective-C 24 | JFWeatherManager *weatherManager = [[JFWeatherManager alloc]init]; 25 | 26 | [weatherManager fetchWeatherDataForLatitude:toAdd.coordinate.latitude andLongitude:toAdd.coordinate.longitude withAPIKeyOrNil:API_KEY :^(JFWeatherData *returnedWeatherData){ 27 | NSLog(@"Latitude %.3f",[returnedWeatherData latitudeCoordinateOfRequest]); 28 | NSLog(@"Longitude %.3f",[returnedWeatherData longitudeCoordinateOfRequest]); 29 | NSLog(@"Country %@",[returnedWeatherData countryCode]); 30 | NSLog(@"Conditions are %@",[returnedWeatherData currentConditionsTextualDescription]); 31 | NSLog(@"Temperature is %f",[returnedWeatherData temperatureInUnitFormat:kTemperatureCelcius]); 32 | NSLog(@"Sunrise is %@",[returnedWeatherData sunriseTime]); 33 | NSLog(@"Sunset is %@",[returnedWeatherData sunsetTime]); 34 | NSLog(@"Hours of Day Light are %@",[returnedWeatherData dayLightHours]); 35 | NSLog(@"Humidity is %@",[returnedWeatherData humidityPercentage]); 36 | NSLog(@"Pressure is %0.1f",[returnedWeatherData pressureInUnitFormat:kPressureHectopascal]); 37 | NSLog(@"Wind Speed is %0.1f",[returnedWeatherData windSpeedInUnitFormat:kWindSpeedMPH]); 38 | NSLog(@"Wind Direction is %@",[returnedWeatherData windDirectionInGeographicalDirection]); 39 | NSLog(@"Cloud Coverage %@",[returnedWeatherData cloudCovergePercentage]); 40 | NSLog(@"Rainfall Over Next 3h is %0.1fmm",[returnedWeatherData rainFallVolumeOver3HoursInMillimeters]); 41 | NSLog(@"SnowFall Over Next 3h is %0.1fmm",[returnedWeatherData snowFallVolumeOver3HoursInMillimeters]); 42 | }]; 43 | ``` 44 | The data and format's that can be returned by the API are: 45 | ```Objective-C 46 | - (NSString *)currentConditionsTextualDescription; //e.g Broken Clouds 47 | - (double)temperatureInUnitFormat:(TemperatureUnit)temperatureUnit; //e.g 3.0°C , Temperature Available in Kelvin, Celsius and Fahrenheit 48 | - (double)pressureInUnitFormat:(PressureUnit)pressureUnit; //e.g 1007.0 hPA , Pressure Available in Hectopascal, and Pascal 49 | - (NSString *)sunriseTime; //e.g 06:33 (Time Shown is Localised based on Latitude and Longitude of the request) 50 | - (NSString *)sunsetTime; //e.g 19:32 (Time Shown is Localised based on Latitude and Longitude of the request) 51 | - (NSString *)dayLightHours; //e.g 12:15 52 | - (NSString *)humidityPercentage; //e.g 88% 53 | - (NSString *)cloudCovergePercentage; //e.g 32% 54 | - (double)windSpeedInUnitFormat:(WindSpeedUnit)windSpeedUnit; //e.g 20.8 MPH, Wind Speed Available in Meters Per Second, Miles Per Hour, Kilometres Per Hour 55 | - (double)windDirectionInDegrees; //e.g 320° 56 | - (NSString *)windDirectionInGeographicalDirection; //e.g N (North) 57 | - (double)rainFallVolumeOver3HoursInMillimeters; //e.g 3mm 58 | - (double)snowFallVolumeOver3HoursInMillimeters; //e.g 7mm 59 | - (double)latitudeCoordinateOfRequest; //e.g 32.79 60 | - (double)longitudeCoordinateOfRequest; //e.g -96.0 61 | - (NSString *)countryCode; // E.g. GB / US / DE 62 | ``` 63 | 64 | Temperature Formats (Kelvin, Celcius, Farenheit) 65 | ```Objective-C 66 | typedef enum temperatureUnits {kTemperatureKelvin, kTemperatureCelcius, kTemperatureFarenheit} TemperatureUnit; 67 | ``` 68 | 69 | Pressure Formats (Hectopascal , Pascal) 70 | ```Objective-C 71 | typedef enum pressureUnits {kPressureHectopascal, kPressurePascal} PressureUnit; 72 | ``` 73 | 74 | Wind Speed Units (MPS,MPH,KPH) 75 | ```Objective-C 76 | typedef enum windSpeedUnits {kWindSpeedMPS, kWindSpeedMPH, kWindSpeedKPH} WindSpeedUnit; 77 | ``` 78 | 79 | ======================= 80 | 81 | Attribution (Special Thanks) 82 | 83 | OpenWeatherMap API http://openweathermap.org for their great API! 84 | AFNetworking for making the best network library on iOS and Mac OSX (Bundled with this project) http://afnetworking.com 85 | APTimeZones for providing a great library for localizing the time zones based on latitude and longitude (Bundled with this project) https://github.com/Alterplay/APTimeZones 86 | 87 | ======================= 88 | 89 | Contact - Jonathan Field | http://jonathanfield.me 90 | -------------------------------------------------------------------------------- /JFOpenWeatherMapManager/APTimeZones/APTimeZones.m: -------------------------------------------------------------------------------- 1 | // 2 | // APTimeZones.h 3 | // APTimeZones 4 | // 5 | // Created by Sergii Kryvoblotskyi on 10/17/13. 6 | // Copyright (c) 2013 Alterplay. All rights reserved. 7 | // 8 | // Permission is hereby granted, free of charge, to any person obtaining a copy 9 | // of this software and associated documentation files (the "Software"), to deal 10 | // in the Software without restriction, including without limitation the rights 11 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | // copies of the Software, and to permit persons to whom the Software is 13 | // furnished to do so, subject to the following conditions: 14 | // 15 | // The above copyright notice and this permission notice shall be included in 16 | // all copies or substantial portions of the Software. 17 | // 18 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | // THE SOFTWARE. 25 | 26 | #import "APTimeZones.h" 27 | 28 | @interface APTimeZones () 29 | @property (nonatomic, strong) NSArray *timeZonesDB; 30 | @end 31 | 32 | @implementation APTimeZones 33 | 34 | #pragma mark - Public 35 | 36 | /* 37 | Get timezone with lat/lon and country code 38 | */ 39 | 40 | - (NSTimeZone *)timeZoneWithLocation:(CLLocation *)location { 41 | 42 | NSDictionary *closeseZoneInfo = [self closesZoneInfoWithLocation:location 43 | source:self.timeZonesDB]; 44 | 45 | //We've found nothing. Let's use system. 46 | if (closeseZoneInfo == nil) { 47 | return [NSTimeZone systemTimeZone]; 48 | } 49 | 50 | //Get timezone 51 | NSTimeZone *timeZone = [self timeZoneWithDictionary:closeseZoneInfo]; 52 | 53 | //Can't create time zone. Take system. 54 | if (timeZone == nil) { 55 | NSAssert(timeZone != nil, @"Can't create timezone: %@", closeseZoneInfo); 56 | timeZone = [NSTimeZone systemTimeZone]; 57 | } 58 | 59 | return timeZone; 60 | } 61 | 62 | /* 63 | Get timezone with lat/lon and country code 64 | */ 65 | 66 | - (NSTimeZone *)timeZoneWithLocation:(CLLocation *)location countryCode:(NSString *)countryCode { 67 | 68 | //No country 69 | if (countryCode == nil) { 70 | return [self timeZoneWithLocation:location]; 71 | } 72 | 73 | //Filter 74 | NSArray *filteredZones = [self filteredTimeZonesWithCountyCode:countryCode]; 75 | 76 | //Get closest zone info 77 | NSDictionary *closeseZoneInfo = [self closesZoneInfoWithLocation:location 78 | source:filteredZones]; 79 | //Get timezone 80 | NSTimeZone *timeZone = [self timeZoneWithDictionary:closeseZoneInfo]; 81 | 82 | //If there is no time zone with code. Let's try to find it anyway 83 | if (timeZone == nil) { 84 | return [self timeZoneWithLocation:location]; 85 | } 86 | return timeZone; 87 | } 88 | 89 | #pragma mark - Private 90 | - (NSArray *)timeZonesDB { 91 | if (_timeZonesDB == nil) { 92 | _timeZonesDB = [self importDataBaseFromFile:@"timezonesDB.json"]; 93 | } 94 | return _timeZonesDB; 95 | } 96 | 97 | /* 98 | Import from DB 99 | */ 100 | - (NSArray *)importDataBaseFromFile:(NSString *)fileName { 101 | NSString *filePath = [[NSBundle mainBundle] pathForResource:fileName ofType:nil]; 102 | NSData *jsonData = [NSData dataWithContentsOfFile:filePath]; 103 | 104 | NSAssert(jsonData.length != 0, @"timezonesDB.json not found in app bundle"); 105 | 106 | NSError *error = nil; 107 | NSArray *timeZones = [NSJSONSerialization JSONObjectWithData:jsonData 108 | options:NSJSONReadingAllowFragments 109 | error:&error]; 110 | 111 | NSAssert(error == nil, @"JSON parsing failed"); 112 | return timeZones; 113 | } 114 | 115 | /* 116 | Calculates the closest distance from source 117 | */ 118 | - (NSDictionary *)closesZoneInfoWithLocation:(CLLocation *)location source:(NSArray *)source { 119 | CLLocationDistance closestDistance = DBL_MAX; 120 | NSDictionary *closestZoneInfo = nil; 121 | 122 | for (NSDictionary *locationInfo in source) { 123 | 124 | double latitude = [locationInfo[@"latitude"] doubleValue]; 125 | double longitude = [locationInfo[@"longitude"] doubleValue]; 126 | 127 | CLLocation *zoneLocation = [[CLLocation alloc] initWithLatitude:latitude longitude:longitude]; 128 | CLLocationDistance distance = [location distanceFromLocation:zoneLocation]; 129 | if (distance < closestDistance) { 130 | closestDistance = distance; 131 | closestZoneInfo = locationInfo; 132 | } 133 | } 134 | return closestZoneInfo; 135 | } 136 | 137 | /* 138 | Filtering the whole DB with the country code 139 | */ 140 | 141 | - (NSArray *)filteredTimeZonesWithCountyCode:(NSString *)countryCode { 142 | NSPredicate *predicate = [NSPredicate predicateWithFormat:@"country_code LIKE %@", countryCode]; 143 | return [self.timeZonesDB filteredArrayUsingPredicate:predicate]; 144 | } 145 | 146 | /* 147 | Timezone from dict 148 | */ 149 | - (NSTimeZone *)timeZoneWithDictionary:(NSDictionary *)zoneInfo { 150 | NSString *zoneName = zoneInfo[@"zone"]; 151 | NSTimeZone *timeZone = [NSTimeZone timeZoneWithName:zoneName]; 152 | return timeZone; 153 | } 154 | 155 | #pragma mark - Singleton 156 | + (APTimeZones *)sharedInstance { 157 | static dispatch_once_t pred; 158 | static APTimeZones *sharedInstance = nil; 159 | dispatch_once(&pred, ^{ 160 | sharedInstance = [[[self class] alloc] init]; 161 | }); 162 | return sharedInstance; 163 | } 164 | 165 | @end 166 | -------------------------------------------------------------------------------- /JFOpenWeatherMapManager/AFNetworking/AFHTTPRequestOperation.m: -------------------------------------------------------------------------------- 1 | // AFHTTPRequestOperation.m 2 | // 3 | // Copyright (c) 2013 AFNetworking (http://afnetworking.com) 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | #import "AFHTTPRequestOperation.h" 24 | 25 | static dispatch_queue_t http_request_operation_processing_queue() { 26 | static dispatch_queue_t af_http_request_operation_processing_queue; 27 | static dispatch_once_t onceToken; 28 | dispatch_once(&onceToken, ^{ 29 | af_http_request_operation_processing_queue = dispatch_queue_create("com.alamofire.networking.http-request.processing", DISPATCH_QUEUE_CONCURRENT); 30 | }); 31 | 32 | return af_http_request_operation_processing_queue; 33 | } 34 | 35 | static dispatch_group_t http_request_operation_completion_group() { 36 | static dispatch_group_t af_http_request_operation_completion_group; 37 | static dispatch_once_t onceToken; 38 | dispatch_once(&onceToken, ^{ 39 | af_http_request_operation_completion_group = dispatch_group_create(); 40 | }); 41 | 42 | return af_http_request_operation_completion_group; 43 | } 44 | 45 | #pragma mark - 46 | 47 | @interface AFHTTPRequestOperation () 48 | @property (readwrite, nonatomic, strong) NSURLRequest *request; 49 | @property (readwrite, nonatomic, strong) NSHTTPURLResponse *response; 50 | @property (readwrite, nonatomic, strong) id responseObject; 51 | @property (readwrite, nonatomic, strong) NSError *responseSerializationError; 52 | @property (readwrite, nonatomic, strong) NSRecursiveLock *lock; 53 | @end 54 | 55 | @implementation AFHTTPRequestOperation 56 | @dynamic lock; 57 | 58 | - (instancetype)initWithRequest:(NSURLRequest *)urlRequest { 59 | self = [super initWithRequest:urlRequest]; 60 | if (!self) { 61 | return nil; 62 | } 63 | 64 | self.responseSerializer = [AFHTTPResponseSerializer serializer]; 65 | 66 | return self; 67 | } 68 | 69 | - (void)setResponseSerializer:(AFHTTPResponseSerializer *)responseSerializer { 70 | NSParameterAssert(responseSerializer); 71 | 72 | [self.lock lock]; 73 | _responseSerializer = responseSerializer; 74 | self.responseObject = nil; 75 | self.responseSerializationError = nil; 76 | [self.lock unlock]; 77 | } 78 | 79 | - (id)responseObject { 80 | [self.lock lock]; 81 | if (!_responseObject && [self isFinished] && !self.error) { 82 | NSError *error = nil; 83 | self.responseObject = [self.responseSerializer responseObjectForResponse:self.response data:self.responseData error:&error]; 84 | if (error) { 85 | self.responseSerializationError = error; 86 | } 87 | } 88 | [self.lock unlock]; 89 | 90 | return _responseObject; 91 | } 92 | 93 | - (NSError *)error { 94 | if (_responseSerializationError) { 95 | return _responseSerializationError; 96 | } else { 97 | return [super error]; 98 | } 99 | } 100 | 101 | #pragma mark - AFHTTPRequestOperation 102 | 103 | - (void)setCompletionBlockWithSuccess:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success 104 | failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure 105 | { 106 | // completionBlock is manually nilled out in AFURLConnectionOperation to break the retain cycle. 107 | #pragma clang diagnostic push 108 | #pragma clang diagnostic ignored "-Warc-retain-cycles" 109 | #pragma clang diagnostic ignored "-Wgnu" 110 | self.completionBlock = ^{ 111 | if (self.completionGroup) { 112 | dispatch_group_enter(self.completionGroup); 113 | } 114 | 115 | dispatch_async(http_request_operation_processing_queue(), ^{ 116 | if (self.error) { 117 | if (failure) { 118 | dispatch_group_async(self.completionGroup ?: http_request_operation_completion_group(), self.completionQueue ?: dispatch_get_main_queue(), ^{ 119 | failure(self, self.error); 120 | }); 121 | } 122 | } else { 123 | id responseObject = self.responseObject; 124 | if (self.error) { 125 | if (failure) { 126 | dispatch_group_async(self.completionGroup ?: http_request_operation_completion_group(), self.completionQueue ?: dispatch_get_main_queue(), ^{ 127 | failure(self, self.error); 128 | }); 129 | } 130 | } else { 131 | if (success) { 132 | dispatch_group_async(self.completionGroup ?: http_request_operation_completion_group(), self.completionQueue ?: dispatch_get_main_queue(), ^{ 133 | success(self, responseObject); 134 | }); 135 | } 136 | } 137 | } 138 | 139 | if (self.completionGroup) { 140 | dispatch_group_leave(self.completionGroup); 141 | } 142 | }); 143 | }; 144 | #pragma clang diagnostic pop 145 | } 146 | 147 | #pragma mark - AFURLRequestOperation 148 | 149 | - (void)pause { 150 | int64_t offset = 0; 151 | if ([self.outputStream propertyForKey:NSStreamFileCurrentOffsetKey]) { 152 | offset = [(NSNumber *)[self.outputStream propertyForKey:NSStreamFileCurrentOffsetKey] longLongValue]; 153 | } else { 154 | offset = [(NSData *)[self.outputStream propertyForKey:NSStreamDataWrittenToMemoryStreamKey] length]; 155 | } 156 | 157 | NSMutableURLRequest *mutableURLRequest = [self.request mutableCopy]; 158 | if ([self.response respondsToSelector:@selector(allHeaderFields)] && [[self.response allHeaderFields] valueForKey:@"ETag"]) { 159 | [mutableURLRequest setValue:[[self.response allHeaderFields] valueForKey:@"ETag"] forHTTPHeaderField:@"If-Range"]; 160 | } 161 | [mutableURLRequest setValue:[NSString stringWithFormat:@"bytes=%llu-", offset] forHTTPHeaderField:@"Range"]; 162 | self.request = mutableURLRequest; 163 | 164 | [super pause]; 165 | } 166 | 167 | #pragma mark - NSCoding 168 | 169 | - (id)initWithCoder:(NSCoder *)decoder { 170 | self = [super initWithCoder:decoder]; 171 | if (!self) { 172 | return nil; 173 | } 174 | 175 | self.responseSerializer = [decoder decodeObjectForKey:NSStringFromSelector(@selector(responseSerializer))]; 176 | 177 | return self; 178 | } 179 | 180 | - (void)encodeWithCoder:(NSCoder *)coder { 181 | [super encodeWithCoder:coder]; 182 | 183 | [coder encodeObject:self.responseSerializer forKey:NSStringFromSelector(@selector(responseSerializer))]; 184 | } 185 | 186 | #pragma mark - NSCopying 187 | 188 | - (id)copyWithZone:(NSZone *)zone { 189 | AFHTTPRequestOperation *operation = [[[self class] allocWithZone:zone] initWithRequest:self.request]; 190 | 191 | operation.responseSerializer = [self.responseSerializer copyWithZone:zone]; 192 | operation.completionQueue = self.completionQueue; 193 | operation.completionGroup = self.completionGroup; 194 | 195 | return operation; 196 | } 197 | 198 | @end 199 | -------------------------------------------------------------------------------- /JFOpenWeatherMapManager/AFNetworking/AFNetworkReachabilityManager.h: -------------------------------------------------------------------------------- 1 | // AFNetworkReachabilityManager.h 2 | // 3 | // Copyright (c) 2013 AFNetworking (http://afnetworking.com) 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | #import 24 | #import 25 | 26 | #import 27 | #import 28 | #import 29 | #import 30 | #import 31 | 32 | typedef NS_ENUM(NSInteger, AFNetworkReachabilityStatus) { 33 | AFNetworkReachabilityStatusUnknown = -1, 34 | AFNetworkReachabilityStatusNotReachable = 0, 35 | AFNetworkReachabilityStatusReachableViaWWAN = 1, 36 | AFNetworkReachabilityStatusReachableViaWiFi = 2, 37 | }; 38 | 39 | /** 40 | `AFNetworkReachabilityManager` monitors the reachability of domains, and addresses for both WWAN and WiFi network interfaces. 41 | 42 | See Apple's Reachability Sample Code (https://developer.apple.com/library/ios/samplecode/reachability/) 43 | */ 44 | @interface AFNetworkReachabilityManager : NSObject 45 | 46 | /** 47 | The current network reachability status. 48 | */ 49 | @property (readonly, nonatomic, assign) AFNetworkReachabilityStatus networkReachabilityStatus; 50 | 51 | /** 52 | Whether or not the network is currently reachable. 53 | */ 54 | @property (readonly, nonatomic, assign, getter = isReachable) BOOL reachable; 55 | 56 | /** 57 | Whether or not the network is currently reachable via WWAN. 58 | */ 59 | @property (readonly, nonatomic, assign, getter = isReachableViaWWAN) BOOL reachableViaWWAN; 60 | 61 | /** 62 | Whether or not the network is currently reachable via WiFi. 63 | */ 64 | @property (readonly, nonatomic, assign, getter = isReachableViaWiFi) BOOL reachableViaWiFi; 65 | 66 | ///--------------------- 67 | /// @name Initialization 68 | ///--------------------- 69 | 70 | /** 71 | Returns the shared network reachability manager. 72 | */ 73 | + (instancetype)sharedManager; 74 | 75 | /** 76 | Creates and returns a network reachability manager for the specified domain. 77 | 78 | @param domain The domain used to evaluate network reachability. 79 | 80 | @return An initialized network reachability manager, actively monitoring the specified domain. 81 | */ 82 | + (instancetype)managerForDomain:(NSString *)domain; 83 | 84 | /** 85 | Creates and returns a network reachability manager for the socket address. 86 | 87 | @param address The socket address used to evaluate network reachability. 88 | 89 | @return An initialized network reachability manager, actively monitoring the specified socket address. 90 | */ 91 | + (instancetype)managerForAddress:(const struct sockaddr_in *)address; 92 | 93 | /** 94 | Initializes an instance of a network reachability manager from the specified reachability object. 95 | 96 | @param reachability The reachability object to monitor. 97 | 98 | @return An initialized network reachability manager, actively monitoring the specified reachability. 99 | */ 100 | - (instancetype)initWithReachability:(SCNetworkReachabilityRef)reachability; 101 | 102 | ///-------------------------------------------------- 103 | /// @name Starting & Stopping Reachability Monitoring 104 | ///-------------------------------------------------- 105 | 106 | /** 107 | Starts monitoring for changes in network reachability status. 108 | */ 109 | - (void)startMonitoring; 110 | 111 | /** 112 | Stops monitoring for changes in network reachability status. 113 | */ 114 | - (void)stopMonitoring; 115 | 116 | ///------------------------------------------------- 117 | /// @name Getting Localized Reachability Description 118 | ///------------------------------------------------- 119 | 120 | /** 121 | Returns a localized string representation of the current network reachability status. 122 | */ 123 | - (NSString *)localizedNetworkReachabilityStatusString; 124 | 125 | ///--------------------------------------------------- 126 | /// @name Setting Network Reachability Change Callback 127 | ///--------------------------------------------------- 128 | 129 | /** 130 | Sets a callback to be executed when the network availability of the `baseURL` host changes. 131 | 132 | @param block A block object to be executed when the network availability of the `baseURL` host changes.. This block has no return value and takes a single argument which represents the various reachability states from the device to the `baseURL`. 133 | */ 134 | - (void)setReachabilityStatusChangeBlock:(void (^)(AFNetworkReachabilityStatus status))block; 135 | 136 | @end 137 | 138 | ///---------------- 139 | /// @name Constants 140 | ///---------------- 141 | 142 | /** 143 | ## Network Reachability 144 | 145 | The following constants are provided by `AFNetworkReachabilityManager` as possible network reachability statuses. 146 | 147 | enum { 148 | AFNetworkReachabilityStatusUnknown, 149 | AFNetworkReachabilityStatusNotReachable, 150 | AFNetworkReachabilityStatusReachableViaWWAN, 151 | AFNetworkReachabilityStatusReachableViaWiFi, 152 | } 153 | 154 | `AFNetworkReachabilityStatusUnknown` 155 | The `baseURL` host reachability is not known. 156 | 157 | `AFNetworkReachabilityStatusNotReachable` 158 | The `baseURL` host cannot be reached. 159 | 160 | `AFNetworkReachabilityStatusReachableViaWWAN` 161 | The `baseURL` host can be reached via a cellular connection, such as EDGE or GPRS. 162 | 163 | `AFNetworkReachabilityStatusReachableViaWiFi` 164 | The `baseURL` host can be reached via a Wi-Fi connection. 165 | 166 | ### Keys for Notification UserInfo Dictionary 167 | 168 | Strings that are used as keys in a `userInfo` dictionary in a network reachability status change notification. 169 | 170 | `AFNetworkingReachabilityNotificationStatusItem` 171 | A key in the userInfo dictionary in a `AFNetworkingReachabilityDidChangeNotification` notification. 172 | The corresponding value is an `NSNumber` object representing the `AFNetworkReachabilityStatus` value for the current reachability status. 173 | */ 174 | 175 | ///-------------------- 176 | /// @name Notifications 177 | ///-------------------- 178 | 179 | /** 180 | Posted when network reachability changes. 181 | This notification assigns no notification object. The `userInfo` dictionary contains an `NSNumber` object under the `AFNetworkingReachabilityNotificationStatusItem` key, representing the `AFNetworkReachabilityStatus` value for the current network reachability. 182 | 183 | @warning In order for network reachability to be monitored, include the `SystemConfiguration` framework in the active target's "Link Binary With Library" build phase, and add `#import ` to the header prefix of the project (`Prefix.pch`). 184 | */ 185 | extern NSString * const AFNetworkingReachabilityDidChangeNotification; 186 | extern NSString * const AFNetworkingReachabilityNotificationStatusItem; 187 | 188 | ///-------------------- 189 | /// @name Functions 190 | ///-------------------- 191 | 192 | /** 193 | Returns a localized string representation of an `AFNetworkReachabilityStatus` value. 194 | */ 195 | extern NSString * AFStringFromNetworkReachabilityStatus(AFNetworkReachabilityStatus status); 196 | -------------------------------------------------------------------------------- /JFOpenWeatherMapManager/JFViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // JFViewController.m 3 | // JFOpenWeatherMapManager 4 | // 5 | // Created by Jonathan Field on 27/10/2013. 6 | // Copyright (c) 2013 Jonathan Field. All rights reserved. 7 | // 8 | 9 | #import "JFViewController.h" 10 | 11 | static NSString *API_KEY = @"YOUR_API_KEY_HERE"; 12 | 13 | @interface JFViewController () 14 | 15 | @end 16 | 17 | @implementation JFViewController 18 | 19 | 20 | 21 | - (void)viewDidLoad 22 | { 23 | [super viewDidLoad]; 24 | tableViewContents = [[NSMutableArray alloc]initWithCapacity:15]; 25 | 26 | for (NSInteger i=0; i<15; i++) { 27 | [tableViewContents addObject:@"TBC"]; 28 | } 29 | 30 | [self.mapView setDelegate:self]; 31 | [self.tableView setDataSource:self]; 32 | [self.tableView setDelegate:self]; 33 | 34 | [self.mapView setShowsUserLocation:TRUE]; 35 | [self addGestureRecogniserToMapView]; 36 | 37 | weatherManager = [[JFWeatherManager alloc]init]; 38 | 39 | } 40 | 41 | - (void)didReceiveMemoryWarning 42 | { 43 | [super didReceiveMemoryWarning]; 44 | // Dispose of any resources that can be recreated. 45 | } 46 | 47 | #pragma UITableView DataSource 48 | - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView 49 | { 50 | // Return the number of sections. 51 | return 1; 52 | } 53 | 54 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 55 | { 56 | // Return the number of rows in the section. 57 | return 15; 58 | } 59 | 60 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 61 | { 62 | static NSString *CellIdentifier = @"Cell"; 63 | UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 64 | 65 | switch ([indexPath row]) { 66 | case 0: 67 | [cell.textLabel setText:@"Latitude"]; 68 | break; 69 | 70 | case 1: 71 | [cell.textLabel setText:@"Longitude"]; 72 | break; 73 | 74 | case 2: 75 | [cell.textLabel setText:@"Conditions"]; 76 | break; 77 | 78 | case 3: 79 | [cell.textLabel setText:@"Temperature (°C)"]; 80 | break; 81 | 82 | case 4: 83 | [cell.textLabel setText:@"Sunrise"]; 84 | break; 85 | 86 | case 5: 87 | [cell.textLabel setText:@"Sunset"]; 88 | break; 89 | 90 | case 6: 91 | [cell.textLabel setText:@"Hours of Day Light"]; 92 | break; 93 | 94 | case 7: 95 | [cell.textLabel setText:@"Humidity"]; 96 | break; 97 | 98 | case 8: 99 | [cell.textLabel setText:@"Pressure (hPA)"]; 100 | break; 101 | 102 | case 9: 103 | [cell.textLabel setText:@"Wind Speed (MPH)"]; 104 | break; 105 | 106 | case 10: 107 | [cell.textLabel setText:@"Wind Direction"]; 108 | break; 109 | 110 | case 11: 111 | [cell.textLabel setText:@"Cloud Coverage"]; 112 | break; 113 | 114 | case 12: 115 | [cell.textLabel setText:@"Rain"]; 116 | break; 117 | 118 | case 13: 119 | [cell.textLabel setText:@"Snow"]; 120 | break; 121 | 122 | case 14: 123 | [cell.textLabel setText:@"Country"]; 124 | break; 125 | } 126 | 127 | [cell.detailTextLabel setText:[tableViewContents objectAtIndex:[indexPath row]]]; 128 | 129 | return cell; 130 | } 131 | 132 | 133 | - (void)addGestureRecogniserToMapView{ 134 | 135 | UILongPressGestureRecognizer *lpgr = [[UILongPressGestureRecognizer alloc] 136 | initWithTarget:self action:@selector(addPinToMap:)]; 137 | lpgr.minimumPressDuration = 0.5; // 138 | [self.mapView addGestureRecognizer:lpgr]; 139 | 140 | } 141 | 142 | - (void)addPinToMap:(UIGestureRecognizer *)gestureRecognizer 143 | { 144 | 145 | if (gestureRecognizer.state != UIGestureRecognizerStateBegan) 146 | return; 147 | 148 | CGPoint touchPoint = [gestureRecognizer locationInView:self.mapView]; 149 | CLLocationCoordinate2D touchMapCoordinate = 150 | [self.mapView convertPoint:touchPoint toCoordinateFromView:self.mapView]; 151 | 152 | MKPointAnnotation *toAdd = [[MKPointAnnotation alloc]init]; 153 | 154 | toAdd.coordinate = touchMapCoordinate; 155 | toAdd.title = @"Dropped Pin"; 156 | 157 | //Set your API Key at the top of this class, if you do not want to use an API key pass in nil 158 | [weatherManager fetchWeatherDataForLatitude:toAdd.coordinate.latitude andLongitude:toAdd.coordinate.longitude withAPIKeyOrNil:API_KEY :^(JFWeatherData *returnedWeatherData) { 159 | 160 | NSLog(@"Latitude %.3f",[returnedWeatherData latitudeCoordinateOfRequest]); 161 | NSLog(@"Longitude %.3f",[returnedWeatherData longitudeCoordinateOfRequest]); 162 | NSLog(@"Country %@",[returnedWeatherData countryCode]); 163 | NSLog(@"Conditions are %@",[returnedWeatherData currentConditionsTextualDescription]); 164 | NSLog(@"Temperature is %f",[returnedWeatherData temperatureInUnitFormat:kTemperatureCelcius]); 165 | NSLog(@"Sunrise is %@",[returnedWeatherData sunriseTime]); 166 | NSLog(@"Sunset is %@",[returnedWeatherData sunsetTime]); 167 | NSLog(@"Hours of Day Light are %@",[returnedWeatherData dayLightHours]); 168 | NSLog(@"Humidity is %@",[returnedWeatherData humidityPercentage]); 169 | NSLog(@"Pressure is %0.1f",[returnedWeatherData pressureInUnitFormat:kPressureHectopascal]); 170 | NSLog(@"Wind Speed is %0.1f",[returnedWeatherData windSpeedInUnitFormat:kWindSpeedMPH]); 171 | NSLog(@"Wind Direction is %@",[returnedWeatherData windDirectionInGeographicalDirection]); 172 | NSLog(@"Cloud Coverage %@",[returnedWeatherData cloudCovergePercentage]); 173 | NSLog(@"Rainfall Over Next 3h is %0.1fmm",[returnedWeatherData rainFallVolumeOver3HoursInMillimeters]); 174 | NSLog(@"SnowFall Over Next 3h is %0.1fmm",[returnedWeatherData snowFallVolumeOver3HoursInMillimeters]); 175 | 176 | [tableViewContents removeAllObjects]; 177 | [tableViewContents addObject:[NSString stringWithFormat:@"%.2f",[returnedWeatherData latitudeCoordinateOfRequest]]]; 178 | [tableViewContents addObject:[NSString stringWithFormat:@"%.2f",[returnedWeatherData longitudeCoordinateOfRequest]]]; 179 | [tableViewContents addObject:[returnedWeatherData currentConditionsTextualDescription]]; 180 | [tableViewContents addObject:[NSString stringWithFormat:@"%.1f°",[returnedWeatherData temperatureInUnitFormat:kTemperatureCelcius]]]; 181 | [tableViewContents addObject:[returnedWeatherData sunriseTime]]; 182 | [tableViewContents addObject:[returnedWeatherData sunsetTime]]; 183 | [tableViewContents addObject:[returnedWeatherData dayLightHours]]; 184 | [tableViewContents addObject:[returnedWeatherData humidityPercentage]]; 185 | [tableViewContents addObject:[NSString stringWithFormat:@"%.1f",[returnedWeatherData pressureInUnitFormat:kPressureHectopascal]]]; 186 | [tableViewContents addObject:[NSString stringWithFormat:@"%.1f",[returnedWeatherData windSpeedInUnitFormat:kWindSpeedMPH]]]; 187 | [tableViewContents addObject:[returnedWeatherData windDirectionInGeographicalDirection]]; 188 | [tableViewContents addObject:[returnedWeatherData cloudCovergePercentage]]; 189 | [tableViewContents addObject:[NSString stringWithFormat:@"%.1fmm",[returnedWeatherData rainFallVolumeOver3HoursInMillimeters]]]; 190 | [tableViewContents addObject:[NSString stringWithFormat:@"%.1fmm",[returnedWeatherData snowFallVolumeOver3HoursInMillimeters]]]; 191 | [tableViewContents addObject:[NSString stringWithFormat:@"%@",[returnedWeatherData countryCode]]]; 192 | 193 | [self.tableView reloadData]; 194 | 195 | }]; 196 | [self.mapView addAnnotation:toAdd]; 197 | 198 | } 199 | 200 | 201 | @end 202 | -------------------------------------------------------------------------------- /JFOpenWeatherMapManager/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 45 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | -------------------------------------------------------------------------------- /JFOpenWeatherMapManager/AFNetworking/AFNetworkReachabilityManager.m: -------------------------------------------------------------------------------- 1 | // AFNetworkReachabilityManager.m 2 | // 3 | // Copyright (c) 2013 AFNetworking (http://afnetworking.com) 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | #import "AFNetworkReachabilityManager.h" 24 | 25 | NSString * const AFNetworkingReachabilityDidChangeNotification = @"com.alamofire.networking.reachability.change"; 26 | NSString * const AFNetworkingReachabilityNotificationStatusItem = @"AFNetworkingReachabilityNotificationStatusItem"; 27 | 28 | typedef void (^AFNetworkReachabilityStatusBlock)(AFNetworkReachabilityStatus status); 29 | 30 | NSString * AFStringFromNetworkReachabilityStatus(AFNetworkReachabilityStatus status) { 31 | switch (status) { 32 | case AFNetworkReachabilityStatusNotReachable: 33 | return NSLocalizedStringFromTable(@"Not Reachable", @"AFNetworking", nil); 34 | case AFNetworkReachabilityStatusReachableViaWWAN: 35 | return NSLocalizedStringFromTable(@"Reachable via WWAN", @"AFNetworking", nil); 36 | case AFNetworkReachabilityStatusReachableViaWiFi: 37 | return NSLocalizedStringFromTable(@"Reachable via WiFi", @"AFNetworking", nil); 38 | case AFNetworkReachabilityStatusUnknown: 39 | default: 40 | return NSLocalizedStringFromTable(@"Unknown", @"AFNetworking", nil); 41 | } 42 | } 43 | 44 | static AFNetworkReachabilityStatus AFNetworkReachabilityStatusForFlags(SCNetworkReachabilityFlags flags) { 45 | BOOL isReachable = ((flags & kSCNetworkReachabilityFlagsReachable) != 0); 46 | BOOL needsConnection = ((flags & kSCNetworkReachabilityFlagsConnectionRequired) != 0); 47 | BOOL canConnectionAutomatically = (((flags & kSCNetworkReachabilityFlagsConnectionOnDemand ) != 0) || ((flags & kSCNetworkReachabilityFlagsConnectionOnTraffic) != 0)); 48 | BOOL canConnectWithoutUserInteraction = (canConnectionAutomatically && (flags & kSCNetworkReachabilityFlagsInterventionRequired) == 0); 49 | BOOL isNetworkReachable = (isReachable && (!needsConnection || canConnectWithoutUserInteraction)); 50 | 51 | AFNetworkReachabilityStatus status = AFNetworkReachabilityStatusUnknown; 52 | if (isNetworkReachable == NO) { 53 | status = AFNetworkReachabilityStatusNotReachable; 54 | } 55 | #if TARGET_OS_IPHONE 56 | else if ((flags & kSCNetworkReachabilityFlagsIsWWAN) != 0) { 57 | status = AFNetworkReachabilityStatusReachableViaWWAN; 58 | } 59 | #endif 60 | else { 61 | status = AFNetworkReachabilityStatusReachableViaWiFi; 62 | } 63 | 64 | return status; 65 | } 66 | 67 | static void AFNetworkReachabilityCallback(SCNetworkReachabilityRef __unused target, SCNetworkReachabilityFlags flags, void *info) { 68 | AFNetworkReachabilityStatus status = AFNetworkReachabilityStatusForFlags(flags); 69 | AFNetworkReachabilityStatusBlock block = (__bridge AFNetworkReachabilityStatusBlock)info; 70 | if (block) { 71 | block(status); 72 | } 73 | 74 | 75 | dispatch_async(dispatch_get_main_queue(), ^{ 76 | NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter]; 77 | [notificationCenter postNotificationName:AFNetworkingReachabilityDidChangeNotification object:nil userInfo:@{ AFNetworkingReachabilityNotificationStatusItem: @(status) }]; 78 | }); 79 | } 80 | 81 | static const void * AFNetworkReachabilityRetainCallback(const void *info) { 82 | return Block_copy(info); 83 | } 84 | 85 | static void AFNetworkReachabilityReleaseCallback(const void *info) { 86 | if (info) { 87 | Block_release(info); 88 | } 89 | } 90 | 91 | @interface AFNetworkReachabilityManager () 92 | @property (readwrite, nonatomic, assign) SCNetworkReachabilityRef networkReachability; 93 | @property (readwrite, nonatomic, assign) AFNetworkReachabilityStatus networkReachabilityStatus; 94 | @property (readwrite, nonatomic, copy) AFNetworkReachabilityStatusBlock networkReachabilityStatusBlock; 95 | @end 96 | 97 | @implementation AFNetworkReachabilityManager 98 | 99 | + (instancetype)sharedManager { 100 | static AFNetworkReachabilityManager *_sharedManager = nil; 101 | static dispatch_once_t onceToken; 102 | dispatch_once(&onceToken, ^{ 103 | struct sockaddr_in address; 104 | bzero(&address, sizeof(address)); 105 | address.sin_len = sizeof(address); 106 | address.sin_family = AF_INET; 107 | 108 | _sharedManager = [self managerForAddress:&address]; 109 | }); 110 | 111 | return _sharedManager; 112 | } 113 | 114 | + (instancetype)managerForDomain:(NSString *)domain { 115 | SCNetworkReachabilityRef reachability = SCNetworkReachabilityCreateWithName(kCFAllocatorDefault, [domain UTF8String]); 116 | 117 | return [[self alloc] initWithReachability:reachability]; 118 | } 119 | 120 | + (instancetype)managerForAddress:(const struct sockaddr_in *)address { 121 | SCNetworkReachabilityRef reachability = SCNetworkReachabilityCreateWithAddress(kCFAllocatorDefault, (const struct sockaddr *)address); 122 | 123 | return [[self alloc] initWithReachability:reachability]; 124 | } 125 | 126 | - (instancetype)initWithReachability:(SCNetworkReachabilityRef)reachability { 127 | self = [super init]; 128 | if (!self) { 129 | return nil; 130 | } 131 | 132 | self.networkReachability = reachability; 133 | 134 | self.networkReachabilityStatus = AFNetworkReachabilityStatusUnknown; 135 | 136 | return self; 137 | } 138 | 139 | - (void)dealloc { 140 | [self stopMonitoring]; 141 | 142 | CFRelease(_networkReachability); 143 | _networkReachability = NULL; 144 | } 145 | 146 | #pragma mark - 147 | 148 | - (BOOL)isReachable { 149 | return [self isReachableViaWWAN] || [self isReachableViaWiFi]; 150 | } 151 | 152 | - (BOOL)isReachableViaWWAN { 153 | return self.networkReachabilityStatus == AFNetworkReachabilityStatusReachableViaWWAN; 154 | } 155 | 156 | - (BOOL)isReachableViaWiFi { 157 | return self.networkReachabilityStatus == AFNetworkReachabilityStatusReachableViaWiFi; 158 | } 159 | 160 | #pragma mark - 161 | 162 | - (void)startMonitoring { 163 | [self stopMonitoring]; 164 | 165 | if (!self.networkReachability) { 166 | return; 167 | } 168 | 169 | __weak __typeof(self)weakSelf = self; 170 | AFNetworkReachabilityStatusBlock callback = ^(AFNetworkReachabilityStatus status) { 171 | __strong __typeof(weakSelf)strongSelf = weakSelf; 172 | 173 | strongSelf.networkReachabilityStatus = status; 174 | if (strongSelf.networkReachabilityStatusBlock) { 175 | strongSelf.networkReachabilityStatusBlock(status); 176 | } 177 | }; 178 | 179 | SCNetworkReachabilityContext context = {0, (__bridge void *)callback, AFNetworkReachabilityRetainCallback, AFNetworkReachabilityReleaseCallback, NULL}; 180 | SCNetworkReachabilitySetCallback(self.networkReachability, AFNetworkReachabilityCallback, &context); 181 | 182 | SCNetworkReachabilityFlags flags; 183 | SCNetworkReachabilityGetFlags(self.networkReachability, &flags); 184 | dispatch_async(dispatch_get_main_queue(), ^{ 185 | AFNetworkReachabilityStatus status = AFNetworkReachabilityStatusForFlags(flags); 186 | callback(status); 187 | }); 188 | 189 | SCNetworkReachabilityScheduleWithRunLoop(self.networkReachability, CFRunLoopGetMain(), kCFRunLoopCommonModes); 190 | } 191 | 192 | - (void)stopMonitoring { 193 | if (!self.networkReachability) { 194 | return; 195 | } 196 | 197 | SCNetworkReachabilityUnscheduleFromRunLoop(self.networkReachability, CFRunLoopGetMain(), kCFRunLoopCommonModes); 198 | } 199 | 200 | #pragma mark - 201 | 202 | - (NSString *)localizedNetworkReachabilityStatusString { 203 | return AFStringFromNetworkReachabilityStatus(self.networkReachabilityStatus); 204 | } 205 | 206 | #pragma mark - 207 | 208 | - (void)setReachabilityStatusChangeBlock:(void (^)(AFNetworkReachabilityStatus status))block { 209 | self.networkReachabilityStatusBlock = block; 210 | } 211 | 212 | #pragma mark - NSKeyValueObserving 213 | 214 | + (NSSet *)keyPathsForValuesAffectingValueForKey:(NSString *)key { 215 | if ([key isEqualToString:@"reachable"] || [key isEqualToString:@"reachableViaWWAN"] || [key isEqualToString:@"reachableViaWiFi"]) { 216 | return [NSSet setWithObject:@"networkReachabilityStatus"]; 217 | } 218 | 219 | return [super keyPathsForValuesAffectingValueForKey:key]; 220 | } 221 | 222 | @end 223 | -------------------------------------------------------------------------------- /JFOpenWeatherMapManager/AFNetworking/AFSecurityPolicy.m: -------------------------------------------------------------------------------- 1 | // AFSecurity.m 2 | // 3 | // Copyright (c) 2013 AFNetworking (http://afnetworking.com) 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | #import "AFSecurityPolicy.h" 24 | 25 | #if !defined(__IPHONE_OS_VERSION_MIN_REQUIRED) 26 | static NSData * AFSecKeyGetData(SecKeyRef key) { 27 | CFDataRef data = NULL; 28 | 29 | #if defined(NS_BLOCK_ASSERTIONS) 30 | SecItemExport(key, kSecFormatUnknown, kSecItemPemArmour, NULL, &data); 31 | #else 32 | OSStatus status = SecItemExport(key, kSecFormatUnknown, kSecItemPemArmour, NULL, &data); 33 | NSCAssert(status == errSecSuccess, @"SecItemExport error: %ld", (long int)status); 34 | #endif 35 | 36 | NSCParameterAssert(data); 37 | 38 | return (__bridge_transfer NSData *)data; 39 | } 40 | #endif 41 | 42 | static BOOL AFSecKeyIsEqualToKey(SecKeyRef key1, SecKeyRef key2) { 43 | #if defined(__IPHONE_OS_VERSION_MIN_REQUIRED) 44 | return [(__bridge id)key1 isEqual:(__bridge id)key2]; 45 | #else 46 | return [AFSecKeyGetData(key1) isEqual:AFSecKeyGetData(key2)]; 47 | #endif 48 | } 49 | 50 | static id AFPublicKeyForCertificate(NSData *certificate) { 51 | SecCertificateRef allowedCertificate = SecCertificateCreateWithData(NULL, (__bridge CFDataRef)certificate); 52 | NSCParameterAssert(allowedCertificate); 53 | 54 | SecCertificateRef allowedCertificates[] = {allowedCertificate}; 55 | CFArrayRef tempCertificates = CFArrayCreate(NULL, (const void **)allowedCertificates, 1, NULL); 56 | 57 | SecPolicyRef policy = SecPolicyCreateBasicX509(); 58 | SecTrustRef allowedTrust = NULL; 59 | #if defined(NS_BLOCK_ASSERTIONS) 60 | SecTrustCreateWithCertificates(tempCertificates, policy, &allowedTrust); 61 | #else 62 | OSStatus status = SecTrustCreateWithCertificates(tempCertificates, policy, &allowedTrust); 63 | NSCAssert(status == errSecSuccess, @"SecTrustCreateWithCertificates error: %ld", (long int)status); 64 | #endif 65 | 66 | SecTrustResultType result = 0; 67 | 68 | #if defined(NS_BLOCK_ASSERTIONS) 69 | SecTrustEvaluate(allowedTrust, &result); 70 | #else 71 | status = SecTrustEvaluate(allowedTrust, &result); 72 | NSCAssert(status == errSecSuccess, @"SecTrustEvaluate error: %ld", (long int)status); 73 | #endif 74 | 75 | SecKeyRef allowedPublicKey = SecTrustCopyPublicKey(allowedTrust); 76 | NSCParameterAssert(allowedPublicKey); 77 | 78 | CFRelease(allowedTrust); 79 | CFRelease(policy); 80 | CFRelease(tempCertificates); 81 | CFRelease(allowedCertificate); 82 | 83 | return (__bridge_transfer id)allowedPublicKey; 84 | } 85 | 86 | static BOOL AFServerTrustIsValid(SecTrustRef serverTrust) { 87 | SecTrustResultType result = 0; 88 | 89 | #if defined(NS_BLOCK_ASSERTIONS) 90 | SecTrustEvaluate(serverTrust, &result); 91 | #else 92 | OSStatus status = SecTrustEvaluate(serverTrust, &result); 93 | NSCAssert(status == errSecSuccess, @"SecTrustEvaluate error: %ld", (long int)status); 94 | #endif 95 | 96 | return (result == kSecTrustResultUnspecified || result == kSecTrustResultProceed); 97 | } 98 | 99 | static NSArray * AFCertificateTrustChainForServerTrust(SecTrustRef serverTrust) { 100 | CFIndex certificateCount = SecTrustGetCertificateCount(serverTrust); 101 | NSMutableArray *trustChain = [NSMutableArray arrayWithCapacity:(NSUInteger)certificateCount]; 102 | 103 | for (CFIndex i = 0; i < certificateCount; i++) { 104 | SecCertificateRef certificate = SecTrustGetCertificateAtIndex(serverTrust, i); 105 | [trustChain addObject:(__bridge_transfer NSData *)SecCertificateCopyData(certificate)]; 106 | } 107 | 108 | return [NSArray arrayWithArray:trustChain]; 109 | } 110 | 111 | static NSArray * AFPublicKeyTrustChainForServerTrust(SecTrustRef serverTrust) { 112 | SecPolicyRef policy = SecPolicyCreateBasicX509(); 113 | CFIndex certificateCount = SecTrustGetCertificateCount(serverTrust); 114 | NSMutableArray *trustChain = [NSMutableArray arrayWithCapacity:(NSUInteger)certificateCount]; 115 | for (CFIndex i = 0; i < certificateCount; i++) { 116 | SecCertificateRef certificate = SecTrustGetCertificateAtIndex(serverTrust, i); 117 | 118 | SecCertificateRef someCertificates[] = {certificate}; 119 | CFArrayRef certificates = CFArrayCreate(NULL, (const void **)someCertificates, 1, NULL); 120 | 121 | SecTrustRef trust = NULL; 122 | 123 | OSStatus status = SecTrustCreateWithCertificates(certificates, policy, &trust); 124 | NSCAssert(status == errSecSuccess, @"SecTrustCreateWithCertificates error: %ld", (long int)status); 125 | 126 | SecTrustResultType result; 127 | status = SecTrustEvaluate(trust, &result); 128 | NSCAssert(status == errSecSuccess, @"SecTrustEvaluate error: %ld", (long int)status); 129 | 130 | [trustChain addObject:(__bridge_transfer id)SecTrustCopyPublicKey(trust)]; 131 | 132 | CFRelease(trust); 133 | CFRelease(certificates); 134 | } 135 | CFRelease(policy); 136 | 137 | return [NSArray arrayWithArray:trustChain]; 138 | } 139 | 140 | #pragma mark - 141 | 142 | @interface AFSecurityPolicy() 143 | @property (readwrite, nonatomic, strong) NSArray *pinnedPublicKeys; 144 | @end 145 | 146 | @implementation AFSecurityPolicy 147 | 148 | + (NSArray *)defaultPinnedCertificates { 149 | static NSArray *_defaultPinnedCertificates = nil; 150 | static dispatch_once_t onceToken; 151 | dispatch_once(&onceToken, ^{ 152 | NSBundle *bundle = [NSBundle bundleForClass:[self class]]; 153 | NSArray *paths = [bundle pathsForResourcesOfType:@"cer" inDirectory:@"."]; 154 | 155 | NSMutableArray *certificates = [NSMutableArray arrayWithCapacity:[paths count]]; 156 | for (NSString *path in paths) { 157 | NSData *certificateData = [NSData dataWithContentsOfFile:path]; 158 | [certificates addObject:certificateData]; 159 | } 160 | 161 | _defaultPinnedCertificates = [[NSArray alloc] initWithArray:certificates]; 162 | }); 163 | 164 | return _defaultPinnedCertificates; 165 | } 166 | 167 | + (instancetype)defaultPolicy { 168 | AFSecurityPolicy *securityPolicy = [[self alloc] init]; 169 | securityPolicy.SSLPinningMode = AFSSLPinningModeNone; 170 | 171 | return securityPolicy; 172 | } 173 | 174 | + (instancetype)policyWithPinningMode:(AFSSLPinningMode)pinningMode { 175 | AFSecurityPolicy *securityPolicy = [[self alloc] init]; 176 | securityPolicy.SSLPinningMode = pinningMode; 177 | [securityPolicy setPinnedCertificates:[self defaultPinnedCertificates]]; 178 | 179 | return securityPolicy; 180 | } 181 | 182 | #pragma mark - 183 | 184 | - (void)setPinnedCertificates:(NSArray *)pinnedCertificates { 185 | _pinnedCertificates = pinnedCertificates; 186 | 187 | if (self.pinnedCertificates) { 188 | NSMutableArray *mutablePinnedPublicKeys = [NSMutableArray arrayWithCapacity:[self.pinnedCertificates count]]; 189 | for (NSData *certificate in self.pinnedCertificates) { 190 | [mutablePinnedPublicKeys addObject:AFPublicKeyForCertificate(certificate)]; 191 | } 192 | self.pinnedPublicKeys = [NSArray arrayWithArray:mutablePinnedPublicKeys]; 193 | } else { 194 | self.pinnedPublicKeys = nil; 195 | } 196 | } 197 | 198 | #pragma mark - 199 | 200 | - (BOOL)evaluateServerTrust:(SecTrustRef)serverTrust { 201 | switch (self.SSLPinningMode) { 202 | case AFSSLPinningModeNone: 203 | return (self.allowInvalidCertificates || AFServerTrustIsValid(serverTrust)); 204 | case AFSSLPinningModeCertificate: { 205 | for (NSData *trustChainCertificate in AFCertificateTrustChainForServerTrust(serverTrust)) { 206 | if ([self.pinnedCertificates containsObject:trustChainCertificate]) { 207 | return YES; 208 | } 209 | } 210 | } 211 | break; 212 | case AFSSLPinningModePublicKey: { 213 | for (id trustChainPublicKey in AFPublicKeyTrustChainForServerTrust(serverTrust)) { 214 | for (id pinnedPublicKey in self.pinnedPublicKeys) { 215 | if (AFSecKeyIsEqualToKey((__bridge SecKeyRef)trustChainPublicKey, (__bridge SecKeyRef)pinnedPublicKey)) { 216 | return YES; 217 | } 218 | } 219 | } 220 | } 221 | break; 222 | default: 223 | break; 224 | } 225 | 226 | return NO; 227 | } 228 | 229 | #pragma mark - NSKeyValueObserving 230 | 231 | + (NSSet *)keyPathsForValuesAffectingPinnedPublicKeys { 232 | return [NSSet setWithObject:@"pinnedCertificates"]; 233 | } 234 | 235 | @end 236 | -------------------------------------------------------------------------------- /JFOpenWeatherMapManager/AFNetworking/AFURLResponseSerialization.h: -------------------------------------------------------------------------------- 1 | // AFSerialization.h 2 | // 3 | // Copyright (c) 2013 AFNetworking (http://afnetworking.com) 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | #import 24 | #import 25 | 26 | /** 27 | The `AFURLResponseSerialization` protocol is adopted by an object that decodes data into a more useful object representation, according to details in the server response. Response serializers may additionally perform validation on the incoming response and data. 28 | 29 | For example, a JSON response serializer may check for an acceptable status code (`2XX` range) and content type (`application/json`), decoding a valid JSON response into an object. 30 | */ 31 | @protocol AFURLResponseSerialization 32 | 33 | /** 34 | The response object decoded from the data associated with a specified response. 35 | 36 | @param response The response to be processed. 37 | @param data The response data to be decoded. 38 | @param error The error that occurred while attempting to decode the response data. 39 | 40 | @return The object decoded from the specified response data. 41 | */ 42 | - (id)responseObjectForResponse:(NSURLResponse *)response 43 | data:(NSData *)data 44 | error:(NSError *__autoreleasing *)error; 45 | 46 | @end 47 | 48 | #pragma mark - 49 | 50 | /** 51 | `AFHTTPResponseSerializer` conforms to the `AFURLRequestSerialization` & `AFURLResponseSerialization` protocols, offering a concrete base implementation of query string / URL form-encoded parameter serialization and default request headers, as well as response status code and content type validation. 52 | 53 | Any request or response serializer dealing with HTTP is encouraged to subclass `AFHTTPResponseSerializer` in order to ensure consistent default behavior. 54 | */ 55 | @interface AFHTTPResponseSerializer : NSObject 56 | 57 | /** 58 | The string encoding used to serialize parameters. 59 | */ 60 | @property (nonatomic, assign) NSStringEncoding stringEncoding; 61 | 62 | /** 63 | Creates and returns a serializer with default configuration. 64 | */ 65 | + (instancetype)serializer; 66 | 67 | ///----------------------------------------- 68 | /// @name Configuring Response Serialization 69 | ///----------------------------------------- 70 | 71 | /** 72 | The acceptable HTTP status codes for responses. When non-`nil`, responses with status codes not contained by the set will result in an error during validation. 73 | 74 | See http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html 75 | */ 76 | @property (nonatomic, strong) NSIndexSet *acceptableStatusCodes; 77 | 78 | /** 79 | The acceptable MIME types for responses. When non-`nil`, responses with a `Content-Type` with MIME types that do not intersect with the set will result in an error during validation. 80 | */ 81 | @property (nonatomic, strong) NSSet *acceptableContentTypes; 82 | 83 | /** 84 | Validates the specified response and data. 85 | 86 | In its base implementation, this method checks for an acceptable status code and content type. Subclasses may wish to add other domain-specific checks. 87 | 88 | @param response The response to be validated. 89 | @param data The data associated with the response. 90 | @param error The error that occurred while attempting to validate the response. 91 | 92 | @return `YES` if the response is valid, otherwise `NO`. 93 | */ 94 | - (BOOL)validateResponse:(NSHTTPURLResponse *)response 95 | data:(NSData *)data 96 | error:(NSError *__autoreleasing *)error; 97 | 98 | @end 99 | 100 | #pragma mark - 101 | 102 | 103 | /** 104 | `AFJSONSerializer` is a subclass of `AFHTTPResponseSerializer` that validates and decodes JSON responses. 105 | 106 | By default, `AFJSONSerializer` accepts the following MIME types, which includes the official standard, `application/json`, as well as other commonly-used types: 107 | 108 | - `application/json` 109 | - `text/json` 110 | - `text/javascript` 111 | */ 112 | @interface AFJSONResponseSerializer : AFHTTPResponseSerializer 113 | 114 | /** 115 | Options for reading the response JSON data and creating the Foundation objects. For possible values, see the `NSJSONSerialization` documentation section "NSJSONReadingOptions". `0` by default. 116 | */ 117 | @property (nonatomic, assign) NSJSONReadingOptions readingOptions; 118 | 119 | /** 120 | Creates and returns a JSON serializer with specified reading and writing options. 121 | 122 | @param readingOptions The specified JSON reading options. 123 | */ 124 | + (instancetype)serializerWithReadingOptions:(NSJSONReadingOptions)readingOptions; 125 | 126 | @end 127 | 128 | #pragma mark - 129 | 130 | /** 131 | `AFXMLParserSerializer` is a subclass of `AFHTTPResponseSerializer` that validates and decodes XML responses as an `NSXMLParser` objects. 132 | 133 | By default, `AFXMLParserSerializer` accepts the following MIME types, which includes the official standard, `application/xml`, as well as other commonly-used types: 134 | 135 | - `application/xml` 136 | - `text/xml` 137 | */ 138 | @interface AFXMLParserResponseSerializer : AFHTTPResponseSerializer 139 | 140 | @end 141 | 142 | #pragma mark - 143 | 144 | #ifdef __MAC_OS_X_VERSION_MIN_REQUIRED 145 | 146 | /** 147 | `AFXMLDocumentSerializer` is a subclass of `AFHTTPResponseSerializer` that validates and decodes XML responses as an `NSXMLDocument` objects. 148 | 149 | By default, `AFXMLDocumentSerializer` accepts the following MIME types, which includes the official standard, `application/xml`, as well as other commonly-used types: 150 | 151 | - `application/xml` 152 | - `text/xml` 153 | */ 154 | @interface AFXMLDocumentResponseSerializer : AFHTTPResponseSerializer 155 | 156 | /** 157 | Input and output options specifically intended for `NSXMLDocument` objects. For possible values, see the `NSJSONSerialization` documentation section "NSJSONReadingOptions". `0` by default. 158 | */ 159 | @property (nonatomic, assign) NSUInteger options; 160 | 161 | /** 162 | Creates and returns an XML document serializer with the specified options. 163 | 164 | @param mask The XML document options. 165 | */ 166 | + (instancetype)serializerWithXMLDocumentOptions:(NSUInteger)mask; 167 | 168 | @end 169 | 170 | #endif 171 | 172 | #pragma mark - 173 | 174 | /** 175 | `AFPropertyListSerializer` is a subclass of `AFHTTPResponseSerializer` that validates and decodes XML responses as an `NSXMLDocument` objects. 176 | 177 | By default, `AFPropertyListSerializer` accepts the following MIME types: 178 | 179 | - `application/x-plist` 180 | */ 181 | @interface AFPropertyListResponseSerializer : AFHTTPResponseSerializer 182 | 183 | /** 184 | The property list format. Possible values are described in "NSPropertyListFormat". 185 | */ 186 | @property (nonatomic, assign) NSPropertyListFormat format; 187 | 188 | /** 189 | The property list reading options. Possible values are described in "NSPropertyListMutabilityOptions." 190 | */ 191 | @property (nonatomic, assign) NSPropertyListReadOptions readOptions; 192 | 193 | /** 194 | Creates and returns a property list serializer with a specified format, read options, and write options. 195 | 196 | @param format The property list format. 197 | @param readOptions The property list reading options. 198 | */ 199 | + (instancetype)serializerWithFormat:(NSPropertyListFormat)format 200 | readOptions:(NSPropertyListReadOptions)readOptions; 201 | 202 | @end 203 | 204 | #pragma mark - 205 | 206 | /** 207 | `AFImageSerializer` is a subclass of `AFHTTPResponseSerializer` that validates and decodes image responses. 208 | 209 | By default, `AFImageSerializer` accepts the following MIME types, which correspond to the image formats supported by UIImage or NSImage: 210 | 211 | - `image/tiff` 212 | - `image/jpeg` 213 | - `image/gif` 214 | - `image/png` 215 | - `image/ico` 216 | - `image/x-icon` 217 | - `image/bmp` 218 | - `image/x-bmp` 219 | - `image/x-xbitmap` 220 | - `image/x-win-bitmap` 221 | */ 222 | @interface AFImageResponseSerializer : AFHTTPResponseSerializer 223 | 224 | #if defined(__IPHONE_OS_VERSION_MIN_REQUIRED) 225 | /** 226 | The scale factor used when interpreting the image data to construct `responseImage`. Specifying a scale factor of 1.0 results in an image whose size matches the pixel-based dimensions of the image. Applying a different scale factor changes the size of the image as reported by the size property. This is set to the value of scale of the main screen by default, which automatically scales images for retina displays, for instance. 227 | */ 228 | @property (nonatomic, assign) CGFloat imageScale; 229 | 230 | /** 231 | Whether to automatically inflate response image data for compressed formats (such as PNG or JPEG). Enabling this can significantly improve drawing performance on iOS when used with `setCompletionBlockWithSuccess:failure:`, as it allows a bitmap representation to be constructed in the background rather than on the main thread. `YES` by default. 232 | */ 233 | @property (nonatomic, assign) BOOL automaticallyInflatesResponseImage; 234 | #endif 235 | 236 | @end 237 | 238 | #pragma mark - 239 | 240 | /** 241 | `AFCompoundSerializer` is a subclass of `AFHTTPResponseSerializer` that delegates the response serialization to the first `AFHTTPResponseSerializer` object that returns `YES` to `validateResponse:data:error:`, falling back on the default behavior of `AFHTTPResponseSerializer`. This is useful for supporting multiple potential types and structures of server responses with a single serializer. 242 | */ 243 | @interface AFCompoundResponseSerializer : AFHTTPResponseSerializer 244 | 245 | /** 246 | The component response serializers. 247 | */ 248 | @property (readonly, nonatomic, strong) NSArray *responseSerializers; 249 | 250 | /** 251 | Creates and returns a compound serializer comprised of the specified response serializers. 252 | 253 | @warning Each response serializer specified must be a subclass of `AFHTTPResponseSerializer`, and response to `-validateResponse:data:error:`. 254 | */ 255 | + (instancetype)compoundSerializerWithResponseSerializers:(NSArray *)responseSerializers; 256 | 257 | @end 258 | -------------------------------------------------------------------------------- /JFOpenWeatherMapManager/AFNetworking/AFHTTPRequestOperationManager.m: -------------------------------------------------------------------------------- 1 | // AFHTTPRequestOperationManager.m 2 | // 3 | // Copyright (c) 2013 AFNetworking (http://afnetworking.com) 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | #import 24 | 25 | #import "AFHTTPRequestOperationManager.h" 26 | #import "AFHTTPRequestOperation.h" 27 | 28 | #import 29 | #import 30 | 31 | #if defined(__IPHONE_OS_VERSION_MIN_REQUIRED) 32 | #import 33 | #endif 34 | 35 | @interface AFHTTPRequestOperationManager () 36 | @property (readwrite, nonatomic, strong) NSURL *baseURL; 37 | @property (readwrite, nonatomic, strong) AFNetworkReachabilityManager *reachabilityManager; 38 | @end 39 | 40 | @implementation AFHTTPRequestOperationManager 41 | 42 | + (instancetype)manager { 43 | return [[AFHTTPRequestOperationManager alloc] initWithBaseURL:nil]; 44 | } 45 | 46 | - (instancetype)initWithBaseURL:(NSURL *)url { 47 | self = [super init]; 48 | if (!self) { 49 | return nil; 50 | } 51 | 52 | // Ensure terminal slash for baseURL path, so that NSURL +URLWithString:relativeToURL: works as expected 53 | if ([[url path] length] > 0 && ![[url absoluteString] hasSuffix:@"/"]) { 54 | url = [url URLByAppendingPathComponent:@""]; 55 | } 56 | 57 | self.baseURL = url; 58 | 59 | self.requestSerializer = [AFHTTPRequestSerializer serializer]; 60 | self.responseSerializer = [AFJSONResponseSerializer serializer]; 61 | 62 | self.securityPolicy = [AFSecurityPolicy defaultPolicy]; 63 | 64 | if (self.baseURL.host) { 65 | self.reachabilityManager = [AFNetworkReachabilityManager managerForDomain:self.baseURL.host]; 66 | } else { 67 | self.reachabilityManager = [AFNetworkReachabilityManager sharedManager]; 68 | } 69 | 70 | [self.reachabilityManager startMonitoring]; 71 | 72 | self.operationQueue = [[NSOperationQueue alloc] init]; 73 | 74 | return self; 75 | } 76 | 77 | - (NSString *)description { 78 | return [NSString stringWithFormat:@"<%@: %p, baseURL: %@, operationQueue: %@>", NSStringFromClass([self class]), self, [self.baseURL absoluteString], self.operationQueue]; 79 | } 80 | 81 | #pragma mark - 82 | 83 | #ifdef _SYSTEMCONFIGURATION_H 84 | #endif 85 | 86 | - (void)setRequestSerializer:(AFHTTPRequestSerializer *)requestSerializer { 87 | NSParameterAssert(requestSerializer); 88 | 89 | _requestSerializer = requestSerializer; 90 | } 91 | 92 | - (void)setResponseSerializer:(AFHTTPResponseSerializer *)responseSerializer { 93 | NSParameterAssert(responseSerializer); 94 | 95 | _responseSerializer = responseSerializer; 96 | } 97 | 98 | #pragma mark - 99 | 100 | - (AFHTTPRequestOperation *)HTTPRequestOperationWithRequest:(NSURLRequest *)request 101 | success:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success 102 | failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure 103 | { 104 | AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request]; 105 | operation.responseSerializer = self.responseSerializer; 106 | operation.shouldUseCredentialStorage = self.shouldUseCredentialStorage; 107 | operation.credential = self.credential; 108 | operation.securityPolicy = self.securityPolicy; 109 | 110 | [operation setCompletionBlockWithSuccess:success failure:failure]; 111 | 112 | return operation; 113 | } 114 | 115 | #pragma mark - 116 | 117 | - (AFHTTPRequestOperation *)GET:(NSString *)URLString 118 | parameters:(NSDictionary *)parameters 119 | success:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success 120 | failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure 121 | { 122 | NSMutableURLRequest *request = [self.requestSerializer requestWithMethod:@"GET" URLString:[[NSURL URLWithString:URLString relativeToURL:self.baseURL] absoluteString] parameters:parameters]; 123 | AFHTTPRequestOperation *operation = [self HTTPRequestOperationWithRequest:request success:success failure:failure]; 124 | [self.operationQueue addOperation:operation]; 125 | 126 | return operation; 127 | } 128 | 129 | - (AFHTTPRequestOperation *)HEAD:(NSString *)URLString 130 | parameters:(NSDictionary *)parameters 131 | success:(void (^)(AFHTTPRequestOperation *operation))success 132 | failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure 133 | { 134 | NSMutableURLRequest *request = [self.requestSerializer requestWithMethod:@"HEAD" URLString:[[NSURL URLWithString:URLString relativeToURL:self.baseURL] absoluteString] parameters:parameters]; 135 | AFHTTPRequestOperation *operation = [self HTTPRequestOperationWithRequest:request success:^(AFHTTPRequestOperation *requestOperation, __unused id responseObject) { 136 | if (success) { 137 | success(requestOperation); 138 | } 139 | } failure:failure]; 140 | [self.operationQueue addOperation:operation]; 141 | 142 | return operation; 143 | } 144 | 145 | - (AFHTTPRequestOperation *)POST:(NSString *)URLString 146 | parameters:(NSDictionary *)parameters 147 | success:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success 148 | failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure 149 | { 150 | NSMutableURLRequest *request = [self.requestSerializer requestWithMethod:@"POST" URLString:[[NSURL URLWithString:URLString relativeToURL:self.baseURL] absoluteString] parameters:parameters]; 151 | AFHTTPRequestOperation *operation = [self HTTPRequestOperationWithRequest:request success:success failure:failure]; 152 | [self.operationQueue addOperation:operation]; 153 | 154 | return operation; 155 | } 156 | 157 | - (AFHTTPRequestOperation *)POST:(NSString *)URLString 158 | parameters:(NSDictionary *)parameters 159 | constructingBodyWithBlock:(void (^)(id formData))block 160 | success:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success 161 | failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure 162 | { 163 | NSMutableURLRequest *request = [self.requestSerializer multipartFormRequestWithMethod:@"POST" URLString:[[NSURL URLWithString:URLString relativeToURL:self.baseURL] absoluteString] parameters:parameters constructingBodyWithBlock:block]; 164 | AFHTTPRequestOperation *operation = [self HTTPRequestOperationWithRequest:request success:success failure:failure]; 165 | [self.operationQueue addOperation:operation]; 166 | 167 | return operation; 168 | } 169 | 170 | - (AFHTTPRequestOperation *)PUT:(NSString *)URLString 171 | parameters:(NSDictionary *)parameters 172 | success:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success 173 | failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure 174 | { 175 | NSMutableURLRequest *request = [self.requestSerializer requestWithMethod:@"PUT" URLString:[[NSURL URLWithString:URLString relativeToURL:self.baseURL] absoluteString] parameters:parameters]; 176 | AFHTTPRequestOperation *operation = [self HTTPRequestOperationWithRequest:request success:success failure:failure]; 177 | [self.operationQueue addOperation:operation]; 178 | 179 | return operation; 180 | } 181 | 182 | - (AFHTTPRequestOperation *)PATCH:(NSString *)URLString 183 | parameters:(NSDictionary *)parameters 184 | success:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success 185 | failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure 186 | { 187 | NSMutableURLRequest *request = [self.requestSerializer requestWithMethod:@"PATCH" URLString:[[NSURL URLWithString:URLString relativeToURL:self.baseURL] absoluteString] parameters:parameters]; 188 | AFHTTPRequestOperation *operation = [self HTTPRequestOperationWithRequest:request success:success failure:failure]; 189 | [self.operationQueue addOperation:operation]; 190 | 191 | return operation; 192 | } 193 | 194 | - (AFHTTPRequestOperation *)DELETE:(NSString *)URLString 195 | parameters:(NSDictionary *)parameters 196 | success:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success 197 | failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure 198 | { 199 | NSMutableURLRequest *request = [self.requestSerializer requestWithMethod:@"DELETE" URLString:[[NSURL URLWithString:URLString relativeToURL:self.baseURL] absoluteString] parameters:parameters]; 200 | AFHTTPRequestOperation *operation = [self HTTPRequestOperationWithRequest:request success:success failure:failure]; 201 | [self.operationQueue addOperation:operation]; 202 | 203 | return operation; 204 | } 205 | 206 | #pragma mark - NSCoding 207 | 208 | - (id)initWithCoder:(NSCoder *)decoder { 209 | NSURL *baseURL = [decoder decodeObjectForKey:NSStringFromSelector(@selector(baseURL))]; 210 | 211 | self = [self initWithBaseURL:baseURL]; 212 | if (!self) { 213 | return nil; 214 | } 215 | 216 | self.requestSerializer = [decoder decodeObjectForKey:NSStringFromSelector(@selector(requestSerializer))]; 217 | self.responseSerializer = [decoder decodeObjectForKey:NSStringFromSelector(@selector(responseSerializer))]; 218 | 219 | return self; 220 | } 221 | 222 | - (void)encodeWithCoder:(NSCoder *)coder { 223 | [coder encodeObject:self.baseURL forKey:NSStringFromSelector(@selector(baseURL))]; 224 | [coder encodeObject:self.requestSerializer forKey:NSStringFromSelector(@selector(requestSerializer))]; 225 | [coder encodeObject:self.responseSerializer forKey:NSStringFromSelector(@selector(responseSerializer))]; 226 | } 227 | 228 | #pragma mark - NSCopying 229 | 230 | - (id)copyWithZone:(NSZone *)zone { 231 | AFHTTPRequestOperationManager *HTTPClient = [[[self class] allocWithZone:zone] initWithBaseURL:self.baseURL]; 232 | 233 | HTTPClient.requestSerializer = [self.requestSerializer copyWithZone:zone]; 234 | HTTPClient.responseSerializer = [self.responseSerializer copyWithZone:zone]; 235 | 236 | return HTTPClient; 237 | } 238 | 239 | @end 240 | -------------------------------------------------------------------------------- /JFOpenWeatherMapManager/AFNetworking/AFHTTPSessionManager.m: -------------------------------------------------------------------------------- 1 | // AFHTTPSessionManager.m 2 | // 3 | // Copyright (c) 2013 AFNetworking (http://afnetworking.com) 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | #import "AFHTTPSessionManager.h" 24 | 25 | #if (defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 70000) || (defined(__MAC_OS_X_VERSION_MAX_ALLOWED) && __MAC_OS_X_VERSION_MAX_ALLOWED >= 1090) 26 | 27 | #import "AFHTTPRequestOperation.h" 28 | 29 | #import 30 | #import 31 | 32 | #ifdef _SYSTEMCONFIGURATION_H 33 | #import 34 | #import 35 | #import 36 | #import 37 | #import 38 | #endif 39 | 40 | #if defined(__IPHONE_OS_VERSION_MIN_REQUIRED) 41 | #import 42 | #endif 43 | 44 | @interface AFHTTPSessionManager () 45 | @property (readwrite, nonatomic, strong) NSURL *baseURL; 46 | @property (readwrite, nonatomic, strong) AFNetworkReachabilityManager *reachabilityManager; 47 | @end 48 | 49 | @implementation AFHTTPSessionManager 50 | 51 | + (instancetype)manager { 52 | return [[AFHTTPSessionManager alloc] initWithBaseURL:nil]; 53 | } 54 | 55 | - (instancetype)init { 56 | return [self initWithBaseURL:nil]; 57 | } 58 | 59 | - (instancetype)initWithBaseURL:(NSURL *)url { 60 | return [self initWithBaseURL:url sessionConfiguration:nil]; 61 | } 62 | 63 | - (instancetype)initWithSessionConfiguration:(NSURLSessionConfiguration *)configuration { 64 | return [self initWithBaseURL:nil sessionConfiguration:configuration]; 65 | } 66 | 67 | - (instancetype)initWithBaseURL:(NSURL *)url 68 | sessionConfiguration:(NSURLSessionConfiguration *)configuration 69 | { 70 | self = [super initWithSessionConfiguration:configuration]; 71 | if (!self) { 72 | return nil; 73 | } 74 | 75 | // Ensure terminal slash for baseURL path, so that NSURL +URLWithString:relativeToURL: works as expected 76 | if ([[url path] length] > 0 && ![[url absoluteString] hasSuffix:@"/"]) { 77 | url = [url URLByAppendingPathComponent:@""]; 78 | } 79 | 80 | self.baseURL = url; 81 | 82 | self.requestSerializer = [AFHTTPRequestSerializer serializer]; 83 | self.responseSerializer = [AFJSONResponseSerializer serializer]; 84 | 85 | self.securityPolicy = [AFSecurityPolicy defaultPolicy]; 86 | 87 | if (self.baseURL.host) { 88 | self.reachabilityManager = [AFNetworkReachabilityManager managerForDomain:self.baseURL.host]; 89 | } else { 90 | self.reachabilityManager = [AFNetworkReachabilityManager sharedManager]; 91 | } 92 | 93 | return self; 94 | } 95 | 96 | - (NSString *)description { 97 | return [NSString stringWithFormat:@"<%@: %p, baseURL: %@, session: %@, operationQueue: %@>", NSStringFromClass([self class]), self, [self.baseURL absoluteString], self.session, self.operationQueue]; 98 | } 99 | 100 | #pragma mark - 101 | 102 | #ifdef _SYSTEMCONFIGURATION_H 103 | #endif 104 | 105 | - (void)setRequestSerializer:(AFHTTPRequestSerializer *)requestSerializer { 106 | NSParameterAssert(requestSerializer); 107 | 108 | _requestSerializer = requestSerializer; 109 | } 110 | 111 | - (void)setResponseSerializer:(AFHTTPResponseSerializer *)responseSerializer { 112 | NSParameterAssert(responseSerializer); 113 | 114 | [super setResponseSerializer:responseSerializer]; 115 | } 116 | 117 | #pragma mark - 118 | 119 | - (NSURLSessionDataTask *)GET:(NSString *)URLString 120 | parameters:(NSDictionary *)parameters 121 | success:(void (^)(NSURLSessionDataTask *task, id responseObject))success 122 | failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure 123 | { 124 | NSMutableURLRequest *request = [self.requestSerializer requestWithMethod:@"GET" URLString:[[NSURL URLWithString:URLString relativeToURL:self.baseURL] absoluteString] parameters:parameters]; 125 | 126 | __block NSURLSessionDataTask *task = [self dataTaskWithRequest:request completionHandler:^(NSURLResponse * __unused response, id responseObject, NSError *error) { 127 | if (error) { 128 | if (failure) { 129 | failure(task, error); 130 | } 131 | } else { 132 | if (success) { 133 | success(task, responseObject); 134 | } 135 | } 136 | }]; 137 | 138 | [task resume]; 139 | 140 | return task; 141 | } 142 | 143 | - (NSURLSessionDataTask *)HEAD:(NSString *)URLString 144 | parameters:(NSDictionary *)parameters 145 | success:(void (^)(NSURLSessionDataTask *task))success 146 | failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure 147 | { 148 | NSMutableURLRequest *request = [self.requestSerializer requestWithMethod:@"HEAD" URLString:[[NSURL URLWithString:URLString relativeToURL:self.baseURL] absoluteString] parameters:parameters]; 149 | 150 | __block NSURLSessionDataTask *task = [self dataTaskWithRequest:request completionHandler:^(NSURLResponse * __unused response, id __unused responseObject, NSError *error) { 151 | if (error) { 152 | if (failure) { 153 | failure(task, error); 154 | } 155 | } else { 156 | if (success) { 157 | success(task); 158 | } 159 | } 160 | }]; 161 | 162 | [task resume]; 163 | 164 | return task; 165 | } 166 | 167 | - (NSURLSessionDataTask *)POST:(NSString *)URLString 168 | parameters:(NSDictionary *)parameters 169 | success:(void (^)(NSURLSessionDataTask *task, id responseObject))success 170 | failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure 171 | { 172 | NSMutableURLRequest *request = [self.requestSerializer requestWithMethod:@"POST" URLString:[[NSURL URLWithString:URLString relativeToURL:self.baseURL] absoluteString] parameters:parameters]; 173 | 174 | __block NSURLSessionDataTask *task = [self dataTaskWithRequest:request completionHandler:^(NSURLResponse * __unused response, id responseObject, NSError *error) { 175 | if (error) { 176 | if (failure) { 177 | failure(task, error); 178 | } 179 | } else { 180 | if (success) { 181 | success(task, responseObject); 182 | } 183 | } 184 | }]; 185 | 186 | [task resume]; 187 | 188 | return task; 189 | } 190 | 191 | - (NSURLSessionDataTask *)POST:(NSString *)URLString 192 | parameters:(NSDictionary *)parameters 193 | constructingBodyWithBlock:(void (^)(id formData))block 194 | success:(void (^)(NSURLSessionDataTask *task, id responseObject))success 195 | failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure 196 | { 197 | NSMutableURLRequest *request = [self.requestSerializer multipartFormRequestWithMethod:@"POST" URLString:[[NSURL URLWithString:URLString relativeToURL:self.baseURL] absoluteString] parameters:parameters constructingBodyWithBlock:block]; 198 | 199 | __block NSURLSessionDataTask *task = [self dataTaskWithRequest:request completionHandler:^(NSURLResponse * __unused response, id responseObject, NSError *error) { 200 | if (error) { 201 | if (failure) { 202 | failure(task, error); 203 | } 204 | } else { 205 | if (success) { 206 | success(task, responseObject); 207 | } 208 | } 209 | }]; 210 | 211 | [task resume]; 212 | 213 | return task; 214 | } 215 | 216 | - (NSURLSessionDataTask *)PUT:(NSString *)URLString 217 | parameters:(NSDictionary *)parameters 218 | success:(void (^)(NSURLSessionDataTask *task, id responseObject))success 219 | failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure 220 | { 221 | NSMutableURLRequest *request = [self.requestSerializer requestWithMethod:@"PUT" URLString:[[NSURL URLWithString:URLString relativeToURL:self.baseURL] absoluteString] parameters:parameters]; 222 | 223 | __block NSURLSessionDataTask *task = [self dataTaskWithRequest:request completionHandler:^(NSURLResponse * __unused response, id responseObject, NSError *error) { 224 | if (error) { 225 | if (failure) { 226 | failure(task, error); 227 | } 228 | } else { 229 | if (success) { 230 | success(task, responseObject); 231 | } 232 | } 233 | }]; 234 | 235 | [task resume]; 236 | 237 | return task; 238 | } 239 | 240 | - (NSURLSessionDataTask *)PATCH:(NSString *)URLString 241 | parameters:(NSDictionary *)parameters 242 | success:(void (^)(NSURLSessionDataTask *task, id responseObject))success 243 | failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure 244 | { 245 | NSMutableURLRequest *request = [self.requestSerializer requestWithMethod:@"PATCH" URLString:[[NSURL URLWithString:URLString relativeToURL:self.baseURL] absoluteString] parameters:parameters]; 246 | 247 | __block NSURLSessionDataTask *task = [self dataTaskWithRequest:request completionHandler:^(NSURLResponse * __unused response, id responseObject, NSError *error) { 248 | if (error) { 249 | if (failure) { 250 | failure(task, error); 251 | } 252 | } else { 253 | if (success) { 254 | success(task, responseObject); 255 | } 256 | } 257 | }]; 258 | 259 | [task resume]; 260 | 261 | return task; 262 | } 263 | 264 | - (NSURLSessionDataTask *)DELETE:(NSString *)URLString 265 | parameters:(NSDictionary *)parameters 266 | success:(void (^)(NSURLSessionDataTask *task, id responseObject))success 267 | failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure 268 | { 269 | NSMutableURLRequest *request = [self.requestSerializer requestWithMethod:@"DELETE" URLString:[[NSURL URLWithString:URLString relativeToURL:self.baseURL] absoluteString] parameters:parameters]; 270 | 271 | __block NSURLSessionDataTask *task = [self dataTaskWithRequest:request completionHandler:^(NSURLResponse * __unused response, id responseObject, NSError *error) { 272 | if (error) { 273 | if (failure) { 274 | failure(task, error); 275 | } 276 | } else { 277 | if (success) { 278 | success(task, responseObject); 279 | } 280 | } 281 | }]; 282 | 283 | [task resume]; 284 | 285 | return task; 286 | } 287 | 288 | #pragma mark - NSCoding 289 | 290 | - (id)initWithCoder:(NSCoder *)decoder { 291 | NSURL *baseURL = [decoder decodeObjectForKey:NSStringFromSelector(@selector(baseURL))]; 292 | NSURLSessionConfiguration *configuration = [decoder decodeObjectForKey:@"sessionConfiguration"]; 293 | 294 | self = [self initWithBaseURL:baseURL sessionConfiguration:configuration]; 295 | if (!self) { 296 | return nil; 297 | } 298 | 299 | self.requestSerializer = [decoder decodeObjectForKey:NSStringFromSelector(@selector(requestSerializer))]; 300 | self.responseSerializer = [decoder decodeObjectForKey:NSStringFromSelector(@selector(responseSerializer))]; 301 | 302 | return self; 303 | } 304 | 305 | - (void)encodeWithCoder:(NSCoder *)coder { 306 | [super encodeWithCoder:coder]; 307 | 308 | [coder encodeObject:self.baseURL forKey:NSStringFromSelector(@selector(baseURL))]; 309 | [coder encodeObject:self.session.configuration forKey:@"sessionConfiguration"]; 310 | [coder encodeObject:self.requestSerializer forKey:NSStringFromSelector(@selector(requestSerializer))]; 311 | [coder encodeObject:self.responseSerializer forKey:NSStringFromSelector(@selector(responseSerializer))]; 312 | } 313 | 314 | #pragma mark - NSCopying 315 | 316 | - (id)copyWithZone:(NSZone *)zone { 317 | AFHTTPSessionManager *HTTPClient = [[[self class] allocWithZone:zone] initWithBaseURL:self.baseURL sessionConfiguration:self.session.configuration]; 318 | 319 | HTTPClient.requestSerializer = [self.requestSerializer copyWithZone:zone]; 320 | HTTPClient.responseSerializer = [self.responseSerializer copyWithZone:zone]; 321 | 322 | return HTTPClient; 323 | } 324 | 325 | @end 326 | 327 | #endif 328 | -------------------------------------------------------------------------------- /JFOpenWeatherMapManager/JFWeatherData.m: -------------------------------------------------------------------------------- 1 | // 2 | // JFWeatherData.m 3 | // 4 | // Created by Jonathan Field on 27/10/2013 5 | // Copyright (c) 2013 __MyCompanyName__. All rights reserved. 6 | // 7 | 8 | #import "JFWeatherData.h" 9 | 10 | 11 | NSString *const kJFWeatherDataBase = @"base"; 12 | NSString *const kJFWeatherDataId = @"id"; 13 | NSString *const kJFWeatherDataDt = @"dt"; 14 | NSString *const kJFWeatherDataMain = @"main"; 15 | NSString *const kJFWeatherDataWind = @"wind"; 16 | NSString *const kJFWeatherDataCoord = @"coord"; 17 | NSString *const kJFWeatherDataSys = @"sys"; 18 | NSString *const kJFWeatherDataWeather = @"weather"; 19 | NSString *const kJFWeatherDataClouds = @"clouds"; 20 | NSString *const kJFWeatherDataCod = @"cod"; 21 | NSString *const kJFWeatherDataName = @"name"; 22 | NSString *const kJFWeatherDataRain = @"rain"; 23 | NSString *const kJFWeatherDataSnow = @"snow"; 24 | 25 | 26 | @interface JFWeatherData () 27 | 28 | - (id)objectOrNilForKey:(id)aKey fromDictionary:(NSDictionary *)dict; 29 | 30 | @end 31 | 32 | @implementation JFWeatherData 33 | 34 | @synthesize base = _base; 35 | @synthesize internalBaseClassIdentifier = _internalBaseClassIdentifier; 36 | @synthesize dt = _dt; 37 | @synthesize main = _main; 38 | @synthesize wind = _wind; 39 | @synthesize coord = _coord; 40 | @synthesize sys = _sys; 41 | @synthesize weather = _weather; 42 | @synthesize clouds = _clouds; 43 | @synthesize cod = _cod; 44 | @synthesize name = _name; 45 | @synthesize rain = _rain; 46 | @synthesize snow = _snow; 47 | 48 | 49 | + (JFWeatherData *)modelObjectWithDictionary:(NSDictionary *)dict 50 | { 51 | JFWeatherData *instance = [[JFWeatherData alloc] initWithDictionary:dict]; 52 | return instance; 53 | } 54 | 55 | - (instancetype)initWithDictionary:(NSDictionary *)dict 56 | { 57 | self = [super init]; 58 | 59 | // This check serves to make sure that a non-NSDictionary object 60 | // passed into the model class doesn't break the parsing. 61 | if(self && [dict isKindOfClass:[NSDictionary class]]) { 62 | self.base = [self objectOrNilForKey:kJFWeatherDataBase fromDictionary:dict]; 63 | self.internalBaseClassIdentifier = [[self objectOrNilForKey:kJFWeatherDataId fromDictionary:dict] doubleValue]; 64 | self.dt = [[self objectOrNilForKey:kJFWeatherDataDt fromDictionary:dict] doubleValue]; 65 | self.main = [Main modelObjectWithDictionary:[dict objectForKey:kJFWeatherDataMain]]; 66 | self.wind = [Wind modelObjectWithDictionary:[dict objectForKey:kJFWeatherDataWind]]; 67 | self.coord = [Coord modelObjectWithDictionary:[dict objectForKey:kJFWeatherDataCoord]]; 68 | self.sys = [Sys modelObjectWithDictionary:[dict objectForKey:kJFWeatherDataSys]]; 69 | NSObject *receivedJFWeather = [dict objectForKey:kJFWeatherDataWeather]; 70 | NSMutableArray *parsedJFWeather = [NSMutableArray array]; 71 | if ([receivedJFWeather isKindOfClass:[NSArray class]]) { 72 | for (NSDictionary *item in (NSArray *)receivedJFWeather) { 73 | if ([item isKindOfClass:[NSDictionary class]]) { 74 | [parsedJFWeather addObject:[Weather modelObjectWithDictionary:item]]; 75 | } 76 | } 77 | } else if ([receivedJFWeather isKindOfClass:[NSDictionary class]]) { 78 | [parsedJFWeather addObject:[Weather modelObjectWithDictionary:(NSDictionary *)receivedJFWeather]]; 79 | } 80 | 81 | self.weather = [NSArray arrayWithArray:parsedJFWeather]; 82 | self.clouds = [Clouds modelObjectWithDictionary:[dict objectForKey:kJFWeatherDataClouds]]; 83 | self.cod = [[self objectOrNilForKey:kJFWeatherDataCod fromDictionary:dict] doubleValue]; 84 | self.name = [self objectOrNilForKey:kJFWeatherDataName fromDictionary:dict]; 85 | self.rain = [Rain modelObjectWithDictionary:[dict objectForKey:kJFWeatherDataRain]]; 86 | self.snow = [Snow modelObjectWithDictionary:[dict objectForKey:kJFWeatherDataSnow]]; 87 | 88 | } 89 | 90 | return self; 91 | 92 | } 93 | 94 | - (NSDictionary *)dictionaryRepresentation 95 | { 96 | NSMutableDictionary *mutableDict = [NSMutableDictionary dictionary]; 97 | [mutableDict setValue:self.base forKey:kJFWeatherDataBase]; 98 | [mutableDict setValue:[NSNumber numberWithDouble:self.internalBaseClassIdentifier] forKey:kJFWeatherDataId]; 99 | [mutableDict setValue:[NSNumber numberWithDouble:self.dt] forKey:kJFWeatherDataDt]; 100 | [mutableDict setValue:[self.main dictionaryRepresentation] forKey:kJFWeatherDataMain]; 101 | [mutableDict setValue:[self.wind dictionaryRepresentation] forKey:kJFWeatherDataWind]; 102 | [mutableDict setValue:[self.coord dictionaryRepresentation] forKey:kJFWeatherDataCoord]; 103 | [mutableDict setValue:[self.sys dictionaryRepresentation] forKey:kJFWeatherDataSys]; 104 | NSMutableArray *tempArrayForWeather = [NSMutableArray array]; 105 | for (NSObject *subArrayObject in self.weather) { 106 | if([subArrayObject respondsToSelector:@selector(dictionaryRepresentation)]) { 107 | // This class is a model object 108 | [tempArrayForWeather addObject:[subArrayObject performSelector:@selector(dictionaryRepresentation)]]; 109 | } else { 110 | // Generic object 111 | [tempArrayForWeather addObject:subArrayObject]; 112 | } 113 | } 114 | [mutableDict setValue:[NSArray arrayWithArray:tempArrayForWeather] forKey:@"kJFWeatherDataWeather"]; 115 | [mutableDict setValue:[self.clouds dictionaryRepresentation] forKey:kJFWeatherDataClouds]; 116 | [mutableDict setValue:[NSNumber numberWithDouble:self.cod] forKey:kJFWeatherDataCod]; 117 | [mutableDict setValue:self.name forKey:kJFWeatherDataName]; 118 | [mutableDict setValue:[self.rain dictionaryRepresentation] forKey:kJFWeatherDataRain]; 119 | [mutableDict setValue:[self.snow dictionaryRepresentation] forKey:kJFWeatherDataSnow]; 120 | 121 | return [NSDictionary dictionaryWithDictionary:mutableDict]; 122 | } 123 | 124 | - (NSString *)description 125 | { 126 | return [NSString stringWithFormat:@"%@", [self dictionaryRepresentation]]; 127 | } 128 | 129 | #pragma mark - Helper Method 130 | - (id)objectOrNilForKey:(id)aKey fromDictionary:(NSDictionary *)dict 131 | { 132 | id object = [dict objectForKey:aKey]; 133 | return [object isEqual:[NSNull null]] ? nil : object; 134 | } 135 | 136 | 137 | #pragma mark - NSCoding Methods 138 | 139 | - (id)initWithCoder:(NSCoder *)aDecoder 140 | { 141 | self = [super init]; 142 | 143 | self.base = [aDecoder decodeObjectForKey:kJFWeatherDataBase]; 144 | self.internalBaseClassIdentifier = [aDecoder decodeDoubleForKey:kJFWeatherDataId]; 145 | self.dt = [aDecoder decodeDoubleForKey:kJFWeatherDataDt]; 146 | self.main = [aDecoder decodeObjectForKey:kJFWeatherDataMain]; 147 | self.wind = [aDecoder decodeObjectForKey:kJFWeatherDataWind]; 148 | self.coord = [aDecoder decodeObjectForKey:kJFWeatherDataCoord]; 149 | self.sys = [aDecoder decodeObjectForKey:kJFWeatherDataSys]; 150 | self.weather = [aDecoder decodeObjectForKey:kJFWeatherDataWeather]; 151 | self.clouds = [aDecoder decodeObjectForKey:kJFWeatherDataClouds]; 152 | self.cod = [aDecoder decodeDoubleForKey:kJFWeatherDataCod]; 153 | self.name = [aDecoder decodeObjectForKey:kJFWeatherDataName]; 154 | self.rain = [aDecoder decodeObjectForKey:kJFWeatherDataRain]; 155 | self.snow = [aDecoder decodeObjectForKey:kJFWeatherDataSnow]; 156 | return self; 157 | } 158 | 159 | - (void)encodeWithCoder:(NSCoder *)aCoder 160 | { 161 | 162 | [aCoder encodeObject:_base forKey:kJFWeatherDataBase]; 163 | [aCoder encodeDouble:_internalBaseClassIdentifier forKey:kJFWeatherDataId]; 164 | [aCoder encodeDouble:_dt forKey:kJFWeatherDataDt]; 165 | [aCoder encodeObject:_main forKey:kJFWeatherDataMain]; 166 | [aCoder encodeObject:_wind forKey:kJFWeatherDataWind]; 167 | [aCoder encodeObject:_coord forKey:kJFWeatherDataCoord]; 168 | [aCoder encodeObject:_sys forKey:kJFWeatherDataSys]; 169 | [aCoder encodeObject:_weather forKey:kJFWeatherDataWeather]; 170 | [aCoder encodeObject:_clouds forKey:kJFWeatherDataClouds]; 171 | [aCoder encodeDouble:_cod forKey:kJFWeatherDataCod]; 172 | [aCoder encodeObject:_name forKey:kJFWeatherDataName]; 173 | [aCoder encodeObject:_rain forKey:kJFWeatherDataRain]; 174 | [aCoder encodeObject:_snow forKey:kJFWeatherDataSnow]; 175 | } 176 | 177 | - (NSString *)currentConditionsTextualDescription{ 178 | 179 | NSString *retval; 180 | 181 | @try { 182 | NSArray *currentConditionsList = self.weather; 183 | Weather *currentConditions = [currentConditionsList objectAtIndex:0]; 184 | retval = currentConditions.weatherDescription; 185 | } 186 | @catch (NSException *exception) { 187 | NSLog(@"Exception %@",exception); 188 | retval = nil; 189 | } 190 | 191 | return [retval capitalizedString]; 192 | 193 | } 194 | 195 | - (double)temperatureInUnitFormat:(TemperatureUnit)temperatureUnit{ 196 | 197 | double retval; 198 | 199 | switch (temperatureUnit) { 200 | case kTemperatureKelvin: 201 | retval = self.main.temp; 202 | break; 203 | 204 | case kTemperatureCelcius: 205 | retval = self.main.temp - 273.15; 206 | break; 207 | 208 | case kTemperatureFarenheit: 209 | retval = (self.main.temp - 273.15) * 1.8000 + 32.00; 210 | break; 211 | } 212 | 213 | return retval ? retval : 0.0; 214 | 215 | 216 | } 217 | 218 | - (double)pressureInUnitFormat:(PressureUnit)pressureUnit{ 219 | 220 | double retval; 221 | 222 | switch (pressureUnit) { 223 | case kPressureHectopascal: 224 | retval = self.main.pressure; 225 | break; 226 | 227 | case kPressurePascal: 228 | retval = self.main.pressure / 100; 229 | break; 230 | } 231 | 232 | return retval ? retval : 0.0; 233 | 234 | } 235 | 236 | - (double)windSpeedInUnitFormat:(WindSpeedUnit)windSpeedUnit{ 237 | 238 | double retval; 239 | 240 | switch (windSpeedUnit) { 241 | case kWindSpeedMPS: 242 | retval = self.wind.speed; 243 | break; 244 | 245 | case kWindSpeedMPH: 246 | retval = self.wind.speed * 2.2369; 247 | break; 248 | 249 | case kWindSpeedKPH: 250 | retval = self.wind.speed * 3.6; 251 | break; 252 | } 253 | 254 | return retval ? retval : 0.0; 255 | 256 | 257 | } 258 | 259 | - (NSString *)sunriseTime{ 260 | 261 | CLLocation *location = [[CLLocation alloc] initWithLatitude:self.latitudeCoordinateOfRequest longitude:self.longitudeCoordinateOfRequest]; 262 | 263 | NSTimeInterval rawSunrise = (double)self.sys.sunrise; 264 | NSDate *sunriseUtcTimeStamp = [NSDate date]; 265 | sunriseUtcTimeStamp = [NSDate dateWithTimeIntervalSince1970:rawSunrise]; 266 | 267 | NSDateFormatter *localTimeZoneFormatter = [NSDateFormatter new]; 268 | localTimeZoneFormatter.timeZone = location.timeZone; 269 | localTimeZoneFormatter.dateFormat = @"HH:mm"; 270 | NSString *localSunriseTime = [localTimeZoneFormatter stringFromDate:sunriseUtcTimeStamp]; 271 | 272 | return localSunriseTime; 273 | 274 | } 275 | 276 | - (NSString *)sunsetTime{ 277 | 278 | CLLocation *location = [[CLLocation alloc] initWithLatitude:self.latitudeCoordinateOfRequest longitude:self.longitudeCoordinateOfRequest]; 279 | 280 | NSTimeInterval rawSunset = (double)self.sys.sunset; 281 | NSDate *sunsetUtcTimeStamp = [NSDate date]; 282 | sunsetUtcTimeStamp = [NSDate dateWithTimeIntervalSince1970:rawSunset]; 283 | 284 | NSDateFormatter *localTimeZoneFormatter = [NSDateFormatter new]; 285 | localTimeZoneFormatter.timeZone = location.timeZone; 286 | localTimeZoneFormatter.dateFormat = @"HH:mm"; 287 | NSString *localSunsetTime = [localTimeZoneFormatter stringFromDate:sunsetUtcTimeStamp]; 288 | 289 | return localSunsetTime; 290 | 291 | } 292 | 293 | - (NSString *)dayLightHours{ 294 | 295 | NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; 296 | [dateFormatter setDateFormat:@"HH:mm"]; 297 | NSDate *sunrise = [dateFormatter dateFromString:[self sunriseTime]]; 298 | NSDate *sunset = [dateFormatter dateFromString:[self sunsetTime]]; 299 | NSTimeInterval interval = [sunset timeIntervalSinceDate:sunrise]; 300 | NSInteger hours = (NSInteger)interval / 3600; 301 | NSInteger minutes = (interval - (hours * 3600)) / 60; 302 | NSString *timeDiff = [NSString stringWithFormat:@"%ld:%02ld", (long)hours, (long)minutes]; 303 | 304 | return timeDiff; 305 | 306 | } 307 | 308 | - (NSString *)humidityPercentage{ 309 | 310 | return [NSString stringWithFormat:@"%0.f%%",self.main.humidity]; 311 | 312 | } 313 | 314 | - (NSString *)cloudCovergePercentage{ 315 | 316 | return [NSString stringWithFormat:@"%0.f%%",self.clouds.all]; 317 | 318 | } 319 | 320 | - (double)windDirectionInDegrees{ 321 | 322 | return self.wind.deg ? self.wind.deg : 0.0; 323 | 324 | } 325 | 326 | - (NSString *)windDirectionInGeographicalDirection{ 327 | 328 | double directionInDegrees = [self windDirectionInDegrees]; 329 | NSString *retval; 330 | 331 | if ((directionInDegrees >= 339) || (directionInDegrees <= 22)) { 332 | retval = @"N"; 333 | }else if ((directionInDegrees > 23) && (directionInDegrees <= 68)) { 334 | retval = @"NE"; 335 | }else if ((directionInDegrees > 69) && (directionInDegrees <= 113)) { 336 | retval = @"E"; 337 | }else if ((directionInDegrees > 114) && (directionInDegrees <= 158)) { 338 | retval = @"SE"; 339 | }else if ((directionInDegrees > 159) && (directionInDegrees <= 203)) { 340 | retval = @"S"; 341 | }else if ((directionInDegrees > 204) && (directionInDegrees <= 248)) { 342 | retval = @"SW"; 343 | }else if ((directionInDegrees > 249) && (directionInDegrees <= 293)) { 344 | retval = @"W"; 345 | }else if ((directionInDegrees > 294) && (directionInDegrees <= 338)) { 346 | retval = @"NW"; 347 | } 348 | 349 | return retval ? retval : @"N/A"; 350 | 351 | } 352 | 353 | - (double)rainFallVolumeOver3HoursInMillimeters{ 354 | 355 | return self.rain.threeHour ? self.rain.threeHour : 0.0; 356 | 357 | } 358 | 359 | - (double)snowFallVolumeOver3HoursInMillimeters{ 360 | 361 | return self.snow.threeHour ? self.snow.threeHour : 0.0; 362 | 363 | } 364 | 365 | - (double)latitudeCoordinateOfRequest{ 366 | 367 | return self.coord.lat ? self.coord.lat : 0.0; 368 | 369 | } 370 | 371 | - (double)longitudeCoordinateOfRequest{ 372 | 373 | return self.coord.lon ? self.coord.lon : 0.0; 374 | 375 | } 376 | 377 | - (NSString *)countryCode{ 378 | 379 | return self.sys.country ? self.sys.country : @"N/A"; 380 | 381 | } 382 | 383 | @end 384 | -------------------------------------------------------------------------------- /JFOpenWeatherMapManager/AFNetworking/AFHTTPSessionManager.h: -------------------------------------------------------------------------------- 1 | // AFHTTPSessionManager.h 2 | // 3 | // Copyright (c) 2013 AFNetworking (http://afnetworking.com) 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | #import 24 | #import 25 | #import 26 | 27 | #if __IPHONE_OS_VERSION_MIN_REQUIRED 28 | #import 29 | #else 30 | #import 31 | #endif 32 | 33 | #import "AFURLSessionManager.h" 34 | 35 | /** 36 | `AFHTTPSessionManager` is a subclass of `AFURLSessionManager` with convenience methods for making HTTP requests. When a `baseURL` is provided, requests made with the `GET` / `POST` / et al. convenience methods can be made with relative paths; network reachability is also scoped to the host of the base URL as well. 37 | 38 | ## Subclassing Notes 39 | 40 | Developers targeting iOS 7 or Mac OS X 10.9 or later that deal extensively with a web service are encouraged to subclass `AFHTTPSessionManager`, providing a class method that returns a shared singleton object on which authentication and other configuration can be shared across the application. 41 | 42 | For developers targeting iOS 6 or Mac OS X 10.8 or earlier, `AFHTTPRequestOperationManager` may be used to similar effect. 43 | 44 | ## Methods to Override 45 | 46 | To change the behavior of all data task operation construction, which is also used in the `GET` / `POST` / et al. convenience methods, override `dataTaskWithRequest:completionHandler:`. 47 | 48 | ## Serialization 49 | 50 | Requests created by an HTTP client will contain default headers and encode parameters according to the `requestSerializer` property, which is an object conforming to ``. 51 | 52 | Responses received from the server are automatically validated and serialized by the `responseSerializers` property, which is an object conforming to `` 53 | 54 | ## URL Construction Using Relative Paths 55 | 56 | For HTTP convenience methods, the request serializer constructs URLs from the path relative to the `-baseURL`, using `NSURL +URLWithString:relativeToURL:`, when provided. If `baseURL` is `nil`, `path` needs to resolve to a valid `NSURL` object using `NSURL +URLWithString:`. 57 | 58 | Below are a few examples of how `baseURL` and relative paths interact: 59 | 60 | NSURL *baseURL = [NSURL URLWithString:@"http://example.com/v1/"]; 61 | [NSURL URLWithString:@"foo" relativeToURL:baseURL]; // http://example.com/v1/foo 62 | [NSURL URLWithString:@"foo?bar=baz" relativeToURL:baseURL]; // http://example.com/v1/foo?bar=baz 63 | [NSURL URLWithString:@"/foo" relativeToURL:baseURL]; // http://example.com/foo 64 | [NSURL URLWithString:@"foo/" relativeToURL:baseURL]; // http://example.com/v1/foo 65 | [NSURL URLWithString:@"/foo/" relativeToURL:baseURL]; // http://example.com/foo/ 66 | [NSURL URLWithString:@"http://example2.com/" relativeToURL:baseURL]; // http://example2.com/ 67 | 68 | Also important to note is that a trailing slash will be added to any `baseURL` without one. This would otherwise cause unexpected behavior when constructing URLs using paths without a leading slash. 69 | */ 70 | 71 | #if (defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 70000) || (defined(__MAC_OS_X_VERSION_MAX_ALLOWED) && __MAC_OS_X_VERSION_MAX_ALLOWED >= 1090) 72 | 73 | @interface AFHTTPSessionManager : AFURLSessionManager 74 | 75 | /** 76 | The URL used to monitor reachability, and construct requests from relative paths in methods like `requestWithMethod:URLString:parameters:`, and the `GET` / `POST` / et al. convenience methods. 77 | */ 78 | @property (readonly, nonatomic, strong) NSURL *baseURL; 79 | 80 | /** 81 | Requests created with `requestWithMethod:URLString:parameters:` & `multipartFormRequestWithMethod:URLString:parameters:constructingBodyWithBlock:` are constructed with a set of default headers using a parameter serialization specified by this property. By default, this is set to an instance of `AFHTTPRequestSerializer`, which serializes query string parameters for `GET`, `HEAD`, and `DELETE` requests, or otherwise URL-form-encodes HTTP message bodies. 82 | 83 | @warning `requestSerializer` must not be `nil`. 84 | */ 85 | @property (nonatomic, strong) AFHTTPRequestSerializer * requestSerializer; 86 | 87 | /** 88 | Responses sent from the server in data tasks created with `dataTaskWithRequest:success:failure:` and run using the `GET` / `POST` / et al. convenience methods are automatically validated and serialized by the response serializer. By default, this property is set to an instance of `AFJSONResponseSerializer`. 89 | 90 | @warning `responseSerializer` must not be `nil`. 91 | */ 92 | @property (nonatomic, strong) AFHTTPResponseSerializer * responseSerializer; 93 | 94 | ///--------------------- 95 | /// @name Initialization 96 | ///--------------------- 97 | 98 | /** 99 | Creates and returns an `AFHTTPSessionManager` object. 100 | */ 101 | + (instancetype)manager; 102 | 103 | /** 104 | Initializes an `AFHTTPSessionManager` object with the specified base URL. 105 | 106 | @param url The base URL for the HTTP client. 107 | 108 | @return The newly-initialized HTTP client 109 | */ 110 | - (instancetype)initWithBaseURL:(NSURL *)url; 111 | 112 | /** 113 | Initializes an `AFHTTPSessionManager` object with the specified base URL. 114 | 115 | This is the designated initializer. 116 | 117 | @param url The base URL for the HTTP client. 118 | @param configuration The configuration used to create the managed session. 119 | 120 | @return The newly-initialized HTTP client 121 | */ 122 | - (instancetype)initWithBaseURL:(NSURL *)url 123 | sessionConfiguration:(NSURLSessionConfiguration *)configuration; 124 | 125 | ///--------------------------- 126 | /// @name Making HTTP Requests 127 | ///--------------------------- 128 | 129 | /** 130 | Creates and runs an `NSURLSessionDataTask` with a `GET` request. 131 | 132 | @param URLString The URL string used to create the request URL. 133 | @param parameters The parameters to be encoded according to the client request serializer. 134 | @param success A block object to be executed when the task finishes successfully. This block has no return value and takes two arguments: the data task, and the response object created by the client response serializer. 135 | @param failure A block object to be executed when the task finishes unsuccessfully, or that finishes successfully, but encountered an error while parsing the response data. This block has no return value and takes a two arguments: the data task and the error describing the network or parsing error that occurred. 136 | 137 | @see -dataTaskWithRequest:completionHandler: 138 | */ 139 | - (NSURLSessionDataTask *)GET:(NSString *)URLString 140 | parameters:(NSDictionary *)parameters 141 | success:(void (^)(NSURLSessionDataTask *task, id responseObject))success 142 | failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure; 143 | 144 | /** 145 | Creates and runs an `NSURLSessionDataTask` with a `HEAD` request. 146 | 147 | @param URLString The URL string used to create the request URL. 148 | @param parameters The parameters to be encoded according to the client request serializer. 149 | @param success A block object to be executed when the task finishes successfully. This block has no return value and takes a single arguments: the data task. 150 | @param failure A block object to be executed when the task finishes unsuccessfully, or that finishes successfully, but encountered an error while parsing the response data. This block has no return value and takes a two arguments: the data task and the error describing the network or parsing error that occurred. 151 | 152 | @see -dataTaskWithRequest:completionHandler: 153 | */ 154 | - (NSURLSessionDataTask *)HEAD:(NSString *)URLString 155 | parameters:(NSDictionary *)parameters 156 | success:(void (^)(NSURLSessionDataTask *task))success 157 | failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure; 158 | 159 | /** 160 | Creates and runs an `NSURLSessionDataTask` with a `POST` request. 161 | 162 | @param URLString The URL string used to create the request URL. 163 | @param parameters The parameters to be encoded according to the client request serializer. 164 | @param success A block object to be executed when the task finishes successfully. This block has no return value and takes two arguments: the data task, and the response object created by the client response serializer. 165 | @param failure A block object to be executed when the task finishes unsuccessfully, or that finishes successfully, but encountered an error while parsing the response data. This block has no return value and takes a two arguments: the data task and the error describing the network or parsing error that occurred. 166 | 167 | @see -dataTaskWithRequest:completionHandler: 168 | */ 169 | - (NSURLSessionDataTask *)POST:(NSString *)URLString 170 | parameters:(NSDictionary *)parameters 171 | success:(void (^)(NSURLSessionDataTask *task, id responseObject))success 172 | failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure; 173 | 174 | /** 175 | Creates and runs an `NSURLSessionDataTask` with a multipart `POST` request. 176 | 177 | @param URLString The URL string used to create the request URL. 178 | @param parameters The parameters to be encoded according to the client request serializer. 179 | @param block A block that takes a single argument and appends data to the HTTP body. The block argument is an object adopting the `AFMultipartFormData` protocol. 180 | @param success A block object to be executed when the task finishes successfully. This block has no return value and takes two arguments: the data task, and the response object created by the client response serializer. 181 | @param failure A block object to be executed when the task finishes unsuccessfully, or that finishes successfully, but encountered an error while parsing the response data. This block has no return value and takes a two arguments: the data task and the error describing the network or parsing error that occurred. 182 | 183 | @see -dataTaskWithRequest:completionHandler: 184 | */ 185 | - (NSURLSessionDataTask *)POST:(NSString *)URLString 186 | parameters:(NSDictionary *)parameters 187 | constructingBodyWithBlock:(void (^)(id formData))block 188 | success:(void (^)(NSURLSessionDataTask *task, id responseObject))success 189 | failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure; 190 | 191 | /** 192 | Creates and runs an `NSURLSessionDataTask` with a `PUT` request. 193 | 194 | @param URLString The URL string used to create the request URL. 195 | @param parameters The parameters to be encoded according to the client request serializer. 196 | @param success A block object to be executed when the task finishes successfully. This block has no return value and takes two arguments: the data task, and the response object created by the client response serializer. 197 | @param failure A block object to be executed when the task finishes unsuccessfully, or that finishes successfully, but encountered an error while parsing the response data. This block has no return value and takes a two arguments: the data task and the error describing the network or parsing error that occurred. 198 | 199 | @see -dataTaskWithRequest:completionHandler: 200 | */ 201 | - (NSURLSessionDataTask *)PUT:(NSString *)URLString 202 | parameters:(NSDictionary *)parameters 203 | success:(void (^)(NSURLSessionDataTask *task, id responseObject))success 204 | failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure; 205 | 206 | /** 207 | Creates and runs an `NSURLSessionDataTask` with a `PATCH` request. 208 | 209 | @param URLString The URL string used to create the request URL. 210 | @param parameters The parameters to be encoded according to the client request serializer. 211 | @param success A block object to be executed when the task finishes successfully. This block has no return value and takes two arguments: the data task, and the response object created by the client response serializer. 212 | @param failure A block object to be executed when the task finishes unsuccessfully, or that finishes successfully, but encountered an error while parsing the response data. This block has no return value and takes a two arguments: the data task and the error describing the network or parsing error that occurred. 213 | 214 | @see -dataTaskWithRequest:completionHandler: 215 | */ 216 | - (NSURLSessionDataTask *)PATCH:(NSString *)URLString 217 | parameters:(NSDictionary *)parameters 218 | success:(void (^)(NSURLSessionDataTask *task, id responseObject))success 219 | failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure; 220 | 221 | /** 222 | Creates and runs an `NSURLSessionDataTask` with a `DELETE` request. 223 | 224 | @param URLString The URL string used to create the request URL. 225 | @param parameters The parameters to be encoded according to the client request serializer. 226 | @param success A block object to be executed when the task finishes successfully. This block has no return value and takes two arguments: the data task, and the response object created by the client response serializer. 227 | @param failure A block object to be executed when the task finishes unsuccessfully, or that finishes successfully, but encountered an error while parsing the response data. This block has no return value and takes a two arguments: the data task and the error describing the network or parsing error that occurred. 228 | 229 | @see -dataTaskWithRequest:completionHandler: 230 | */ 231 | - (NSURLSessionDataTask *)DELETE:(NSString *)URLString 232 | parameters:(NSDictionary *)parameters 233 | success:(void (^)(NSURLSessionDataTask *task, id responseObject))success 234 | failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure; 235 | 236 | @end 237 | 238 | #endif 239 | -------------------------------------------------------------------------------- /JFOpenWeatherMapManager/AFNetworking/AFURLRequestSerialization.h: -------------------------------------------------------------------------------- 1 | // AFSerialization.h 2 | // 3 | // Copyright (c) 2013 AFNetworking (http://afnetworking.com) 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | #import 24 | #if defined(__IPHONE_OS_VERSION_MIN_REQUIRED) 25 | #import 26 | #endif 27 | 28 | /** 29 | The `AFURLRequestSerialization` protocol is adopted by an object that encodes parameters for a specified HTTP requests. Request serializers may encode parameters as query strings, HTTP bodies, setting the appropriate HTTP header fields as necessary. 30 | 31 | For example, a JSON request serializer may set the HTTP body of the request to a JSON representation, and set the `Content-Type` HTTP header field value to `application/json`. 32 | */ 33 | @protocol AFURLRequestSerialization 34 | 35 | /** 36 | Returns a request with the specified parameters encoded into a copy of the original request. 37 | 38 | @param request The original request. 39 | @param parameters The parameters to be encoded. 40 | @param error The error that occurred while attempting to encode the request parameters. 41 | 42 | @return A serialized request. 43 | */ 44 | - (NSURLRequest *)requestBySerializingRequest:(NSURLRequest *)request 45 | withParameters:(NSDictionary *)parameters 46 | error:(NSError *__autoreleasing *)error; 47 | 48 | @end 49 | 50 | #pragma mark - 51 | 52 | /** 53 | 54 | */ 55 | typedef NS_ENUM(NSUInteger, AFHTTPRequestQueryStringSerializationStyle) { 56 | AFHTTPRequestQueryStringDefaultStyle = 0, 57 | }; 58 | 59 | @protocol AFMultipartFormData; 60 | 61 | /** 62 | `AFHTTPRequestSerializer` conforms to the `AFURLRequestSerialization` & `AFURLResponseSerialization` protocols, offering a concrete base implementation of query string / URL form-encoded parameter serialization and default request headers, as well as response status code and content type validation. 63 | 64 | Any request or response serializer dealing with HTTP is encouraged to subclass `AFHTTPRequestSerializer` in order to ensure consistent default behavior. 65 | */ 66 | @interface AFHTTPRequestSerializer : NSObject 67 | 68 | /** 69 | The string encoding used to serialize parameters. 70 | */ 71 | @property (nonatomic, assign) NSStringEncoding stringEncoding; 72 | 73 | ///--------------------------------------- 74 | /// @name Configuring HTTP Request Headers 75 | ///--------------------------------------- 76 | 77 | /** 78 | Default HTTP header field values to be applied to serialized requests. 79 | */ 80 | @property (readonly, nonatomic, strong) NSDictionary *HTTPRequestHeaders; 81 | 82 | /** 83 | Creates and returns a serializer with default configuration. 84 | */ 85 | + (instancetype)serializer; 86 | 87 | /** 88 | Sets the value for the HTTP headers set in request objects made by the HTTP client. If `nil`, removes the existing value for that header. 89 | 90 | @param field The HTTP header to set a default value for 91 | @param value The value set as default for the specified header, or `nil` 92 | */ 93 | - (void)setValue:(NSString *)value forHTTPHeaderField:(NSString *)field; 94 | 95 | /** 96 | Sets the "Authorization" HTTP header set in request objects made by the HTTP client to a basic authentication value with Base64-encoded username and password. This overwrites any existing value for this header. 97 | 98 | @param username The HTTP basic auth username 99 | @param password The HTTP basic auth password 100 | */ 101 | - (void)setAuthorizationHeaderFieldWithUsername:(NSString *)username 102 | password:(NSString *)password; 103 | 104 | /** 105 | Sets the "Authorization" HTTP header set in request objects made by the HTTP client to a token-based authentication value, such as an OAuth access token. This overwrites any existing value for this header. 106 | 107 | @param token The authentication token 108 | */ 109 | - (void)setAuthorizationHeaderFieldWithToken:(NSString *)token; 110 | 111 | 112 | /** 113 | Clears any existing value for the "Authorization" HTTP header. 114 | */ 115 | - (void)clearAuthorizationHeader; 116 | 117 | ///------------------------------------------------------- 118 | /// @name Configuring Query String Parameter Serialization 119 | ///------------------------------------------------------- 120 | 121 | /** 122 | HTTP methods for which serialized requests will encode parameters as a query string. `GET`, `HEAD`, and `DELETE` by default. 123 | */ 124 | @property (nonatomic, strong) NSSet *HTTPMethodsEncodingParametersInURI; 125 | 126 | /** 127 | Set the method of query string serialization according to one of the pre-defined styles. 128 | 129 | @param style The serialization style. 130 | 131 | @see AFHTTPRequestQueryStringSerializationStyle 132 | */ 133 | - (void)setQueryStringSerializationWithStyle:(AFHTTPRequestQueryStringSerializationStyle)style; 134 | 135 | /** 136 | Set the a custom method of query string serialization according to the specified block. 137 | 138 | @param block A block that defines a process of encoding parameters into a query string. This block returns the query string and takes three arguments: the request, the parameters to encode, and the error that occurred when attempting to encode parameters for the given request. 139 | */ 140 | - (void)setQueryStringSerializationWithBlock:(NSString * (^)(NSURLRequest *request, NSDictionary *parameters, NSError *__autoreleasing *error))block; 141 | 142 | ///------------------------------- 143 | /// @name Creating Request Objects 144 | ///------------------------------- 145 | 146 | /** 147 | Creates an `NSMutableURLRequest` object with the specified HTTP method and URL string. 148 | 149 | If the HTTP method is `GET`, `HEAD`, or `DELETE`, the parameters will be used to construct a url-encoded query string that is appended to the request's URL. Otherwise, the parameters will be encoded according to the value of the `parameterEncoding` property, and set as the request body. 150 | 151 | @param method The HTTP method for the request, such as `GET`, `POST`, `PUT`, or `DELETE`. This parameter must not be `nil`. 152 | @param URLString The URL string used to create the request URL. 153 | @param parameters The parameters to be either set as a query string for `GET` requests, or the request HTTP body. 154 | 155 | @return An `NSMutableURLRequest` object. 156 | */ 157 | - (NSMutableURLRequest *)requestWithMethod:(NSString *)method 158 | URLString:(NSString *)URLString 159 | parameters:(NSDictionary *)parameters; 160 | 161 | /** 162 | Creates an `NSMutableURLRequest` object with the specified HTTP method and URLString, and constructs a `multipart/form-data` HTTP body, using the specified parameters and multipart form data block. See http://www.w3.org/TR/html4/interact/forms.html#h-17.13.4.2 163 | 164 | Multipart form requests are automatically streamed, reading files directly from disk along with in-memory data in a single HTTP body. The resulting `NSMutableURLRequest` object has an `HTTPBodyStream` property, so refrain from setting `HTTPBodyStream` or `HTTPBody` on this request object, as it will clear out the multipart form body stream. 165 | 166 | @param method The HTTP method for the request. This parameter must not be `GET` or `HEAD`, or `nil`. 167 | @param URLString The URL string used to create the request URL. 168 | @param parameters The parameters to be encoded and set in the request HTTP body. 169 | @param block A block that takes a single argument and appends data to the HTTP body. The block argument is an object adopting the `AFMultipartFormData` protocol. 170 | 171 | @return An `NSMutableURLRequest` object 172 | */ 173 | - (NSMutableURLRequest *)multipartFormRequestWithMethod:(NSString *)method 174 | URLString:(NSString *)URLString 175 | parameters:(NSDictionary *)parameters 176 | constructingBodyWithBlock:(void (^)(id formData))block; 177 | 178 | @end 179 | 180 | #pragma mark - 181 | 182 | extern NSUInteger const kAFUploadStream3GSuggestedPacketSize; 183 | extern NSTimeInterval const kAFUploadStream3GSuggestedDelay; 184 | 185 | /** 186 | The `AFMultipartFormData` protocol defines the methods supported by the parameter in the block argument of `AFHTTPRequestSerializer -multipartFormRequestWithMethod:URLString:parameters:constructingBodyWithBlock:`. 187 | */ 188 | @protocol AFMultipartFormData 189 | 190 | /** 191 | Appends the HTTP header `Content-Disposition: file; filename=#{generated filename}; name=#{name}"` and `Content-Type: #{generated mimeType}`, followed by the encoded file data and the multipart form boundary. 192 | 193 | The filename and MIME type for this data in the form will be automatically generated, using the last path component of the `fileURL` and system associated MIME type for the `fileURL` extension, respectively. 194 | 195 | @param fileURL The URL corresponding to the file whose content will be appended to the form. This parameter must not be `nil`. 196 | @param name The name to be associated with the specified data. This parameter must not be `nil`. 197 | @param error If an error occurs, upon return contains an `NSError` object that describes the problem. 198 | 199 | @return `YES` if the file data was successfully appended, otherwise `NO`. 200 | */ 201 | - (BOOL)appendPartWithFileURL:(NSURL *)fileURL 202 | name:(NSString *)name 203 | error:(NSError * __autoreleasing *)error; 204 | 205 | /** 206 | Appends the HTTP header `Content-Disposition: file; filename=#{filename}; name=#{name}"` and `Content-Type: #{mimeType}`, followed by the encoded file data and the multipart form boundary. 207 | 208 | @param fileURL The URL corresponding to the file whose content will be appended to the form. This parameter must not be `nil`. 209 | @param name The name to be associated with the specified data. This parameter must not be `nil`. 210 | @param fileName The file name to be used in the `Content-Disposition` header. This parameter must not be `nil`. 211 | @param mimeType The declared MIME type of the file data. This parameter must not be `nil`. 212 | @param error If an error occurs, upon return contains an `NSError` object that describes the problem. 213 | 214 | @return `YES` if the file data was successfully appended otherwise `NO`. 215 | */ 216 | - (BOOL)appendPartWithFileURL:(NSURL *)fileURL 217 | name:(NSString *)name 218 | fileName:(NSString *)fileName 219 | mimeType:(NSString *)mimeType 220 | error:(NSError * __autoreleasing *)error; 221 | 222 | /** 223 | Appends the HTTP header `Content-Disposition: file; filename=#{filename}; name=#{name}"` and `Content-Type: #{mimeType}`, followed by the data from the input stream and the multipart form boundary. 224 | 225 | @param inputStream The input stream to be appended to the form data 226 | @param name The name to be associated with the specified input stream. This parameter must not be `nil`. 227 | @param fileName The filename to be associated with the specified input stream. This parameter must not be `nil`. 228 | @param length The length of the specified input stream in bytes. 229 | @param mimeType The MIME type of the specified data. (For example, the MIME type for a JPEG image is image/jpeg.) For a list of valid MIME types, see http://www.iana.org/assignments/media-types/. This parameter must not be `nil`. 230 | */ 231 | - (void)appendPartWithInputStream:(NSInputStream *)inputStream 232 | name:(NSString *)name 233 | fileName:(NSString *)fileName 234 | length:(int64_t)length 235 | mimeType:(NSString *)mimeType; 236 | 237 | /** 238 | Appends the HTTP header `Content-Disposition: file; filename=#{filename}; name=#{name}"` and `Content-Type: #{mimeType}`, followed by the encoded file data and the multipart form boundary. 239 | 240 | @param data The data to be encoded and appended to the form data. 241 | @param name The name to be associated with the specified data. This parameter must not be `nil`. 242 | @param fileName The filename to be associated with the specified data. This parameter must not be `nil`. 243 | @param mimeType The MIME type of the specified data. (For example, the MIME type for a JPEG image is image/jpeg.) For a list of valid MIME types, see http://www.iana.org/assignments/media-types/. This parameter must not be `nil`. 244 | */ 245 | - (void)appendPartWithFileData:(NSData *)data 246 | name:(NSString *)name 247 | fileName:(NSString *)fileName 248 | mimeType:(NSString *)mimeType; 249 | 250 | /** 251 | Appends the HTTP headers `Content-Disposition: form-data; name=#{name}"`, followed by the encoded data and the multipart form boundary. 252 | 253 | @param data The data to be encoded and appended to the form data. 254 | @param name The name to be associated with the specified data. This parameter must not be `nil`. 255 | */ 256 | 257 | - (void)appendPartWithFormData:(NSData *)data 258 | name:(NSString *)name; 259 | 260 | 261 | /** 262 | Appends HTTP headers, followed by the encoded data and the multipart form boundary. 263 | 264 | @param headers The HTTP headers to be appended to the form data. 265 | @param body The data to be encoded and appended to the form data. 266 | */ 267 | - (void)appendPartWithHeaders:(NSDictionary *)headers 268 | body:(NSData *)body; 269 | 270 | /** 271 | Throttles request bandwidth by limiting the packet size and adding a delay for each chunk read from the upload stream. 272 | 273 | When uploading over a 3G or EDGE connection, requests may fail with "request body stream exhausted". Setting a maximum packet size and delay according to the recommended values (`kAFUploadStream3GSuggestedPacketSize` and `kAFUploadStream3GSuggestedDelay`) lowers the risk of the input stream exceeding its allocated bandwidth. Unfortunately, there is no definite way to distinguish between a 3G, EDGE, or LTE connection over `NSURLConnection`. As such, it is not recommended that you throttle bandwidth based solely on network reachability. Instead, you should consider checking for the "request body stream exhausted" in a failure block, and then retrying the request with throttled bandwidth. 274 | 275 | @param numberOfBytes Maximum packet size, in number of bytes. The default packet size for an input stream is 16kb. 276 | @param delay Duration of delay each time a packet is read. By default, no delay is set. 277 | */ 278 | - (void)throttleBandwidthWithPacketSize:(NSUInteger)numberOfBytes 279 | delay:(NSTimeInterval)delay; 280 | 281 | @end 282 | 283 | ///---------------- 284 | /// @name Constants 285 | ///---------------- 286 | 287 | /** 288 | ## Throttling Bandwidth for HTTP Request Input Streams 289 | 290 | @see -throttleBandwidthWithPacketSize:delay: 291 | 292 | `kAFUploadStream3GSuggestedPacketSize` 293 | Maximum packet size, in number of bytes. Equal to 16kb. 294 | 295 | `kAFUploadStream3GSuggestedDelay` 296 | Duration of delay each time a packet is read. Equal to 0.2 seconds. 297 | */ 298 | 299 | #pragma mark - 300 | 301 | @interface AFJSONRequestSerializer : AFHTTPRequestSerializer 302 | 303 | /** 304 | The property list format. Possible values are described in "NSPropertyListFormat". 305 | */ 306 | @property (nonatomic, assign) NSPropertyListFormat format; 307 | 308 | /** 309 | Options for writing the request JSON data from Foundation objects. For possible values, see the `NSJSONSerialization` documentation section "NSJSONWritingOptions". `0` by default. 310 | */ 311 | @property (nonatomic, assign) NSJSONWritingOptions writingOptions; 312 | 313 | /** 314 | Creates and returns a JSON serializer with specified reading and writing options. 315 | 316 | @param writingOptions The specified JSON writing options. 317 | */ 318 | + (instancetype)serializerWithWritingOptions:(NSJSONWritingOptions)writingOptions; 319 | 320 | @end 321 | 322 | @interface AFPropertyListRequestSerializer : AFHTTPRequestSerializer 323 | 324 | /** 325 | The property list format. Possible values are described in "NSPropertyListFormat". 326 | */ 327 | @property (nonatomic, assign) NSPropertyListFormat format; 328 | 329 | /** 330 | @warning The `writeOptions` property is currently unused. 331 | */ 332 | @property (nonatomic, assign) NSPropertyListWriteOptions writeOptions; 333 | 334 | /** 335 | Creates and returns a property list serializer with a specified format, read options, and write options. 336 | 337 | @param format The property list format. 338 | @param writeOptions The property list write options. 339 | 340 | @warning The `writeOptions` property is currently unused. 341 | */ 342 | + (instancetype)serializerWithFormat:(NSPropertyListFormat)format 343 | writeOptions:(NSPropertyListWriteOptions)writeOptions; 344 | 345 | @end 346 | --------------------------------------------------------------------------------