├── Pods ├── Target Support Files │ ├── Alamofire │ │ ├── Alamofire-prefix.pch │ │ ├── Alamofire.modulemap │ │ ├── Alamofire-dummy.m │ │ ├── Alamofire-umbrella.h │ │ ├── Alamofire.xcconfig │ │ └── Info.plist │ ├── PromiseKit │ │ ├── PromiseKit-prefix.pch │ │ ├── PromiseKit-dummy.m │ │ ├── PromiseKit.xcconfig │ │ ├── Info.plist │ │ └── PromiseKit.modulemap │ ├── SwiftyJSON │ │ ├── SwiftyJSON-prefix.pch │ │ ├── SwiftyJSON.modulemap │ │ ├── SwiftyJSON-dummy.m │ │ ├── SwiftyJSON-umbrella.h │ │ ├── SwiftyJSON.xcconfig │ │ └── Info.plist │ ├── OMGHTTPURLRQ │ │ ├── OMGHTTPURLRQ-prefix.pch │ │ ├── OMGHTTPURLRQ.modulemap │ │ ├── OMGHTTPURLRQ-dummy.m │ │ ├── OMGHTTPURLRQ-umbrella.h │ │ ├── OMGHTTPURLRQ.xcconfig │ │ └── Info.plist │ ├── Pods-Network-Evolution-PracticeTests │ │ ├── Pods-Network-Evolution-PracticeTests-acknowledgements.markdown │ │ ├── Pods-Network-Evolution-PracticeTests.modulemap │ │ ├── Pods-Network-Evolution-PracticeTests-dummy.m │ │ ├── Pods-Network-Evolution-PracticeTests-umbrella.h │ │ ├── Pods-Network-Evolution-PracticeTests.debug.xcconfig │ │ ├── Pods-Network-Evolution-PracticeTests.release.xcconfig │ │ ├── Info.plist │ │ ├── Pods-Network-Evolution-PracticeTests-acknowledgements.plist │ │ └── Pods-Network-Evolution-PracticeTests-frameworks.sh │ ├── Pods-Network-Evolution-Practice │ │ ├── Pods-Network-Evolution-Practice.modulemap │ │ ├── Pods-Network-Evolution-Practice-dummy.m │ │ ├── Pods-Network-Evolution-Practice-umbrella.h │ │ ├── Info.plist │ │ ├── Pods-Network-Evolution-Practice.debug.xcconfig │ │ ├── Pods-Network-Evolution-Practice.release.xcconfig │ │ ├── Pods-Network-Evolution-Practice-acknowledgements.markdown │ │ ├── Pods-Network-Evolution-Practice-frameworks.sh │ │ └── Pods-Network-Evolution-Practice-acknowledgements.plist │ └── Pods-Network-Evolution-PracticeUITests │ │ ├── Pods-Network-Evolution-PracticeUITests-acknowledgements.markdown │ │ ├── Pods-Network-Evolution-PracticeUITests.modulemap │ │ ├── Pods-Network-Evolution-PracticeUITests-dummy.m │ │ ├── Pods-Network-Evolution-PracticeUITests-umbrella.h │ │ ├── Pods-Network-Evolution-PracticeUITests.debug.xcconfig │ │ ├── Pods-Network-Evolution-PracticeUITests.release.xcconfig │ │ ├── Info.plist │ │ ├── Pods-Network-Evolution-PracticeUITests-acknowledgements.plist │ │ └── Pods-Network-Evolution-PracticeUITests-frameworks.sh ├── OMGHTTPURLRQ │ └── Sources │ │ ├── OMGUserAgent.h │ │ ├── OMGFormURLEncode.h │ │ ├── OMGUserAgent.m │ │ ├── OMGHTTPURLRQ.h │ │ └── OMGFormURLEncode.m ├── PromiseKit │ ├── Sources │ │ ├── dispatch_promise.m │ │ ├── after.m │ │ ├── NSError+Cancellation.h │ │ ├── after.swift │ │ ├── dispatch_promise.swift │ │ ├── hang.m │ │ ├── race.swift │ │ ├── PMK.modulemap │ │ ├── AnyPromise+Private.h │ │ ├── join.m │ │ ├── join.swift │ │ ├── Promise+Properties.swift │ │ ├── NSMethodSignatureForBlock.m │ │ ├── Umbrella.h │ │ ├── when.m │ │ ├── URLDataPromise.swift │ │ ├── State.swift │ │ ├── AnyPromise.m │ │ └── PMKCallVariadicBlock.m │ ├── Categories │ │ ├── Foundation │ │ │ ├── NSNotificationCenter+AnyPromise.m │ │ │ ├── afterlife.swift │ │ │ ├── NSNotificationCenter+AnyPromise.h │ │ │ ├── NSNotificationCenter+Promise.swift │ │ │ ├── NSObject+Promise.swift │ │ │ ├── NSURLSession+Promise.swift │ │ │ ├── NSURLConnection+Promise.swift │ │ │ └── NSURLConnection+AnyPromise.m │ │ ├── QuartzCore │ │ │ ├── CALayer+AnyPromise.h │ │ │ └── CALayer+AnyPromise.m │ │ └── UIKit │ │ │ ├── UIAlertView+AnyPromise.h │ │ │ ├── UIActionSheet+AnyPromise.h │ │ │ ├── UIAlertView+AnyPromise.m │ │ │ ├── UIActionSheet+AnyPromise.m │ │ │ ├── UIView+Promise.swift │ │ │ ├── UIAlertView+Promise.swift │ │ │ ├── UIActionSheet+Promise.swift │ │ │ ├── UIView+AnyPromise.m │ │ │ ├── UIViewController+AnyPromise.h │ │ │ ├── UIView+AnyPromise.h │ │ │ ├── PMKAlertController.swift │ │ │ └── UIViewController+AnyPromise.m │ └── LICENSE ├── SwiftyJSON │ └── LICENSE ├── Alamofire │ ├── LICENSE │ └── Source │ │ ├── Notifications.swift │ │ ├── Result.swift │ │ ├── Response.swift │ │ └── Error.swift ├── Manifest.lock └── Pods.xcodeproj │ └── xcuserdata │ └── David.xcuserdatad │ └── xcschemes │ ├── xcschememanagement.plist │ ├── Alamofire.xcscheme │ ├── PromiseKit.xcscheme │ ├── SwiftyJSON.xcscheme │ ├── OMGHTTPURLRQ.xcscheme │ ├── Pods-Network-Evolution-Practice.xcscheme │ ├── Pods-Network-Evolution-PracticeTests.xcscheme │ └── Pods-Network-Evolution-PracticeUITests.xcscheme ├── Network-Evolution-Practice.xcworkspace ├── xcuserdata │ └── David.xcuserdatad │ │ └── xcdebugger │ │ └── Breakpoints_v2.xcbkptlist └── contents.xcworkspacedata ├── Network-Evolution-Practice.xcodeproj ├── project.xcworkspace │ └── contents.xcworkspacedata └── xcuserdata │ └── David.xcuserdatad │ └── xcschemes │ ├── xcschememanagement.plist │ └── Network-Evolution-Practice.xcscheme ├── Network-Evolution-Practice ├── JSONDecodable.swift ├── User.swift ├── FetchUser.swift ├── Assets.xcassets │ └── AppIcon.appiconset │ │ └── Contents.json ├── ViewController.swift ├── NetworkClient.swift ├── Info.plist ├── NetworkRequest.swift ├── Base.lproj │ └── LaunchScreen.storyboard ├── AppDelegate.swift └── ViewController.xib ├── Podfile ├── Network-Evolution-PracticeTests ├── Info.plist └── ViewControllerTests.swift ├── Network-Evolution-PracticeUITests ├── Info.plist └── Network_Evolution_PracticeUITests.swift └── Podfile.lock /Pods/Target Support Files/Alamofire/Alamofire-prefix.pch: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #endif 4 | 5 | -------------------------------------------------------------------------------- /Pods/Target Support Files/PromiseKit/PromiseKit-prefix.pch: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #endif 4 | 5 | -------------------------------------------------------------------------------- /Pods/Target Support Files/SwiftyJSON/SwiftyJSON-prefix.pch: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #endif 4 | 5 | -------------------------------------------------------------------------------- /Pods/Target Support Files/OMGHTTPURLRQ/OMGHTTPURLRQ-prefix.pch: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #endif 4 | 5 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Alamofire/Alamofire.modulemap: -------------------------------------------------------------------------------- 1 | framework module Alamofire { 2 | umbrella header "Alamofire-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /Pods/Target Support Files/SwiftyJSON/SwiftyJSON.modulemap: -------------------------------------------------------------------------------- 1 | framework module SwiftyJSON { 2 | umbrella header "SwiftyJSON-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Alamofire/Alamofire-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_Alamofire : NSObject 3 | @end 4 | @implementation PodsDummy_Alamofire 5 | @end 6 | -------------------------------------------------------------------------------- /Pods/Target Support Files/OMGHTTPURLRQ/OMGHTTPURLRQ.modulemap: -------------------------------------------------------------------------------- 1 | framework module OMGHTTPURLRQ { 2 | umbrella header "OMGHTTPURLRQ-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /Pods/Target Support Files/PromiseKit/PromiseKit-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_PromiseKit : NSObject 3 | @end 4 | @implementation PodsDummy_PromiseKit 5 | @end 6 | -------------------------------------------------------------------------------- /Pods/Target Support Files/SwiftyJSON/SwiftyJSON-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_SwiftyJSON : NSObject 3 | @end 4 | @implementation PodsDummy_SwiftyJSON 5 | @end 6 | -------------------------------------------------------------------------------- /Pods/Target Support Files/OMGHTTPURLRQ/OMGHTTPURLRQ-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_OMGHTTPURLRQ : NSObject 3 | @end 4 | @implementation PodsDummy_OMGHTTPURLRQ 5 | @end 6 | -------------------------------------------------------------------------------- /Network-Evolution-Practice.xcworkspace/xcuserdata/David.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Alamofire/Alamofire-umbrella.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | 4 | FOUNDATION_EXPORT double AlamofireVersionNumber; 5 | FOUNDATION_EXPORT const unsigned char AlamofireVersionString[]; 6 | 7 | -------------------------------------------------------------------------------- /Pods/Target Support Files/SwiftyJSON/SwiftyJSON-umbrella.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | 4 | FOUNDATION_EXPORT double SwiftyJSONVersionNumber; 5 | FOUNDATION_EXPORT const unsigned char SwiftyJSONVersionString[]; 6 | 7 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-Network-Evolution-PracticeTests/Pods-Network-Evolution-PracticeTests-acknowledgements.markdown: -------------------------------------------------------------------------------- 1 | # Acknowledgements 2 | This application makes use of the following third party libraries: 3 | Generated by CocoaPods - https://cocoapods.org 4 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-Network-Evolution-Practice/Pods-Network-Evolution-Practice.modulemap: -------------------------------------------------------------------------------- 1 | framework module Pods_Network_Evolution_Practice { 2 | umbrella header "Pods-Network-Evolution-Practice-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-Network-Evolution-PracticeUITests/Pods-Network-Evolution-PracticeUITests-acknowledgements.markdown: -------------------------------------------------------------------------------- 1 | # Acknowledgements 2 | This application makes use of the following third party libraries: 3 | Generated by CocoaPods - https://cocoapods.org 4 | -------------------------------------------------------------------------------- /Network-Evolution-Practice.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-Network-Evolution-Practice/Pods-Network-Evolution-Practice-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_Pods_Network_Evolution_Practice : NSObject 3 | @end 4 | @implementation PodsDummy_Pods_Network_Evolution_Practice 5 | @end 6 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-Network-Evolution-PracticeTests/Pods-Network-Evolution-PracticeTests.modulemap: -------------------------------------------------------------------------------- 1 | framework module Pods_Network_Evolution_PracticeTests { 2 | umbrella header "Pods-Network-Evolution-PracticeTests-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-Network-Evolution-PracticeTests/Pods-Network-Evolution-PracticeTests-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_Pods_Network_Evolution_PracticeTests : NSObject 3 | @end 4 | @implementation PodsDummy_Pods_Network_Evolution_PracticeTests 5 | @end 6 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-Network-Evolution-PracticeUITests/Pods-Network-Evolution-PracticeUITests.modulemap: -------------------------------------------------------------------------------- 1 | framework module Pods_Network_Evolution_PracticeUITests { 2 | umbrella header "Pods-Network-Evolution-PracticeUITests-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-Network-Evolution-Practice/Pods-Network-Evolution-Practice-umbrella.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | 4 | FOUNDATION_EXPORT double Pods_Network_Evolution_PracticeVersionNumber; 5 | FOUNDATION_EXPORT const unsigned char Pods_Network_Evolution_PracticeVersionString[]; 6 | 7 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-Network-Evolution-PracticeUITests/Pods-Network-Evolution-PracticeUITests-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_Pods_Network_Evolution_PracticeUITests : NSObject 3 | @end 4 | @implementation PodsDummy_Pods_Network_Evolution_PracticeUITests 5 | @end 6 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-Network-Evolution-PracticeTests/Pods-Network-Evolution-PracticeTests-umbrella.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | 4 | FOUNDATION_EXPORT double Pods_Network_Evolution_PracticeTestsVersionNumber; 5 | FOUNDATION_EXPORT const unsigned char Pods_Network_Evolution_PracticeTestsVersionString[]; 6 | 7 | -------------------------------------------------------------------------------- /Pods/Target Support Files/OMGHTTPURLRQ/OMGHTTPURLRQ-umbrella.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | #import "OMGFormURLEncode.h" 4 | #import "OMGHTTPURLRQ.h" 5 | #import "OMGUserAgent.h" 6 | 7 | FOUNDATION_EXPORT double OMGHTTPURLRQVersionNumber; 8 | FOUNDATION_EXPORT const unsigned char OMGHTTPURLRQVersionString[]; 9 | 10 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-Network-Evolution-PracticeUITests/Pods-Network-Evolution-PracticeUITests-umbrella.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | 4 | FOUNDATION_EXPORT double Pods_Network_Evolution_PracticeUITestsVersionNumber; 5 | FOUNDATION_EXPORT const unsigned char Pods_Network_Evolution_PracticeUITestsVersionString[]; 6 | 7 | -------------------------------------------------------------------------------- /Network-Evolution-Practice/JSONDecodable.swift: -------------------------------------------------------------------------------- 1 | // 2 | // JSONDecodable.swift 3 | // Network-Evolution-Practice 4 | // 5 | // Created by David on 2016/9/2. 6 | // Copyright © 2016年 David. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import SwiftyJSON 11 | 12 | protocol JSONDecodable { 13 | init(json: JSON) throws 14 | } -------------------------------------------------------------------------------- /Network-Evolution-Practice.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /Pods/OMGHTTPURLRQ/Sources/OMGUserAgent.h: -------------------------------------------------------------------------------- 1 | #import 2 | @class NSString; 3 | 4 | #if __has_feature(nullability) && defined(NS_ASSUME_NONNULL_BEGIN) 5 | NS_ASSUME_NONNULL_BEGIN 6 | #endif 7 | 8 | NSString *OMGUserAgent(); 9 | 10 | #if __has_feature(nullability) && defined(NS_ASSUME_NONNULL_END) 11 | NS_ASSUME_NONNULL_END 12 | #endif 13 | -------------------------------------------------------------------------------- /Pods/PromiseKit/Sources/dispatch_promise.m: -------------------------------------------------------------------------------- 1 | @import Dispatch; 2 | #import "PromiseKit.h" 3 | 4 | AnyPromise *dispatch_promise(id block) { 5 | return dispatch_promise_on(dispatch_get_global_queue(0, 0), block); 6 | } 7 | 8 | AnyPromise *dispatch_promise_on(dispatch_queue_t queue, id block) { 9 | return [AnyPromise promiseWithValue:nil].thenOn(queue, block); 10 | } 11 | -------------------------------------------------------------------------------- /Network-Evolution-Practice/User.swift: -------------------------------------------------------------------------------- 1 | // 2 | // User.swift 3 | // Network-Evolution-Practice 4 | // 5 | // Created by David on 2016/9/2. 6 | // Copyright © 2016年 David. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import SwiftyJSON 11 | 12 | struct User { 13 | let name: String 14 | } 15 | 16 | extension User : JSONDecodable { 17 | init(json: JSON) throws { 18 | guard let name = json["json"]["param"].string else { throw JSONError.MissingKey("json.param") } 19 | self.name = name 20 | } 21 | } -------------------------------------------------------------------------------- /Pods/PromiseKit/Sources/after.m: -------------------------------------------------------------------------------- 1 | #import "AnyPromise.h" 2 | @import Dispatch; 3 | @import Foundation.NSDate; 4 | @import Foundation.NSValue; 5 | 6 | AnyPromise *PMKAfter(NSTimeInterval duration) { 7 | return [AnyPromise promiseWithResolverBlock:^(PMKResolver resolve) { 8 | dispatch_time_t time = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(duration * NSEC_PER_SEC)); 9 | dispatch_after(time, dispatch_get_global_queue(0, 0), ^{ 10 | resolve(@(duration)); 11 | }); 12 | }]; 13 | } 14 | -------------------------------------------------------------------------------- /Pods/Target Support Files/OMGHTTPURLRQ/OMGHTTPURLRQ.xcconfig: -------------------------------------------------------------------------------- 1 | CONFIGURATION_BUILD_DIR = $PODS_CONFIGURATION_BUILD_DIR/OMGHTTPURLRQ 2 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 3 | HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Public" 4 | PODS_BUILD_DIR = $BUILD_DIR 5 | PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 6 | PODS_ROOT = ${SRCROOT} 7 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} 8 | SKIP_INSTALL = YES 9 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Alamofire/Alamofire.xcconfig: -------------------------------------------------------------------------------- 1 | CONFIGURATION_BUILD_DIR = $PODS_CONFIGURATION_BUILD_DIR/Alamofire 2 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 3 | HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Public" 4 | OTHER_SWIFT_FLAGS = $(inherited) "-D" "COCOAPODS" 5 | PODS_BUILD_DIR = $BUILD_DIR 6 | PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 7 | PODS_ROOT = ${SRCROOT} 8 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} 9 | SKIP_INSTALL = YES 10 | -------------------------------------------------------------------------------- /Pods/Target Support Files/SwiftyJSON/SwiftyJSON.xcconfig: -------------------------------------------------------------------------------- 1 | CONFIGURATION_BUILD_DIR = $PODS_CONFIGURATION_BUILD_DIR/SwiftyJSON 2 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 3 | HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Public" 4 | OTHER_SWIFT_FLAGS = $(inherited) "-D" "COCOAPODS" 5 | PODS_BUILD_DIR = $BUILD_DIR 6 | PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 7 | PODS_ROOT = ${SRCROOT} 8 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} 9 | SKIP_INSTALL = YES 10 | -------------------------------------------------------------------------------- /Pods/PromiseKit/Sources/NSError+Cancellation.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | #if !defined(SWIFT_PASTE) 4 | # define SWIFT_PASTE_HELPER(x, y) x##y 5 | # define SWIFT_PASTE(x, y) SWIFT_PASTE_HELPER(x, y) 6 | #endif 7 | 8 | #if !defined(SWIFT_EXTENSION) 9 | # define SWIFT_EXTENSION(M) SWIFT_PASTE(M##_Swift_, __LINE__) 10 | #endif 11 | 12 | @interface NSError (SWIFT_EXTENSION(PromiseKit)) 13 | + (NSError * __nonnull)cancelledError; 14 | + (void)registerCancelledErrorDomain:(NSString * __nonnull)domain code:(NSInteger)code; 15 | @property (nonatomic, readonly) BOOL cancelled; 16 | @end 17 | -------------------------------------------------------------------------------- /Podfile: -------------------------------------------------------------------------------- 1 | # Uncomment this line to define a global platform for your project 2 | platform :ios, '9.0' 3 | 4 | target 'Network-Evolution-Practice' do 5 | # Comment this line if you're not using Swift and don't want to use dynamic frameworks 6 | use_frameworks! 7 | 8 | # Pods for Network-Evolution-Practice 9 | pod 'Alamofire' 10 | pod 'SwiftyJSON' 11 | pod "PromiseKit" 12 | 13 | target 'Network-Evolution-PracticeTests' do 14 | inherit! :search_paths 15 | # Pods for testing 16 | end 17 | 18 | target 'Network-Evolution-PracticeUITests' do 19 | inherit! :search_paths 20 | # Pods for testing 21 | end 22 | 23 | end 24 | -------------------------------------------------------------------------------- /Pods/PromiseKit/Sources/after.swift: -------------------------------------------------------------------------------- 1 | import Dispatch 2 | import Foundation.NSDate 3 | 4 | /** 5 | ``` 6 | after(1).then { 7 | //… 8 | } 9 | ``` 10 | 11 | - Returns: A new promise that resolves after the specified duration. 12 | - Parameter duration: The duration in seconds to wait before this promise is resolve. 13 | */ 14 | public func after(delay: NSTimeInterval) -> Promise { 15 | return Promise { fulfill, _ in 16 | let delta = delay * NSTimeInterval(NSEC_PER_SEC) 17 | let when = dispatch_time(DISPATCH_TIME_NOW, Int64(delta)) 18 | dispatch_after(when, dispatch_get_global_queue(0, 0), fulfill) 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Pods/PromiseKit/Sources/dispatch_promise.swift: -------------------------------------------------------------------------------- 1 | import Dispatch 2 | import Foundation.NSError 3 | 4 | /** 5 | ``` 6 | dispatch_promise { 7 | try md5(input) 8 | }.then { md5 in 9 | //… 10 | } 11 | ``` 12 | 13 | - Parameter on: The queue on which to dispatch `body`. 14 | - Parameter body: The closure that resolves this promise. 15 | - Returns: A new promise resolved by the provided closure. 16 | */ 17 | public func dispatch_promise(on queue: dispatch_queue_t = dispatch_get_global_queue(0, 0), body: () throws -> T) -> Promise { 18 | return Promise(sealant: { resolve in 19 | contain_zalgo(queue, rejecter: resolve) { 20 | resolve(.Fulfilled(try body())) 21 | } 22 | }) 23 | } 24 | -------------------------------------------------------------------------------- /Network-Evolution-Practice/FetchUser.swift: -------------------------------------------------------------------------------- 1 | // 2 | // FetchUser.swift 3 | // Network-Evolution-Practice 4 | // 5 | // Created by David on 2016/9/2. 6 | // Copyright © 2016年 David. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import Alamofire 11 | import PromiseKit 12 | 13 | class FetchUser: NetworkRequest { 14 | typealias ResponseType = User 15 | 16 | var endpoint: String { return "post" } 17 | var method: Alamofire.Method { return .POST } 18 | var parameters: [String : AnyObject] { return ["param": username] } 19 | 20 | private var username: String = "" 21 | 22 | func perform(username: String) -> Promise { 23 | self.username = username 24 | return networkClient.performRequest(self).then(responseHandler) 25 | } 26 | 27 | } -------------------------------------------------------------------------------- /Pods/Target Support Files/PromiseKit/PromiseKit.xcconfig: -------------------------------------------------------------------------------- 1 | CONFIGURATION_BUILD_DIR = $PODS_CONFIGURATION_BUILD_DIR/PromiseKit 2 | FRAMEWORK_SEARCH_PATHS = $(inherited) "$PODS_CONFIGURATION_BUILD_DIR/OMGHTTPURLRQ" 3 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 4 | HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Public" 5 | OTHER_LDFLAGS = -framework "Foundation" -framework "QuartzCore" -framework "UIKit" 6 | OTHER_SWIFT_FLAGS = $(inherited) "-D" "COCOAPODS" 7 | PODS_BUILD_DIR = $BUILD_DIR 8 | PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 9 | PODS_ROOT = ${SRCROOT} 10 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} 11 | SKIP_INSTALL = YES 12 | SWIFT_INSTALL_OBJC_HEADER = NO 13 | -------------------------------------------------------------------------------- /Pods/PromiseKit/Categories/Foundation/NSNotificationCenter+AnyPromise.m: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | #import 4 | #import "NSNotificationCenter+AnyPromise.h" 5 | 6 | 7 | @implementation NSNotificationCenter (PromiseKit) 8 | 9 | + (AnyPromise *)once:(NSString *)name { 10 | return [AnyPromise promiseWithResolverBlock:^(PMKResolver resolve) { 11 | __block id identifier = [[NSNotificationCenter defaultCenter] addObserverForName:name object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *note) { 12 | [[NSNotificationCenter defaultCenter] removeObserver:identifier name:name object:nil]; 13 | resolve(PMKManifold(note, note.userInfo)); 14 | }]; 15 | }]; 16 | } 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /Network-Evolution-Practice/Assets.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" : "29x29", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "40x40", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "40x40", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "60x60", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "60x60", 31 | "scale" : "3x" 32 | } 33 | ], 34 | "info" : { 35 | "version" : 1, 36 | "author" : "xcode" 37 | } 38 | } -------------------------------------------------------------------------------- /Pods/PromiseKit/Sources/hang.m: -------------------------------------------------------------------------------- 1 | #import "AnyPromise.h" 2 | #import "AnyPromise+Private.h" 3 | @import CoreFoundation.CFRunLoop; 4 | 5 | id PMKHang(AnyPromise *promise) { 6 | if (promise.pending) { 7 | static CFRunLoopSourceContext context; 8 | 9 | CFRunLoopRef runLoop = CFRunLoopGetCurrent(); 10 | CFRunLoopSourceRef runLoopSource = CFRunLoopSourceCreate(NULL, 0, &context); 11 | CFRunLoopAddSource(runLoop, runLoopSource, kCFRunLoopDefaultMode); 12 | 13 | promise.finally(^{ 14 | CFRunLoopStop(runLoop); 15 | }); 16 | while (promise.pending) { 17 | CFRunLoopRun(); 18 | } 19 | CFRunLoopRemoveSource(runLoop, runLoopSource, kCFRunLoopDefaultMode); 20 | CFRelease(runLoopSource); 21 | } 22 | 23 | return promise.value; 24 | } 25 | -------------------------------------------------------------------------------- /Pods/OMGHTTPURLRQ/Sources/OMGFormURLEncode.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | #import 4 | 5 | #if __has_feature(nullability) && defined(NS_ASSUME_NONNULL_BEGIN) 6 | NS_ASSUME_NONNULL_BEGIN 7 | #endif 8 | 9 | /** 10 | Express this dictionary as a `application/x-www-form-urlencoded` string. 11 | 12 | Most users would recognize the result of this transformation as the query 13 | string in a browser bar. For our purposes it is the query string in a GET 14 | request and the HTTP body for POST, PUT and DELETE requests. 15 | 16 | If the parameters dictionary is nil or empty, returns nil. 17 | */ 18 | NSString *OMGFormURLEncode(NSDictionary *parameters); 19 | 20 | #if __has_feature(nullability) && defined(NS_ASSUME_NONNULL_END) 21 | NS_ASSUME_NONNULL_END 22 | #endif 23 | -------------------------------------------------------------------------------- /Network-Evolution-PracticeTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /Network-Evolution-PracticeUITests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /Network-Evolution-Practice.xcodeproj/xcuserdata/David.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | Network-Evolution-Practice.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | 63B332761D7864DF0089C066 16 | 17 | primary 18 | 19 | 20 | 63B3328A1D7864DF0089C066 21 | 22 | primary 23 | 24 | 25 | 63B332951D7864DF0089C066 26 | 27 | primary 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /Pods/PromiseKit/Categories/Foundation/afterlife.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | #if !COCOAPODS 3 | import PromiseKit 4 | #endif 5 | 6 | /** 7 | @return A promise that resolves when the provided object deallocates 8 | 9 | @warning *Important* The promise is not guarenteed to resolve immediately 10 | when the provided object is deallocated. So you cannot write code that 11 | depends on exact timing. 12 | */ 13 | public func after(life object: NSObject) -> Promise { 14 | var reaper = objc_getAssociatedObject(object, &handle) as? GrimReaper 15 | if reaper == nil { 16 | reaper = GrimReaper() 17 | objc_setAssociatedObject(object, &handle, reaper, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) 18 | } 19 | return reaper!.promise 20 | } 21 | 22 | private var handle: UInt8 = 0 23 | 24 | private class GrimReaper: NSObject { 25 | deinit { 26 | fulfill() 27 | } 28 | let (promise, fulfill, _) = Promise.pendingPromise() 29 | } 30 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-Network-Evolution-PracticeTests/Pods-Network-Evolution-PracticeTests.debug.xcconfig: -------------------------------------------------------------------------------- 1 | FRAMEWORK_SEARCH_PATHS = $(inherited) "$PODS_CONFIGURATION_BUILD_DIR/Alamofire" "$PODS_CONFIGURATION_BUILD_DIR/OMGHTTPURLRQ" "$PODS_CONFIGURATION_BUILD_DIR/PromiseKit" "$PODS_CONFIGURATION_BUILD_DIR/SwiftyJSON" 2 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 3 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' 4 | OTHER_CFLAGS = $(inherited) -iquote "$PODS_CONFIGURATION_BUILD_DIR/Alamofire/Alamofire.framework/Headers" -iquote "$PODS_CONFIGURATION_BUILD_DIR/OMGHTTPURLRQ/OMGHTTPURLRQ.framework/Headers" -iquote "$PODS_CONFIGURATION_BUILD_DIR/PromiseKit/PromiseKit.framework/Headers" -iquote "$PODS_CONFIGURATION_BUILD_DIR/SwiftyJSON/SwiftyJSON.framework/Headers" 5 | PODS_BUILD_DIR = $BUILD_DIR 6 | PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 7 | PODS_ROOT = ${SRCROOT}/Pods 8 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-Network-Evolution-PracticeTests/Pods-Network-Evolution-PracticeTests.release.xcconfig: -------------------------------------------------------------------------------- 1 | FRAMEWORK_SEARCH_PATHS = $(inherited) "$PODS_CONFIGURATION_BUILD_DIR/Alamofire" "$PODS_CONFIGURATION_BUILD_DIR/OMGHTTPURLRQ" "$PODS_CONFIGURATION_BUILD_DIR/PromiseKit" "$PODS_CONFIGURATION_BUILD_DIR/SwiftyJSON" 2 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 3 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' 4 | OTHER_CFLAGS = $(inherited) -iquote "$PODS_CONFIGURATION_BUILD_DIR/Alamofire/Alamofire.framework/Headers" -iquote "$PODS_CONFIGURATION_BUILD_DIR/OMGHTTPURLRQ/OMGHTTPURLRQ.framework/Headers" -iquote "$PODS_CONFIGURATION_BUILD_DIR/PromiseKit/PromiseKit.framework/Headers" -iquote "$PODS_CONFIGURATION_BUILD_DIR/SwiftyJSON/SwiftyJSON.framework/Headers" 5 | PODS_BUILD_DIR = $BUILD_DIR 6 | PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 7 | PODS_ROOT = ${SRCROOT}/Pods 8 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Alamofire/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | ${PRODUCT_BUNDLE_IDENTIFIER} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | ${PRODUCT_NAME} 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 3.4.2 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Pods/Target Support Files/OMGHTTPURLRQ/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | ${PRODUCT_BUNDLE_IDENTIFIER} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | ${PRODUCT_NAME} 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 3.2.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-Network-Evolution-PracticeUITests/Pods-Network-Evolution-PracticeUITests.debug.xcconfig: -------------------------------------------------------------------------------- 1 | FRAMEWORK_SEARCH_PATHS = $(inherited) "$PODS_CONFIGURATION_BUILD_DIR/Alamofire" "$PODS_CONFIGURATION_BUILD_DIR/OMGHTTPURLRQ" "$PODS_CONFIGURATION_BUILD_DIR/PromiseKit" "$PODS_CONFIGURATION_BUILD_DIR/SwiftyJSON" 2 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 3 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' 4 | OTHER_CFLAGS = $(inherited) -iquote "$PODS_CONFIGURATION_BUILD_DIR/Alamofire/Alamofire.framework/Headers" -iquote "$PODS_CONFIGURATION_BUILD_DIR/OMGHTTPURLRQ/OMGHTTPURLRQ.framework/Headers" -iquote "$PODS_CONFIGURATION_BUILD_DIR/PromiseKit/PromiseKit.framework/Headers" -iquote "$PODS_CONFIGURATION_BUILD_DIR/SwiftyJSON/SwiftyJSON.framework/Headers" 5 | PODS_BUILD_DIR = $BUILD_DIR 6 | PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 7 | PODS_ROOT = ${SRCROOT}/Pods 8 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-Network-Evolution-PracticeUITests/Pods-Network-Evolution-PracticeUITests.release.xcconfig: -------------------------------------------------------------------------------- 1 | FRAMEWORK_SEARCH_PATHS = $(inherited) "$PODS_CONFIGURATION_BUILD_DIR/Alamofire" "$PODS_CONFIGURATION_BUILD_DIR/OMGHTTPURLRQ" "$PODS_CONFIGURATION_BUILD_DIR/PromiseKit" "$PODS_CONFIGURATION_BUILD_DIR/SwiftyJSON" 2 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 3 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' 4 | OTHER_CFLAGS = $(inherited) -iquote "$PODS_CONFIGURATION_BUILD_DIR/Alamofire/Alamofire.framework/Headers" -iquote "$PODS_CONFIGURATION_BUILD_DIR/OMGHTTPURLRQ/OMGHTTPURLRQ.framework/Headers" -iquote "$PODS_CONFIGURATION_BUILD_DIR/PromiseKit/PromiseKit.framework/Headers" -iquote "$PODS_CONFIGURATION_BUILD_DIR/SwiftyJSON/SwiftyJSON.framework/Headers" 5 | PODS_BUILD_DIR = $BUILD_DIR 6 | PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 7 | PODS_ROOT = ${SRCROOT}/Pods 8 | -------------------------------------------------------------------------------- /Pods/Target Support Files/PromiseKit/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | ${PRODUCT_BUNDLE_IDENTIFIER} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | ${PRODUCT_NAME} 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 3.5.1 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Pods/Target Support Files/SwiftyJSON/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | ${PRODUCT_BUNDLE_IDENTIFIER} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | ${PRODUCT_NAME} 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 2.3.2 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-Network-Evolution-Practice/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | ${PRODUCT_BUNDLE_IDENTIFIER} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | ${PRODUCT_NAME} 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-Network-Evolution-PracticeTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | ${PRODUCT_BUNDLE_IDENTIFIER} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | ${PRODUCT_NAME} 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-Network-Evolution-PracticeUITests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | ${PRODUCT_BUNDLE_IDENTIFIER} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | ${PRODUCT_NAME} 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Pods/OMGHTTPURLRQ/Sources/OMGUserAgent.m: -------------------------------------------------------------------------------- 1 | #import 2 | #import "OMGUserAgent.h" 3 | 4 | NSString *OMGUserAgent() { 5 | static NSString *ua; 6 | static dispatch_once_t onceToken; 7 | dispatch_once(&onceToken, ^{ 8 | id info = [NSBundle mainBundle].infoDictionary; 9 | id name = info[@"CFBundleDisplayName"] ?: info[(__bridge NSString *)kCFBundleIdentifierKey]; 10 | id vers = (__bridge id)CFBundleGetValueForInfoDictionaryKey(CFBundleGetMainBundle(), kCFBundleVersionKey) ?: info[(__bridge NSString *)kCFBundleVersionKey]; 11 | #ifdef UIKIT_EXTERN 12 | float scale = ([[UIScreen mainScreen] respondsToSelector:@selector(scale)] ? [UIScreen mainScreen].scale : 1.0f); 13 | ua = [NSString stringWithFormat:@"%@/%@ (%@; iOS %@; Scale/%0.2f)", name, vers, [UIDevice currentDevice].model, [UIDevice currentDevice].systemVersion, scale]; 14 | #else 15 | ua = [NSString stringWithFormat:@"%@/%@", name, vers]; 16 | #endif 17 | }); 18 | return ua; 19 | } 20 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-Network-Evolution-PracticeTests/Pods-Network-Evolution-PracticeTests-acknowledgements.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreferenceSpecifiers 6 | 7 | 8 | FooterText 9 | This application makes use of the following third party libraries: 10 | Title 11 | Acknowledgements 12 | Type 13 | PSGroupSpecifier 14 | 15 | 16 | FooterText 17 | Generated by CocoaPods - https://cocoapods.org 18 | Title 19 | 20 | Type 21 | PSGroupSpecifier 22 | 23 | 24 | StringsTable 25 | Acknowledgements 26 | Title 27 | Acknowledgements 28 | 29 | 30 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-Network-Evolution-PracticeUITests/Pods-Network-Evolution-PracticeUITests-acknowledgements.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreferenceSpecifiers 6 | 7 | 8 | FooterText 9 | This application makes use of the following third party libraries: 10 | Title 11 | Acknowledgements 12 | Type 13 | PSGroupSpecifier 14 | 15 | 16 | FooterText 17 | Generated by CocoaPods - https://cocoapods.org 18 | Title 19 | 20 | Type 21 | PSGroupSpecifier 22 | 23 | 24 | StringsTable 25 | Acknowledgements 26 | Title 27 | Acknowledgements 28 | 29 | 30 | -------------------------------------------------------------------------------- /Pods/PromiseKit/Categories/QuartzCore/CALayer+AnyPromise.h: -------------------------------------------------------------------------------- 1 | // 2 | // CALayer+AnyPromise.h 3 | // 4 | // Created by María Patricia Montalvo Dzib on 24/11/14. 5 | // Copyright (c) 2014 Aluxoft SCP. All rights reserved. 6 | // 7 | 8 | #import 9 | #import 10 | 11 | /** 12 | To import the `CALayer` category: 13 | 14 | use_frameworks! 15 | pod "PromiseKit/QuartzCore" 16 | 17 | Or `CALayer` is one of the categories imported by the umbrella pod: 18 | 19 | use_frameworks! 20 | pod "PromiseKit" 21 | 22 | And then in your sources: 23 | 24 | #import 25 | */ 26 | @interface CALayer (PromiseKit) 27 | 28 | /** 29 | Add the specified animation object to the layer’s render tree. 30 | 31 | @return A promise that thens two parameters: 32 | 33 | 1. `@YES` if the animation progressed entirely to completion. 34 | 2. The `CAAnimation` object. 35 | 36 | @see addAnimation:forKey 37 | */ 38 | - (AnyPromise *)promiseAnimation:(CAAnimation *)animation forKey:(NSString *)key; 39 | 40 | @end 41 | -------------------------------------------------------------------------------- /Network-Evolution-Practice/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // Network-Evolution-Practice 4 | // 5 | // Created by David on 2016/9/1. 6 | // Copyright © 2016年 David. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import SwiftyJSON 11 | import Alamofire 12 | 13 | class ViewController: UIViewController { 14 | 15 | convenience init() { 16 | self.init(nibName: "ViewController", bundle: nil) 17 | } 18 | 19 | @IBOutlet weak var label: UILabel! 20 | var fetchUser: FetchUser = FetchUser() 21 | 22 | override func viewDidLoad() { 23 | super.viewDidLoad() 24 | // Do any additional setup after loading the view, typically from a nib. 25 | 26 | // make a request 27 | fetchUser.perform("yoxisem544") 28 | .then { user in 29 | self.label.text = "Username: " + user.name 30 | } 31 | .error { error in 32 | self.label.text = "Request failed" 33 | } 34 | } 35 | 36 | override func didReceiveMemoryWarning() { 37 | super.didReceiveMemoryWarning() 38 | // Dispose of any resources that can be recreated. 39 | } 40 | 41 | 42 | } 43 | 44 | -------------------------------------------------------------------------------- /Pods/PromiseKit/Categories/QuartzCore/CALayer+AnyPromise.m: -------------------------------------------------------------------------------- 1 | // 2 | // CALayer+PromiseKit.m 3 | // 4 | // Created by María Patricia Montalvo Dzib on 24/11/14. 5 | // Copyright (c) 2014 Aluxoft SCP. All rights reserved. 6 | // 7 | 8 | #import 9 | #import "CALayer+AnyPromise.h" 10 | 11 | 12 | @interface PMKCAAnimationDelegate : NSObject { 13 | @public 14 | PMKResolver resolve; 15 | CAAnimation *animation; 16 | } 17 | @end 18 | 19 | @implementation PMKCAAnimationDelegate 20 | 21 | - (void)animationDidStop:(CAAnimation *)ignoreOrRetainCycleHappens finished:(BOOL)flag { 22 | resolve(PMKManifold(@(flag), animation)); 23 | animation.delegate = nil; 24 | } 25 | 26 | @end 27 | 28 | 29 | 30 | @implementation CALayer (PromiseKit) 31 | 32 | - (AnyPromise *)promiseAnimation:(CAAnimation *)animation forKey:(NSString *)key { 33 | PMKCAAnimationDelegate *d = animation.delegate = [PMKCAAnimationDelegate new]; 34 | d->animation = animation; 35 | [self addAnimation:animation forKey:key]; 36 | return [[AnyPromise alloc] initWithResolver:&d->resolve]; 37 | } 38 | 39 | @end 40 | -------------------------------------------------------------------------------- /Network-Evolution-Practice/NetworkClient.swift: -------------------------------------------------------------------------------- 1 | // 2 | // NetworkClient.swift 3 | // Network-Evolution-Practice 4 | // 5 | // Created by David on 2016/9/2. 6 | // Copyright © 2016年 David. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import Alamofire 11 | import SwiftyJSON 12 | import PromiseKit 13 | 14 | protocol NetworkClientType { 15 | func performRequest(networkRequest: Request) -> Promise 16 | } 17 | 18 | struct NetworkClient: NetworkClientType { 19 | 20 | func performRequest(networkRequest: Request) -> Promise { 21 | 22 | let (promise, success, failure) = Promise.pendingPromise() 23 | 24 | request(networkRequest.method, 25 | networkRequest.url, 26 | parameters: networkRequest.parameters, 27 | encoding: networkRequest.encoding, 28 | headers: networkRequest.headers) 29 | .response { (_, _, data, error) in 30 | if let data = data where error == nil { 31 | success(data) 32 | } else if let error = error { 33 | failure(error) 34 | } 35 | } 36 | 37 | return promise 38 | } 39 | 40 | } -------------------------------------------------------------------------------- /Pods/PromiseKit/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2016, Max Howell; mxcl@me.com 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a 4 | copy of this software and associated documentation files (the 5 | "Software"), to deal in the Software without restriction, including 6 | without limitation the rights to use, copy, modify, merge, publish, 7 | distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to 9 | the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included 12 | in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 15 | OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 18 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 19 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 20 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /Pods/SwiftyJSON/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Ruoyu Fu 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 | -------------------------------------------------------------------------------- /Pods/Alamofire/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2014-2016 Alamofire Software Foundation (http://alamofire.org/) 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - Alamofire (3.4.2) 3 | - OMGHTTPURLRQ (3.2.0): 4 | - OMGHTTPURLRQ/RQ (= 3.2.0) 5 | - OMGHTTPURLRQ/FormURLEncode (3.2.0) 6 | - OMGHTTPURLRQ/RQ (3.2.0): 7 | - OMGHTTPURLRQ/FormURLEncode 8 | - OMGHTTPURLRQ/UserAgent 9 | - OMGHTTPURLRQ/UserAgent (3.2.0) 10 | - PromiseKit (3.5.1): 11 | - PromiseKit/Foundation (= 3.5.1) 12 | - PromiseKit/QuartzCore (= 3.5.1) 13 | - PromiseKit/UIKit (= 3.5.1) 14 | - PromiseKit/CorePromise (3.5.1) 15 | - PromiseKit/Foundation (3.5.1): 16 | - OMGHTTPURLRQ (~> 3.2.0) 17 | - PromiseKit/CorePromise 18 | - PromiseKit/QuartzCore (3.5.1): 19 | - PromiseKit/CorePromise 20 | - PromiseKit/UIKit (3.5.1): 21 | - PromiseKit/CorePromise 22 | - SwiftyJSON (2.3.2) 23 | 24 | DEPENDENCIES: 25 | - Alamofire 26 | - PromiseKit 27 | - SwiftyJSON 28 | 29 | SPEC CHECKSUMS: 30 | Alamofire: 6aa33201d20d069e1598891cf928883ff1888c7a 31 | OMGHTTPURLRQ: 1e54807cb7d5dbb506926e53498e1e9ac5720c79 32 | PromiseKit: 99ea973444a4bff6c38ffb97fa1bb175e619bcf0 33 | SwiftyJSON: 04ccea08915aa0109039157c7974cf0298da292a 34 | 35 | PODFILE CHECKSUM: c2e8f3801e6e170b863a6f605433275943a528ea 36 | 37 | COCOAPODS: 1.0.1 38 | -------------------------------------------------------------------------------- /Pods/Manifest.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - Alamofire (3.4.2) 3 | - OMGHTTPURLRQ (3.2.0): 4 | - OMGHTTPURLRQ/RQ (= 3.2.0) 5 | - OMGHTTPURLRQ/FormURLEncode (3.2.0) 6 | - OMGHTTPURLRQ/RQ (3.2.0): 7 | - OMGHTTPURLRQ/FormURLEncode 8 | - OMGHTTPURLRQ/UserAgent 9 | - OMGHTTPURLRQ/UserAgent (3.2.0) 10 | - PromiseKit (3.5.1): 11 | - PromiseKit/Foundation (= 3.5.1) 12 | - PromiseKit/QuartzCore (= 3.5.1) 13 | - PromiseKit/UIKit (= 3.5.1) 14 | - PromiseKit/CorePromise (3.5.1) 15 | - PromiseKit/Foundation (3.5.1): 16 | - OMGHTTPURLRQ (~> 3.2.0) 17 | - PromiseKit/CorePromise 18 | - PromiseKit/QuartzCore (3.5.1): 19 | - PromiseKit/CorePromise 20 | - PromiseKit/UIKit (3.5.1): 21 | - PromiseKit/CorePromise 22 | - SwiftyJSON (2.3.2) 23 | 24 | DEPENDENCIES: 25 | - Alamofire 26 | - PromiseKit 27 | - SwiftyJSON 28 | 29 | SPEC CHECKSUMS: 30 | Alamofire: 6aa33201d20d069e1598891cf928883ff1888c7a 31 | OMGHTTPURLRQ: 1e54807cb7d5dbb506926e53498e1e9ac5720c79 32 | PromiseKit: 99ea973444a4bff6c38ffb97fa1bb175e619bcf0 33 | SwiftyJSON: 04ccea08915aa0109039157c7974cf0298da292a 34 | 35 | PODFILE CHECKSUM: c2e8f3801e6e170b863a6f605433275943a528ea 36 | 37 | COCOAPODS: 1.0.1 38 | -------------------------------------------------------------------------------- /Pods/PromiseKit/Categories/UIKit/UIAlertView+AnyPromise.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | 4 | /** 5 | To import the `UIAlertView` category: 6 | 7 | use_frameworks! 8 | pod "PromiseKit/UIKit" 9 | 10 | Or `UIKit` is one of the categories imported by the umbrella pod: 11 | 12 | use_frameworks! 13 | pod "PromiseKit" 14 | 15 | And then in your sources: 16 | 17 | #import 18 | */ 19 | @interface UIAlertView (PromiseKit) 20 | 21 | /** 22 | Displays the alert view. 23 | 24 | UIAlertView *alert = [UIAlertView new]; 25 | alert.title = @"OHAI"; 26 | [alert addButtonWithTitle:@"OK"]; 27 | [alert promise].then(^(NSNumber *dismissedButtonIndex){ 28 | //… 29 | }); 30 | 31 | @warning *Important* If a cancelButtonIndex is set the promise will be *cancelled* if that button is pressed. Cancellation in PromiseKit has special behavior, see the relevant documentation for more details. 32 | 33 | @return A promise the fulfills with two parameters: 34 | 35 | 1) The index of the button that was tapped to dismiss the alert. 36 | 2) This alert view. 37 | */ 38 | - (AnyPromise *)promise; 39 | 40 | @end 41 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-Network-Evolution-Practice/Pods-Network-Evolution-Practice.debug.xcconfig: -------------------------------------------------------------------------------- 1 | EMBEDDED_CONTENT_CONTAINS_SWIFT = YES 2 | FRAMEWORK_SEARCH_PATHS = $(inherited) "$PODS_CONFIGURATION_BUILD_DIR/Alamofire" "$PODS_CONFIGURATION_BUILD_DIR/OMGHTTPURLRQ" "$PODS_CONFIGURATION_BUILD_DIR/PromiseKit" "$PODS_CONFIGURATION_BUILD_DIR/SwiftyJSON" 3 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 4 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' 5 | OTHER_CFLAGS = $(inherited) -iquote "$PODS_CONFIGURATION_BUILD_DIR/Alamofire/Alamofire.framework/Headers" -iquote "$PODS_CONFIGURATION_BUILD_DIR/OMGHTTPURLRQ/OMGHTTPURLRQ.framework/Headers" -iquote "$PODS_CONFIGURATION_BUILD_DIR/PromiseKit/PromiseKit.framework/Headers" -iquote "$PODS_CONFIGURATION_BUILD_DIR/SwiftyJSON/SwiftyJSON.framework/Headers" 6 | OTHER_LDFLAGS = $(inherited) -framework "Alamofire" -framework "OMGHTTPURLRQ" -framework "PromiseKit" -framework "SwiftyJSON" 7 | OTHER_SWIFT_FLAGS = $(inherited) "-D" "COCOAPODS" 8 | PODS_BUILD_DIR = $BUILD_DIR 9 | PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 10 | PODS_ROOT = ${SRCROOT}/Pods 11 | SWIFT_INSTALL_OBJC_HEADER = NO 12 | -------------------------------------------------------------------------------- /Pods/PromiseKit/Sources/race.swift: -------------------------------------------------------------------------------- 1 | import Foundation.NSError 2 | 3 | /** 4 | Resolves with the first resolving promise from a set of promises. 5 | 6 | ``` 7 | race(promise1, promise2, promise3).then { winner in 8 | //… 9 | } 10 | ``` 11 | 12 | - Returns: A new promise that resolves when the first promise in the provided promises resolves. 13 | - Warning: If any of the provided promises reject, the returned promise is rejected. 14 | */ 15 | public func race(promises: Promise...) -> Promise { 16 | return try! race(promises) // race only throws when the array param is empty, which is not possible from this 17 | // variadic paramater version, so we can safely use `try!` 18 | } 19 | 20 | public func race(promises: [Promise]) throws -> Promise { 21 | guard !promises.isEmpty else { 22 | let message = "Cannot race with an empty list of runners (Promises)" 23 | throw NSError(domain: PMKErrorDomain, code: PMKInvalidUsageError, userInfo: ["message": message, "messaage": message]) 24 | } 25 | 26 | return Promise(sealant: { resolve in 27 | for promise in promises { 28 | promise.pipe(resolve) 29 | } 30 | }) 31 | } 32 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-Network-Evolution-Practice/Pods-Network-Evolution-Practice.release.xcconfig: -------------------------------------------------------------------------------- 1 | EMBEDDED_CONTENT_CONTAINS_SWIFT = YES 2 | FRAMEWORK_SEARCH_PATHS = $(inherited) "$PODS_CONFIGURATION_BUILD_DIR/Alamofire" "$PODS_CONFIGURATION_BUILD_DIR/OMGHTTPURLRQ" "$PODS_CONFIGURATION_BUILD_DIR/PromiseKit" "$PODS_CONFIGURATION_BUILD_DIR/SwiftyJSON" 3 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 4 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' 5 | OTHER_CFLAGS = $(inherited) -iquote "$PODS_CONFIGURATION_BUILD_DIR/Alamofire/Alamofire.framework/Headers" -iquote "$PODS_CONFIGURATION_BUILD_DIR/OMGHTTPURLRQ/OMGHTTPURLRQ.framework/Headers" -iquote "$PODS_CONFIGURATION_BUILD_DIR/PromiseKit/PromiseKit.framework/Headers" -iquote "$PODS_CONFIGURATION_BUILD_DIR/SwiftyJSON/SwiftyJSON.framework/Headers" 6 | OTHER_LDFLAGS = $(inherited) -framework "Alamofire" -framework "OMGHTTPURLRQ" -framework "PromiseKit" -framework "SwiftyJSON" 7 | OTHER_SWIFT_FLAGS = $(inherited) "-D" "COCOAPODS" 8 | PODS_BUILD_DIR = $BUILD_DIR 9 | PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 10 | PODS_ROOT = ${SRCROOT}/Pods 11 | SWIFT_INSTALL_OBJC_HEADER = NO 12 | -------------------------------------------------------------------------------- /Pods/PromiseKit/Sources/PMK.modulemap: -------------------------------------------------------------------------------- 1 | framework module PromiseKit { 2 | umbrella header "Umbrella.h" 3 | 4 | header "NSError+Cancellation.h" 5 | 6 | exclude header "AnyPromise.h" 7 | exclude header "PromiseKit.h" 8 | exclude header "PMKPromise.h" 9 | exclude header "Promise.h" 10 | 11 | exclude header "Pods-PromiseKit-umbrella.h" 12 | 13 | exclude header "ACAccountStore+AnyPromise.h" 14 | exclude header "AVAudioSession+AnyPromise.h" 15 | exclude header "CKContainer+AnyPromise.h" 16 | exclude header "CKDatabase+AnyPromise.h" 17 | exclude header "CLGeocoder+AnyPromise.h" 18 | exclude header "CLLocationManager+AnyPromise.h" 19 | exclude header "NSNotificationCenter+AnyPromise.h" 20 | exclude header "NSTask+AnyPromise.h" 21 | exclude header "NSURLConnection+AnyPromise.h" 22 | exclude header "MKDirections+AnyPromise.h" 23 | exclude header "MKMapSnapshotter+AnyPromise.h" 24 | exclude header "CALayer+AnyPromise.h" 25 | exclude header "SLRequest+AnyPromise.h" 26 | exclude header "SKRequest+AnyPromise.h" 27 | exclude header "SCNetworkReachability+AnyPromise.h" 28 | exclude header "UIActionSheet+AnyPromise.h" 29 | exclude header "UIAlertView+AnyPromise.h" 30 | exclude header "UIView+AnyPromise.h" 31 | exclude header "UIViewController+AnyPromise.h" 32 | exclude header "NSURLSession+AnyPromise.h" 33 | } 34 | -------------------------------------------------------------------------------- /Pods/PromiseKit/Categories/UIKit/UIActionSheet+AnyPromise.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | 4 | /** 5 | To import the `UIActionSheet` category: 6 | 7 | use_frameworks! 8 | pod "PromiseKit/UIKit" 9 | 10 | Or `UIKit` is one of the categories imported by the umbrella pod: 11 | 12 | use_frameworks! 13 | pod "PromiseKit" 14 | 15 | And then in your sources: 16 | 17 | #import 18 | */ 19 | @interface UIActionSheet (PromiseKit) 20 | 21 | /** 22 | Displays the action sheet originating from the specified view. 23 | 24 | UIActionSheet *sheet = [UIActionSheet new]; 25 | sheet.title = @"OHAI"; 26 | [sheet addButtonWithTitle:@"OK"]; 27 | [sheet promiseInView:nil].then(^(NSNumber *dismissedButtonIndex){ 28 | //… 29 | }); 30 | 31 | @param view The view from which the action sheet originates. 32 | 33 | @warning *Important* If a cancelButtonIndex is set the promise will be *cancelled* if that button is pressed. Cancellation in PromiseKit has special behavior, see the relevant documentation for more details. 34 | 35 | @return A promise that fulfills with two parameters: 36 | 37 | 1) The index (NSNumber) of the button that was tapped to dismiss the sheet. 38 | 2) This action sheet. 39 | */ 40 | - (AnyPromise *)promiseInView:(UIView *)view; 41 | 42 | @end 43 | -------------------------------------------------------------------------------- /Pods/PromiseKit/Categories/UIKit/UIAlertView+AnyPromise.m: -------------------------------------------------------------------------------- 1 | #import 2 | #import "UIAlertView+AnyPromise.h" 3 | 4 | 5 | @interface PMKAlertViewDelegate : NSObject { 6 | @public 7 | PMKResolver resolve; 8 | id retainCycle; 9 | } 10 | @end 11 | 12 | 13 | @implementation PMKAlertViewDelegate 14 | 15 | - (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex { 16 | if (buttonIndex != alertView.cancelButtonIndex) { 17 | resolve(PMKManifold(@(buttonIndex), alertView)); 18 | } else { 19 | resolve([NSError cancelledError]); 20 | } 21 | retainCycle = nil; 22 | } 23 | 24 | @end 25 | 26 | 27 | @implementation UIAlertView (PromiseKit) 28 | 29 | - (AnyPromise *)promise { 30 | PMKAlertViewDelegate *d = [PMKAlertViewDelegate new]; 31 | d->retainCycle = self.delegate = d; 32 | [self show]; 33 | 34 | if (self.numberOfButtons == 1 && self.cancelButtonIndex == 0) { 35 | NSLog(@"PromiseKit: An alert view is being promised with a single button that is set as the cancelButtonIndex. The promise *will* be cancelled which may result in unexpected behavior. See http://promisekit.org/PromiseKit-2.0-Released/ for cancellation documentation."); 36 | } 37 | 38 | return [[AnyPromise alloc] initWithResolver:&d->resolve]; 39 | } 40 | 41 | @end 42 | -------------------------------------------------------------------------------- /Pods/Target Support Files/PromiseKit/PromiseKit.modulemap: -------------------------------------------------------------------------------- 1 | framework module PromiseKit { 2 | umbrella header "Umbrella.h" 3 | 4 | header "NSError+Cancellation.h" 5 | 6 | exclude header "AnyPromise.h" 7 | exclude header "PromiseKit.h" 8 | exclude header "PMKPromise.h" 9 | exclude header "Promise.h" 10 | 11 | exclude header "Pods-PromiseKit-umbrella.h" 12 | 13 | exclude header "ACAccountStore+AnyPromise.h" 14 | exclude header "AVAudioSession+AnyPromise.h" 15 | exclude header "CKContainer+AnyPromise.h" 16 | exclude header "CKDatabase+AnyPromise.h" 17 | exclude header "CLGeocoder+AnyPromise.h" 18 | exclude header "CLLocationManager+AnyPromise.h" 19 | exclude header "NSNotificationCenter+AnyPromise.h" 20 | exclude header "NSTask+AnyPromise.h" 21 | exclude header "NSURLConnection+AnyPromise.h" 22 | exclude header "MKDirections+AnyPromise.h" 23 | exclude header "MKMapSnapshotter+AnyPromise.h" 24 | exclude header "CALayer+AnyPromise.h" 25 | exclude header "SLRequest+AnyPromise.h" 26 | exclude header "SKRequest+AnyPromise.h" 27 | exclude header "SCNetworkReachability+AnyPromise.h" 28 | exclude header "UIActionSheet+AnyPromise.h" 29 | exclude header "UIAlertView+AnyPromise.h" 30 | exclude header "UIView+AnyPromise.h" 31 | exclude header "UIViewController+AnyPromise.h" 32 | exclude header "NSURLSession+AnyPromise.h" 33 | } 34 | -------------------------------------------------------------------------------- /Pods/PromiseKit/Sources/AnyPromise+Private.h: -------------------------------------------------------------------------------- 1 | @import Foundation.NSError; 2 | @import Foundation.NSPointerArray; 3 | 4 | #if TARGET_OS_IPHONE 5 | #define NSPointerArrayMake(N) ({ \ 6 | NSPointerArray *aa = [NSPointerArray strongObjectsPointerArray]; \ 7 | aa.count = N; \ 8 | aa; \ 9 | }) 10 | #else 11 | static inline NSPointerArray * __nonnull NSPointerArrayMake(NSUInteger count) { 12 | #pragma clang diagnostic push 13 | #pragma clang diagnostic ignored "-Wdeprecated-declarations" 14 | NSPointerArray *aa = [[NSPointerArray class] respondsToSelector:@selector(strongObjectsPointerArray)] 15 | ? [NSPointerArray strongObjectsPointerArray] 16 | : [NSPointerArray pointerArrayWithStrongObjects]; 17 | #pragma clang diagnostic pop 18 | aa.count = count; 19 | return aa; 20 | } 21 | #endif 22 | 23 | #define IsError(o) [o isKindOfClass:[NSError class]] 24 | #define IsPromise(o) [o isKindOfClass:[AnyPromise class]] 25 | 26 | #import "AnyPromise.h" 27 | 28 | @interface AnyPromise (Swift) 29 | - (void)pipe:(void (^ __nonnull)(id __nonnull))body; 30 | - (AnyPromise * __nonnull)initWithBridge:(void (^ __nonnull)(PMKResolver __nonnull))resolver; 31 | @end 32 | 33 | extern NSError * __nullable PMKProcessUnhandledException(id __nonnull thrown); 34 | 35 | @interface NSError (PMKUnhandledErrorHandler) 36 | - (void)pmk_consume; 37 | @end 38 | -------------------------------------------------------------------------------- /Pods/PromiseKit/Categories/UIKit/UIActionSheet+AnyPromise.m: -------------------------------------------------------------------------------- 1 | #import 2 | #import "UIActionSheet+AnyPromise.h" 3 | 4 | 5 | @interface PMKActionSheetDelegate : NSObject { 6 | @public 7 | id retainCycle; 8 | PMKResolver resolve; 9 | } 10 | @end 11 | 12 | 13 | @implementation PMKActionSheetDelegate 14 | 15 | - (void)actionSheet:(UIActionSheet *)actionSheet didDismissWithButtonIndex:(NSInteger)buttonIndex { 16 | if (buttonIndex == actionSheet.cancelButtonIndex) { 17 | resolve([NSError cancelledError]); 18 | } else { 19 | resolve(PMKManifold(@(buttonIndex), actionSheet)); 20 | } 21 | retainCycle = nil; 22 | } 23 | 24 | @end 25 | 26 | 27 | @implementation UIActionSheet (PromiseKit) 28 | 29 | - (AnyPromise *)promiseInView:(UIView *)view { 30 | PMKActionSheetDelegate *d = [PMKActionSheetDelegate new]; 31 | d->retainCycle = self.delegate = d; 32 | [self showInView:view]; 33 | 34 | if (self.numberOfButtons == 1 && self.cancelButtonIndex == 0) { 35 | NSLog(@"PromiseKit: An action sheet is being promised with a single button that is set as the cancelButtonIndex. The promise *will* be cancelled which may result in unexpected behavior. See http://promisekit.org/PromiseKit-2.0-Released/ for cancellation documentation."); 36 | } 37 | 38 | return [[AnyPromise alloc] initWithResolver:&d->resolve]; 39 | } 40 | 41 | @end 42 | -------------------------------------------------------------------------------- /Network-Evolution-Practice/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | NSAppTransportSecurity 6 | 7 | NSAllowsArbitraryLoads 8 | 9 | 10 | CFBundleDevelopmentRegion 11 | en 12 | CFBundleExecutable 13 | $(EXECUTABLE_NAME) 14 | CFBundleIdentifier 15 | $(PRODUCT_BUNDLE_IDENTIFIER) 16 | CFBundleInfoDictionaryVersion 17 | 6.0 18 | CFBundleName 19 | $(PRODUCT_NAME) 20 | CFBundlePackageType 21 | APPL 22 | CFBundleShortVersionString 23 | 1.0 24 | CFBundleSignature 25 | ???? 26 | CFBundleVersion 27 | 1 28 | LSRequiresIPhoneOS 29 | 30 | UILaunchStoryboardName 31 | LaunchScreen 32 | UIRequiredDeviceCapabilities 33 | 34 | armv7 35 | 36 | UISupportedInterfaceOrientations 37 | 38 | UIInterfaceOrientationPortrait 39 | UIInterfaceOrientationLandscapeLeft 40 | UIInterfaceOrientationLandscapeRight 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /Network-Evolution-PracticeUITests/Network_Evolution_PracticeUITests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Network_Evolution_PracticeUITests.swift 3 | // Network-Evolution-PracticeUITests 4 | // 5 | // Created by David on 2016/9/1. 6 | // Copyright © 2016年 David. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | 11 | class Network_Evolution_PracticeUITests: XCTestCase { 12 | 13 | override func setUp() { 14 | super.setUp() 15 | 16 | // Put setup code here. This method is called before the invocation of each test method in the class. 17 | 18 | // In UI tests it is usually best to stop immediately when a failure occurs. 19 | continueAfterFailure = false 20 | // UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method. 21 | XCUIApplication().launch() 22 | 23 | // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this. 24 | } 25 | 26 | override func tearDown() { 27 | // Put teardown code here. This method is called after the invocation of each test method in the class. 28 | super.tearDown() 29 | } 30 | 31 | func testExample() { 32 | // Use recording to get started writing UI tests. 33 | // Use XCTAssert and related functions to verify your tests produce the correct results. 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /Pods/PromiseKit/Categories/Foundation/NSNotificationCenter+AnyPromise.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | 4 | 5 | /** 6 | To import the `NSNotificationCenter` category: 7 | 8 | use_frameworks! 9 | pod "PromiseKit/Foundation" 10 | 11 | Or `NSNotificationCenter` is one of the categories imported by the umbrella pod: 12 | 13 | use_frameworks! 14 | pod "PromiseKit" 15 | 16 | And then in your sources: 17 | 18 | #import 19 | */ 20 | @interface NSNotificationCenter (PromiseKit) 21 | /** 22 | Observe the named notification once. 23 | 24 | [NSNotificationCenter once:UIKeyboardWillShowNotification].then(^(id note, id userInfo){ 25 | UIViewAnimationCurve curve = [userInfo[UIKeyboardAnimationCurveUserInfoKey] integerValue]; 26 | CGFloat duration = [userInfo[UIKeyboardAnimationDurationUserInfoKey] floatValue]; 27 | 28 | return [UIView promiseWithDuration:duration delay:0.0 options:(curve << 16) animations:^{ 29 | 30 | }]; 31 | }); 32 | 33 | @warning *Important* Promises only resolve once. If you need your block to execute more than once then use `-addObserverForName:object:queue:usingBlock:`. 34 | 35 | @param notificationName The name of the notification for which to register the observer. 36 | 37 | @return A promise that fulfills with two parameters: 38 | 39 | 1. The NSNotification object. 40 | 2. The NSNotification’s userInfo property. 41 | */ 42 | + (AnyPromise *)once:(NSString *)notificationName; 43 | @end 44 | -------------------------------------------------------------------------------- /Network-Evolution-Practice/NetworkRequest.swift: -------------------------------------------------------------------------------- 1 | // 2 | // NetworkRequest.swift 3 | // Network-Evolution-Practice 4 | // 5 | // Created by David on 2016/9/2. 6 | // Copyright © 2016年 David. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import Alamofire 11 | import SwiftyJSON 12 | 13 | enum JSONError: ErrorType { 14 | case MissingKey(String) 15 | } 16 | 17 | protocol NetworkRequest { 18 | associatedtype ResponseType 19 | 20 | // Required 21 | var endpoint: String { get } 22 | var responseHandler: NSData throws -> ResponseType { get } 23 | 24 | // Optional 25 | var baseURL: String { get } 26 | var method: Alamofire.Method { get } 27 | var encoding: Alamofire.ParameterEncoding { get } 28 | 29 | var parameters: [String : AnyObject] { get } 30 | var headers: [String : String] { get } 31 | 32 | var networkClient: NetworkClientType { get } 33 | } 34 | 35 | extension NetworkRequest { 36 | var url: String { return baseURL + endpoint } 37 | var baseURL: String { return "http://httpbin.org/" } 38 | var method: Alamofire.Method { return .GET } 39 | var encoding: Alamofire.ParameterEncoding { return .JSON } 40 | 41 | var parameters: [String : AnyObject] { return [:] } 42 | var headers: [String : String] { return [:] } 43 | 44 | var networkClient: NetworkClientType { return NetworkClient() } 45 | } 46 | 47 | extension NetworkRequest where ResponseType: JSONDecodable { 48 | var responseHandler: NSData throws -> ResponseType { return jsonResponseHandler } 49 | } 50 | 51 | private func jsonResponseHandler(data: NSData) throws -> Response { 52 | let json = JSON(data: data) 53 | return try Response(json: json) 54 | } 55 | 56 | -------------------------------------------------------------------------------- /Network-Evolution-Practice/Base.lproj/LaunchScreen.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 | -------------------------------------------------------------------------------- /Pods/PromiseKit/Categories/UIKit/UIView+Promise.swift: -------------------------------------------------------------------------------- 1 | import UIKit.UIView 2 | #if !COCOAPODS 3 | import PromiseKit 4 | #endif 5 | 6 | /** 7 | To import the `UIView` category: 8 | 9 | use_frameworks! 10 | pod "PromiseKit/UIKit" 11 | 12 | Or `UIKit` is one of the categories imported by the umbrella pod: 13 | 14 | use_frameworks! 15 | pod "PromiseKit" 16 | 17 | And then in your sources: 18 | 19 | import PromiseKit 20 | */ 21 | extension UIView { 22 | /** 23 | Animate changes to one or more views using the specified duration, delay, 24 | options, and completion handler. 25 | 26 | @param duration The total duration of the animations, measured in 27 | seconds. If you specify a negative value or 0, the changes are made 28 | without animating them. 29 | 30 | @param delay The amount of time (measured in seconds) to wait before 31 | beginning the animations. Specify a value of 0 to begin the animations 32 | immediately. 33 | 34 | @param options A mask of options indicating how you want to perform the 35 | animations. For a list of valid constants, see UIViewAnimationOptions. 36 | 37 | @param animations A block object containing the changes to commit to the 38 | views. 39 | 40 | @return A promise that fulfills with a boolean NSNumber indicating 41 | whether or not the animations actually finished. 42 | */ 43 | public class func animate(duration duration: NSTimeInterval = 0.3, delay: NSTimeInterval = 0, options: UIViewAnimationOptions = UIViewAnimationOptions(), animations: () -> Void) -> Promise { 44 | return Promise { fulfill, _ in 45 | self.animateWithDuration(duration, delay: delay, options: options, animations: animations, completion: fulfill) 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /Pods/PromiseKit/Categories/UIKit/UIAlertView+Promise.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | import UIKit.UIAlertView 3 | #if !COCOAPODS 4 | import PromiseKit 5 | #endif 6 | 7 | /** 8 | To import the `UIActionSheet` category: 9 | 10 | use_frameworks! 11 | pod "PromiseKit/UIKit" 12 | 13 | Or `UIKit` is one of the categories imported by the umbrella pod: 14 | 15 | use_frameworks! 16 | pod "PromiseKit" 17 | 18 | And then in your sources: 19 | 20 | import PromiseKit 21 | */ 22 | extension UIAlertView { 23 | public func promise() -> Promise { 24 | let proxy = PMKAlertViewDelegate() 25 | delegate = proxy 26 | proxy.retainCycle = proxy 27 | show() 28 | 29 | if numberOfButtons == 1 && cancelButtonIndex == 0 { 30 | NSLog("PromiseKit: An alert view is being promised with a single button that is set as the cancelButtonIndex. The promise *will* be cancelled which may result in unexpected behavior. See http://promisekit.org/PromiseKit-2.0-Released/ for cancellation documentation.") 31 | } 32 | 33 | return proxy.promise 34 | } 35 | 36 | public enum Error: CancellableErrorType { 37 | case Cancelled 38 | 39 | public var cancelled: Bool { 40 | switch self { 41 | case .Cancelled: return true 42 | } 43 | } 44 | } 45 | } 46 | 47 | private class PMKAlertViewDelegate: NSObject, UIAlertViewDelegate { 48 | let (promise, fulfill, reject) = Promise.pendingPromise() 49 | var retainCycle: NSObject? 50 | 51 | @objc func alertView(alertView: UIAlertView, didDismissWithButtonIndex buttonIndex: Int) { 52 | if buttonIndex != alertView.cancelButtonIndex { 53 | fulfill(buttonIndex) 54 | } else { 55 | reject(UIAlertView.Error.Cancelled) 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /Pods/PromiseKit/Sources/join.m: -------------------------------------------------------------------------------- 1 | #import "AnyPromise.h" 2 | #import "AnyPromise+Private.h" 3 | @import Foundation.NSDictionary; 4 | @import Foundation.NSError; 5 | @import Foundation.NSNull; 6 | #import 7 | #import 8 | 9 | @implementation AnyPromise (join) 10 | 11 | AnyPromise *PMKJoin(NSArray *promises) { 12 | if (promises == nil) 13 | return [AnyPromise promiseWithValue:[NSError errorWithDomain:PMKErrorDomain code:PMKInvalidUsageError userInfo:@{NSLocalizedDescriptionKey: @"PMKJoin(nil)"}]]; 14 | 15 | if (promises.count == 0) 16 | return [AnyPromise promiseWithValue:promises]; 17 | 18 | return [AnyPromise promiseWithResolverBlock:^(PMKResolver resolve) { 19 | NSPointerArray *results = NSPointerArrayMake(promises.count); 20 | __block int32_t countdown = (int32_t)promises.count; 21 | __block BOOL rejected = NO; 22 | 23 | [promises enumerateObjectsUsingBlock:^(AnyPromise *promise, NSUInteger ii, BOOL *stop) { 24 | [promise pipe:^(id value) { 25 | 26 | if (IsError(value)) { 27 | [value pmk_consume]; 28 | rejected = YES; 29 | } 30 | 31 | [results replacePointerAtIndex:ii withPointer:(__bridge void *)(value ?: [NSNull null])]; 32 | 33 | if (OSAtomicDecrement32(&countdown) == 0) { 34 | if (!rejected) { 35 | resolve(results.allObjects); 36 | } else { 37 | id userInfo = @{PMKJoinPromisesKey: promises}; 38 | id err = [NSError errorWithDomain:PMKErrorDomain code:PMKJoinError userInfo:userInfo]; 39 | resolve(err); 40 | } 41 | } 42 | }]; 43 | }]; 44 | }]; 45 | } 46 | 47 | @end 48 | -------------------------------------------------------------------------------- /Pods/PromiseKit/Categories/UIKit/UIActionSheet+Promise.swift: -------------------------------------------------------------------------------- 1 | import UIKit.UIActionSheet 2 | #if !COCOAPODS 3 | import PromiseKit 4 | #endif 5 | 6 | /** 7 | To import the `UIActionSheet` category: 8 | 9 | use_frameworks! 10 | pod "PromiseKit/UIKit" 11 | 12 | Or `UIKit` is one of the categories imported by the umbrella pod: 13 | 14 | use_frameworks! 15 | pod "PromiseKit" 16 | 17 | And then in your sources: 18 | 19 | import PromiseKit 20 | */ 21 | extension UIActionSheet { 22 | public func promiseInView(view: UIView) -> Promise { 23 | let proxy = PMKActionSheetDelegate() 24 | delegate = proxy 25 | proxy.retainCycle = proxy 26 | showInView(view) 27 | 28 | if numberOfButtons == 1 && cancelButtonIndex == 0 { 29 | NSLog("PromiseKit: An action sheet is being promised with a single button that is set as the cancelButtonIndex. The promise *will* be cancelled which may result in unexpected behavior. See http://promisekit.org/PromiseKit-2.0-Released/ for cancellation documentation.") 30 | } 31 | 32 | return proxy.promise 33 | } 34 | 35 | public enum Error: CancellableErrorType { 36 | case Cancelled 37 | 38 | public var cancelled: Bool { 39 | switch self { 40 | case .Cancelled: return true 41 | } 42 | } 43 | } 44 | } 45 | 46 | private class PMKActionSheetDelegate: NSObject, UIActionSheetDelegate { 47 | let (promise, fulfill, reject) = Promise.pendingPromise() 48 | var retainCycle: NSObject? 49 | 50 | @objc func actionSheet(actionSheet: UIActionSheet, didDismissWithButtonIndex buttonIndex: Int) { 51 | defer { retainCycle = nil } 52 | 53 | if buttonIndex != actionSheet.cancelButtonIndex { 54 | fulfill(buttonIndex) 55 | } else { 56 | reject(UIActionSheet.Error.Cancelled) 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /Pods/PromiseKit/Categories/Foundation/NSNotificationCenter+Promise.swift: -------------------------------------------------------------------------------- 1 | import Foundation.NSNotification 2 | #if !COCOAPODS 3 | import PromiseKit 4 | #endif 5 | 6 | /** 7 | To import the `NSNotificationCenter` category: 8 | 9 | use_frameworks! 10 | pod "PromiseKit/Foundation" 11 | 12 | Or `NSNotificationCenter` is one of the categories imported by the umbrella pod: 13 | 14 | use_frameworks! 15 | pod "PromiseKit" 16 | 17 | And then in your sources: 18 | 19 | import PromiseKit 20 | */ 21 | extension NSNotificationCenter { 22 | public class func once(name: String) -> NotificationPromise { 23 | return NSNotificationCenter.defaultCenter().once(name) 24 | } 25 | 26 | public func once(name: String) -> NotificationPromise { 27 | let (promise, fulfill) = NotificationPromise.go() 28 | let id = addObserverForName(name, object: nil, queue: nil, usingBlock: fulfill) 29 | promise.then(on: zalgo) { _ in self.removeObserver(id) } 30 | return promise 31 | } 32 | } 33 | 34 | public class NotificationPromise: Promise<[NSObject: AnyObject]> { 35 | /// Hack to fix https://github.com/mxcl/PromiseKit/issues/415 36 | private class NotePromise: Promise {} 37 | 38 | private let (parentPromise, parentFulfill, _) = NotePromise.pendingPromise() 39 | 40 | public func asNotification() -> Promise { 41 | return parentPromise 42 | } 43 | 44 | private class func go() -> (NotificationPromise, (NSNotification) -> Void) { 45 | var fulfill: (([NSObject: AnyObject]) -> Void)! 46 | let promise = NotificationPromise { f, _ in fulfill = f } 47 | promise.parentPromise.then { fulfill($0.userInfo ?? [:]) } 48 | return (promise, promise.parentFulfill) 49 | } 50 | 51 | private override init(@noescape resolvers: (fulfill: ([NSObject: AnyObject]) -> Void, reject: (ErrorType) -> Void) throws -> Void) { 52 | super.init(resolvers: resolvers) 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /Pods/PromiseKit/Sources/join.swift: -------------------------------------------------------------------------------- 1 | import Dispatch 2 | 3 | /** 4 | Waits on all provided promises. 5 | 6 | `when` rejects as soon as one of the provided promises rejects. `join` waits on all provided promises, then rejects if any of those promises rejected, otherwise it fulfills with values from the provided promises. 7 | 8 | join(promise1, promise2, promise3).then { results in 9 | //… 10 | }.error { error in 11 | switch error { 12 | case Error.Join(let promises): 13 | //… 14 | } 15 | } 16 | 17 | - Returns: A new promise that resolves once all the provided promises resolve. 18 | */ 19 | public func join(promises: Promise...) -> Promise<[T]> { 20 | return join(promises) 21 | } 22 | 23 | public func join(promises: [Promise]) -> Promise { 24 | return join(promises).then(on: zalgo) { (_: [Void]) in return Promise() } 25 | } 26 | 27 | public func join(promises: [Promise]) -> Promise<[T]> { 28 | guard !promises.isEmpty else { return Promise<[T]>([]) } 29 | 30 | var countdown = promises.count 31 | let barrier = dispatch_queue_create("org.promisekit.barrier.join", DISPATCH_QUEUE_CONCURRENT) 32 | var rejected = false 33 | 34 | return Promise { fulfill, reject in 35 | for promise in promises { 36 | promise.pipe { resolution in 37 | dispatch_barrier_sync(barrier) { 38 | if case .Rejected(_, let token) = resolution { 39 | token.consumed = true // the parent Error.Join consumes all 40 | rejected = true 41 | } 42 | countdown -= 1 43 | if countdown == 0 { 44 | if rejected { 45 | reject(Error.Join(promises)) 46 | } else { 47 | fulfill(promises.map{ $0.value! }) 48 | } 49 | } 50 | } 51 | } 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /Pods/Pods.xcodeproj/xcuserdata/David.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | Alamofire.xcscheme 8 | 9 | isShown 10 | 11 | 12 | OMGHTTPURLRQ.xcscheme 13 | 14 | isShown 15 | 16 | 17 | Pods-Network-Evolution-Practice.xcscheme 18 | 19 | isShown 20 | 21 | 22 | Pods-Network-Evolution-PracticeTests.xcscheme 23 | 24 | isShown 25 | 26 | 27 | Pods-Network-Evolution-PracticeUITests.xcscheme 28 | 29 | isShown 30 | 31 | 32 | PromiseKit.xcscheme 33 | 34 | isShown 35 | 36 | 37 | SwiftyJSON.xcscheme 38 | 39 | isShown 40 | 41 | 42 | 43 | SuppressBuildableAutocreation 44 | 45 | 190ACD3A51BC90B85EADB13E9CDD207B 46 | 47 | primary 48 | 49 | 50 | 1D7B7D1845939C458D07D60CCFAD5631 51 | 52 | primary 53 | 54 | 55 | 2B489AEA7C122C04C375920BDE495CFE 56 | 57 | primary 58 | 59 | 60 | 626012EB288C9C14190DD0944792D62D 61 | 62 | primary 63 | 64 | 65 | 79C040AFDDCE1BCBF6D8B5EB0B85887F 66 | 67 | primary 68 | 69 | 70 | 7DE5E8B8A5CCDAF35CAE2CC5D610496A 71 | 72 | primary 73 | 74 | 75 | C51AA3E5FF3C077380DCB915375278C1 76 | 77 | primary 78 | 79 | 80 | 81 | 82 | 83 | -------------------------------------------------------------------------------- /Network-Evolution-PracticeTests/ViewControllerTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewControllerTests.swift 3 | // Network-Evolution-Practice 4 | // 5 | // Created by David on 2016/9/2. 6 | // Copyright © 2016年 David. All rights reserved. 7 | // 8 | 9 | @testable import Network_Evolution_Practice 10 | import SwiftyJSON 11 | import PromiseKit 12 | import XCTest 13 | 14 | class ViewControllerTests: XCTestCase { 15 | 16 | var viewController: ViewController! 17 | 18 | override func setUp() { 19 | super.setUp() 20 | // Put setup code here. This method is called before the invocation of each test method in the class. 21 | viewController = ViewController() 22 | } 23 | 24 | } 25 | 26 | extension ViewControllerTests { 27 | func test_successNetworkResponse_showsUsername() { 28 | viewController.fetchUser = MockSuccessFetchUser() 29 | viewController.loadViewIfNeeded() 30 | 31 | let expectation = expectationWithDescription("Label set") 32 | dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 10), dispatch_get_main_queue()) { 33 | XCTAssertEqual(self.viewController.label.text, "Username: yoxisem544") 34 | expectation.fulfill() 35 | } 36 | waitForExpectationsWithTimeout(10, handler: nil) 37 | } 38 | 39 | func test_failureNetworkResponse_showsUsername() { 40 | viewController.fetchUser = MockFailureFetchUser() 41 | viewController.loadViewIfNeeded() 42 | 43 | let expectation = expectationWithDescription("Label set") 44 | dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 10), dispatch_get_main_queue()) { 45 | XCTAssertEqual(self.viewController.label.text, "Request failed") 46 | expectation.fulfill() 47 | } 48 | waitForExpectationsWithTimeout(10, handler: nil) 49 | } 50 | } 51 | 52 | // MARK: - Mocks 53 | private class MockSuccessFetchUser: FetchUser { 54 | private override func perform(username: String) -> Promise { 55 | return Promise(User(name: username)) 56 | } 57 | } 58 | 59 | private class MockFailureFetchUser: FetchUser { 60 | private override func perform(username: String) -> Promise { 61 | return Promise(error: NSError(domain: "", code: -1, userInfo: nil)) 62 | } 63 | } -------------------------------------------------------------------------------- /Pods/Pods.xcodeproj/xcuserdata/David.xcuserdatad/xcschemes/Alamofire.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 43 | 44 | 45 | 46 | 52 | 53 | 55 | 56 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /Pods/Pods.xcodeproj/xcuserdata/David.xcuserdatad/xcschemes/PromiseKit.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 43 | 44 | 45 | 46 | 52 | 53 | 55 | 56 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /Pods/Pods.xcodeproj/xcuserdata/David.xcuserdatad/xcschemes/SwiftyJSON.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 43 | 44 | 45 | 46 | 52 | 53 | 55 | 56 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /Pods/Pods.xcodeproj/xcuserdata/David.xcuserdatad/xcschemes/OMGHTTPURLRQ.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 43 | 44 | 45 | 46 | 52 | 53 | 55 | 56 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /Network-Evolution-Practice/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // Network-Evolution-Practice 4 | // 5 | // Created by David on 2016/9/1. 6 | // Copyright © 2016年 David. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | @UIApplicationMain 12 | class AppDelegate: UIResponder, UIApplicationDelegate { 13 | 14 | var window: UIWindow? 15 | 16 | 17 | func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool { 18 | // Override point for customization after application launch. 19 | window = UIWindow(frame: UIScreen.mainScreen().bounds) 20 | let vc = ViewController() 21 | window?.rootViewController = vc 22 | window?.makeKeyAndVisible() 23 | 24 | return true 25 | } 26 | 27 | func applicationWillResignActive(application: UIApplication) { 28 | // 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. 29 | // 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. 30 | } 31 | 32 | func applicationDidEnterBackground(application: UIApplication) { 33 | // 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. 34 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 35 | } 36 | 37 | func applicationWillEnterForeground(application: UIApplication) { 38 | // 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. 39 | } 40 | 41 | func applicationDidBecomeActive(application: UIApplication) { 42 | // 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. 43 | } 44 | 45 | func applicationWillTerminate(application: UIApplication) { 46 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 47 | } 48 | 49 | 50 | } 51 | 52 | -------------------------------------------------------------------------------- /Pods/PromiseKit/Categories/Foundation/NSObject+Promise.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | #if !COCOAPODS 3 | import PromiseKit 4 | #endif 5 | 6 | /** 7 | To import the `NSObject` category: 8 | 9 | use_frameworks! 10 | pod "PromiseKit/Foundation" 11 | 12 | Or `NSObject` is one of the categories imported by the umbrella pod: 13 | 14 | use_frameworks! 15 | pod "PromiseKit" 16 | 17 | And then in your sources: 18 | 19 | import PromiseKit 20 | */ 21 | extension NSObject { 22 | /** 23 | @return A promise that resolves when the provided keyPath changes. 24 | 25 | @warning *Important* The promise must not outlive the object under observation. 26 | 27 | @see Apple’s KVO documentation. 28 | */ 29 | public func observe(keyPath: String) -> Promise { 30 | let (promise, fulfill, reject) = Promise.pendingPromise() 31 | let proxy = KVOProxy(observee: self, keyPath: keyPath) { obj in 32 | if let obj = obj as? T { 33 | fulfill(obj) 34 | } else { 35 | let info = [NSLocalizedDescriptionKey: "The observed property was not of the requested type."] 36 | reject(NSError(domain: PMKErrorDomain, code: PMKInvalidUsageError, userInfo: info)) 37 | } 38 | } 39 | proxy.retainCycle = proxy 40 | return promise 41 | } 42 | } 43 | 44 | private class KVOProxy: NSObject { 45 | var retainCycle: KVOProxy? 46 | let fulfill: (AnyObject?) -> Void 47 | 48 | init(observee: NSObject, keyPath: String, resolve: (AnyObject?) -> Void) { 49 | fulfill = resolve 50 | super.init() 51 | observee.addObserver(self, forKeyPath: keyPath, options: NSKeyValueObservingOptions.New, context: pointer) 52 | } 53 | 54 | override func observeValueForKeyPath(keyPath: String?, ofObject object: AnyObject?, change: [String : AnyObject]?, context: UnsafeMutablePointer) { 55 | if let change = change where context == pointer { 56 | defer { retainCycle = nil } 57 | fulfill(change[NSKeyValueChangeNewKey]) 58 | if let object = object, keyPath = keyPath { 59 | object.removeObserver(self, forKeyPath: keyPath) 60 | } 61 | } 62 | } 63 | 64 | private lazy var pointer: UnsafeMutablePointer = { 65 | return UnsafeMutablePointer(Unmanaged.passUnretained(self).toOpaque()) 66 | }() 67 | } 68 | -------------------------------------------------------------------------------- /Pods/PromiseKit/Categories/UIKit/UIView+AnyPromise.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIView+PromiseKit_UIAnimation.m 3 | // YahooDenaStudy 4 | // 5 | // Created by Masafumi Yoshida on 2014/07/11. 6 | // Copyright (c) 2014年 DeNA. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "UIView+AnyPromise.h" 11 | 12 | 13 | #define CopyPasta \ 14 | NSAssert([NSThread isMainThread], @"UIKit animation must be performed on the main thread"); \ 15 | \ 16 | if (![NSThread isMainThread]) { \ 17 | id error = [NSError errorWithDomain:PMKErrorDomain code:PMKInvalidUsageError userInfo:@{NSLocalizedDescriptionKey: @"Animation was attempted on a background thread"}]; \ 18 | return [AnyPromise promiseWithValue:error]; \ 19 | } \ 20 | \ 21 | PMKResolver resolve = nil; \ 22 | AnyPromise *promise = [[AnyPromise alloc] initWithResolver:&resolve]; 23 | 24 | 25 | @implementation UIView (PromiseKit) 26 | 27 | + (AnyPromise *)promiseWithDuration:(NSTimeInterval)duration animations:(void (^)(void))animations { 28 | return [self promiseWithDuration:duration delay:0 options:0 animations:animations]; 29 | } 30 | 31 | + (AnyPromise *)promiseWithDuration:(NSTimeInterval)duration delay:(NSTimeInterval)delay options:(UIViewAnimationOptions)options animations:(void(^)(void))animations 32 | { 33 | CopyPasta; 34 | 35 | [UIView animateWithDuration:duration delay:delay options:options animations:animations completion:^(BOOL finished) { 36 | resolve(@(finished)); 37 | }]; 38 | 39 | return promise; 40 | } 41 | 42 | + (AnyPromise *)promiseWithDuration:(NSTimeInterval)duration delay:(NSTimeInterval)delay usingSpringWithDamping:(CGFloat)dampingRatio initialSpringVelocity:(CGFloat)velocity options:(UIViewAnimationOptions)options animations:(void(^)(void))animations 43 | { 44 | CopyPasta; 45 | 46 | [UIView animateWithDuration:duration delay:delay usingSpringWithDamping:dampingRatio initialSpringVelocity:velocity options:options animations:animations completion:^(BOOL finished) { 47 | resolve(@(finished)); 48 | }]; 49 | 50 | return promise; 51 | } 52 | 53 | + (AnyPromise *)promiseWithDuration:(NSTimeInterval)duration delay:(NSTimeInterval)delay options:(UIViewKeyframeAnimationOptions)options keyframeAnimations:(void(^)(void))animations 54 | { 55 | CopyPasta; 56 | 57 | [UIView animateKeyframesWithDuration:duration delay:delay options:options animations:animations completion:^(BOOL finished) { 58 | resolve(@(finished)); 59 | }]; 60 | 61 | return promise; 62 | } 63 | 64 | @end 65 | -------------------------------------------------------------------------------- /Pods/PromiseKit/Sources/Promise+Properties.swift: -------------------------------------------------------------------------------- 1 | extension Promise { 2 | /** 3 | - Returns: The error with which this promise was rejected; `nil` if this promise is not rejected. 4 | */ 5 | public var error: ErrorType? { 6 | switch state.get() { 7 | case .None: 8 | return nil 9 | case .Some(.Fulfilled): 10 | return nil 11 | case .Some(.Rejected(let error, _)): 12 | return error 13 | } 14 | } 15 | 16 | /** 17 | Provides an alias for the `error` property for cases where the Swift 18 | compiler cannot disambiguate from our `error` function. 19 | 20 | More than likely use of this alias will never be necessary as it's 21 | the inverse situation where Swift usually becomes confused. But 22 | we provide this anyway just in case. 23 | 24 | If you absolutely cannot get Swift to accept `error` then 25 | `errorValue` may be used instead as it returns the same thing. 26 | 27 | - Warning: This alias will be unavailable in PromiseKit 4.0.0 28 | - SeeAlso: [https://github.com/mxcl/PromiseKit/issues/347](https://github.com/mxcl/PromiseKit/issues/347) 29 | */ 30 | @available(*, deprecated, renamed="error", message="Temporary alias `errorValue` will eventually be removed and should only be used when the Swift compiler cannot be satisfied with `error`") 31 | public var errorValue: ErrorType? { 32 | return self.error 33 | } 34 | 35 | /** 36 | - Returns: `true` if the promise has not yet resolved. 37 | */ 38 | public var pending: Bool { 39 | return state.get() == nil 40 | } 41 | 42 | /** 43 | - Returns: `true` if the promise has resolved. 44 | */ 45 | public var resolved: Bool { 46 | return !pending 47 | } 48 | 49 | /** 50 | - Returns: `true` if the promise was fulfilled. 51 | */ 52 | public var fulfilled: Bool { 53 | return value != nil 54 | } 55 | 56 | /** 57 | - Returns: `true` if the promise was rejected. 58 | */ 59 | public var rejected: Bool { 60 | return error != nil 61 | } 62 | 63 | /** 64 | - Returns: The value with which this promise was fulfilled or `nil` if this promise is pending or rejected. 65 | */ 66 | public var value: T? { 67 | switch state.get() { 68 | case .None: 69 | return nil 70 | case .Some(.Fulfilled(let value)): 71 | return value 72 | case .Some(.Rejected): 73 | return nil 74 | } 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /Network-Evolution-Practice/ViewController.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /Pods/Alamofire/Source/Notifications.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Notifications.swift 3 | // 4 | // Copyright (c) 2014-2016 Alamofire Software Foundation (http://alamofire.org/) 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | // 24 | 25 | import Foundation 26 | 27 | /// Contains all the `NSNotification` names posted by Alamofire with descriptions of each notification's payload. 28 | public struct Notifications { 29 | /// Used as a namespace for all `NSURLSessionTask` related notifications. 30 | public struct Task { 31 | /// Notification posted when an `NSURLSessionTask` is resumed. The notification `object` contains the resumed 32 | /// `NSURLSessionTask`. 33 | public static let DidResume = "com.alamofire.notifications.task.didResume" 34 | 35 | /// Notification posted when an `NSURLSessionTask` is suspended. The notification `object` contains the 36 | /// suspended `NSURLSessionTask`. 37 | public static let DidSuspend = "com.alamofire.notifications.task.didSuspend" 38 | 39 | /// Notification posted when an `NSURLSessionTask` is cancelled. The notification `object` contains the 40 | /// cancelled `NSURLSessionTask`. 41 | public static let DidCancel = "com.alamofire.notifications.task.didCancel" 42 | 43 | /// Notification posted when an `NSURLSessionTask` is completed. The notification `object` contains the 44 | /// completed `NSURLSessionTask`. 45 | public static let DidComplete = "com.alamofire.notifications.task.didComplete" 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /Pods/OMGHTTPURLRQ/Sources/OMGHTTPURLRQ.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | FOUNDATION_EXPORT double OMGHTTPURLRQVersionNumber; 4 | FOUNDATION_EXPORT const unsigned char OMGHTTPURLRQVersionString[]; 5 | 6 | #import 7 | #import 8 | #import 9 | #import 10 | #import "OMGFormURLEncode.h" 11 | #import "OMGUserAgent.h" 12 | 13 | 14 | #if __has_feature(nullability) && defined(NS_ASSUME_NONNULL_BEGIN) 15 | NS_ASSUME_NONNULL_BEGIN 16 | #else 17 | #define nullable 18 | #endif 19 | 20 | /** 21 | The error will either be a JSON error (NSCocoaDomain :/) or in the NSURLErrorDomain 22 | with code: NSURLErrorUnsupportedURL. 23 | */ 24 | @interface OMGHTTPURLRQ : NSObject 25 | 26 | + (nullable NSMutableURLRequest *)GET:(NSString *)url :(nullable NSDictionary *)parameters error:(NSError **)error; 27 | + (nullable NSMutableURLRequest *)POST:(NSString *)url :(nullable id)parametersOrMultipartFormData error:(NSError **)error; 28 | + (nullable NSMutableURLRequest *)POST:(NSString *)url JSON:(nullable id)JSONObject error:(NSError **)error; 29 | + (nullable NSMutableURLRequest *)PUT:(NSString *)url :(nullable NSDictionary *)parameters error:(NSError **)error; 30 | + (nullable NSMutableURLRequest *)PUT:(NSString *)url JSON:(nullable id)JSONObject error:(NSError **)error; 31 | + (nullable NSMutableURLRequest *)PATCH:(NSString *)url JSON:(nullable id)JSONObject error:(NSError **)error; 32 | + (nullable NSMutableURLRequest *)DELETE:(NSString *)url :(nullable NSDictionary *)parameters error:(NSError **)error; 33 | 34 | @end 35 | 36 | 37 | /** 38 | POST this with `OMGHTTPURLRQ`’s `-POST::` class method. 39 | */ 40 | @interface OMGMultipartFormData : NSObject 41 | 42 | /** 43 | The `filename` parameter is optional. The content-type is optional, and 44 | if left `nil` will default to *octet-stream*. 45 | */ 46 | - (void)addFile:(NSData *)data parameterName:(NSString *)parameterName filename:(nullable NSString *)filename contentType:(nullable NSString *)contentType; 47 | 48 | - (void)addText:(NSString *)text parameterName:(NSString *)parameterName; 49 | 50 | /** 51 | Technically adding parameters to a multipart/form-data request is abusing 52 | the specification. What we do is add each parameter as a text-item. Any 53 | API that expects parameters in a multipart/form-data request will expect 54 | the parameters to be encoded in this way. 55 | */ 56 | - (void)addParameters:(NSDictionary *)parameters; 57 | 58 | @end 59 | 60 | 61 | #if __has_feature(nullability) && defined(NS_ASSUME_NONNULL_END) 62 | NS_ASSUME_NONNULL_END 63 | #else 64 | #undef nullable 65 | #endif 66 | -------------------------------------------------------------------------------- /Pods/OMGHTTPURLRQ/Sources/OMGFormURLEncode.m: -------------------------------------------------------------------------------- 1 | #import 2 | #import "OMGFormURLEncode.h" 3 | 4 | static inline NSString *enc(id in, NSString *ignore) { 5 | NSMutableCharacterSet *allowedSet = [NSMutableCharacterSet characterSetWithCharactersInString:ignore]; 6 | [allowedSet formUnionWithCharacterSet:[NSCharacterSet URLQueryAllowedCharacterSet]]; 7 | [allowedSet removeCharactersInString:@":/?&=;+!@#$()',*"]; 8 | 9 | return [[in description] stringByAddingPercentEncodingWithAllowedCharacters:allowedSet]; 10 | } 11 | 12 | #define enckey(in) enc(in, @"[]") 13 | #define encval(in) enc(in, @"") 14 | 15 | static NSArray *DoQueryMagic(NSString *key, id value) { 16 | NSMutableArray *parts = [NSMutableArray new]; 17 | 18 | // Sort dictionary keys to ensure consistent ordering in query string, 19 | // which is important when deserializing potentially ambiguous sequences, 20 | // such as an array of dictionaries 21 | #define sortDescriptor [NSSortDescriptor sortDescriptorWithKey:@"description" ascending:YES selector:@selector(compare:)] 22 | 23 | if ([value isKindOfClass:[NSDictionary class]]) { 24 | NSDictionary *dictionary = value; 25 | for (id nestedKey in [dictionary.allKeys sortedArrayUsingDescriptors:@[sortDescriptor]]) { 26 | id recursiveKey = key ? [NSString stringWithFormat:@"%@[%@]", key, nestedKey] : nestedKey; 27 | [parts addObjectsFromArray:DoQueryMagic(recursiveKey, dictionary[nestedKey])]; 28 | } 29 | } else if ([value isKindOfClass:[NSArray class]]) { 30 | for (id nestedValue in value) 31 | [parts addObjectsFromArray:DoQueryMagic([NSString stringWithFormat:@"%@[]", key], nestedValue)]; 32 | } else if ([value isKindOfClass:[NSSet class]]) { 33 | for (id obj in [value sortedArrayUsingDescriptors:@[sortDescriptor]]) 34 | [parts addObjectsFromArray:DoQueryMagic(key, obj)]; 35 | } else { 36 | [parts addObjectsFromArray:[NSArray arrayWithObjects:key, value, nil]]; 37 | } 38 | 39 | return parts; 40 | 41 | #undef sortDescriptor 42 | } 43 | 44 | NSString *OMGFormURLEncode(NSDictionary *parameters) { 45 | if (parameters.count == 0) 46 | return @""; 47 | NSMutableString *queryString = [NSMutableString new]; 48 | NSEnumerator *e = DoQueryMagic(nil, parameters).objectEnumerator; 49 | for (;;) { 50 | id const obj = e.nextObject; 51 | if (!obj) break; 52 | [queryString appendFormat:@"%@=%@&", enckey(obj), encval(e.nextObject)]; 53 | } 54 | [queryString deleteCharactersInRange:NSMakeRange(queryString.length - 1, 1)]; 55 | return queryString; 56 | } 57 | -------------------------------------------------------------------------------- /Pods/PromiseKit/Categories/Foundation/NSURLSession+Promise.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | // When using Carthage add `github "mxcl/OMGHTTPURLRQ"` to your Cartfile. 3 | import OMGHTTPURLRQ 4 | #if !COCOAPODS 5 | import PromiseKit 6 | #endif 7 | 8 | //TODO cancellation 9 | 10 | /** 11 | To import the `NSURLSession` category: 12 | 13 | use_frameworks! 14 | pod "PromiseKit/Foundation" 15 | 16 | Or `NSURLSession` is one of the categories imported by the umbrella pod: 17 | 18 | use_frameworks! 19 | pod "PromiseKit" 20 | 21 | And then in your sources: 22 | 23 | import PromiseKit 24 | 25 | We provide convenience categories for the `sharedSession`, or 26 | an instance method `promise`. If you need more complicated behavior 27 | we recommend wrapping that usage in a Promise initializer. 28 | */ 29 | extension NSURLSession { 30 | public class func GET(URL: String, query: [NSObject: AnyObject]? = nil) -> URLDataPromise { 31 | return start(try OMGHTTPURLRQ.GET(URL, query)) 32 | } 33 | 34 | public class func POST(URL: String, formData: [NSObject: AnyObject]? = nil) -> URLDataPromise { 35 | return start(try OMGHTTPURLRQ.POST(URL, formData)) 36 | } 37 | 38 | public class func POST(URL: String, multipartFormData: OMGMultipartFormData) -> URLDataPromise { 39 | return start(try OMGHTTPURLRQ.POST(URL, multipartFormData)) 40 | } 41 | 42 | public class func PUT(URL: String, JSON: NSDictionary? = nil) -> URLDataPromise { 43 | return start(try OMGHTTPURLRQ.PUT(URL, JSON: JSON)) 44 | } 45 | 46 | public class func DELETE(URL: String) -> URLDataPromise { 47 | return start(try OMGHTTPURLRQ.DELETE(URL, nil)) 48 | } 49 | 50 | public class func PATCH(URL: String, JSON: NSDictionary) -> URLDataPromise { 51 | return start(try OMGHTTPURLRQ.PATCH(URL, JSON: JSON)) 52 | } 53 | 54 | public func promise(request: NSURLRequest) -> URLDataPromise { 55 | return start(request, session: self) 56 | } 57 | } 58 | 59 | private func start(@autoclosure body: () throws -> NSURLRequest, session: NSURLSession = NSURLSession.sharedSession()) -> URLDataPromise { 60 | do { 61 | var request = try body() 62 | 63 | if request.valueForHTTPHeaderField("User-Agent") == nil { 64 | let rq = request.mutableCopy() as! NSMutableURLRequest 65 | rq.setValue(OMGUserAgent(), forHTTPHeaderField: "User-Agent") 66 | request = rq 67 | } 68 | 69 | return URLDataPromise.go(request) { completionHandler in 70 | let task = session.dataTaskWithRequest(request, completionHandler: completionHandler) 71 | task.resume() 72 | } 73 | } catch { 74 | return URLDataPromise(error: error) 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /Pods/PromiseKit/Categories/Foundation/NSURLConnection+Promise.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | // When using Carthage add `github "mxcl/OMGHTTPURLRQ"` to your Cartfile. 3 | import OMGHTTPURLRQ 4 | #if !COCOAPODS 5 | import PromiseKit 6 | #endif 7 | 8 | /** 9 | To import the `NSURLConnection` category: 10 | 11 | use_frameworks! 12 | pod "PromiseKit/Foundation" 13 | 14 | Or `NSURLConnection` is one of the categories imported by the umbrella pod: 15 | 16 | use_frameworks! 17 | pod "PromiseKit" 18 | 19 | And then in your sources: 20 | 21 | import PromiseKit 22 | */ 23 | extension NSURLConnection { 24 | public class func GET(URL: String, query: [NSObject:AnyObject]? = nil) -> URLDataPromise { 25 | return go(try OMGHTTPURLRQ.GET(URL, query)) 26 | } 27 | 28 | public class func POST(URL: String, formData: [NSObject:AnyObject]? = nil) -> URLDataPromise { 29 | return go(try OMGHTTPURLRQ.POST(URL, formData)) 30 | } 31 | 32 | public class func POST(URL: String, JSON: [NSObject:AnyObject]) -> URLDataPromise { 33 | return go(try OMGHTTPURLRQ.POST(URL, JSON: JSON)) 34 | } 35 | 36 | public class func POST(URL: String, multipartFormData: OMGMultipartFormData) -> URLDataPromise { 37 | return go(try OMGHTTPURLRQ.POST(URL, multipartFormData)) 38 | } 39 | 40 | public class func PUT(URL: String, formData: [NSObject:AnyObject]? = nil) -> URLDataPromise { 41 | return go(try OMGHTTPURLRQ.PUT(URL, formData)) 42 | } 43 | 44 | public class func PUT(URL: String, JSON: [NSObject:AnyObject]) -> URLDataPromise { 45 | return go(try OMGHTTPURLRQ.PUT(URL, JSON: JSON)) 46 | } 47 | 48 | public class func DELETE(URL: String) -> URLDataPromise { 49 | return go(try OMGHTTPURLRQ.DELETE(URL, nil)) 50 | } 51 | 52 | public class func PATCH(URL: String, JSON: NSDictionary) -> URLDataPromise { 53 | return go(try OMGHTTPURLRQ.PATCH(URL, JSON: JSON)) 54 | } 55 | 56 | public class func promise(request: NSURLRequest) -> URLDataPromise { 57 | return go(request) 58 | } 59 | } 60 | 61 | private func go(@autoclosure body: () throws -> NSURLRequest) -> URLDataPromise { 62 | do { 63 | var request = try body() 64 | 65 | if request.valueForHTTPHeaderField("User-Agent") == nil { 66 | let rq = request.mutableCopy() as! NSMutableURLRequest 67 | rq.setValue(OMGUserAgent(), forHTTPHeaderField: "User-Agent") 68 | request = rq 69 | } 70 | 71 | return URLDataPromise.go(request) { completionHandler in 72 | NSURLConnection.sendAsynchronousRequest(request, queue: Q, completionHandler: { completionHandler($1, $0, $2) }) 73 | } 74 | } catch { 75 | return URLDataPromise(error: error) 76 | } 77 | } 78 | 79 | private let Q = NSOperationQueue() 80 | -------------------------------------------------------------------------------- /Pods/Pods.xcodeproj/xcuserdata/David.xcuserdatad/xcschemes/Pods-Network-Evolution-Practice.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 34 | 35 | 45 | 46 | 52 | 53 | 54 | 55 | 56 | 57 | 63 | 64 | 66 | 67 | 70 | 71 | 72 | -------------------------------------------------------------------------------- /Pods/PromiseKit/Categories/UIKit/UIViewController+AnyPromise.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | 4 | /** 5 | To import the `UIViewController` category: 6 | 7 | use_frameworks! 8 | pod "PromiseKit/UIKit" 9 | 10 | Or `UIKit` is one of the categories imported by the umbrella pod: 11 | 12 | use_frameworks! 13 | pod "PromiseKit" 14 | 15 | And then in your sources: 16 | 17 | #import 18 | */ 19 | @interface UIViewController (PromiseKit) 20 | 21 | /** 22 | Presents a view controller modally. 23 | 24 | If the view controller is one of the following: 25 | 26 | - MFMailComposeViewController 27 | - MFMessageComposeViewController 28 | - UIImagePickerController 29 | - SLComposeViewController 30 | 31 | Then PromiseKit presents the view controller returning a promise that is 32 | resolved as per the documentation for those classes. Eg. if you present a 33 | `UIImagePickerController` the view controller will be presented for you 34 | and the returned promise will resolve with the media the user selected. 35 | 36 | [self promiseViewController:[MFMailComposeViewController new] animated:YES completion:nil].then(^{ 37 | //… 38 | }); 39 | 40 | Otherwise PromiseKit expects your view controller to implement a 41 | `promise` property. This promise will be returned from this method and 42 | presentation and dismissal of the presented view controller will be 43 | managed for you. 44 | 45 | @interface MyViewController: UIViewController 46 | @property (readonly) AnyPromise *promise; 47 | @end 48 | 49 | @implementation MyViewController { 50 | PMKResolver resolve; 51 | } 52 | 53 | - (void)viewDidLoad { 54 | _promise = [[AnyPromise alloc] initWithResolver:&resolve]; 55 | } 56 | 57 | - (void)later { 58 | resolve(@"some fulfilled value"); 59 | } 60 | 61 | @end 62 | 63 | 64 | 65 | [self promiseViewController:[MyViewController new] aniamted:YES completion:nil].then(^(id value){ 66 | // value == @"some fulfilled value" 67 | }); 68 | 69 | @return A promise that can be resolved by the presented view controller. 70 | */ 71 | - (AnyPromise *)promiseViewController:(UIViewController *)vc animated:(BOOL)animated completion:(void (^)(void))block; 72 | 73 | @end 74 | 75 | 76 | 77 | @interface UIViewController (PMKUnavailable) 78 | 79 | #define PMKRationale \ 80 | "The promiseViewController system has been rennovated: the fullfil and " \ 81 | "reject category methods have been removed due to runtime safety " \ 82 | "concerns and instead you should implement a -promise property on your " \ 83 | "view controller subclass. @see promiseViewController:animated:completion:" 84 | 85 | - (void)fulfill:(id)value __attribute__((unavailable(PMKRationale))); 86 | - (void)reject:(NSError *)value __attribute__((unavailable(PMKRationale))); 87 | 88 | #undef PMKRationale 89 | 90 | @end 91 | -------------------------------------------------------------------------------- /Pods/PromiseKit/Categories/Foundation/NSURLConnection+AnyPromise.m: -------------------------------------------------------------------------------- 1 | #import "NSURLConnection+AnyPromise.h" 2 | #import // github "mxcl/OMGHTTPURLRQ" ~> 3.2 3 | #import 4 | #import 5 | 6 | typedef void (^PMKURLDataCompletionHandler)(NSData *, NSURLResponse *, NSError *); 7 | PMKURLDataCompletionHandler PMKMakeURLDataHandler(NSURLRequest *, PMKResolver); 8 | extern id PMKURLRequestFromURLFormat(NSError **err, id urlFormat, ...); 9 | 10 | 11 | @implementation NSURLConnection (PromiseKit) 12 | 13 | + (AnyPromise *)GET:(id)urlFormat, ... { 14 | id err; 15 | id rq = PMKURLRequestFromURLFormat(&err, urlFormat); 16 | if (err) { 17 | return [AnyPromise promiseWithValue:err]; 18 | } else { 19 | return [self promise:rq]; 20 | } 21 | } 22 | 23 | + (AnyPromise *)GET:(NSString *)url query:(NSDictionary *)params { 24 | id err; 25 | id rq = [OMGHTTPURLRQ GET:url:params error:&err]; 26 | if (err) return [AnyPromise promiseWithValue:err]; 27 | return [self promise:rq]; 28 | } 29 | 30 | + (AnyPromise *)POST:(NSString *)url formURLEncodedParameters:(NSDictionary *)params { 31 | id err; 32 | id rq = [OMGHTTPURLRQ POST:url:params error:&err]; 33 | if (err) return [AnyPromise promiseWithValue:err]; 34 | return [self promise:rq]; 35 | } 36 | 37 | + (AnyPromise *)POST:(NSString *)urlString JSON:(NSDictionary *)params { 38 | id err; 39 | id rq = [OMGHTTPURLRQ POST:urlString JSON:params error:&err]; 40 | if (err) [AnyPromise promiseWithValue:err]; 41 | return [self promise:rq]; 42 | } 43 | 44 | + (AnyPromise *)PUT:(NSString *)url formURLEncodedParameters:(NSDictionary *)params { 45 | id err; 46 | id rq = [OMGHTTPURLRQ PUT:url:params error:&err]; 47 | if (err) [AnyPromise promiseWithValue:err]; 48 | return [self promise:rq]; 49 | 50 | } 51 | 52 | + (AnyPromise *)DELETE:(NSString *)url formURLEncodedParameters:(NSDictionary *)params { 53 | id err; 54 | id rq = [OMGHTTPURLRQ DELETE:url :params error:&err]; 55 | if (err) [AnyPromise promiseWithValue:err]; 56 | return [self promise:rq]; 57 | } 58 | 59 | + (AnyPromise *)PATCH:(NSString *)url JSON:(NSDictionary *)params { 60 | id err; 61 | id rq = [OMGHTTPURLRQ PATCH:url JSON:params error:&err]; 62 | if (err) [AnyPromise promiseWithValue:err]; 63 | return [self promise:rq]; 64 | } 65 | 66 | + (AnyPromise *)promise:(NSURLRequest *)rq { 67 | static id q = nil; 68 | static dispatch_once_t onceToken; 69 | dispatch_once(&onceToken, ^{ 70 | q = [NSOperationQueue new]; 71 | }); 72 | 73 | return [AnyPromise promiseWithResolverBlock:^(PMKResolver resolve) { 74 | [NSURLConnection sendAsynchronousRequest:rq queue:q completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) { 75 | PMKMakeURLDataHandler(rq, resolve)(data, response, connectionError); 76 | }]; 77 | }]; 78 | } 79 | 80 | @end 81 | -------------------------------------------------------------------------------- /Pods/Pods.xcodeproj/xcuserdata/David.xcuserdatad/xcschemes/Pods-Network-Evolution-PracticeTests.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 34 | 35 | 45 | 46 | 52 | 53 | 54 | 55 | 56 | 57 | 63 | 64 | 66 | 67 | 70 | 71 | 72 | -------------------------------------------------------------------------------- /Pods/Pods.xcodeproj/xcuserdata/David.xcuserdatad/xcschemes/Pods-Network-Evolution-PracticeUITests.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 34 | 35 | 45 | 46 | 52 | 53 | 54 | 55 | 56 | 57 | 63 | 64 | 66 | 67 | 70 | 71 | 72 | -------------------------------------------------------------------------------- /Pods/PromiseKit/Categories/UIKit/UIView+AnyPromise.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | 4 | // Created by Masafumi Yoshida on 2014/07/11. 5 | // Copyright (c) 2014年 DeNA. All rights reserved. 6 | 7 | /** 8 | To import the `UIView` category: 9 | 10 | use_frameworks! 11 | pod "PromiseKit/UIKit" 12 | 13 | Or `UIKit` is one of the categories imported by the umbrella pod: 14 | 15 | use_frameworks! 16 | pod "PromiseKit" 17 | 18 | And then in your sources: 19 | 20 | #import 21 | */ 22 | @interface UIView (PromiseKit) 23 | 24 | /** 25 | Animate changes to one or more views using the specified duration. 26 | 27 | @param duration The total duration of the animations, measured in 28 | seconds. If you specify a negative value or 0, the changes are made 29 | without animating them. 30 | 31 | @param animations A block object containing the changes to commit to the 32 | views. 33 | 34 | @return A promise that fulfills with a boolean NSNumber indicating 35 | whether or not the animations actually finished. 36 | */ 37 | + (AnyPromise *)promiseWithDuration:(NSTimeInterval)duration animations:(void (^)(void))animations; 38 | 39 | /** 40 | Animate changes to one or more views using the specified duration, delay, 41 | options, and completion handler. 42 | 43 | @param duration The total duration of the animations, measured in 44 | seconds. If you specify a negative value or 0, the changes are made 45 | without animating them. 46 | 47 | @param delay The amount of time (measured in seconds) to wait before 48 | beginning the animations. Specify a value of 0 to begin the animations 49 | immediately. 50 | 51 | @param options A mask of options indicating how you want to perform the 52 | animations. For a list of valid constants, see UIViewAnimationOptions. 53 | 54 | @param animations A block object containing the changes to commit to the 55 | views. 56 | 57 | @return A promise that fulfills with a boolean NSNumber indicating 58 | whether or not the animations actually finished. 59 | */ 60 | + (AnyPromise *)promiseWithDuration:(NSTimeInterval)duration delay:(NSTimeInterval)delay options:(UIViewAnimationOptions)options animations:(void (^)(void))animations; 61 | 62 | /** 63 | Performs a view animation using a timing curve corresponding to the 64 | motion of a physical spring. 65 | 66 | @return A promise that fulfills with a boolean NSNumber indicating 67 | whether or not the animations actually finished. 68 | */ 69 | + (AnyPromise *)promiseWithDuration:(NSTimeInterval)duration delay:(NSTimeInterval)delay usingSpringWithDamping:(CGFloat)dampingRatio initialSpringVelocity:(CGFloat)velocity options:(UIViewAnimationOptions)options animations:(void (^)(void))animations; 70 | 71 | /** 72 | Creates an animation block object that can be used to set up 73 | keyframe-based animations for the current view. 74 | 75 | @return A promise that fulfills with a boolean NSNumber indicating 76 | whether or not the animations actually finished. 77 | */ 78 | + (AnyPromise *)promiseWithDuration:(NSTimeInterval)duration delay:(NSTimeInterval)delay options:(UIViewKeyframeAnimationOptions)options keyframeAnimations:(void (^)(void))animations; 79 | 80 | @end 81 | -------------------------------------------------------------------------------- /Pods/PromiseKit/Sources/NSMethodSignatureForBlock.m: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | struct PMKBlockLiteral { 4 | void *isa; // initialized to &_NSConcreteStackBlock or &_NSConcreteGlobalBlock 5 | int flags; 6 | int reserved; 7 | void (*invoke)(void *, ...); 8 | struct block_descriptor { 9 | unsigned long int reserved; // NULL 10 | unsigned long int size; // sizeof(struct Block_literal_1) 11 | // optional helper functions 12 | void (*copy_helper)(void *dst, void *src); // IFF (1<<25) 13 | void (*dispose_helper)(void *src); // IFF (1<<25) 14 | // required ABI.2010.3.16 15 | const char *signature; // IFF (1<<30) 16 | } *descriptor; 17 | // imported variables 18 | }; 19 | 20 | typedef NS_OPTIONS(NSUInteger, PMKBlockDescriptionFlags) { 21 | PMKBlockDescriptionFlagsHasCopyDispose = (1 << 25), 22 | PMKBlockDescriptionFlagsHasCtor = (1 << 26), // helpers have C++ code 23 | PMKBlockDescriptionFlagsIsGlobal = (1 << 28), 24 | PMKBlockDescriptionFlagsHasStret = (1 << 29), // IFF BLOCK_HAS_SIGNATURE 25 | PMKBlockDescriptionFlagsHasSignature = (1 << 30) 26 | }; 27 | 28 | // It appears 10.7 doesn't support quotes in method signatures. Remove them 29 | // via @rabovik's method. See https://github.com/OliverLetterer/SLObjectiveCRuntimeAdditions/pull/2 30 | #if defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED < __MAC_10_8 31 | NS_INLINE static const char * pmk_removeQuotesFromMethodSignature(const char *str){ 32 | char *result = malloc(strlen(str) + 1); 33 | BOOL skip = NO; 34 | char *to = result; 35 | char c; 36 | while ((c = *str++)) { 37 | if ('"' == c) { 38 | skip = !skip; 39 | continue; 40 | } 41 | if (skip) continue; 42 | *to++ = c; 43 | } 44 | *to = '\0'; 45 | return result; 46 | } 47 | #endif 48 | 49 | static NSMethodSignature *NSMethodSignatureForBlock(id block) { 50 | if (!block) 51 | return nil; 52 | 53 | struct PMKBlockLiteral *blockRef = (__bridge struct PMKBlockLiteral *)block; 54 | PMKBlockDescriptionFlags flags = (PMKBlockDescriptionFlags)blockRef->flags; 55 | 56 | if (flags & PMKBlockDescriptionFlagsHasSignature) { 57 | void *signatureLocation = blockRef->descriptor; 58 | signatureLocation += sizeof(unsigned long int); 59 | signatureLocation += sizeof(unsigned long int); 60 | 61 | if (flags & PMKBlockDescriptionFlagsHasCopyDispose) { 62 | signatureLocation += sizeof(void(*)(void *dst, void *src)); 63 | signatureLocation += sizeof(void (*)(void *src)); 64 | } 65 | 66 | const char *signature = (*(const char **)signatureLocation); 67 | #if defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED < __MAC_10_8 68 | signature = pmk_removeQuotesFromMethodSignature(signature); 69 | NSMethodSignature *nsSignature = [NSMethodSignature signatureWithObjCTypes:signature]; 70 | free((void *)signature); 71 | 72 | return nsSignature; 73 | #endif 74 | return [NSMethodSignature signatureWithObjCTypes:signature]; 75 | } 76 | return 0; 77 | } 78 | -------------------------------------------------------------------------------- /Pods/PromiseKit/Categories/UIKit/PMKAlertController.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | #if !COCOAPODS 3 | import PromiseKit 4 | #endif 5 | 6 | //TODO tests 7 | //TODO NSCoding 8 | 9 | /** 10 | A “promisable” UIAlertController. 11 | 12 | UIAlertController is not a suitable API for an extension; it has closure 13 | handlers on its main API for each button and an extension would have to 14 | either replace all these when the controller is presented or force you to 15 | use an extended addAction method, which would be easy to forget part of 16 | the time. Hence we provide a facade pattern that can be promised. 17 | 18 | let alert = PMKAlertController("OHAI") 19 | let sup = alert.addActionWithTitle("SUP") 20 | let bye = alert.addActionWithTitle("BYE") 21 | promiseViewController(alert).then { action in 22 | switch action { 23 | case is sup: 24 | //… 25 | case is bye: 26 | //… 27 | } 28 | } 29 | */ 30 | public class PMKAlertController { 31 | public var title: String? { return UIAlertController.title } 32 | public var message: String? { return UIAlertController.message } 33 | public var preferredStyle: UIAlertControllerStyle { return UIAlertController.preferredStyle } 34 | public var actions: [UIAlertAction] { return UIAlertController.actions } 35 | public var textFields: [UITextField]? { return UIAlertController.textFields } 36 | public var popoverPresentationController: UIPopoverPresentationController? { return UIAlertController.popoverPresentationController } 37 | 38 | public required init(title: String?, message: String? = nil, preferredStyle: UIAlertControllerStyle = .Alert) { 39 | UIAlertController = UIKit.UIAlertController(title: title, message: message, preferredStyle: preferredStyle) 40 | } 41 | 42 | public func addActionWithTitle(title: String, style: UIAlertActionStyle = .Default) -> UIAlertAction { 43 | let action = UIAlertAction(title: title, style: style) { action in 44 | if style != UIAlertActionStyle.Cancel { 45 | self.fulfill(action) 46 | } else { 47 | self.reject(Error.Cancelled) 48 | } 49 | } 50 | UIAlertController.addAction(action) 51 | return action 52 | } 53 | 54 | public func addTextFieldWithConfigurationHandler(configurationHandler: ((UITextField) -> Void)?) { 55 | UIAlertController.addTextFieldWithConfigurationHandler(configurationHandler) 56 | } 57 | 58 | private let UIAlertController: UIKit.UIAlertController 59 | private let (promise, fulfill, reject) = Promise.pendingPromise() 60 | private var retainCycle: PMKAlertController? 61 | 62 | public enum Error: CancellableErrorType { 63 | case Cancelled 64 | 65 | public var cancelled: Bool { 66 | return self == .Cancelled 67 | } 68 | } 69 | } 70 | 71 | extension UIViewController { 72 | public func promiseViewController(vc: PMKAlertController, animated: Bool = true, completion: (() -> Void)? = nil) -> Promise { 73 | vc.retainCycle = vc 74 | presentViewController(vc.UIAlertController, animated: animated, completion: completion) 75 | vc.promise.always { _ -> Void in 76 | vc.retainCycle = nil 77 | } 78 | return vc.promise 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /Pods/PromiseKit/Sources/Umbrella.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | #import 4 | 5 | FOUNDATION_EXPORT double PromiseKitVersionNumber; 6 | FOUNDATION_EXPORT const unsigned char PromiseKitVersionString[]; 7 | 8 | extern NSString * const PMKErrorDomain; 9 | 10 | #define PMKFailingPromiseIndexKey @"PMKFailingPromiseIndexKey" 11 | #define PMKURLErrorFailingURLResponseKey @"PMKURLErrorFailingURLResponseKey" 12 | #define PMKURLErrorFailingDataKey @"PMKURLErrorFailingDataKey" 13 | #define PMKURLErrorFailingStringKey @"PMKURLErrorFailingStringKey" 14 | #define PMKJSONErrorJSONObjectKey @"PMKJSONErrorJSONObjectKey" 15 | #define PMKJoinPromisesKey @"PMKJoinPromisesKey" 16 | 17 | #define PMKUnexpectedError 1l 18 | #define PMKUnknownError 2l 19 | #define PMKInvalidUsageError 3l 20 | #define PMKAccessDeniedError 4l 21 | #define PMKOperationCancelled 5l 22 | #define PMKNotFoundError 6l 23 | #define PMKJSONError 7l 24 | #define PMKOperationFailed 8l 25 | #define PMKTaskError 9l 26 | #define PMKJoinError 10l 27 | 28 | /** 29 | This block lets you override the default dispatch queue for Promises. 30 | 31 | By default this returns dispatch_get_main_queue() 32 | */ 33 | FOUNDATION_EXPORT dispatch_queue_t (^PMKDefaultDispatchQueue)(); 34 | 35 | #if !(defined(PMKEZBake) && defined(SWIFT_CLASS)) 36 | #if !defined(SWIFT_PASTE) 37 | # define SWIFT_PASTE_HELPER(x, y) x##y 38 | # define SWIFT_PASTE(x, y) SWIFT_PASTE_HELPER(x, y) 39 | #endif 40 | #if !defined(SWIFT_METATYPE) 41 | # define SWIFT_METATYPE(X) Class 42 | #endif 43 | 44 | #if defined(__has_attribute) && __has_attribute(objc_runtime_name) 45 | # define SWIFT_RUNTIME_NAME(X) __attribute__((objc_runtime_name(X))) 46 | #else 47 | # define SWIFT_RUNTIME_NAME(X) 48 | #endif 49 | #if !defined(SWIFT_CLASS_EXTRA) 50 | # define SWIFT_CLASS_EXTRA 51 | #endif 52 | #if !defined(SWIFT_CLASS) 53 | # if defined(__has_attribute) && __has_attribute(objc_subclassing_restricted) 54 | # define SWIFT_CLASS(SWIFT_NAME) SWIFT_RUNTIME_NAME(SWIFT_NAME) __attribute__((objc_subclassing_restricted)) SWIFT_CLASS_EXTRA 55 | # define SWIFT_CLASS_NAMED(SWIFT_NAME) __attribute__((objc_subclassing_restricted)) SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_CLASS_EXTRA 56 | # else 57 | # define SWIFT_CLASS(SWIFT_NAME) SWIFT_RUNTIME_NAME(SWIFT_NAME) SWIFT_CLASS_EXTRA 58 | # define SWIFT_CLASS_NAMED(SWIFT_NAME) SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_CLASS_EXTRA 59 | # endif 60 | #endif 61 | 62 | #if !defined(SWIFT_PROTOCOL_EXTRA) 63 | # define SWIFT_PROTOCOL_EXTRA 64 | #endif 65 | #if !defined(SWIFT_PROTOCOL) 66 | # define SWIFT_PROTOCOL(SWIFT_NAME) SWIFT_RUNTIME_NAME(SWIFT_NAME) SWIFT_PROTOCOL_EXTRA 67 | # define SWIFT_PROTOCOL_NAMED(SWIFT_NAME) SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_PROTOCOL_EXTRA 68 | #endif 69 | 70 | SWIFT_CLASS("AnyPromise") 71 | @interface AnyPromise : NSObject 72 | @property (nonatomic, readonly) BOOL pending; 73 | @property (nonatomic, readonly) BOOL resolved; 74 | @property (nonatomic, readonly) BOOL fulfilled; 75 | @property (nonatomic, readonly) BOOL rejected; 76 | @end 77 | 78 | SWIFT_PROTOCOL("Promisable") 79 | @protocol Promisable 80 | @property (nonatomic, readonly, strong) id promise; 81 | @end 82 | 83 | #endif 84 | 85 | typedef NS_OPTIONS(NSInteger, PMKAnimationOptions) { 86 | PMKAnimationOptionsNone = 1 << 0, 87 | PMKAnimationOptionsAppear = 1 << 1, 88 | PMKAnimationOptionsDisappear = 1 << 2, 89 | }; 90 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-Network-Evolution-PracticeTests/Pods-Network-Evolution-PracticeTests-frameworks.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 5 | mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 6 | 7 | SWIFT_STDLIB_PATH="${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" 8 | 9 | install_framework() 10 | { 11 | if [ -r "${BUILT_PRODUCTS_DIR}/$1" ]; then 12 | local source="${BUILT_PRODUCTS_DIR}/$1" 13 | elif [ -r "${BUILT_PRODUCTS_DIR}/$(basename "$1")" ]; then 14 | local source="${BUILT_PRODUCTS_DIR}/$(basename "$1")" 15 | elif [ -r "$1" ]; then 16 | local source="$1" 17 | fi 18 | 19 | local destination="${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 20 | 21 | if [ -L "${source}" ]; then 22 | echo "Symlinked..." 23 | source="$(readlink "${source}")" 24 | fi 25 | 26 | # use filter instead of exclude so missing patterns dont' throw errors 27 | echo "rsync -av --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${destination}\"" 28 | rsync -av --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${destination}" 29 | 30 | local basename 31 | basename="$(basename -s .framework "$1")" 32 | binary="${destination}/${basename}.framework/${basename}" 33 | if ! [ -r "$binary" ]; then 34 | binary="${destination}/${basename}" 35 | fi 36 | 37 | # Strip invalid architectures so "fat" simulator / device frameworks work on device 38 | if [[ "$(file "$binary")" == *"dynamically linked shared library"* ]]; then 39 | strip_invalid_archs "$binary" 40 | fi 41 | 42 | # Resign the code if required by the build settings to avoid unstable apps 43 | code_sign_if_enabled "${destination}/$(basename "$1")" 44 | 45 | # Embed linked Swift runtime libraries. No longer necessary as of Xcode 7. 46 | if [ "${XCODE_VERSION_MAJOR}" -lt 7 ]; then 47 | local swift_runtime_libs 48 | swift_runtime_libs=$(xcrun otool -LX "$binary" | grep --color=never @rpath/libswift | sed -E s/@rpath\\/\(.+dylib\).*/\\1/g | uniq -u && exit ${PIPESTATUS[0]}) 49 | for lib in $swift_runtime_libs; do 50 | echo "rsync -auv \"${SWIFT_STDLIB_PATH}/${lib}\" \"${destination}\"" 51 | rsync -auv "${SWIFT_STDLIB_PATH}/${lib}" "${destination}" 52 | code_sign_if_enabled "${destination}/${lib}" 53 | done 54 | fi 55 | } 56 | 57 | # Signs a framework with the provided identity 58 | code_sign_if_enabled() { 59 | if [ -n "${EXPANDED_CODE_SIGN_IDENTITY}" -a "${CODE_SIGNING_REQUIRED}" != "NO" -a "${CODE_SIGNING_ALLOWED}" != "NO" ]; then 60 | # Use the current code_sign_identitiy 61 | echo "Code Signing $1 with Identity ${EXPANDED_CODE_SIGN_IDENTITY_NAME}" 62 | echo "/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS} --preserve-metadata=identifier,entitlements \"$1\"" 63 | /usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS} --preserve-metadata=identifier,entitlements "$1" 64 | fi 65 | } 66 | 67 | # Strip invalid architectures 68 | strip_invalid_archs() { 69 | binary="$1" 70 | # Get architectures for current file 71 | archs="$(lipo -info "$binary" | rev | cut -d ':' -f1 | rev)" 72 | stripped="" 73 | for arch in $archs; do 74 | if ! [[ "${VALID_ARCHS}" == *"$arch"* ]]; then 75 | # Strip non-valid architectures in-place 76 | lipo -remove "$arch" -output "$binary" "$binary" || exit 1 77 | stripped="$stripped $arch" 78 | fi 79 | done 80 | if [[ "$stripped" ]]; then 81 | echo "Stripped $binary of architectures:$stripped" 82 | fi 83 | } 84 | 85 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-Network-Evolution-PracticeUITests/Pods-Network-Evolution-PracticeUITests-frameworks.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 5 | mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 6 | 7 | SWIFT_STDLIB_PATH="${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" 8 | 9 | install_framework() 10 | { 11 | if [ -r "${BUILT_PRODUCTS_DIR}/$1" ]; then 12 | local source="${BUILT_PRODUCTS_DIR}/$1" 13 | elif [ -r "${BUILT_PRODUCTS_DIR}/$(basename "$1")" ]; then 14 | local source="${BUILT_PRODUCTS_DIR}/$(basename "$1")" 15 | elif [ -r "$1" ]; then 16 | local source="$1" 17 | fi 18 | 19 | local destination="${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 20 | 21 | if [ -L "${source}" ]; then 22 | echo "Symlinked..." 23 | source="$(readlink "${source}")" 24 | fi 25 | 26 | # use filter instead of exclude so missing patterns dont' throw errors 27 | echo "rsync -av --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${destination}\"" 28 | rsync -av --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${destination}" 29 | 30 | local basename 31 | basename="$(basename -s .framework "$1")" 32 | binary="${destination}/${basename}.framework/${basename}" 33 | if ! [ -r "$binary" ]; then 34 | binary="${destination}/${basename}" 35 | fi 36 | 37 | # Strip invalid architectures so "fat" simulator / device frameworks work on device 38 | if [[ "$(file "$binary")" == *"dynamically linked shared library"* ]]; then 39 | strip_invalid_archs "$binary" 40 | fi 41 | 42 | # Resign the code if required by the build settings to avoid unstable apps 43 | code_sign_if_enabled "${destination}/$(basename "$1")" 44 | 45 | # Embed linked Swift runtime libraries. No longer necessary as of Xcode 7. 46 | if [ "${XCODE_VERSION_MAJOR}" -lt 7 ]; then 47 | local swift_runtime_libs 48 | swift_runtime_libs=$(xcrun otool -LX "$binary" | grep --color=never @rpath/libswift | sed -E s/@rpath\\/\(.+dylib\).*/\\1/g | uniq -u && exit ${PIPESTATUS[0]}) 49 | for lib in $swift_runtime_libs; do 50 | echo "rsync -auv \"${SWIFT_STDLIB_PATH}/${lib}\" \"${destination}\"" 51 | rsync -auv "${SWIFT_STDLIB_PATH}/${lib}" "${destination}" 52 | code_sign_if_enabled "${destination}/${lib}" 53 | done 54 | fi 55 | } 56 | 57 | # Signs a framework with the provided identity 58 | code_sign_if_enabled() { 59 | if [ -n "${EXPANDED_CODE_SIGN_IDENTITY}" -a "${CODE_SIGNING_REQUIRED}" != "NO" -a "${CODE_SIGNING_ALLOWED}" != "NO" ]; then 60 | # Use the current code_sign_identitiy 61 | echo "Code Signing $1 with Identity ${EXPANDED_CODE_SIGN_IDENTITY_NAME}" 62 | echo "/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS} --preserve-metadata=identifier,entitlements \"$1\"" 63 | /usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS} --preserve-metadata=identifier,entitlements "$1" 64 | fi 65 | } 66 | 67 | # Strip invalid architectures 68 | strip_invalid_archs() { 69 | binary="$1" 70 | # Get architectures for current file 71 | archs="$(lipo -info "$binary" | rev | cut -d ':' -f1 | rev)" 72 | stripped="" 73 | for arch in $archs; do 74 | if ! [[ "${VALID_ARCHS}" == *"$arch"* ]]; then 75 | # Strip non-valid architectures in-place 76 | lipo -remove "$arch" -output "$binary" "$binary" || exit 1 77 | stripped="$stripped $arch" 78 | fi 79 | done 80 | if [[ "$stripped" ]]; then 81 | echo "Stripped $binary of architectures:$stripped" 82 | fi 83 | } 84 | 85 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-Network-Evolution-Practice/Pods-Network-Evolution-Practice-acknowledgements.markdown: -------------------------------------------------------------------------------- 1 | # Acknowledgements 2 | This application makes use of the following third party libraries: 3 | 4 | ## Alamofire 5 | 6 | Copyright (c) 2014-2016 Alamofire Software Foundation (http://alamofire.org/) 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 | 27 | ## OMGHTTPURLRQ 28 | 29 | https://github.com/mxcl/OMGHTTPURLRQ/blob/master/README.markdown 30 | 31 | ## PromiseKit 32 | 33 | Copyright 2016, Max Howell; mxcl@me.com 34 | 35 | Permission is hereby granted, free of charge, to any person obtaining a 36 | copy of this software and associated documentation files (the 37 | "Software"), to deal in the Software without restriction, including 38 | without limitation the rights to use, copy, modify, merge, publish, 39 | distribute, sublicense, and/or sell copies of the Software, and to 40 | permit persons to whom the Software is furnished to do so, subject to 41 | the following conditions: 42 | 43 | The above copyright notice and this permission notice shall be included 44 | in all copies or substantial portions of the Software. 45 | 46 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 47 | OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 48 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 49 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 50 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 51 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 52 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 53 | 54 | 55 | ## SwiftyJSON 56 | 57 | The MIT License (MIT) 58 | 59 | Copyright (c) 2014 Ruoyu Fu 60 | 61 | Permission is hereby granted, free of charge, to any person obtaining a copy 62 | of this software and associated documentation files (the "Software"), to deal 63 | in the Software without restriction, including without limitation the rights 64 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 65 | copies of the Software, and to permit persons to whom the Software is 66 | furnished to do so, subject to the following conditions: 67 | 68 | The above copyright notice and this permission notice shall be included in 69 | all copies or substantial portions of the Software. 70 | 71 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 72 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 73 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 74 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 75 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 76 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 77 | THE SOFTWARE. 78 | 79 | Generated by CocoaPods - https://cocoapods.org 80 | -------------------------------------------------------------------------------- /Pods/PromiseKit/Sources/when.m: -------------------------------------------------------------------------------- 1 | #import "AnyPromise.h" 2 | #import "AnyPromise+Private.h" 3 | @import Foundation.NSDictionary; 4 | @import Foundation.NSError; 5 | @import Foundation.NSProgress; 6 | @import Foundation.NSNull; 7 | #import 8 | #import "Umbrella.h" 9 | 10 | // NSProgress resources: 11 | // * https://robots.thoughtbot.com/asynchronous-nsprogress 12 | // * http://oleb.net/blog/2014/03/nsprogress/ 13 | // NSProgress! Beware! 14 | // * https://github.com/AFNetworking/AFNetworking/issues/2261 15 | 16 | AnyPromise *PMKWhen(id promises) { 17 | if (promises == nil) 18 | return [AnyPromise promiseWithValue:[NSError errorWithDomain:PMKErrorDomain code:PMKInvalidUsageError userInfo:@{NSLocalizedDescriptionKey: @"PMKWhen(nil)"}]]; 19 | 20 | if ([promises isKindOfClass:[NSArray class]] || [promises isKindOfClass:[NSDictionary class]]) { 21 | if ([promises count] == 0) 22 | return [AnyPromise promiseWithValue:promises]; 23 | } else if ([promises isKindOfClass:[AnyPromise class]]) { 24 | promises = @[promises]; 25 | } else { 26 | return [AnyPromise promiseWithValue:promises]; 27 | } 28 | 29 | #ifndef PMKDisableProgress 30 | NSProgress *progress = [NSProgress progressWithTotalUnitCount:[promises count]]; 31 | progress.pausable = NO; 32 | progress.cancellable = NO; 33 | #else 34 | struct PMKProgress { 35 | int completedUnitCount; 36 | int totalUnitCount; 37 | double fractionCompleted; 38 | }; 39 | __block struct PMKProgress progress; 40 | #endif 41 | 42 | __block int32_t countdown = (int32_t)[promises count]; 43 | BOOL const isdict = [promises isKindOfClass:[NSDictionary class]]; 44 | 45 | return [AnyPromise promiseWithResolverBlock:^(PMKResolver resolve) { 46 | NSInteger index = 0; 47 | 48 | for (__strong id key in promises) { 49 | AnyPromise *promise = isdict ? promises[key] : key; 50 | if (!isdict) key = @(index); 51 | 52 | if (![promise isKindOfClass:[AnyPromise class]]) 53 | promise = [AnyPromise promiseWithValue:promise]; 54 | 55 | [promise pipe:^(id value){ 56 | if (progress.fractionCompleted >= 1) 57 | return; 58 | 59 | if (IsError(value)) { 60 | progress.completedUnitCount = progress.totalUnitCount; 61 | 62 | NSMutableDictionary *userInfo = [NSMutableDictionary dictionaryWithDictionary:[value userInfo] ?: @{}]; 63 | userInfo[PMKFailingPromiseIndexKey] = key; 64 | [userInfo setObject:value forKey:NSUnderlyingErrorKey]; 65 | id err = [[NSError alloc] initWithDomain:[value domain] code:[value code] userInfo:userInfo]; 66 | resolve(err); 67 | } 68 | else if (OSAtomicDecrement32(&countdown) == 0) { 69 | progress.completedUnitCount = progress.totalUnitCount; 70 | 71 | id results; 72 | if (isdict) { 73 | results = [NSMutableDictionary new]; 74 | for (id key in promises) { 75 | id promise = promises[key]; 76 | results[key] = IsPromise(promise) ? ((AnyPromise *)promise).value : promise; 77 | } 78 | } else { 79 | results = [NSMutableArray new]; 80 | for (AnyPromise *promise in promises) { 81 | id value = IsPromise(promise) ? (promise.value ?: [NSNull null]) : promise; 82 | [results addObject:value]; 83 | } 84 | } 85 | resolve(results); 86 | } else { 87 | progress.completedUnitCount++; 88 | } 89 | }]; 90 | } 91 | }]; 92 | } 93 | -------------------------------------------------------------------------------- /Pods/Alamofire/Source/Result.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Result.swift 3 | // 4 | // Copyright (c) 2014-2016 Alamofire Software Foundation (http://alamofire.org/) 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | // 24 | 25 | import Foundation 26 | 27 | /** 28 | Used to represent whether a request was successful or encountered an error. 29 | 30 | - Success: The request and all post processing operations were successful resulting in the serialization of the 31 | provided associated value. 32 | - Failure: The request encountered an error resulting in a failure. The associated values are the original data 33 | provided by the server as well as the error that caused the failure. 34 | */ 35 | public enum Result { 36 | case Success(Value) 37 | case Failure(Error) 38 | 39 | /// Returns `true` if the result is a success, `false` otherwise. 40 | public var isSuccess: Bool { 41 | switch self { 42 | case .Success: 43 | return true 44 | case .Failure: 45 | return false 46 | } 47 | } 48 | 49 | /// Returns `true` if the result is a failure, `false` otherwise. 50 | public var isFailure: Bool { 51 | return !isSuccess 52 | } 53 | 54 | /// Returns the associated value if the result is a success, `nil` otherwise. 55 | public var value: Value? { 56 | switch self { 57 | case .Success(let value): 58 | return value 59 | case .Failure: 60 | return nil 61 | } 62 | } 63 | 64 | /// Returns the associated error value if the result is a failure, `nil` otherwise. 65 | public var error: Error? { 66 | switch self { 67 | case .Success: 68 | return nil 69 | case .Failure(let error): 70 | return error 71 | } 72 | } 73 | } 74 | 75 | // MARK: - CustomStringConvertible 76 | 77 | extension Result: CustomStringConvertible { 78 | /// The textual representation used when written to an output stream, which includes whether the result was a 79 | /// success or failure. 80 | public var description: String { 81 | switch self { 82 | case .Success: 83 | return "SUCCESS" 84 | case .Failure: 85 | return "FAILURE" 86 | } 87 | } 88 | } 89 | 90 | // MARK: - CustomDebugStringConvertible 91 | 92 | extension Result: CustomDebugStringConvertible { 93 | /// The debug textual representation used when written to an output stream, which includes whether the result was a 94 | /// success or failure in addition to the value or error. 95 | public var debugDescription: String { 96 | switch self { 97 | case .Success(let value): 98 | return "SUCCESS: \(value)" 99 | case .Failure(let error): 100 | return "FAILURE: \(error)" 101 | } 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /Pods/Alamofire/Source/Response.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Response.swift 3 | // 4 | // Copyright (c) 2014-2016 Alamofire Software Foundation (http://alamofire.org/) 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | // 24 | 25 | import Foundation 26 | 27 | /// Used to store all response data returned from a completed `Request`. 28 | public struct Response { 29 | /// The URL request sent to the server. 30 | public let request: NSURLRequest? 31 | 32 | /// The server's response to the URL request. 33 | public let response: NSHTTPURLResponse? 34 | 35 | /// The data returned by the server. 36 | public let data: NSData? 37 | 38 | /// The result of response serialization. 39 | public let result: Result 40 | 41 | /// The timeline of the complete lifecycle of the `Request`. 42 | public let timeline: Timeline 43 | 44 | /** 45 | Initializes the `Response` instance with the specified URL request, URL response, server data and response 46 | serialization result. 47 | 48 | - parameter request: The URL request sent to the server. 49 | - parameter response: The server's response to the URL request. 50 | - parameter data: The data returned by the server. 51 | - parameter result: The result of response serialization. 52 | - parameter timeline: The timeline of the complete lifecycle of the `Request`. Defaults to `Timeline()`. 53 | 54 | - returns: the new `Response` instance. 55 | */ 56 | public init( 57 | request: NSURLRequest?, 58 | response: NSHTTPURLResponse?, 59 | data: NSData?, 60 | result: Result, 61 | timeline: Timeline = Timeline()) 62 | { 63 | self.request = request 64 | self.response = response 65 | self.data = data 66 | self.result = result 67 | self.timeline = timeline 68 | } 69 | } 70 | 71 | // MARK: - CustomStringConvertible 72 | 73 | extension Response: CustomStringConvertible { 74 | /// The textual representation used when written to an output stream, which includes whether the result was a 75 | /// success or failure. 76 | public var description: String { 77 | return result.debugDescription 78 | } 79 | } 80 | 81 | // MARK: - CustomDebugStringConvertible 82 | 83 | extension Response: CustomDebugStringConvertible { 84 | /// The debug textual representation used when written to an output stream, which includes the URL request, the URL 85 | /// response, the server data and the response serialization result. 86 | public var debugDescription: String { 87 | var output: [String] = [] 88 | 89 | output.append(request != nil ? "[Request]: \(request!)" : "[Request]: nil") 90 | output.append(response != nil ? "[Response]: \(response!)" : "[Response]: nil") 91 | output.append("[Data]: \(data?.length ?? 0) bytes") 92 | output.append("[Result]: \(result.debugDescription)") 93 | output.append("[Timeline]: \(timeline.debugDescription)") 94 | 95 | return output.joinWithSeparator("\n") 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /Pods/Alamofire/Source/Error.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Error.swift 3 | // 4 | // Copyright (c) 2014-2016 Alamofire Software Foundation (http://alamofire.org/) 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | // 24 | 25 | import Foundation 26 | 27 | /// The `Error` struct provides a convenience for creating custom Alamofire NSErrors. 28 | public struct Error { 29 | /// The domain used for creating all Alamofire errors. 30 | public static let Domain = "com.alamofire.error" 31 | 32 | /// The custom error codes generated by Alamofire. 33 | public enum Code: Int { 34 | case InputStreamReadFailed = -6000 35 | case OutputStreamWriteFailed = -6001 36 | case ContentTypeValidationFailed = -6002 37 | case StatusCodeValidationFailed = -6003 38 | case DataSerializationFailed = -6004 39 | case StringSerializationFailed = -6005 40 | case JSONSerializationFailed = -6006 41 | case PropertyListSerializationFailed = -6007 42 | } 43 | 44 | /// Custom keys contained within certain NSError `userInfo` dictionaries generated by Alamofire. 45 | public struct UserInfoKeys { 46 | /// The content type user info key for a `.ContentTypeValidationFailed` error stored as a `String` value. 47 | public static let ContentType = "ContentType" 48 | 49 | /// The status code user info key for a `.StatusCodeValidationFailed` error stored as an `Int` value. 50 | public static let StatusCode = "StatusCode" 51 | } 52 | 53 | /** 54 | Creates an `NSError` with the given error code and failure reason. 55 | 56 | - parameter code: The error code. 57 | - parameter failureReason: The failure reason. 58 | 59 | - returns: An `NSError` with the given error code and failure reason. 60 | */ 61 | @available(*, deprecated=3.4.0) 62 | public static func errorWithCode(code: Code, failureReason: String) -> NSError { 63 | return errorWithCode(code.rawValue, failureReason: failureReason) 64 | } 65 | 66 | /** 67 | Creates an `NSError` with the given error code and failure reason. 68 | 69 | - parameter code: The error code. 70 | - parameter failureReason: The failure reason. 71 | 72 | - returns: An `NSError` with the given error code and failure reason. 73 | */ 74 | @available(*, deprecated=3.4.0) 75 | public static func errorWithCode(code: Int, failureReason: String) -> NSError { 76 | let userInfo = [NSLocalizedFailureReasonErrorKey: failureReason] 77 | return NSError(domain: Domain, code: code, userInfo: userInfo) 78 | } 79 | 80 | static func error(domain domain: String = Error.Domain, code: Code, failureReason: String) -> NSError { 81 | return error(domain: domain, code: code.rawValue, failureReason: failureReason) 82 | } 83 | 84 | static func error(domain domain: String = Error.Domain, code: Int, failureReason: String) -> NSError { 85 | let userInfo = [NSLocalizedFailureReasonErrorKey: failureReason] 86 | return NSError(domain: domain, code: code, userInfo: userInfo) 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-Network-Evolution-Practice/Pods-Network-Evolution-Practice-frameworks.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 5 | mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 6 | 7 | SWIFT_STDLIB_PATH="${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" 8 | 9 | install_framework() 10 | { 11 | if [ -r "${BUILT_PRODUCTS_DIR}/$1" ]; then 12 | local source="${BUILT_PRODUCTS_DIR}/$1" 13 | elif [ -r "${BUILT_PRODUCTS_DIR}/$(basename "$1")" ]; then 14 | local source="${BUILT_PRODUCTS_DIR}/$(basename "$1")" 15 | elif [ -r "$1" ]; then 16 | local source="$1" 17 | fi 18 | 19 | local destination="${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 20 | 21 | if [ -L "${source}" ]; then 22 | echo "Symlinked..." 23 | source="$(readlink "${source}")" 24 | fi 25 | 26 | # use filter instead of exclude so missing patterns dont' throw errors 27 | echo "rsync -av --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${destination}\"" 28 | rsync -av --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${destination}" 29 | 30 | local basename 31 | basename="$(basename -s .framework "$1")" 32 | binary="${destination}/${basename}.framework/${basename}" 33 | if ! [ -r "$binary" ]; then 34 | binary="${destination}/${basename}" 35 | fi 36 | 37 | # Strip invalid architectures so "fat" simulator / device frameworks work on device 38 | if [[ "$(file "$binary")" == *"dynamically linked shared library"* ]]; then 39 | strip_invalid_archs "$binary" 40 | fi 41 | 42 | # Resign the code if required by the build settings to avoid unstable apps 43 | code_sign_if_enabled "${destination}/$(basename "$1")" 44 | 45 | # Embed linked Swift runtime libraries. No longer necessary as of Xcode 7. 46 | if [ "${XCODE_VERSION_MAJOR}" -lt 7 ]; then 47 | local swift_runtime_libs 48 | swift_runtime_libs=$(xcrun otool -LX "$binary" | grep --color=never @rpath/libswift | sed -E s/@rpath\\/\(.+dylib\).*/\\1/g | uniq -u && exit ${PIPESTATUS[0]}) 49 | for lib in $swift_runtime_libs; do 50 | echo "rsync -auv \"${SWIFT_STDLIB_PATH}/${lib}\" \"${destination}\"" 51 | rsync -auv "${SWIFT_STDLIB_PATH}/${lib}" "${destination}" 52 | code_sign_if_enabled "${destination}/${lib}" 53 | done 54 | fi 55 | } 56 | 57 | # Signs a framework with the provided identity 58 | code_sign_if_enabled() { 59 | if [ -n "${EXPANDED_CODE_SIGN_IDENTITY}" -a "${CODE_SIGNING_REQUIRED}" != "NO" -a "${CODE_SIGNING_ALLOWED}" != "NO" ]; then 60 | # Use the current code_sign_identitiy 61 | echo "Code Signing $1 with Identity ${EXPANDED_CODE_SIGN_IDENTITY_NAME}" 62 | echo "/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS} --preserve-metadata=identifier,entitlements \"$1\"" 63 | /usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS} --preserve-metadata=identifier,entitlements "$1" 64 | fi 65 | } 66 | 67 | # Strip invalid architectures 68 | strip_invalid_archs() { 69 | binary="$1" 70 | # Get architectures for current file 71 | archs="$(lipo -info "$binary" | rev | cut -d ':' -f1 | rev)" 72 | stripped="" 73 | for arch in $archs; do 74 | if ! [[ "${VALID_ARCHS}" == *"$arch"* ]]; then 75 | # Strip non-valid architectures in-place 76 | lipo -remove "$arch" -output "$binary" "$binary" || exit 1 77 | stripped="$stripped $arch" 78 | fi 79 | done 80 | if [[ "$stripped" ]]; then 81 | echo "Stripped $binary of architectures:$stripped" 82 | fi 83 | } 84 | 85 | 86 | if [[ "$CONFIGURATION" == "Debug" ]]; then 87 | install_framework "$BUILT_PRODUCTS_DIR/Alamofire/Alamofire.framework" 88 | install_framework "$BUILT_PRODUCTS_DIR/OMGHTTPURLRQ/OMGHTTPURLRQ.framework" 89 | install_framework "$BUILT_PRODUCTS_DIR/PromiseKit/PromiseKit.framework" 90 | install_framework "$BUILT_PRODUCTS_DIR/SwiftyJSON/SwiftyJSON.framework" 91 | fi 92 | if [[ "$CONFIGURATION" == "Release" ]]; then 93 | install_framework "$BUILT_PRODUCTS_DIR/Alamofire/Alamofire.framework" 94 | install_framework "$BUILT_PRODUCTS_DIR/OMGHTTPURLRQ/OMGHTTPURLRQ.framework" 95 | install_framework "$BUILT_PRODUCTS_DIR/PromiseKit/PromiseKit.framework" 96 | install_framework "$BUILT_PRODUCTS_DIR/SwiftyJSON/SwiftyJSON.framework" 97 | fi 98 | -------------------------------------------------------------------------------- /Pods/PromiseKit/Sources/URLDataPromise.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | public enum Encoding { 4 | case JSON(NSJSONReadingOptions) 5 | } 6 | 7 | public class URLDataPromise: Promise { 8 | public func asDataAndResponse() -> Promise<(NSData, NSURLResponse)> { 9 | return then(on: zalgo) { ($0, self.URLResponse) } 10 | } 11 | 12 | public func asString() -> Promise { 13 | return then(on: waldo) { data -> String in 14 | guard let str = NSString(data: data, encoding: self.URLResponse.stringEncoding ?? NSUTF8StringEncoding) else { 15 | throw URLError.StringEncoding(self.URLRequest, data, self.URLResponse) 16 | } 17 | return str as String 18 | } 19 | } 20 | 21 | public func asArray(encoding: Encoding = .JSON(.AllowFragments)) -> Promise { 22 | return then(on: waldo) { data -> NSArray in 23 | switch encoding { 24 | case .JSON(let options): 25 | guard !data.b0rkedEmptyRailsResponse else { return NSArray() } 26 | let json = try NSJSONSerialization.JSONObjectWithData(data, options: options) 27 | guard let array = json as? NSArray else { throw JSONError.UnexpectedRootNode(json) } 28 | return array 29 | } 30 | } 31 | } 32 | 33 | public func asDictionary(encoding: Encoding = .JSON(.AllowFragments)) -> Promise { 34 | return then(on: waldo) { data -> NSDictionary in 35 | switch encoding { 36 | case .JSON(let options): 37 | guard !data.b0rkedEmptyRailsResponse else { return NSDictionary() } 38 | let json = try NSJSONSerialization.JSONObjectWithData(data, options: options) 39 | guard let dict = json as? NSDictionary else { throw JSONError.UnexpectedRootNode(json) } 40 | return dict 41 | } 42 | } 43 | } 44 | 45 | private override init(@noescape resolvers: (fulfill: (NSData) -> Void, reject: (ErrorType) -> Void) throws -> Void) { 46 | super.init(resolvers: resolvers) 47 | } 48 | 49 | public override init(error: ErrorType) { 50 | super.init(error: error) 51 | } 52 | 53 | private var URLRequest: NSURLRequest! 54 | private var URLResponse: NSURLResponse! 55 | 56 | public class func go(request: NSURLRequest, @noescape body: ((NSData?, NSURLResponse?, NSError?) -> Void) -> Void) -> URLDataPromise { 57 | var fulfill: ((NSData) -> Void)! 58 | var reject: ((ErrorType) -> Void)! 59 | 60 | let promise = URLDataPromise { fulfill = $0; reject = $1 } 61 | 62 | body { data, rsp, error in 63 | promise.URLRequest = request 64 | promise.URLResponse = rsp 65 | 66 | if let error = error { 67 | reject(URLError.UnderlyingCocoaError(request, data, rsp, error)) 68 | } else if let data = data, rsp = rsp as? NSHTTPURLResponse where rsp.statusCode >= 200 && rsp.statusCode < 300 { 69 | fulfill(data) 70 | } else if let data = data where !(rsp is NSHTTPURLResponse) { 71 | fulfill(data) 72 | } else { 73 | reject(URLError.BadResponse(request, data, rsp)) 74 | } 75 | } 76 | 77 | return promise 78 | } 79 | } 80 | 81 | #if os(iOS) 82 | import UIKit.UIImage 83 | 84 | extension URLDataPromise { 85 | public func asImage() -> Promise { 86 | return then(on: waldo) { data -> UIImage in 87 | guard let img = UIImage(data: data), cgimg = img.CGImage else { 88 | throw URLError.InvalidImageData(self.URLRequest, data) 89 | } 90 | return UIImage(CGImage: cgimg, scale: img.scale, orientation: img.imageOrientation) 91 | } 92 | } 93 | } 94 | #endif 95 | 96 | extension NSURLResponse { 97 | private var stringEncoding: UInt? { 98 | guard let encodingName = textEncodingName else { return nil } 99 | let encoding = CFStringConvertIANACharSetNameToEncoding(encodingName) 100 | guard encoding != kCFStringEncodingInvalidId else { return nil } 101 | return CFStringConvertEncodingToNSStringEncoding(encoding) 102 | } 103 | } 104 | 105 | extension NSData { 106 | private var b0rkedEmptyRailsResponse: Bool { 107 | return self == NSData(bytes: " ", length: 1) 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /Pods/PromiseKit/Sources/State.swift: -------------------------------------------------------------------------------- 1 | import Dispatch 2 | import Foundation // NSLog 3 | 4 | enum Seal { 5 | case Pending(Handlers) 6 | case Resolved(R) 7 | } 8 | 9 | enum Resolution { 10 | case Fulfilled(T) 11 | case Rejected(ErrorType, ErrorConsumptionToken) 12 | } 13 | 14 | // would be a protocol, but you can't have typed variables of “generic” 15 | // protocols in Swift 2. That is, I couldn’t do var state: State when 16 | // it was a protocol. There is no work around. 17 | class State { 18 | func get() -> R? { fatalError("Abstract Base Class") } 19 | func get(body: (Seal) -> Void) { fatalError("Abstract Base Class") } 20 | } 21 | 22 | class UnsealedState: State { 23 | private let barrier = dispatch_queue_create("org.promisekit.barrier", DISPATCH_QUEUE_CONCURRENT) 24 | private var seal: Seal 25 | 26 | /** 27 | Quick return, but will not provide the handlers array because 28 | it could be modified while you are using it by another thread. 29 | If you need the handlers, use the second `get` variant. 30 | */ 31 | override func get() -> R? { 32 | var result: R? 33 | dispatch_sync(barrier) { 34 | if case .Resolved(let resolution) = self.seal { 35 | result = resolution 36 | } 37 | } 38 | return result 39 | } 40 | 41 | override func get(body: (Seal) -> Void) { 42 | var sealed = false 43 | dispatch_sync(barrier) { 44 | switch self.seal { 45 | case .Resolved: 46 | sealed = true 47 | case .Pending: 48 | sealed = false 49 | } 50 | } 51 | if !sealed { 52 | dispatch_barrier_sync(barrier) { 53 | switch (self.seal) { 54 | case .Pending: 55 | body(self.seal) 56 | case .Resolved: 57 | sealed = true // welcome to race conditions 58 | } 59 | } 60 | } 61 | if sealed { 62 | body(seal) 63 | } 64 | } 65 | 66 | required init(inout resolver: ((R) -> Void)!) { 67 | seal = .Pending(Handlers()) 68 | super.init() 69 | resolver = { resolution in 70 | var handlers: Handlers? 71 | dispatch_barrier_sync(self.barrier) { 72 | if case .Pending(let hh) = self.seal { 73 | self.seal = .Resolved(resolution) 74 | handlers = hh 75 | } 76 | } 77 | if let handlers = handlers { 78 | for handler in handlers { 79 | handler(resolution) 80 | } 81 | } 82 | } 83 | } 84 | 85 | deinit { 86 | if case .Pending = seal { 87 | NSLog("PromiseKit: Pending Promise deallocated! This is usually a bug") 88 | } 89 | } 90 | } 91 | 92 | class SealedState: State { 93 | private let resolution: R 94 | 95 | init(resolution: R) { 96 | self.resolution = resolution 97 | } 98 | 99 | override func get() -> R? { 100 | return resolution 101 | } 102 | 103 | override func get(body: (Seal) -> Void) { 104 | body(.Resolved(resolution)) 105 | } 106 | } 107 | 108 | 109 | class Handlers: SequenceType { 110 | var bodies: [(R)->Void] = [] 111 | 112 | func append(body: (R)->Void) { 113 | bodies.append(body) 114 | } 115 | 116 | func generate() -> IndexingGenerator<[(R)->Void]> { 117 | return bodies.generate() 118 | } 119 | 120 | var count: Int { 121 | return bodies.count 122 | } 123 | } 124 | 125 | 126 | extension Resolution: CustomStringConvertible { 127 | var description: String { 128 | switch self { 129 | case .Fulfilled(let value): 130 | return "Fulfilled with value: \(value)" 131 | case .Rejected(let error): 132 | return "Rejected with error: \(error)" 133 | } 134 | } 135 | } 136 | 137 | extension UnsealedState: CustomStringConvertible { 138 | var description: String { 139 | var rv: String! 140 | get { seal in 141 | switch seal { 142 | case .Pending(let handlers): 143 | rv = "Pending with \(handlers.count) handlers" 144 | case .Resolved(let resolution): 145 | rv = "\(resolution)" 146 | } 147 | } 148 | return "UnsealedState: \(rv)" 149 | } 150 | } 151 | 152 | extension SealedState: CustomStringConvertible { 153 | var description: String { 154 | return "SealedState: \(resolution)" 155 | } 156 | } 157 | -------------------------------------------------------------------------------- /Pods/PromiseKit/Sources/AnyPromise.m: -------------------------------------------------------------------------------- 1 | #import "AnyPromise.h" 2 | #import "AnyPromise+Private.h" 3 | @import Foundation.NSKeyValueCoding; 4 | #import "PMKCallVariadicBlock.m" 5 | 6 | NSString *const PMKErrorDomain = @"PMKErrorDomain"; 7 | 8 | dispatch_queue_t (^PMKDefaultDispatchQueue)() = ^{ return dispatch_get_main_queue(); }; 9 | 10 | @implementation AnyPromise (objc) 11 | 12 | - (instancetype)initWithResolver:(PMKResolver __strong *)resolver { 13 | return [self initWithBridge:^(PMKResolver resolve){ 14 | *resolver = resolve; 15 | }]; 16 | } 17 | 18 | + (instancetype)promiseWithResolverBlock:(void (^)(PMKResolver))resolveBlock { 19 | return [[self alloc] initWithBridge:resolveBlock]; 20 | } 21 | 22 | + (instancetype)promiseWithValue:(id)value { 23 | return [[self alloc] initWithBridge:^(PMKResolver resolve){ 24 | resolve(value); 25 | }]; 26 | } 27 | 28 | static inline AnyPromise *AnyPromiseWhen(AnyPromise *when, void(^then)(id, PMKResolver)) { 29 | return [[AnyPromise alloc] initWithBridge:^(PMKResolver resolve){ 30 | [when pipe:^(id obj){ 31 | then(obj, resolve); 32 | }]; 33 | }]; 34 | } 35 | 36 | static inline AnyPromise *__then(AnyPromise *self, dispatch_queue_t queue, id block) { 37 | return AnyPromiseWhen(self, ^(id obj, PMKResolver resolve) { 38 | if (IsError(obj)) { 39 | resolve(obj); 40 | } else dispatch_async(queue, ^{ 41 | resolve(PMKCallVariadicBlock(block, obj)); 42 | }); 43 | }); 44 | } 45 | 46 | - (AnyPromise *(^)(id))then { 47 | return ^(id block) { 48 | return __then(self, PMKDefaultDispatchQueue(), block); 49 | }; 50 | } 51 | 52 | - (AnyPromise *(^)(dispatch_queue_t, id))thenOn { 53 | return ^(dispatch_queue_t queue, id block) { 54 | return __then(self, queue, block); 55 | }; 56 | } 57 | 58 | - (AnyPromise *(^)(id))thenInBackground { 59 | return ^(id block) { 60 | return __then(self, dispatch_get_global_queue(0, 0), block); 61 | }; 62 | } 63 | 64 | static inline AnyPromise *__catch(AnyPromise *self, BOOL includeCancellation, id block) { 65 | return AnyPromiseWhen(self, ^(id obj, PMKResolver resolve) { 66 | dispatch_async(PMKDefaultDispatchQueue(), ^{ 67 | if (IsError(obj) && (includeCancellation || ![obj cancelled])) { 68 | [obj pmk_consume]; 69 | resolve(PMKCallVariadicBlock(block, obj)); 70 | } else { 71 | resolve(obj); 72 | } 73 | }); 74 | }); 75 | } 76 | 77 | - (AnyPromise *(^)(id))catch { 78 | return ^(id block) { 79 | return __catch(self, NO, block); 80 | }; 81 | } 82 | 83 | - (AnyPromise *(^)(PMKCatchPolicy, id))catchWithPolicy { 84 | return ^(PMKCatchPolicy policy, id block) { 85 | return __catch(self, policy == PMKCatchPolicyAllErrors, block); 86 | }; 87 | } 88 | 89 | static inline AnyPromise *__finally(AnyPromise *self, dispatch_queue_t queue, dispatch_block_t block) { 90 | return AnyPromiseWhen(self, ^(id obj, PMKResolver resolve) { 91 | dispatch_async(queue, ^{ 92 | block(); 93 | resolve(obj); 94 | }); 95 | }); 96 | } 97 | 98 | - (AnyPromise *(^)(dispatch_block_t))finally { 99 | return ^(dispatch_block_t block) { 100 | return __finally(self, PMKDefaultDispatchQueue(), block); 101 | }; 102 | } 103 | 104 | - (AnyPromise *(^)(dispatch_queue_t, dispatch_block_t))finallyOn { 105 | return ^(dispatch_queue_t queue, dispatch_block_t block) { 106 | return __finally(self, queue, block); 107 | }; 108 | } 109 | 110 | - (id)value { 111 | id result = [self valueForKey:@"__value"]; 112 | return [result isKindOfClass:[PMKArray class]] 113 | ? result[0] 114 | : result; 115 | } 116 | 117 | @end 118 | 119 | 120 | 121 | @implementation AnyPromise (Adapters) 122 | 123 | + (instancetype)promiseWithAdapterBlock:(void (^)(PMKAdapter))block { 124 | return [self promiseWithResolverBlock:^(PMKResolver resolve) { 125 | block(^(id value, id error){ 126 | resolve(error ?: value); 127 | }); 128 | }]; 129 | } 130 | 131 | + (instancetype)promiseWithIntegerAdapterBlock:(void (^)(PMKIntegerAdapter))block { 132 | return [self promiseWithResolverBlock:^(PMKResolver resolve) { 133 | block(^(NSInteger value, id error){ 134 | if (error) { 135 | resolve(error); 136 | } else { 137 | resolve(@(value)); 138 | } 139 | }); 140 | }]; 141 | } 142 | 143 | + (instancetype)promiseWithBooleanAdapterBlock:(void (^)(PMKBooleanAdapter adapter))block { 144 | return [self promiseWithResolverBlock:^(PMKResolver resolve) { 145 | block(^(BOOL value, id error){ 146 | if (error) { 147 | resolve(error); 148 | } else { 149 | resolve(@(value)); 150 | } 151 | }); 152 | }]; 153 | } 154 | 155 | @end 156 | -------------------------------------------------------------------------------- /Network-Evolution-Practice.xcodeproj/xcuserdata/David.xcuserdatad/xcschemes/Network-Evolution-Practice.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 33 | 39 | 40 | 41 | 43 | 49 | 50 | 51 | 52 | 53 | 59 | 60 | 61 | 62 | 63 | 64 | 74 | 76 | 82 | 83 | 84 | 85 | 86 | 87 | 93 | 95 | 101 | 102 | 103 | 104 | 106 | 107 | 110 | 111 | 112 | -------------------------------------------------------------------------------- /Pods/PromiseKit/Categories/UIKit/UIViewController+AnyPromise.m: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | #import 4 | #import "UIViewController+AnyPromise.h" 5 | 6 | @interface PMKGenericDelegate : NSObject { 7 | @public 8 | PMKResolver resolve; 9 | } 10 | + (instancetype)delegateWithPromise:(AnyPromise **)promise; 11 | @end 12 | 13 | 14 | @implementation UIViewController (PromiseKit) 15 | 16 | - (AnyPromise *)promiseViewController:(UIViewController *)vc animated:(BOOL)animated completion:(void (^)(void))block { 17 | __kindof UIViewController *vc2present = vc; 18 | AnyPromise *promise = nil; 19 | 20 | if ([vc isKindOfClass:NSClassFromString(@"MFMailComposeViewController")]) { 21 | PMKGenericDelegate *delegate = [PMKGenericDelegate delegateWithPromise:&promise]; 22 | [vc setValue:delegate forKey:@"mailComposeDelegate"]; 23 | } 24 | else if ([vc isKindOfClass:NSClassFromString(@"MFMessageComposeViewController")]) { 25 | PMKGenericDelegate *delegate = [PMKGenericDelegate delegateWithPromise:&promise]; 26 | [vc setValue:delegate forKey:@"messageComposeDelegate"]; 27 | } 28 | else if ([vc isKindOfClass:NSClassFromString(@"UIImagePickerController")]) { 29 | PMKGenericDelegate *delegate = [PMKGenericDelegate delegateWithPromise:&promise]; 30 | ((UIImagePickerController *)vc).delegate = delegate; 31 | } 32 | else if ([vc isKindOfClass:NSClassFromString(@"SLComposeViewController")]) { 33 | PMKResolver resolve; 34 | promise = [[AnyPromise alloc] initWithResolver:&resolve]; 35 | [vc setValue:^(NSInteger result){ 36 | if (result == 0) { 37 | resolve([NSError cancelledError]); 38 | } else { 39 | resolve(@(result)); 40 | } 41 | } forKey:@"completionHandler"]; 42 | } 43 | else if ([vc isKindOfClass:[UINavigationController class]]) 44 | vc = [(id)vc viewControllers].firstObject; 45 | 46 | if (!vc) { 47 | id userInfo = @{NSLocalizedDescriptionKey: @"nil or effective nil passed to promiseViewController"}; 48 | id err = [NSError errorWithDomain:PMKErrorDomain code:PMKInvalidUsageError userInfo:userInfo]; 49 | return [AnyPromise promiseWithValue:err]; 50 | } 51 | 52 | if (!promise) { 53 | if (![vc respondsToSelector:NSSelectorFromString(@"promise")]) { 54 | id userInfo = @{NSLocalizedDescriptionKey: @"ViewController is not promisable"}; 55 | id err = [NSError errorWithDomain:PMKErrorDomain code:PMKInvalidUsageError userInfo:userInfo]; 56 | return [AnyPromise promiseWithValue:err]; 57 | } 58 | 59 | promise = [vc valueForKey:@"promise"]; 60 | 61 | if (![promise isKindOfClass:[AnyPromise class]]) { 62 | id userInfo = @{NSLocalizedDescriptionKey: @"The promise property is nil or not of type AnyPromise"}; 63 | id err = [NSError errorWithDomain:PMKErrorDomain code:PMKInvalidUsageError userInfo:userInfo]; 64 | return [AnyPromise promiseWithValue:err]; 65 | } 66 | } 67 | 68 | if (!promise.pending) 69 | return promise; 70 | 71 | [self presentViewController:vc2present animated:animated completion:block]; 72 | 73 | promise.finally(^{ 74 | [vc2present.presentingViewController dismissViewControllerAnimated:animated completion:nil]; 75 | }); 76 | 77 | return promise; 78 | } 79 | 80 | @end 81 | 82 | 83 | 84 | @implementation PMKGenericDelegate { 85 | id retainCycle; 86 | } 87 | 88 | + (instancetype)delegateWithPromise:(AnyPromise **)promise; { 89 | PMKGenericDelegate *d = [PMKGenericDelegate new]; 90 | d->retainCycle = d; 91 | *promise = [[AnyPromise alloc] initWithResolver:&d->resolve]; 92 | return d; 93 | } 94 | 95 | - (void)mailComposeController:(id)controller didFinishWithResult:(int)result error:(NSError *)error { 96 | if (error != nil) { 97 | resolve(error); 98 | } else if (result == 0) { 99 | resolve([NSError cancelledError]); 100 | } else { 101 | resolve(@(result)); 102 | } 103 | retainCycle = nil; 104 | } 105 | 106 | - (void)messageComposeViewController:(id)controller didFinishWithResult:(int)result { 107 | if (result == 2) { 108 | id userInfo = @{NSLocalizedDescriptionKey: @"The user’s attempt to save or send the message was unsuccessful."}; 109 | id error = [NSError errorWithDomain:PMKErrorDomain code:PMKOperationFailed userInfo:userInfo]; 110 | resolve(error); 111 | } else { 112 | resolve(@(result)); 113 | } 114 | retainCycle = nil; 115 | } 116 | 117 | - (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info { 118 | id img = info[UIImagePickerControllerEditedImage] ?: info[UIImagePickerControllerOriginalImage]; 119 | resolve(PMKManifold(img, info)); 120 | retainCycle = nil; 121 | } 122 | 123 | - (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker { 124 | resolve([NSError cancelledError]); 125 | retainCycle = nil; 126 | } 127 | 128 | @end 129 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-Network-Evolution-Practice/Pods-Network-Evolution-Practice-acknowledgements.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreferenceSpecifiers 6 | 7 | 8 | FooterText 9 | This application makes use of the following third party libraries: 10 | Title 11 | Acknowledgements 12 | Type 13 | PSGroupSpecifier 14 | 15 | 16 | FooterText 17 | Copyright (c) 2014-2016 Alamofire Software Foundation (http://alamofire.org/) 18 | 19 | Permission is hereby granted, free of charge, to any person obtaining a copy 20 | of this software and associated documentation files (the "Software"), to deal 21 | in the Software without restriction, including without limitation the rights 22 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 23 | copies of the Software, and to permit persons to whom the Software is 24 | furnished to do so, subject to the following conditions: 25 | 26 | The above copyright notice and this permission notice shall be included in 27 | all copies or substantial portions of the Software. 28 | 29 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 30 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 31 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 32 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 33 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 34 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 35 | THE SOFTWARE. 36 | 37 | Title 38 | Alamofire 39 | Type 40 | PSGroupSpecifier 41 | 42 | 43 | FooterText 44 | https://github.com/mxcl/OMGHTTPURLRQ/blob/master/README.markdown 45 | Title 46 | OMGHTTPURLRQ 47 | Type 48 | PSGroupSpecifier 49 | 50 | 51 | FooterText 52 | Copyright 2016, Max Howell; mxcl@me.com 53 | 54 | Permission is hereby granted, free of charge, to any person obtaining a 55 | copy of this software and associated documentation files (the 56 | "Software"), to deal in the Software without restriction, including 57 | without limitation the rights to use, copy, modify, merge, publish, 58 | distribute, sublicense, and/or sell copies of the Software, and to 59 | permit persons to whom the Software is furnished to do so, subject to 60 | the following conditions: 61 | 62 | The above copyright notice and this permission notice shall be included 63 | in all copies or substantial portions of the Software. 64 | 65 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 66 | OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 67 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 68 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 69 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 70 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 71 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 72 | 73 | Title 74 | PromiseKit 75 | Type 76 | PSGroupSpecifier 77 | 78 | 79 | FooterText 80 | The MIT License (MIT) 81 | 82 | Copyright (c) 2014 Ruoyu Fu 83 | 84 | Permission is hereby granted, free of charge, to any person obtaining a copy 85 | of this software and associated documentation files (the "Software"), to deal 86 | in the Software without restriction, including without limitation the rights 87 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 88 | copies of the Software, and to permit persons to whom the Software is 89 | furnished to do so, subject to the following conditions: 90 | 91 | The above copyright notice and this permission notice shall be included in 92 | all copies or substantial portions of the Software. 93 | 94 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 95 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 96 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 97 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 98 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 99 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 100 | THE SOFTWARE. 101 | 102 | Title 103 | SwiftyJSON 104 | Type 105 | PSGroupSpecifier 106 | 107 | 108 | FooterText 109 | Generated by CocoaPods - https://cocoapods.org 110 | Title 111 | 112 | Type 113 | PSGroupSpecifier 114 | 115 | 116 | StringsTable 117 | Acknowledgements 118 | Title 119 | Acknowledgements 120 | 121 | 122 | -------------------------------------------------------------------------------- /Pods/PromiseKit/Sources/PMKCallVariadicBlock.m: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | #import 4 | #import 5 | #import "NSMethodSignatureForBlock.m" 6 | #import 7 | #import 8 | #import 9 | 10 | #ifndef PMKLog 11 | #define PMKLog NSLog 12 | #endif 13 | 14 | @interface PMKArray : NSObject { 15 | @public 16 | id objs[3]; 17 | NSUInteger count; 18 | } @end 19 | 20 | @implementation PMKArray 21 | 22 | - (id)objectAtIndexedSubscript:(NSUInteger)idx { 23 | if (count <= idx) { 24 | // this check is necessary due to lack of checks in `pmk_safely_call_block` 25 | return nil; 26 | } 27 | return objs[idx]; 28 | } 29 | 30 | @end 31 | 32 | id __PMKArrayWithCount(NSUInteger count, ...) { 33 | PMKArray *this = [PMKArray new]; 34 | this->count = count; 35 | va_list args; 36 | va_start(args, count); 37 | for (NSUInteger x = 0; x < count; ++x) 38 | this->objs[x] = va_arg(args, id); 39 | va_end(args); 40 | return this; 41 | } 42 | 43 | 44 | static inline id _PMKCallVariadicBlock(id frock, id result) { 45 | NSCAssert(frock, @""); 46 | 47 | NSMethodSignature *sig = NSMethodSignatureForBlock(frock); 48 | const NSUInteger nargs = sig.numberOfArguments; 49 | const char rtype = sig.methodReturnType[0]; 50 | 51 | #define call_block_with_rtype(type) ({^type{ \ 52 | switch (nargs) { \ 53 | case 1: \ 54 | return ((type(^)(void))frock)(); \ 55 | case 2: { \ 56 | const id arg = [result class] == [PMKArray class] ? result[0] : result; \ 57 | return ((type(^)(id))frock)(arg); \ 58 | } \ 59 | case 3: { \ 60 | type (^block)(id, id) = frock; \ 61 | return [result class] == [PMKArray class] \ 62 | ? block(result[0], result[1]) \ 63 | : block(result, nil); \ 64 | } \ 65 | case 4: { \ 66 | type (^block)(id, id, id) = frock; \ 67 | return [result class] == [PMKArray class] \ 68 | ? block(result[0], result[1], result[2]) \ 69 | : block(result, nil, nil); \ 70 | } \ 71 | default: \ 72 | @throw [NSException exceptionWithName:NSInvalidArgumentException reason:@"PromiseKit: The provided block’s argument count is unsupported." userInfo:nil]; \ 73 | }}();}) 74 | 75 | switch (rtype) { 76 | case 'v': 77 | call_block_with_rtype(void); 78 | return nil; 79 | case '@': 80 | return call_block_with_rtype(id) ?: nil; 81 | case '*': { 82 | char *str = call_block_with_rtype(char *); 83 | return str ? @(str) : nil; 84 | } 85 | case 'c': return @(call_block_with_rtype(char)); 86 | case 'i': return @(call_block_with_rtype(int)); 87 | case 's': return @(call_block_with_rtype(short)); 88 | case 'l': return @(call_block_with_rtype(long)); 89 | case 'q': return @(call_block_with_rtype(long long)); 90 | case 'C': return @(call_block_with_rtype(unsigned char)); 91 | case 'I': return @(call_block_with_rtype(unsigned int)); 92 | case 'S': return @(call_block_with_rtype(unsigned short)); 93 | case 'L': return @(call_block_with_rtype(unsigned long)); 94 | case 'Q': return @(call_block_with_rtype(unsigned long long)); 95 | case 'f': return @(call_block_with_rtype(float)); 96 | case 'd': return @(call_block_with_rtype(double)); 97 | case 'B': return @(call_block_with_rtype(_Bool)); 98 | case '^': 99 | if (strcmp(sig.methodReturnType, "^v") == 0) { 100 | call_block_with_rtype(void); 101 | return nil; 102 | } 103 | // else fall through! 104 | default: 105 | @throw [NSException exceptionWithName:@"PromiseKit" reason:@"PromiseKit: Unsupported method signature." userInfo:nil]; 106 | } 107 | } 108 | 109 | static id PMKCallVariadicBlock(id frock, id result) { 110 | @try { 111 | return _PMKCallVariadicBlock(frock, result); 112 | } @catch (id thrown) { 113 | return PMKProcessUnhandledException(thrown); 114 | } 115 | } 116 | 117 | 118 | static dispatch_once_t onceToken; 119 | static NSError *(^PMKUnhandledExceptionHandler)(id); 120 | 121 | NSError *PMKProcessUnhandledException(id thrown) { 122 | 123 | dispatch_once(&onceToken, ^{ 124 | PMKUnhandledExceptionHandler = ^id(id reason){ 125 | if ([reason isKindOfClass:[NSError class]]) 126 | return reason; 127 | if ([reason isKindOfClass:[NSString class]]) 128 | return [NSError errorWithDomain:PMKErrorDomain code:PMKUnexpectedError userInfo:@{NSLocalizedDescriptionKey: reason}]; 129 | return nil; 130 | }; 131 | }); 132 | 133 | id err = PMKUnhandledExceptionHandler(thrown); 134 | if (!err) { 135 | NSLog(@"PromiseKit no longer catches *all* exceptions. However you can change this behavior by setting a new PMKProcessUnhandledException handler."); 136 | @throw thrown; 137 | } 138 | return err; 139 | } 140 | 141 | void PMKSetUnhandledExceptionHandler(NSError *(^newHandler)(id)) { 142 | dispatch_once(&onceToken, ^{ 143 | PMKUnhandledExceptionHandler = newHandler; 144 | }); 145 | } 146 | --------------------------------------------------------------------------------