├── .DS_Store ├── Podfile ├── Podfile.lock ├── Pods ├── Alamofire │ ├── LICENSE │ ├── README.md │ └── Source │ │ ├── Alamofire.swift │ │ ├── Download.swift │ │ ├── Error.swift │ │ ├── Manager.swift │ │ ├── MultipartFormData.swift │ │ ├── NetworkReachabilityManager.swift │ │ ├── Notifications.swift │ │ ├── ParameterEncoding.swift │ │ ├── Request.swift │ │ ├── Response.swift │ │ ├── ResponseSerialization.swift │ │ ├── Result.swift │ │ ├── ServerTrustPolicy.swift │ │ ├── Stream.swift │ │ ├── Timeline.swift │ │ ├── Upload.swift │ │ └── Validation.swift ├── Manifest.lock ├── Pods.xcodeproj │ ├── project.pbxproj │ └── xcuserdata │ │ └── jtratta.xcuserdatad │ │ └── xcschemes │ │ ├── Alamofire.xcscheme │ │ ├── Pods-SwiftJSS.xcscheme │ │ ├── Pods-SwiftJSSTests.xcscheme │ │ └── xcschememanagement.plist └── Target Support Files │ ├── Alamofire │ ├── Alamofire-dummy.m │ ├── Alamofire-prefix.pch │ ├── Alamofire-umbrella.h │ ├── Alamofire.modulemap │ ├── Alamofire.xcconfig │ └── Info.plist │ ├── Pods-SwiftJSS │ ├── Info.plist │ ├── Pods-SwiftJSS-acknowledgements.markdown │ ├── Pods-SwiftJSS-acknowledgements.plist │ ├── Pods-SwiftJSS-dummy.m │ ├── Pods-SwiftJSS-frameworks.sh │ ├── Pods-SwiftJSS-resources.sh │ ├── Pods-SwiftJSS-umbrella.h │ ├── Pods-SwiftJSS.debug.xcconfig │ ├── Pods-SwiftJSS.modulemap │ └── Pods-SwiftJSS.release.xcconfig │ └── Pods-SwiftJSSTests │ ├── Info.plist │ ├── Pods-SwiftJSSTests-acknowledgements.markdown │ ├── Pods-SwiftJSSTests-acknowledgements.plist │ ├── Pods-SwiftJSSTests-dummy.m │ ├── Pods-SwiftJSSTests-frameworks.sh │ ├── Pods-SwiftJSSTests-resources.sh │ ├── Pods-SwiftJSSTests-umbrella.h │ ├── Pods-SwiftJSSTests.debug.xcconfig │ ├── Pods-SwiftJSSTests.modulemap │ └── Pods-SwiftJSSTests.release.xcconfig ├── README.md ├── SwiftJSS.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcuserdata │ │ └── jtratta.xcuserdatad │ │ └── UserInterfaceState.xcuserstate └── xcuserdata │ └── jtratta.xcuserdatad │ └── xcschemes │ ├── SwiftJSS.xcscheme │ └── xcschememanagement.plist ├── SwiftJSS.xcworkspace ├── contents.xcworkspacedata └── xcuserdata │ └── jtratta.xcuserdatad │ ├── UserInterfaceState.xcuserstate │ └── xcdebugger │ └── Breakpoints_v2.xcbkptlist ├── SwiftJSS ├── AppDelegate.swift ├── Images.xcassets │ └── AppIcon.appiconset │ │ └── Contents.json ├── Info.plist ├── Main.storyboard ├── Screen Shot.png └── ViewController.swift └── SwiftJSSTests ├── Info.plist └── SwiftJSSTests.swift /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jason-tratta/SwiftJSS/a1a53b826b3377d7acbc98d191ad4b3fed0bdfb7/.DS_Store -------------------------------------------------------------------------------- /Podfile: -------------------------------------------------------------------------------- 1 | # Uncomment this line to define a global platform for your project 2 | # platform :ios, '9.0' 3 | 4 | target 'SwiftJSS' 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 SwiftJSS 9 | pod 'Alamofire', '~> 3.4' 10 | 11 | target 'SwiftJSSTests' do 12 | inherit! :search_paths 13 | # Pods for testing 14 | end 15 | 16 | end 17 | -------------------------------------------------------------------------------- /Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - Alamofire (3.4.0) 3 | 4 | DEPENDENCIES: 5 | - Alamofire (~> 3.4) 6 | 7 | SPEC CHECKSUMS: 8 | Alamofire: c19a627cefd6a95f840401c49ab1f124e07f54ee 9 | 10 | PODFILE CHECKSUM: cc3501dec68f096404d9552f1b571e2ba4c8ea11 11 | 12 | COCOAPODS: 1.0.0 13 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /Pods/Alamofire/Source/Alamofire.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Alamofire.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 | // MARK: - URLStringConvertible 28 | 29 | /** 30 | Types adopting the `URLStringConvertible` protocol can be used to construct URL strings, which are then used to 31 | construct URL requests. 32 | */ 33 | public protocol URLStringConvertible { 34 | /** 35 | A URL that conforms to RFC 2396. 36 | 37 | Methods accepting a `URLStringConvertible` type parameter parse it according to RFCs 1738 and 1808. 38 | 39 | See https://tools.ietf.org/html/rfc2396 40 | See https://tools.ietf.org/html/rfc1738 41 | See https://tools.ietf.org/html/rfc1808 42 | */ 43 | var URLString: String { get } 44 | } 45 | 46 | extension String: URLStringConvertible { 47 | public var URLString: String { 48 | return self 49 | } 50 | } 51 | 52 | extension NSURL: URLStringConvertible { 53 | public var URLString: String { 54 | return absoluteString 55 | } 56 | } 57 | 58 | extension NSURLComponents: URLStringConvertible { 59 | public var URLString: String { 60 | return URL!.URLString 61 | } 62 | } 63 | 64 | extension NSURLRequest: URLStringConvertible { 65 | public var URLString: String { 66 | return URL!.URLString 67 | } 68 | } 69 | 70 | // MARK: - URLRequestConvertible 71 | 72 | /** 73 | Types adopting the `URLRequestConvertible` protocol can be used to construct URL requests. 74 | */ 75 | public protocol URLRequestConvertible { 76 | /// The URL request. 77 | var URLRequest: NSMutableURLRequest { get } 78 | } 79 | 80 | extension NSURLRequest: URLRequestConvertible { 81 | public var URLRequest: NSMutableURLRequest { 82 | return self.mutableCopy() as! NSMutableURLRequest 83 | } 84 | } 85 | 86 | // MARK: - Convenience 87 | 88 | func URLRequest( 89 | method: Method, 90 | _ URLString: URLStringConvertible, 91 | headers: [String: String]? = nil) 92 | -> NSMutableURLRequest 93 | { 94 | let mutableURLRequest = NSMutableURLRequest(URL: NSURL(string: URLString.URLString)!) 95 | mutableURLRequest.HTTPMethod = method.rawValue 96 | 97 | if let headers = headers { 98 | for (headerField, headerValue) in headers { 99 | mutableURLRequest.setValue(headerValue, forHTTPHeaderField: headerField) 100 | } 101 | } 102 | 103 | return mutableURLRequest 104 | } 105 | 106 | // MARK: - Request Methods 107 | 108 | /** 109 | Creates a request using the shared manager instance for the specified method, URL string, parameters, and 110 | parameter encoding. 111 | 112 | - parameter method: The HTTP method. 113 | - parameter URLString: The URL string. 114 | - parameter parameters: The parameters. `nil` by default. 115 | - parameter encoding: The parameter encoding. `.URL` by default. 116 | - parameter headers: The HTTP headers. `nil` by default. 117 | 118 | - returns: The created request. 119 | */ 120 | public func request( 121 | method: Method, 122 | _ URLString: URLStringConvertible, 123 | parameters: [String: AnyObject]? = nil, 124 | encoding: ParameterEncoding = .URL, 125 | headers: [String: String]? = nil) 126 | -> Request 127 | { 128 | return Manager.sharedInstance.request( 129 | method, 130 | URLString, 131 | parameters: parameters, 132 | encoding: encoding, 133 | headers: headers 134 | ) 135 | } 136 | 137 | /** 138 | Creates a request using the shared manager instance for the specified URL request. 139 | 140 | If `startRequestsImmediately` is `true`, the request will have `resume()` called before being returned. 141 | 142 | - parameter URLRequest: The URL request 143 | 144 | - returns: The created request. 145 | */ 146 | public func request(URLRequest: URLRequestConvertible) -> Request { 147 | return Manager.sharedInstance.request(URLRequest.URLRequest) 148 | } 149 | 150 | // MARK: - Upload Methods 151 | 152 | // MARK: File 153 | 154 | /** 155 | Creates an upload request using the shared manager instance for the specified method, URL string, and file. 156 | 157 | - parameter method: The HTTP method. 158 | - parameter URLString: The URL string. 159 | - parameter headers: The HTTP headers. `nil` by default. 160 | - parameter file: The file to upload. 161 | 162 | - returns: The created upload request. 163 | */ 164 | public func upload( 165 | method: Method, 166 | _ URLString: URLStringConvertible, 167 | headers: [String: String]? = nil, 168 | file: NSURL) 169 | -> Request 170 | { 171 | return Manager.sharedInstance.upload(method, URLString, headers: headers, file: file) 172 | } 173 | 174 | /** 175 | Creates an upload request using the shared manager instance for the specified URL request and file. 176 | 177 | - parameter URLRequest: The URL request. 178 | - parameter file: The file to upload. 179 | 180 | - returns: The created upload request. 181 | */ 182 | public func upload(URLRequest: URLRequestConvertible, file: NSURL) -> Request { 183 | return Manager.sharedInstance.upload(URLRequest, file: file) 184 | } 185 | 186 | // MARK: Data 187 | 188 | /** 189 | Creates an upload request using the shared manager instance for the specified method, URL string, and data. 190 | 191 | - parameter method: The HTTP method. 192 | - parameter URLString: The URL string. 193 | - parameter headers: The HTTP headers. `nil` by default. 194 | - parameter data: The data to upload. 195 | 196 | - returns: The created upload request. 197 | */ 198 | public func upload( 199 | method: Method, 200 | _ URLString: URLStringConvertible, 201 | headers: [String: String]? = nil, 202 | data: NSData) 203 | -> Request 204 | { 205 | return Manager.sharedInstance.upload(method, URLString, headers: headers, data: data) 206 | } 207 | 208 | /** 209 | Creates an upload request using the shared manager instance for the specified URL request and data. 210 | 211 | - parameter URLRequest: The URL request. 212 | - parameter data: The data to upload. 213 | 214 | - returns: The created upload request. 215 | */ 216 | public func upload(URLRequest: URLRequestConvertible, data: NSData) -> Request { 217 | return Manager.sharedInstance.upload(URLRequest, data: data) 218 | } 219 | 220 | // MARK: Stream 221 | 222 | /** 223 | Creates an upload request using the shared manager instance for the specified method, URL string, and stream. 224 | 225 | - parameter method: The HTTP method. 226 | - parameter URLString: The URL string. 227 | - parameter headers: The HTTP headers. `nil` by default. 228 | - parameter stream: The stream to upload. 229 | 230 | - returns: The created upload request. 231 | */ 232 | public func upload( 233 | method: Method, 234 | _ URLString: URLStringConvertible, 235 | headers: [String: String]? = nil, 236 | stream: NSInputStream) 237 | -> Request 238 | { 239 | return Manager.sharedInstance.upload(method, URLString, headers: headers, stream: stream) 240 | } 241 | 242 | /** 243 | Creates an upload request using the shared manager instance for the specified URL request and stream. 244 | 245 | - parameter URLRequest: The URL request. 246 | - parameter stream: The stream to upload. 247 | 248 | - returns: The created upload request. 249 | */ 250 | public func upload(URLRequest: URLRequestConvertible, stream: NSInputStream) -> Request { 251 | return Manager.sharedInstance.upload(URLRequest, stream: stream) 252 | } 253 | 254 | // MARK: MultipartFormData 255 | 256 | /** 257 | Creates an upload request using the shared manager instance for the specified method and URL string. 258 | 259 | - parameter method: The HTTP method. 260 | - parameter URLString: The URL string. 261 | - parameter headers: The HTTP headers. `nil` by default. 262 | - parameter multipartFormData: The closure used to append body parts to the `MultipartFormData`. 263 | - parameter encodingMemoryThreshold: The encoding memory threshold in bytes. 264 | `MultipartFormDataEncodingMemoryThreshold` by default. 265 | - parameter encodingCompletion: The closure called when the `MultipartFormData` encoding is complete. 266 | */ 267 | public func upload( 268 | method: Method, 269 | _ URLString: URLStringConvertible, 270 | headers: [String: String]? = nil, 271 | multipartFormData: MultipartFormData -> Void, 272 | encodingMemoryThreshold: UInt64 = Manager.MultipartFormDataEncodingMemoryThreshold, 273 | encodingCompletion: (Manager.MultipartFormDataEncodingResult -> Void)?) 274 | { 275 | return Manager.sharedInstance.upload( 276 | method, 277 | URLString, 278 | headers: headers, 279 | multipartFormData: multipartFormData, 280 | encodingMemoryThreshold: encodingMemoryThreshold, 281 | encodingCompletion: encodingCompletion 282 | ) 283 | } 284 | 285 | /** 286 | Creates an upload request using the shared manager instance for the specified method and URL string. 287 | 288 | - parameter URLRequest: The URL request. 289 | - parameter multipartFormData: The closure used to append body parts to the `MultipartFormData`. 290 | - parameter encodingMemoryThreshold: The encoding memory threshold in bytes. 291 | `MultipartFormDataEncodingMemoryThreshold` by default. 292 | - parameter encodingCompletion: The closure called when the `MultipartFormData` encoding is complete. 293 | */ 294 | public func upload( 295 | URLRequest: URLRequestConvertible, 296 | multipartFormData: MultipartFormData -> Void, 297 | encodingMemoryThreshold: UInt64 = Manager.MultipartFormDataEncodingMemoryThreshold, 298 | encodingCompletion: (Manager.MultipartFormDataEncodingResult -> Void)?) 299 | { 300 | return Manager.sharedInstance.upload( 301 | URLRequest, 302 | multipartFormData: multipartFormData, 303 | encodingMemoryThreshold: encodingMemoryThreshold, 304 | encodingCompletion: encodingCompletion 305 | ) 306 | } 307 | 308 | // MARK: - Download Methods 309 | 310 | // MARK: URL Request 311 | 312 | /** 313 | Creates a download request using the shared manager instance for the specified method and URL string. 314 | 315 | - parameter method: The HTTP method. 316 | - parameter URLString: The URL string. 317 | - parameter parameters: The parameters. `nil` by default. 318 | - parameter encoding: The parameter encoding. `.URL` by default. 319 | - parameter headers: The HTTP headers. `nil` by default. 320 | - parameter destination: The closure used to determine the destination of the downloaded file. 321 | 322 | - returns: The created download request. 323 | */ 324 | public func download( 325 | method: Method, 326 | _ URLString: URLStringConvertible, 327 | parameters: [String: AnyObject]? = nil, 328 | encoding: ParameterEncoding = .URL, 329 | headers: [String: String]? = nil, 330 | destination: Request.DownloadFileDestination) 331 | -> Request 332 | { 333 | return Manager.sharedInstance.download( 334 | method, 335 | URLString, 336 | parameters: parameters, 337 | encoding: encoding, 338 | headers: headers, 339 | destination: destination 340 | ) 341 | } 342 | 343 | /** 344 | Creates a download request using the shared manager instance for the specified URL request. 345 | 346 | - parameter URLRequest: The URL request. 347 | - parameter destination: The closure used to determine the destination of the downloaded file. 348 | 349 | - returns: The created download request. 350 | */ 351 | public func download(URLRequest: URLRequestConvertible, destination: Request.DownloadFileDestination) -> Request { 352 | return Manager.sharedInstance.download(URLRequest, destination: destination) 353 | } 354 | 355 | // MARK: Resume Data 356 | 357 | /** 358 | Creates a request using the shared manager instance for downloading from the resume data produced from a 359 | previous request cancellation. 360 | 361 | - parameter resumeData: The resume data. This is an opaque data blob produced by `NSURLSessionDownloadTask` 362 | when a task is cancelled. See `NSURLSession -downloadTaskWithResumeData:` for additional 363 | information. 364 | - parameter destination: The closure used to determine the destination of the downloaded file. 365 | 366 | - returns: The created download request. 367 | */ 368 | public func download(resumeData data: NSData, destination: Request.DownloadFileDestination) -> Request { 369 | return Manager.sharedInstance.download(data, destination: destination) 370 | } 371 | -------------------------------------------------------------------------------- /Pods/Alamofire/Source/Download.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Download.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 | extension Manager { 28 | private enum Downloadable { 29 | case Request(NSURLRequest) 30 | case ResumeData(NSData) 31 | } 32 | 33 | private func download(downloadable: Downloadable, destination: Request.DownloadFileDestination) -> Request { 34 | var downloadTask: NSURLSessionDownloadTask! 35 | 36 | switch downloadable { 37 | case .Request(let request): 38 | dispatch_sync(queue) { 39 | downloadTask = self.session.downloadTaskWithRequest(request) 40 | } 41 | case .ResumeData(let resumeData): 42 | dispatch_sync(queue) { 43 | downloadTask = self.session.downloadTaskWithResumeData(resumeData) 44 | } 45 | } 46 | 47 | let request = Request(session: session, task: downloadTask) 48 | 49 | if let downloadDelegate = request.delegate as? Request.DownloadTaskDelegate { 50 | downloadDelegate.downloadTaskDidFinishDownloadingToURL = { session, downloadTask, URL in 51 | return destination(URL, downloadTask.response as! NSHTTPURLResponse) 52 | } 53 | } 54 | 55 | delegate[request.delegate.task] = request.delegate 56 | 57 | if startRequestsImmediately { 58 | request.resume() 59 | } 60 | 61 | return request 62 | } 63 | 64 | // MARK: Request 65 | 66 | /** 67 | Creates a download request for the specified method, URL string, parameters, parameter encoding, headers 68 | and destination. 69 | 70 | If `startRequestsImmediately` is `true`, the request will have `resume()` called before being returned. 71 | 72 | - parameter method: The HTTP method. 73 | - parameter URLString: The URL string. 74 | - parameter parameters: The parameters. `nil` by default. 75 | - parameter encoding: The parameter encoding. `.URL` by default. 76 | - parameter headers: The HTTP headers. `nil` by default. 77 | - parameter destination: The closure used to determine the destination of the downloaded file. 78 | 79 | - returns: The created download request. 80 | */ 81 | public func download( 82 | method: Method, 83 | _ URLString: URLStringConvertible, 84 | parameters: [String: AnyObject]? = nil, 85 | encoding: ParameterEncoding = .URL, 86 | headers: [String: String]? = nil, 87 | destination: Request.DownloadFileDestination) 88 | -> Request 89 | { 90 | let mutableURLRequest = URLRequest(method, URLString, headers: headers) 91 | let encodedURLRequest = encoding.encode(mutableURLRequest, parameters: parameters).0 92 | 93 | return download(encodedURLRequest, destination: destination) 94 | } 95 | 96 | /** 97 | Creates a request for downloading from the specified URL request. 98 | 99 | If `startRequestsImmediately` is `true`, the request will have `resume()` called before being returned. 100 | 101 | - parameter URLRequest: The URL request 102 | - parameter destination: The closure used to determine the destination of the downloaded file. 103 | 104 | - returns: The created download request. 105 | */ 106 | public func download(URLRequest: URLRequestConvertible, destination: Request.DownloadFileDestination) -> Request { 107 | return download(.Request(URLRequest.URLRequest), destination: destination) 108 | } 109 | 110 | // MARK: Resume Data 111 | 112 | /** 113 | Creates a request for downloading from the resume data produced from a previous request cancellation. 114 | 115 | If `startRequestsImmediately` is `true`, the request will have `resume()` called before being returned. 116 | 117 | - parameter resumeData: The resume data. This is an opaque data blob produced by `NSURLSessionDownloadTask` 118 | when a task is cancelled. See `NSURLSession -downloadTaskWithResumeData:` for 119 | additional information. 120 | - parameter destination: The closure used to determine the destination of the downloaded file. 121 | 122 | - returns: The created download request. 123 | */ 124 | public func download(resumeData: NSData, destination: Request.DownloadFileDestination) -> Request { 125 | return download(.ResumeData(resumeData), destination: destination) 126 | } 127 | } 128 | 129 | // MARK: - 130 | 131 | extension Request { 132 | /** 133 | A closure executed once a request has successfully completed in order to determine where to move the temporary 134 | file written to during the download process. The closure takes two arguments: the temporary file URL and the URL 135 | response, and returns a single argument: the file URL where the temporary file should be moved. 136 | */ 137 | public typealias DownloadFileDestination = (NSURL, NSHTTPURLResponse) -> NSURL 138 | 139 | /** 140 | Creates a download file destination closure which uses the default file manager to move the temporary file to a 141 | file URL in the first available directory with the specified search path directory and search path domain mask. 142 | 143 | - parameter directory: The search path directory. `.DocumentDirectory` by default. 144 | - parameter domain: The search path domain mask. `.UserDomainMask` by default. 145 | 146 | - returns: A download file destination closure. 147 | */ 148 | public class func suggestedDownloadDestination( 149 | directory directory: NSSearchPathDirectory = .DocumentDirectory, 150 | domain: NSSearchPathDomainMask = .UserDomainMask) 151 | -> DownloadFileDestination 152 | { 153 | return { temporaryURL, response -> NSURL in 154 | let directoryURLs = NSFileManager.defaultManager().URLsForDirectory(directory, inDomains: domain) 155 | 156 | if !directoryURLs.isEmpty { 157 | return directoryURLs[0].URLByAppendingPathComponent(response.suggestedFilename!) 158 | } 159 | 160 | return temporaryURL 161 | } 162 | } 163 | 164 | /// The resume data of the underlying download task if available after a failure. 165 | public var resumeData: NSData? { 166 | var data: NSData? 167 | 168 | if let delegate = delegate as? DownloadTaskDelegate { 169 | data = delegate.resumeData 170 | } 171 | 172 | return data 173 | } 174 | 175 | // MARK: - DownloadTaskDelegate 176 | 177 | class DownloadTaskDelegate: TaskDelegate, NSURLSessionDownloadDelegate { 178 | var downloadTask: NSURLSessionDownloadTask? { return task as? NSURLSessionDownloadTask } 179 | var downloadProgress: ((Int64, Int64, Int64) -> Void)? 180 | 181 | var resumeData: NSData? 182 | override var data: NSData? { return resumeData } 183 | 184 | // MARK: - NSURLSessionDownloadDelegate 185 | 186 | // MARK: Override Closures 187 | 188 | var downloadTaskDidFinishDownloadingToURL: ((NSURLSession, NSURLSessionDownloadTask, NSURL) -> NSURL)? 189 | var downloadTaskDidWriteData: ((NSURLSession, NSURLSessionDownloadTask, Int64, Int64, Int64) -> Void)? 190 | var downloadTaskDidResumeAtOffset: ((NSURLSession, NSURLSessionDownloadTask, Int64, Int64) -> Void)? 191 | 192 | // MARK: Delegate Methods 193 | 194 | func URLSession( 195 | session: NSURLSession, 196 | downloadTask: NSURLSessionDownloadTask, 197 | didFinishDownloadingToURL location: NSURL) 198 | { 199 | if let downloadTaskDidFinishDownloadingToURL = downloadTaskDidFinishDownloadingToURL { 200 | do { 201 | let destination = downloadTaskDidFinishDownloadingToURL(session, downloadTask, location) 202 | try NSFileManager.defaultManager().moveItemAtURL(location, toURL: destination) 203 | } catch { 204 | self.error = error as NSError 205 | } 206 | } 207 | } 208 | 209 | func URLSession( 210 | session: NSURLSession, 211 | downloadTask: NSURLSessionDownloadTask, 212 | didWriteData bytesWritten: Int64, 213 | totalBytesWritten: Int64, 214 | totalBytesExpectedToWrite: Int64) 215 | { 216 | if initialResponseTime == nil { initialResponseTime = CFAbsoluteTimeGetCurrent() } 217 | 218 | if let downloadTaskDidWriteData = downloadTaskDidWriteData { 219 | downloadTaskDidWriteData( 220 | session, 221 | downloadTask, 222 | bytesWritten, 223 | totalBytesWritten, 224 | totalBytesExpectedToWrite 225 | ) 226 | } else { 227 | progress.totalUnitCount = totalBytesExpectedToWrite 228 | progress.completedUnitCount = totalBytesWritten 229 | 230 | downloadProgress?(bytesWritten, totalBytesWritten, totalBytesExpectedToWrite) 231 | } 232 | } 233 | 234 | func URLSession( 235 | session: NSURLSession, 236 | downloadTask: NSURLSessionDownloadTask, 237 | didResumeAtOffset fileOffset: Int64, 238 | expectedTotalBytes: Int64) 239 | { 240 | if let downloadTaskDidResumeAtOffset = downloadTaskDidResumeAtOffset { 241 | downloadTaskDidResumeAtOffset(session, downloadTask, fileOffset, expectedTotalBytes) 242 | } else { 243 | progress.totalUnitCount = expectedTotalBytes 244 | progress.completedUnitCount = fileOffset 245 | } 246 | } 247 | } 248 | } 249 | -------------------------------------------------------------------------------- /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/Alamofire/Source/NetworkReachabilityManager.swift: -------------------------------------------------------------------------------- 1 | // 2 | // NetworkReachabilityManager.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 | #if !os(watchOS) 26 | 27 | import Foundation 28 | import SystemConfiguration 29 | 30 | /** 31 | The `NetworkReachabilityManager` class listens for reachability changes of hosts and addresses for both WWAN and 32 | WiFi network interfaces. 33 | 34 | Reachability can be used to determine background information about why a network operation failed, or to retry 35 | network requests when a connection is established. It should not be used to prevent a user from initiating a network 36 | request, as it's possible that an initial request may be required to establish reachability. 37 | */ 38 | public class NetworkReachabilityManager { 39 | /** 40 | Defines the various states of network reachability. 41 | 42 | - Unknown: It is unknown whether the network is reachable. 43 | - NotReachable: The network is not reachable. 44 | - ReachableOnWWAN: The network is reachable over the WWAN connection. 45 | - ReachableOnWiFi: The network is reachable over the WiFi connection. 46 | */ 47 | public enum NetworkReachabilityStatus { 48 | case Unknown 49 | case NotReachable 50 | case Reachable(ConnectionType) 51 | } 52 | 53 | /** 54 | Defines the various connection types detected by reachability flags. 55 | 56 | - EthernetOrWiFi: The connection type is either over Ethernet or WiFi. 57 | - WWAN: The connection type is a WWAN connection. 58 | */ 59 | public enum ConnectionType { 60 | case EthernetOrWiFi 61 | case WWAN 62 | } 63 | 64 | /// A closure executed when the network reachability status changes. The closure takes a single argument: the 65 | /// network reachability status. 66 | public typealias Listener = NetworkReachabilityStatus -> Void 67 | 68 | // MARK: - Properties 69 | 70 | /// Whether the network is currently reachable. 71 | public var isReachable: Bool { return isReachableOnWWAN || isReachableOnEthernetOrWiFi } 72 | 73 | /// Whether the network is currently reachable over the WWAN interface. 74 | public var isReachableOnWWAN: Bool { return networkReachabilityStatus == .Reachable(.WWAN) } 75 | 76 | /// Whether the network is currently reachable over Ethernet or WiFi interface. 77 | public var isReachableOnEthernetOrWiFi: Bool { return networkReachabilityStatus == .Reachable(.EthernetOrWiFi) } 78 | 79 | /// The current network reachability status. 80 | public var networkReachabilityStatus: NetworkReachabilityStatus { 81 | guard let flags = self.flags else { return .Unknown } 82 | return networkReachabilityStatusForFlags(flags) 83 | } 84 | 85 | /// The dispatch queue to execute the `listener` closure on. 86 | public var listenerQueue: dispatch_queue_t = dispatch_get_main_queue() 87 | 88 | /// A closure executed when the network reachability status changes. 89 | public var listener: Listener? 90 | 91 | private var flags: SCNetworkReachabilityFlags? { 92 | var flags = SCNetworkReachabilityFlags() 93 | 94 | if SCNetworkReachabilityGetFlags(reachability, &flags) { 95 | return flags 96 | } 97 | 98 | return nil 99 | } 100 | 101 | private let reachability: SCNetworkReachability 102 | private var previousFlags: SCNetworkReachabilityFlags 103 | 104 | // MARK: - Initialization 105 | 106 | /** 107 | Creates a `NetworkReachabilityManager` instance with the specified host. 108 | 109 | - parameter host: The host used to evaluate network reachability. 110 | 111 | - returns: The new `NetworkReachabilityManager` instance. 112 | */ 113 | public convenience init?(host: String) { 114 | guard let reachability = SCNetworkReachabilityCreateWithName(nil, host) else { return nil } 115 | self.init(reachability: reachability) 116 | } 117 | 118 | /** 119 | Creates a `NetworkReachabilityManager` instance with the default socket IPv4 or IPv6 address. 120 | 121 | - returns: The new `NetworkReachabilityManager` instance. 122 | */ 123 | public convenience init?() { 124 | if #available(iOS 9.0, OSX 10.10, *) { 125 | var address = sockaddr_in6() 126 | address.sin6_len = UInt8(sizeofValue(address)) 127 | address.sin6_family = sa_family_t(AF_INET6) 128 | 129 | guard let reachability = withUnsafePointer(&address, { 130 | SCNetworkReachabilityCreateWithAddress(nil, UnsafePointer($0)) 131 | }) else { return nil } 132 | 133 | self.init(reachability: reachability) 134 | } else { 135 | var address = sockaddr_in() 136 | address.sin_len = UInt8(sizeofValue(address)) 137 | address.sin_family = sa_family_t(AF_INET) 138 | 139 | guard let reachability = withUnsafePointer(&address, { 140 | SCNetworkReachabilityCreateWithAddress(nil, UnsafePointer($0)) 141 | }) else { return nil } 142 | 143 | self.init(reachability: reachability) 144 | } 145 | } 146 | 147 | private init(reachability: SCNetworkReachability) { 148 | self.reachability = reachability 149 | self.previousFlags = SCNetworkReachabilityFlags() 150 | } 151 | 152 | deinit { 153 | stopListening() 154 | } 155 | 156 | // MARK: - Listening 157 | 158 | /** 159 | Starts listening for changes in network reachability status. 160 | 161 | - returns: `true` if listening was started successfully, `false` otherwise. 162 | */ 163 | public func startListening() -> Bool { 164 | var context = SCNetworkReachabilityContext(version: 0, info: nil, retain: nil, release: nil, copyDescription: nil) 165 | context.info = UnsafeMutablePointer(Unmanaged.passUnretained(self).toOpaque()) 166 | 167 | let callbackEnabled = SCNetworkReachabilitySetCallback( 168 | reachability, 169 | { (_, flags, info) in 170 | let reachability = Unmanaged.fromOpaque(COpaquePointer(info)).takeUnretainedValue() 171 | reachability.notifyListener(flags) 172 | }, 173 | &context 174 | ) 175 | 176 | let queueEnabled = SCNetworkReachabilitySetDispatchQueue(reachability, listenerQueue) 177 | 178 | dispatch_async(listenerQueue) { 179 | self.previousFlags = SCNetworkReachabilityFlags() 180 | self.notifyListener(self.flags ?? SCNetworkReachabilityFlags()) 181 | } 182 | 183 | return callbackEnabled && queueEnabled 184 | } 185 | 186 | /** 187 | Stops listening for changes in network reachability status. 188 | */ 189 | public func stopListening() { 190 | SCNetworkReachabilitySetCallback(reachability, nil, nil) 191 | SCNetworkReachabilitySetDispatchQueue(reachability, nil) 192 | } 193 | 194 | // MARK: - Internal - Listener Notification 195 | 196 | func notifyListener(flags: SCNetworkReachabilityFlags) { 197 | guard previousFlags != flags else { return } 198 | previousFlags = flags 199 | 200 | listener?(networkReachabilityStatusForFlags(flags)) 201 | } 202 | 203 | // MARK: - Internal - Network Reachability Status 204 | 205 | func networkReachabilityStatusForFlags(flags: SCNetworkReachabilityFlags) -> NetworkReachabilityStatus { 206 | guard flags.contains(.Reachable) else { return .NotReachable } 207 | 208 | var networkStatus: NetworkReachabilityStatus = .NotReachable 209 | 210 | if !flags.contains(.ConnectionRequired) { networkStatus = .Reachable(.EthernetOrWiFi) } 211 | 212 | if flags.contains(.ConnectionOnDemand) || flags.contains(.ConnectionOnTraffic) { 213 | if !flags.contains(.InterventionRequired) { networkStatus = .Reachable(.EthernetOrWiFi) } 214 | } 215 | 216 | #if os(iOS) 217 | if flags.contains(.IsWWAN) { networkStatus = .Reachable(.WWAN) } 218 | #endif 219 | 220 | return networkStatus 221 | } 222 | } 223 | 224 | // MARK: - 225 | 226 | extension NetworkReachabilityManager.NetworkReachabilityStatus: Equatable {} 227 | 228 | /** 229 | Returns whether the two network reachability status values are equal. 230 | 231 | - parameter lhs: The left-hand side value to compare. 232 | - parameter rhs: The right-hand side value to compare. 233 | 234 | - returns: `true` if the two values are equal, `false` otherwise. 235 | */ 236 | public func ==( 237 | lhs: NetworkReachabilityManager.NetworkReachabilityStatus, 238 | rhs: NetworkReachabilityManager.NetworkReachabilityStatus) 239 | -> Bool 240 | { 241 | switch (lhs, rhs) { 242 | case (.Unknown, .Unknown): 243 | return true 244 | case (.NotReachable, .NotReachable): 245 | return true 246 | case let (.Reachable(lhsConnectionType), .Reachable(rhsConnectionType)): 247 | return lhsConnectionType == rhsConnectionType 248 | default: 249 | return false 250 | } 251 | } 252 | 253 | #endif 254 | -------------------------------------------------------------------------------- /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/Alamofire/Source/ParameterEncoding.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ParameterEncoding.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 | HTTP method definitions. 29 | 30 | See https://tools.ietf.org/html/rfc7231#section-4.3 31 | */ 32 | public enum Method: String { 33 | case OPTIONS, GET, HEAD, POST, PUT, PATCH, DELETE, TRACE, CONNECT 34 | } 35 | 36 | // MARK: ParameterEncoding 37 | 38 | /** 39 | Used to specify the way in which a set of parameters are applied to a URL request. 40 | 41 | - `URL`: Creates a query string to be set as or appended to any existing URL query for `GET`, `HEAD`, 42 | and `DELETE` requests, or set as the body for requests with any other HTTP method. The 43 | `Content-Type` HTTP header field of an encoded request with HTTP body is set to 44 | `application/x-www-form-urlencoded; charset=utf-8`. Since there is no published specification 45 | for how to encode collection types, the convention of appending `[]` to the key for array 46 | values (`foo[]=1&foo[]=2`), and appending the key surrounded by square brackets for nested 47 | dictionary values (`foo[bar]=baz`). 48 | 49 | - `URLEncodedInURL`: Creates query string to be set as or appended to any existing URL query. Uses the same 50 | implementation as the `.URL` case, but always applies the encoded result to the URL. 51 | 52 | - `JSON`: Uses `NSJSONSerialization` to create a JSON representation of the parameters object, which is 53 | set as the body of the request. The `Content-Type` HTTP header field of an encoded request is 54 | set to `application/json`. 55 | 56 | - `PropertyList`: Uses `NSPropertyListSerialization` to create a plist representation of the parameters object, 57 | according to the associated format and write options values, which is set as the body of the 58 | request. The `Content-Type` HTTP header field of an encoded request is set to 59 | `application/x-plist`. 60 | 61 | - `Custom`: Uses the associated closure value to construct a new request given an existing request and 62 | parameters. 63 | */ 64 | public enum ParameterEncoding { 65 | case URL 66 | case URLEncodedInURL 67 | case JSON 68 | case PropertyList(NSPropertyListFormat, NSPropertyListWriteOptions) 69 | case Custom((URLRequestConvertible, [String: AnyObject]?) -> (NSMutableURLRequest, NSError?)) 70 | 71 | /** 72 | Creates a URL request by encoding parameters and applying them onto an existing request. 73 | 74 | - parameter URLRequest: The request to have parameters applied. 75 | - parameter parameters: The parameters to apply. 76 | 77 | - returns: A tuple containing the constructed request and the error that occurred during parameter encoding, 78 | if any. 79 | */ 80 | public func encode( 81 | URLRequest: URLRequestConvertible, 82 | parameters: [String: AnyObject]?) 83 | -> (NSMutableURLRequest, NSError?) 84 | { 85 | var mutableURLRequest = URLRequest.URLRequest 86 | 87 | guard let parameters = parameters else { return (mutableURLRequest, nil) } 88 | 89 | var encodingError: NSError? = nil 90 | 91 | switch self { 92 | case .URL, .URLEncodedInURL: 93 | func query(parameters: [String: AnyObject]) -> String { 94 | var components: [(String, String)] = [] 95 | 96 | for key in parameters.keys.sort(<) { 97 | let value = parameters[key]! 98 | components += queryComponents(key, value) 99 | } 100 | 101 | return (components.map { "\($0)=\($1)" } as [String]).joinWithSeparator("&") 102 | } 103 | 104 | func encodesParametersInURL(method: Method) -> Bool { 105 | switch self { 106 | case .URLEncodedInURL: 107 | return true 108 | default: 109 | break 110 | } 111 | 112 | switch method { 113 | case .GET, .HEAD, .DELETE: 114 | return true 115 | default: 116 | return false 117 | } 118 | } 119 | 120 | if let method = Method(rawValue: mutableURLRequest.HTTPMethod) where encodesParametersInURL(method) { 121 | if let 122 | URLComponents = NSURLComponents(URL: mutableURLRequest.URL!, resolvingAgainstBaseURL: false) 123 | where !parameters.isEmpty 124 | { 125 | let percentEncodedQuery = (URLComponents.percentEncodedQuery.map { $0 + "&" } ?? "") + query(parameters) 126 | URLComponents.percentEncodedQuery = percentEncodedQuery 127 | mutableURLRequest.URL = URLComponents.URL 128 | } 129 | } else { 130 | if mutableURLRequest.valueForHTTPHeaderField("Content-Type") == nil { 131 | mutableURLRequest.setValue( 132 | "application/x-www-form-urlencoded; charset=utf-8", 133 | forHTTPHeaderField: "Content-Type" 134 | ) 135 | } 136 | 137 | mutableURLRequest.HTTPBody = query(parameters).dataUsingEncoding( 138 | NSUTF8StringEncoding, 139 | allowLossyConversion: false 140 | ) 141 | } 142 | case .JSON: 143 | do { 144 | let options = NSJSONWritingOptions() 145 | let data = try NSJSONSerialization.dataWithJSONObject(parameters, options: options) 146 | 147 | if mutableURLRequest.valueForHTTPHeaderField("Content-Type") == nil { 148 | mutableURLRequest.setValue("application/json", forHTTPHeaderField: "Content-Type") 149 | } 150 | 151 | mutableURLRequest.HTTPBody = data 152 | } catch { 153 | encodingError = error as NSError 154 | } 155 | case .PropertyList(let format, let options): 156 | do { 157 | let data = try NSPropertyListSerialization.dataWithPropertyList( 158 | parameters, 159 | format: format, 160 | options: options 161 | ) 162 | 163 | if mutableURLRequest.valueForHTTPHeaderField("Content-Type") == nil { 164 | mutableURLRequest.setValue("application/x-plist", forHTTPHeaderField: "Content-Type") 165 | } 166 | 167 | mutableURLRequest.HTTPBody = data 168 | } catch { 169 | encodingError = error as NSError 170 | } 171 | case .Custom(let closure): 172 | (mutableURLRequest, encodingError) = closure(mutableURLRequest, parameters) 173 | } 174 | 175 | return (mutableURLRequest, encodingError) 176 | } 177 | 178 | /** 179 | Creates percent-escaped, URL encoded query string components from the given key-value pair using recursion. 180 | 181 | - parameter key: The key of the query component. 182 | - parameter value: The value of the query component. 183 | 184 | - returns: The percent-escaped, URL encoded query string components. 185 | */ 186 | public func queryComponents(key: String, _ value: AnyObject) -> [(String, String)] { 187 | var components: [(String, String)] = [] 188 | 189 | if let dictionary = value as? [String: AnyObject] { 190 | for (nestedKey, value) in dictionary { 191 | components += queryComponents("\(key)[\(nestedKey)]", value) 192 | } 193 | } else if let array = value as? [AnyObject] { 194 | for value in array { 195 | components += queryComponents("\(key)[]", value) 196 | } 197 | } else { 198 | components.append((escape(key), escape("\(value)"))) 199 | } 200 | 201 | return components 202 | } 203 | 204 | /** 205 | Returns a percent-escaped string following RFC 3986 for a query string key or value. 206 | 207 | RFC 3986 states that the following characters are "reserved" characters. 208 | 209 | - General Delimiters: ":", "#", "[", "]", "@", "?", "/" 210 | - Sub-Delimiters: "!", "$", "&", "'", "(", ")", "*", "+", ",", ";", "=" 211 | 212 | In RFC 3986 - Section 3.4, it states that the "?" and "/" characters should not be escaped to allow 213 | query strings to include a URL. Therefore, all "reserved" characters with the exception of "?" and "/" 214 | should be percent-escaped in the query string. 215 | 216 | - parameter string: The string to be percent-escaped. 217 | 218 | - returns: The percent-escaped string. 219 | */ 220 | public func escape(string: String) -> String { 221 | let generalDelimitersToEncode = ":#[]@" // does not include "?" or "/" due to RFC 3986 - Section 3.4 222 | let subDelimitersToEncode = "!$&'()*+,;=" 223 | 224 | let allowedCharacterSet = NSCharacterSet.URLQueryAllowedCharacterSet().mutableCopy() as! NSMutableCharacterSet 225 | allowedCharacterSet.removeCharactersInString(generalDelimitersToEncode + subDelimitersToEncode) 226 | 227 | var escaped = "" 228 | 229 | //========================================================================================================== 230 | // 231 | // Batching is required for escaping due to an internal bug in iOS 8.1 and 8.2. Encoding more than a few 232 | // hundred Chinense characters causes various malloc error crashes. To avoid this issue until iOS 8 is no 233 | // longer supported, batching MUST be used for encoding. This introduces roughly a 20% overhead. For more 234 | // info, please refer to: 235 | // 236 | // - https://github.com/Alamofire/Alamofire/issues/206 237 | // 238 | //========================================================================================================== 239 | 240 | if #available(iOS 8.3, OSX 10.10, *) { 241 | escaped = string.stringByAddingPercentEncodingWithAllowedCharacters(allowedCharacterSet) ?? string 242 | } else { 243 | let batchSize = 50 244 | var index = string.startIndex 245 | 246 | while index != string.endIndex { 247 | let startIndex = index 248 | let endIndex = index.advancedBy(batchSize, limit: string.endIndex) 249 | let range = startIndex.. Self 91 | { 92 | let credential = NSURLCredential(user: user, password: password, persistence: persistence) 93 | 94 | return authenticate(usingCredential: credential) 95 | } 96 | 97 | /** 98 | Associates a specified credential with the request. 99 | 100 | - parameter credential: The credential. 101 | 102 | - returns: The request. 103 | */ 104 | public func authenticate(usingCredential credential: NSURLCredential) -> Self { 105 | delegate.credential = credential 106 | 107 | return self 108 | } 109 | 110 | /** 111 | Returns a base64 encoded basic authentication credential as an authorization header dictionary. 112 | 113 | - parameter user: The user. 114 | - parameter password: The password. 115 | 116 | - returns: A dictionary with Authorization key and credential value or empty dictionary if encoding fails. 117 | */ 118 | public static func authorizationHeader(user user: String, password: String) -> [String: String] { 119 | guard let data = "\(user):\(password)".dataUsingEncoding(NSUTF8StringEncoding) else { return [:] } 120 | 121 | let credential = data.base64EncodedStringWithOptions([]) 122 | 123 | return ["Authorization": "Basic \(credential)"] 124 | } 125 | 126 | // MARK: - Progress 127 | 128 | /** 129 | Sets a closure to be called periodically during the lifecycle of the request as data is written to or read 130 | from the server. 131 | 132 | - For uploads, the progress closure returns the bytes written, total bytes written, and total bytes expected 133 | to write. 134 | - For downloads and data tasks, the progress closure returns the bytes read, total bytes read, and total bytes 135 | expected to read. 136 | 137 | - parameter closure: The code to be executed periodically during the lifecycle of the request. 138 | 139 | - returns: The request. 140 | */ 141 | public func progress(closure: ((Int64, Int64, Int64) -> Void)? = nil) -> Self { 142 | if let uploadDelegate = delegate as? UploadTaskDelegate { 143 | uploadDelegate.uploadProgress = closure 144 | } else if let dataDelegate = delegate as? DataTaskDelegate { 145 | dataDelegate.dataProgress = closure 146 | } else if let downloadDelegate = delegate as? DownloadTaskDelegate { 147 | downloadDelegate.downloadProgress = closure 148 | } 149 | 150 | return self 151 | } 152 | 153 | /** 154 | Sets a closure to be called periodically during the lifecycle of the request as data is read from the server. 155 | 156 | This closure returns the bytes most recently received from the server, not including data from previous calls. 157 | If this closure is set, data will only be available within this closure, and will not be saved elsewhere. It is 158 | also important to note that the `response` closure will be called with nil `responseData`. 159 | 160 | - parameter closure: The code to be executed periodically during the lifecycle of the request. 161 | 162 | - returns: The request. 163 | */ 164 | public func stream(closure: (NSData -> Void)? = nil) -> Self { 165 | if let dataDelegate = delegate as? DataTaskDelegate { 166 | dataDelegate.dataStream = closure 167 | } 168 | 169 | return self 170 | } 171 | 172 | // MARK: - State 173 | 174 | /** 175 | Resumes the request. 176 | */ 177 | public func resume() { 178 | if startTime == nil { startTime = CFAbsoluteTimeGetCurrent() } 179 | 180 | task.resume() 181 | NSNotificationCenter.defaultCenter().postNotificationName(Notifications.Task.DidResume, object: task) 182 | } 183 | 184 | /** 185 | Suspends the request. 186 | */ 187 | public func suspend() { 188 | task.suspend() 189 | NSNotificationCenter.defaultCenter().postNotificationName(Notifications.Task.DidSuspend, object: task) 190 | } 191 | 192 | /** 193 | Cancels the request. 194 | */ 195 | public func cancel() { 196 | if let 197 | downloadDelegate = delegate as? DownloadTaskDelegate, 198 | downloadTask = downloadDelegate.downloadTask 199 | { 200 | downloadTask.cancelByProducingResumeData { data in 201 | downloadDelegate.resumeData = data 202 | } 203 | } else { 204 | task.cancel() 205 | } 206 | 207 | NSNotificationCenter.defaultCenter().postNotificationName(Notifications.Task.DidCancel, object: task) 208 | } 209 | 210 | // MARK: - TaskDelegate 211 | 212 | /** 213 | The task delegate is responsible for handling all delegate callbacks for the underlying task as well as 214 | executing all operations attached to the serial operation queue upon task completion. 215 | */ 216 | public class TaskDelegate: NSObject { 217 | 218 | /// The serial operation queue used to execute all operations after the task completes. 219 | public let queue: NSOperationQueue 220 | 221 | let task: NSURLSessionTask 222 | let progress: NSProgress 223 | 224 | var data: NSData? { return nil } 225 | var error: NSError? 226 | 227 | var initialResponseTime: CFAbsoluteTime? 228 | var credential: NSURLCredential? 229 | 230 | init(task: NSURLSessionTask) { 231 | self.task = task 232 | self.progress = NSProgress(totalUnitCount: 0) 233 | self.queue = { 234 | let operationQueue = NSOperationQueue() 235 | operationQueue.maxConcurrentOperationCount = 1 236 | operationQueue.suspended = true 237 | 238 | if #available(OSX 10.10, *) { 239 | operationQueue.qualityOfService = NSQualityOfService.Utility 240 | } 241 | 242 | return operationQueue 243 | }() 244 | } 245 | 246 | deinit { 247 | queue.cancelAllOperations() 248 | queue.suspended = false 249 | } 250 | 251 | // MARK: - NSURLSessionTaskDelegate 252 | 253 | // MARK: Override Closures 254 | 255 | var taskWillPerformHTTPRedirection: ((NSURLSession, NSURLSessionTask, NSHTTPURLResponse, NSURLRequest) -> NSURLRequest?)? 256 | var taskDidReceiveChallenge: ((NSURLSession, NSURLSessionTask, NSURLAuthenticationChallenge) -> (NSURLSessionAuthChallengeDisposition, NSURLCredential?))? 257 | var taskNeedNewBodyStream: ((NSURLSession, NSURLSessionTask) -> NSInputStream?)? 258 | var taskDidCompleteWithError: ((NSURLSession, NSURLSessionTask, NSError?) -> Void)? 259 | 260 | // MARK: Delegate Methods 261 | 262 | func URLSession( 263 | session: NSURLSession, 264 | task: NSURLSessionTask, 265 | willPerformHTTPRedirection response: NSHTTPURLResponse, 266 | newRequest request: NSURLRequest, 267 | completionHandler: ((NSURLRequest?) -> Void)) 268 | { 269 | var redirectRequest: NSURLRequest? = request 270 | 271 | if let taskWillPerformHTTPRedirection = taskWillPerformHTTPRedirection { 272 | redirectRequest = taskWillPerformHTTPRedirection(session, task, response, request) 273 | } 274 | 275 | completionHandler(redirectRequest) 276 | } 277 | 278 | func URLSession( 279 | session: NSURLSession, 280 | task: NSURLSessionTask, 281 | didReceiveChallenge challenge: NSURLAuthenticationChallenge, 282 | completionHandler: ((NSURLSessionAuthChallengeDisposition, NSURLCredential?) -> Void)) 283 | { 284 | var disposition: NSURLSessionAuthChallengeDisposition = .PerformDefaultHandling 285 | var credential: NSURLCredential? 286 | 287 | if let taskDidReceiveChallenge = taskDidReceiveChallenge { 288 | (disposition, credential) = taskDidReceiveChallenge(session, task, challenge) 289 | } else if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust { 290 | let host = challenge.protectionSpace.host 291 | 292 | if let 293 | serverTrustPolicy = session.serverTrustPolicyManager?.serverTrustPolicyForHost(host), 294 | serverTrust = challenge.protectionSpace.serverTrust 295 | { 296 | if serverTrustPolicy.evaluateServerTrust(serverTrust, isValidForHost: host) { 297 | disposition = .UseCredential 298 | credential = NSURLCredential(forTrust: serverTrust) 299 | } else { 300 | disposition = .CancelAuthenticationChallenge 301 | } 302 | } 303 | } else { 304 | if challenge.previousFailureCount > 0 { 305 | disposition = .RejectProtectionSpace 306 | } else { 307 | credential = self.credential ?? session.configuration.URLCredentialStorage?.defaultCredentialForProtectionSpace(challenge.protectionSpace) 308 | 309 | if credential != nil { 310 | disposition = .UseCredential 311 | } 312 | } 313 | } 314 | 315 | completionHandler(disposition, credential) 316 | } 317 | 318 | func URLSession( 319 | session: NSURLSession, 320 | task: NSURLSessionTask, 321 | needNewBodyStream completionHandler: ((NSInputStream?) -> Void)) 322 | { 323 | var bodyStream: NSInputStream? 324 | 325 | if let taskNeedNewBodyStream = taskNeedNewBodyStream { 326 | bodyStream = taskNeedNewBodyStream(session, task) 327 | } 328 | 329 | completionHandler(bodyStream) 330 | } 331 | 332 | func URLSession(session: NSURLSession, task: NSURLSessionTask, didCompleteWithError error: NSError?) { 333 | if let taskDidCompleteWithError = taskDidCompleteWithError { 334 | taskDidCompleteWithError(session, task, error) 335 | } else { 336 | if let error = error { 337 | self.error = error 338 | 339 | if let 340 | downloadDelegate = self as? DownloadTaskDelegate, 341 | userInfo = error.userInfo as? [String: AnyObject], 342 | resumeData = userInfo[NSURLSessionDownloadTaskResumeData] as? NSData 343 | { 344 | downloadDelegate.resumeData = resumeData 345 | } 346 | } 347 | 348 | queue.suspended = false 349 | } 350 | } 351 | } 352 | 353 | // MARK: - DataTaskDelegate 354 | 355 | class DataTaskDelegate: TaskDelegate, NSURLSessionDataDelegate { 356 | var dataTask: NSURLSessionDataTask? { return task as? NSURLSessionDataTask } 357 | 358 | private var totalBytesReceived: Int64 = 0 359 | private var mutableData: NSMutableData 360 | override var data: NSData? { 361 | if dataStream != nil { 362 | return nil 363 | } else { 364 | return mutableData 365 | } 366 | } 367 | 368 | private var expectedContentLength: Int64? 369 | private var dataProgress: ((bytesReceived: Int64, totalBytesReceived: Int64, totalBytesExpectedToReceive: Int64) -> Void)? 370 | private var dataStream: ((data: NSData) -> Void)? 371 | 372 | override init(task: NSURLSessionTask) { 373 | mutableData = NSMutableData() 374 | super.init(task: task) 375 | } 376 | 377 | // MARK: - NSURLSessionDataDelegate 378 | 379 | // MARK: Override Closures 380 | 381 | var dataTaskDidReceiveResponse: ((NSURLSession, NSURLSessionDataTask, NSURLResponse) -> NSURLSessionResponseDisposition)? 382 | var dataTaskDidBecomeDownloadTask: ((NSURLSession, NSURLSessionDataTask, NSURLSessionDownloadTask) -> Void)? 383 | var dataTaskDidReceiveData: ((NSURLSession, NSURLSessionDataTask, NSData) -> Void)? 384 | var dataTaskWillCacheResponse: ((NSURLSession, NSURLSessionDataTask, NSCachedURLResponse) -> NSCachedURLResponse?)? 385 | 386 | // MARK: Delegate Methods 387 | 388 | func URLSession( 389 | session: NSURLSession, 390 | dataTask: NSURLSessionDataTask, 391 | didReceiveResponse response: NSURLResponse, 392 | completionHandler: (NSURLSessionResponseDisposition -> Void)) 393 | { 394 | var disposition: NSURLSessionResponseDisposition = .Allow 395 | 396 | expectedContentLength = response.expectedContentLength 397 | 398 | if let dataTaskDidReceiveResponse = dataTaskDidReceiveResponse { 399 | disposition = dataTaskDidReceiveResponse(session, dataTask, response) 400 | } 401 | 402 | completionHandler(disposition) 403 | } 404 | 405 | func URLSession( 406 | session: NSURLSession, 407 | dataTask: NSURLSessionDataTask, 408 | didBecomeDownloadTask downloadTask: NSURLSessionDownloadTask) 409 | { 410 | dataTaskDidBecomeDownloadTask?(session, dataTask, downloadTask) 411 | } 412 | 413 | func URLSession(session: NSURLSession, dataTask: NSURLSessionDataTask, didReceiveData data: NSData) { 414 | if initialResponseTime == nil { initialResponseTime = CFAbsoluteTimeGetCurrent() } 415 | 416 | if let dataTaskDidReceiveData = dataTaskDidReceiveData { 417 | dataTaskDidReceiveData(session, dataTask, data) 418 | } else { 419 | if let dataStream = dataStream { 420 | dataStream(data: data) 421 | } else { 422 | mutableData.appendData(data) 423 | } 424 | 425 | totalBytesReceived += data.length 426 | let totalBytesExpected = dataTask.response?.expectedContentLength ?? NSURLSessionTransferSizeUnknown 427 | 428 | progress.totalUnitCount = totalBytesExpected 429 | progress.completedUnitCount = totalBytesReceived 430 | 431 | dataProgress?( 432 | bytesReceived: Int64(data.length), 433 | totalBytesReceived: totalBytesReceived, 434 | totalBytesExpectedToReceive: totalBytesExpected 435 | ) 436 | } 437 | } 438 | 439 | func URLSession( 440 | session: NSURLSession, 441 | dataTask: NSURLSessionDataTask, 442 | willCacheResponse proposedResponse: NSCachedURLResponse, 443 | completionHandler: ((NSCachedURLResponse?) -> Void)) 444 | { 445 | var cachedResponse: NSCachedURLResponse? = proposedResponse 446 | 447 | if let dataTaskWillCacheResponse = dataTaskWillCacheResponse { 448 | cachedResponse = dataTaskWillCacheResponse(session, dataTask, proposedResponse) 449 | } 450 | 451 | completionHandler(cachedResponse) 452 | } 453 | } 454 | } 455 | 456 | // MARK: - CustomStringConvertible 457 | 458 | extension Request: CustomStringConvertible { 459 | 460 | /** 461 | The textual representation used when written to an output stream, which includes the HTTP method and URL, as 462 | well as the response status code if a response has been received. 463 | */ 464 | public var description: String { 465 | var components: [String] = [] 466 | 467 | if let HTTPMethod = request?.HTTPMethod { 468 | components.append(HTTPMethod) 469 | } 470 | 471 | if let URLString = request?.URL?.absoluteString { 472 | components.append(URLString) 473 | } 474 | 475 | if let response = response { 476 | components.append("(\(response.statusCode))") 477 | } 478 | 479 | return components.joinWithSeparator(" ") 480 | } 481 | } 482 | 483 | // MARK: - CustomDebugStringConvertible 484 | 485 | extension Request: CustomDebugStringConvertible { 486 | func cURLRepresentation() -> String { 487 | var components = ["$ curl -i"] 488 | 489 | guard let 490 | request = self.request, 491 | URL = request.URL, 492 | host = URL.host 493 | else { 494 | return "$ curl command could not be created" 495 | } 496 | 497 | if let HTTPMethod = request.HTTPMethod where HTTPMethod != "GET" { 498 | components.append("-X \(HTTPMethod)") 499 | } 500 | 501 | if let credentialStorage = self.session.configuration.URLCredentialStorage { 502 | let protectionSpace = NSURLProtectionSpace( 503 | host: host, 504 | port: URL.port?.integerValue ?? 0, 505 | protocol: URL.scheme, 506 | realm: host, 507 | authenticationMethod: NSURLAuthenticationMethodHTTPBasic 508 | ) 509 | 510 | if let credentials = credentialStorage.credentialsForProtectionSpace(protectionSpace)?.values { 511 | for credential in credentials { 512 | components.append("-u \(credential.user!):\(credential.password!)") 513 | } 514 | } else { 515 | if let credential = delegate.credential { 516 | components.append("-u \(credential.user!):\(credential.password!)") 517 | } 518 | } 519 | } 520 | 521 | if session.configuration.HTTPShouldSetCookies { 522 | if let 523 | cookieStorage = session.configuration.HTTPCookieStorage, 524 | cookies = cookieStorage.cookiesForURL(URL) where !cookies.isEmpty 525 | { 526 | let string = cookies.reduce("") { $0 + "\($1.name)=\($1.value ?? String());" } 527 | components.append("-b \"\(string.substringToIndex(string.endIndex.predecessor()))\"") 528 | } 529 | } 530 | 531 | var headers: [NSObject: AnyObject] = [:] 532 | 533 | if let additionalHeaders = session.configuration.HTTPAdditionalHeaders { 534 | for (field, value) in additionalHeaders where field != "Cookie" { 535 | headers[field] = value 536 | } 537 | } 538 | 539 | if let headerFields = request.allHTTPHeaderFields { 540 | for (field, value) in headerFields where field != "Cookie" { 541 | headers[field] = value 542 | } 543 | } 544 | 545 | for (field, value) in headers { 546 | components.append("-H \"\(field): \(value)\"") 547 | } 548 | 549 | if let 550 | HTTPBodyData = request.HTTPBody, 551 | HTTPBody = String(data: HTTPBodyData, encoding: NSUTF8StringEncoding) 552 | { 553 | var escapedBody = HTTPBody.stringByReplacingOccurrencesOfString("\\\"", withString: "\\\\\"") 554 | escapedBody = escapedBody.stringByReplacingOccurrencesOfString("\"", withString: "\\\"") 555 | 556 | components.append("-d \"\(escapedBody)\"") 557 | } 558 | 559 | components.append("\"\(URL.absoluteString)\"") 560 | 561 | return components.joinWithSeparator(" \\\n\t") 562 | } 563 | 564 | /// The textual representation used when written to an output stream, in the form of a cURL command. 565 | public var debugDescription: String { 566 | return cURLRepresentation() 567 | } 568 | } 569 | -------------------------------------------------------------------------------- /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/ResponseSerialization.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ResponseSerialization.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 | // MARK: ResponseSerializer 28 | 29 | /** 30 | The type in which all response serializers must conform to in order to serialize a response. 31 | */ 32 | public protocol ResponseSerializerType { 33 | /// The type of serialized object to be created by this `ResponseSerializerType`. 34 | associatedtype SerializedObject 35 | 36 | /// The type of error to be created by this `ResponseSerializer` if serialization fails. 37 | associatedtype ErrorObject: ErrorType 38 | 39 | /** 40 | A closure used by response handlers that takes a request, response, data and error and returns a result. 41 | */ 42 | var serializeResponse: (NSURLRequest?, NSHTTPURLResponse?, NSData?, NSError?) -> Result { get } 43 | } 44 | 45 | // MARK: - 46 | 47 | /** 48 | A generic `ResponseSerializerType` used to serialize a request, response, and data into a serialized object. 49 | */ 50 | public struct ResponseSerializer: ResponseSerializerType { 51 | /// The type of serialized object to be created by this `ResponseSerializer`. 52 | public typealias SerializedObject = Value 53 | 54 | /// The type of error to be created by this `ResponseSerializer` if serialization fails. 55 | public typealias ErrorObject = Error 56 | 57 | /** 58 | A closure used by response handlers that takes a request, response, data and error and returns a result. 59 | */ 60 | public var serializeResponse: (NSURLRequest?, NSHTTPURLResponse?, NSData?, NSError?) -> Result 61 | 62 | /** 63 | Initializes the `ResponseSerializer` instance with the given serialize response closure. 64 | 65 | - parameter serializeResponse: The closure used to serialize the response. 66 | 67 | - returns: The new generic response serializer instance. 68 | */ 69 | public init(serializeResponse: (NSURLRequest?, NSHTTPURLResponse?, NSData?, NSError?) -> Result) { 70 | self.serializeResponse = serializeResponse 71 | } 72 | } 73 | 74 | // MARK: - Default 75 | 76 | extension Request { 77 | 78 | /** 79 | Adds a handler to be called once the request has finished. 80 | 81 | - parameter queue: The queue on which the completion handler is dispatched. 82 | - parameter completionHandler: The code to be executed once the request has finished. 83 | 84 | - returns: The request. 85 | */ 86 | public func response( 87 | queue queue: dispatch_queue_t? = nil, 88 | completionHandler: (NSURLRequest?, NSHTTPURLResponse?, NSData?, NSError?) -> Void) 89 | -> Self 90 | { 91 | delegate.queue.addOperationWithBlock { 92 | dispatch_async(queue ?? dispatch_get_main_queue()) { 93 | completionHandler(self.request, self.response, self.delegate.data, self.delegate.error) 94 | } 95 | } 96 | 97 | return self 98 | } 99 | 100 | /** 101 | Adds a handler to be called once the request has finished. 102 | 103 | - parameter queue: The queue on which the completion handler is dispatched. 104 | - parameter responseSerializer: The response serializer responsible for serializing the request, response, 105 | and data. 106 | - parameter completionHandler: The code to be executed once the request has finished. 107 | 108 | - returns: The request. 109 | */ 110 | public func response( 111 | queue queue: dispatch_queue_t? = nil, 112 | responseSerializer: T, 113 | completionHandler: Response -> Void) 114 | -> Self 115 | { 116 | delegate.queue.addOperationWithBlock { 117 | let result = responseSerializer.serializeResponse( 118 | self.request, 119 | self.response, 120 | self.delegate.data, 121 | self.delegate.error 122 | ) 123 | 124 | let requestCompletedTime = self.endTime ?? CFAbsoluteTimeGetCurrent() 125 | let initialResponseTime = self.delegate.initialResponseTime ?? requestCompletedTime 126 | 127 | let timeline = Timeline( 128 | requestStartTime: self.startTime ?? CFAbsoluteTimeGetCurrent(), 129 | initialResponseTime: initialResponseTime, 130 | requestCompletedTime: requestCompletedTime, 131 | serializationCompletedTime: CFAbsoluteTimeGetCurrent() 132 | ) 133 | 134 | let response = Response( 135 | request: self.request, 136 | response: self.response, 137 | data: self.delegate.data, 138 | result: result, 139 | timeline: timeline 140 | ) 141 | 142 | dispatch_async(queue ?? dispatch_get_main_queue()) { completionHandler(response) } 143 | } 144 | 145 | return self 146 | } 147 | } 148 | 149 | // MARK: - Data 150 | 151 | extension Request { 152 | 153 | /** 154 | Creates a response serializer that returns the associated data as-is. 155 | 156 | - returns: A data response serializer. 157 | */ 158 | public static func dataResponseSerializer() -> ResponseSerializer { 159 | return ResponseSerializer { _, response, data, error in 160 | guard error == nil else { return .Failure(error!) } 161 | 162 | if let response = response where response.statusCode == 204 { return .Success(NSData()) } 163 | 164 | guard let validData = data else { 165 | let failureReason = "Data could not be serialized. Input data was nil." 166 | let error = Error.error(code: .DataSerializationFailed, failureReason: failureReason) 167 | return .Failure(error) 168 | } 169 | 170 | return .Success(validData) 171 | } 172 | } 173 | 174 | /** 175 | Adds a handler to be called once the request has finished. 176 | 177 | - parameter completionHandler: The code to be executed once the request has finished. 178 | 179 | - returns: The request. 180 | */ 181 | public func responseData( 182 | queue queue: dispatch_queue_t? = nil, 183 | completionHandler: Response -> Void) 184 | -> Self 185 | { 186 | return response(queue: queue, responseSerializer: Request.dataResponseSerializer(), completionHandler: completionHandler) 187 | } 188 | } 189 | 190 | // MARK: - String 191 | 192 | extension Request { 193 | 194 | /** 195 | Creates a response serializer that returns a string initialized from the response data with the specified 196 | string encoding. 197 | 198 | - parameter encoding: The string encoding. If `nil`, the string encoding will be determined from the server 199 | response, falling back to the default HTTP default character set, ISO-8859-1. 200 | 201 | - returns: A string response serializer. 202 | */ 203 | public static func stringResponseSerializer( 204 | encoding encoding: NSStringEncoding? = nil) 205 | -> ResponseSerializer 206 | { 207 | return ResponseSerializer { _, response, data, error in 208 | guard error == nil else { return .Failure(error!) } 209 | 210 | if let response = response where response.statusCode == 204 { return .Success("") } 211 | 212 | guard let validData = data else { 213 | let failureReason = "String could not be serialized. Input data was nil." 214 | let error = Error.error(code: .StringSerializationFailed, failureReason: failureReason) 215 | return .Failure(error) 216 | } 217 | 218 | var convertedEncoding = encoding 219 | 220 | if let encodingName = response?.textEncodingName where convertedEncoding == nil { 221 | convertedEncoding = CFStringConvertEncodingToNSStringEncoding( 222 | CFStringConvertIANACharSetNameToEncoding(encodingName) 223 | ) 224 | } 225 | 226 | let actualEncoding = convertedEncoding ?? NSISOLatin1StringEncoding 227 | 228 | if let string = String(data: validData, encoding: actualEncoding) { 229 | return .Success(string) 230 | } else { 231 | let failureReason = "String could not be serialized with encoding: \(actualEncoding)" 232 | let error = Error.error(code: .StringSerializationFailed, failureReason: failureReason) 233 | return .Failure(error) 234 | } 235 | } 236 | } 237 | 238 | /** 239 | Adds a handler to be called once the request has finished. 240 | 241 | - parameter encoding: The string encoding. If `nil`, the string encoding will be determined from the 242 | server response, falling back to the default HTTP default character set, 243 | ISO-8859-1. 244 | - parameter completionHandler: A closure to be executed once the request has finished. 245 | 246 | - returns: The request. 247 | */ 248 | public func responseString( 249 | queue queue: dispatch_queue_t? = nil, 250 | encoding: NSStringEncoding? = nil, 251 | completionHandler: Response -> Void) 252 | -> Self 253 | { 254 | return response( 255 | queue: queue, 256 | responseSerializer: Request.stringResponseSerializer(encoding: encoding), 257 | completionHandler: completionHandler 258 | ) 259 | } 260 | } 261 | 262 | // MARK: - JSON 263 | 264 | extension Request { 265 | 266 | /** 267 | Creates a response serializer that returns a JSON object constructed from the response data using 268 | `NSJSONSerialization` with the specified reading options. 269 | 270 | - parameter options: The JSON serialization reading options. `.AllowFragments` by default. 271 | 272 | - returns: A JSON object response serializer. 273 | */ 274 | public static func JSONResponseSerializer( 275 | options options: NSJSONReadingOptions = .AllowFragments) 276 | -> ResponseSerializer 277 | { 278 | return ResponseSerializer { _, response, data, error in 279 | guard error == nil else { return .Failure(error!) } 280 | 281 | if let response = response where response.statusCode == 204 { return .Success(NSNull()) } 282 | 283 | guard let validData = data where validData.length > 0 else { 284 | let failureReason = "JSON could not be serialized. Input data was nil or zero length." 285 | let error = Error.error(code: .JSONSerializationFailed, failureReason: failureReason) 286 | return .Failure(error) 287 | } 288 | 289 | do { 290 | let JSON = try NSJSONSerialization.JSONObjectWithData(validData, options: options) 291 | return .Success(JSON) 292 | } catch { 293 | return .Failure(error as NSError) 294 | } 295 | } 296 | } 297 | 298 | /** 299 | Adds a handler to be called once the request has finished. 300 | 301 | - parameter options: The JSON serialization reading options. `.AllowFragments` by default. 302 | - parameter completionHandler: A closure to be executed once the request has finished. 303 | 304 | - returns: The request. 305 | */ 306 | public func responseJSON( 307 | queue queue: dispatch_queue_t? = nil, 308 | options: NSJSONReadingOptions = .AllowFragments, 309 | completionHandler: Response -> Void) 310 | -> Self 311 | { 312 | return response( 313 | queue: queue, 314 | responseSerializer: Request.JSONResponseSerializer(options: options), 315 | completionHandler: completionHandler 316 | ) 317 | } 318 | } 319 | 320 | // MARK: - Property List 321 | 322 | extension Request { 323 | 324 | /** 325 | Creates a response serializer that returns an object constructed from the response data using 326 | `NSPropertyListSerialization` with the specified reading options. 327 | 328 | - parameter options: The property list reading options. `NSPropertyListReadOptions()` by default. 329 | 330 | - returns: A property list object response serializer. 331 | */ 332 | public static func propertyListResponseSerializer( 333 | options options: NSPropertyListReadOptions = NSPropertyListReadOptions()) 334 | -> ResponseSerializer 335 | { 336 | return ResponseSerializer { _, response, data, error in 337 | guard error == nil else { return .Failure(error!) } 338 | 339 | if let response = response where response.statusCode == 204 { return .Success(NSNull()) } 340 | 341 | guard let validData = data where validData.length > 0 else { 342 | let failureReason = "Property list could not be serialized. Input data was nil or zero length." 343 | let error = Error.error(code: .PropertyListSerializationFailed, failureReason: failureReason) 344 | return .Failure(error) 345 | } 346 | 347 | do { 348 | let plist = try NSPropertyListSerialization.propertyListWithData(validData, options: options, format: nil) 349 | return .Success(plist) 350 | } catch { 351 | return .Failure(error as NSError) 352 | } 353 | } 354 | } 355 | 356 | /** 357 | Adds a handler to be called once the request has finished. 358 | 359 | - parameter options: The property list reading options. `0` by default. 360 | - parameter completionHandler: A closure to be executed once the request has finished. The closure takes 3 361 | arguments: the URL request, the URL response, the server data and the result 362 | produced while creating the property list. 363 | 364 | - returns: The request. 365 | */ 366 | public func responsePropertyList( 367 | queue queue: dispatch_queue_t? = nil, 368 | options: NSPropertyListReadOptions = NSPropertyListReadOptions(), 369 | completionHandler: Response -> Void) 370 | -> Self 371 | { 372 | return response( 373 | queue: queue, 374 | responseSerializer: Request.propertyListResponseSerializer(options: options), 375 | completionHandler: completionHandler 376 | ) 377 | } 378 | } 379 | -------------------------------------------------------------------------------- /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/ServerTrustPolicy.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ServerTrustPolicy.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 | /// Responsible for managing the mapping of `ServerTrustPolicy` objects to a given host. 28 | public class ServerTrustPolicyManager { 29 | /// The dictionary of policies mapped to a particular host. 30 | public let policies: [String: ServerTrustPolicy] 31 | 32 | /** 33 | Initializes the `ServerTrustPolicyManager` instance with the given policies. 34 | 35 | Since different servers and web services can have different leaf certificates, intermediate and even root 36 | certficates, it is important to have the flexibility to specify evaluation policies on a per host basis. This 37 | allows for scenarios such as using default evaluation for host1, certificate pinning for host2, public key 38 | pinning for host3 and disabling evaluation for host4. 39 | 40 | - parameter policies: A dictionary of all policies mapped to a particular host. 41 | 42 | - returns: The new `ServerTrustPolicyManager` instance. 43 | */ 44 | public init(policies: [String: ServerTrustPolicy]) { 45 | self.policies = policies 46 | } 47 | 48 | /** 49 | Returns the `ServerTrustPolicy` for the given host if applicable. 50 | 51 | By default, this method will return the policy that perfectly matches the given host. Subclasses could override 52 | this method and implement more complex mapping implementations such as wildcards. 53 | 54 | - parameter host: The host to use when searching for a matching policy. 55 | 56 | - returns: The server trust policy for the given host if found. 57 | */ 58 | public func serverTrustPolicyForHost(host: String) -> ServerTrustPolicy? { 59 | return policies[host] 60 | } 61 | } 62 | 63 | // MARK: - 64 | 65 | extension NSURLSession { 66 | private struct AssociatedKeys { 67 | static var ManagerKey = "NSURLSession.ServerTrustPolicyManager" 68 | } 69 | 70 | var serverTrustPolicyManager: ServerTrustPolicyManager? { 71 | get { 72 | return objc_getAssociatedObject(self, &AssociatedKeys.ManagerKey) as? ServerTrustPolicyManager 73 | } 74 | set (manager) { 75 | objc_setAssociatedObject(self, &AssociatedKeys.ManagerKey, manager, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) 76 | } 77 | } 78 | } 79 | 80 | // MARK: - ServerTrustPolicy 81 | 82 | /** 83 | The `ServerTrustPolicy` evaluates the server trust generally provided by an `NSURLAuthenticationChallenge` when 84 | connecting to a server over a secure HTTPS connection. The policy configuration then evaluates the server trust 85 | with a given set of criteria to determine whether the server trust is valid and the connection should be made. 86 | 87 | Using pinned certificates or public keys for evaluation helps prevent man-in-the-middle (MITM) attacks and other 88 | vulnerabilities. Applications dealing with sensitive customer data or financial information are strongly encouraged 89 | to route all communication over an HTTPS connection with pinning enabled. 90 | 91 | - PerformDefaultEvaluation: Uses the default server trust evaluation while allowing you to control whether to 92 | validate the host provided by the challenge. Applications are encouraged to always 93 | validate the host in production environments to guarantee the validity of the server's 94 | certificate chain. 95 | 96 | - PinCertificates: Uses the pinned certificates to validate the server trust. The server trust is 97 | considered valid if one of the pinned certificates match one of the server certificates. 98 | By validating both the certificate chain and host, certificate pinning provides a very 99 | secure form of server trust validation mitigating most, if not all, MITM attacks. 100 | Applications are encouraged to always validate the host and require a valid certificate 101 | chain in production environments. 102 | 103 | - PinPublicKeys: Uses the pinned public keys to validate the server trust. The server trust is considered 104 | valid if one of the pinned public keys match one of the server certificate public keys. 105 | By validating both the certificate chain and host, public key pinning provides a very 106 | secure form of server trust validation mitigating most, if not all, MITM attacks. 107 | Applications are encouraged to always validate the host and require a valid certificate 108 | chain in production environments. 109 | 110 | - DisableEvaluation: Disables all evaluation which in turn will always consider any server trust as valid. 111 | 112 | - CustomEvaluation: Uses the associated closure to evaluate the validity of the server trust. 113 | */ 114 | public enum ServerTrustPolicy { 115 | case PerformDefaultEvaluation(validateHost: Bool) 116 | case PinCertificates(certificates: [SecCertificate], validateCertificateChain: Bool, validateHost: Bool) 117 | case PinPublicKeys(publicKeys: [SecKey], validateCertificateChain: Bool, validateHost: Bool) 118 | case DisableEvaluation 119 | case CustomEvaluation((serverTrust: SecTrust, host: String) -> Bool) 120 | 121 | // MARK: - Bundle Location 122 | 123 | /** 124 | Returns all certificates within the given bundle with a `.cer` file extension. 125 | 126 | - parameter bundle: The bundle to search for all `.cer` files. 127 | 128 | - returns: All certificates within the given bundle. 129 | */ 130 | public static func certificatesInBundle(bundle: NSBundle = NSBundle.mainBundle()) -> [SecCertificate] { 131 | var certificates: [SecCertificate] = [] 132 | 133 | let paths = Set([".cer", ".CER", ".crt", ".CRT", ".der", ".DER"].map { fileExtension in 134 | bundle.pathsForResourcesOfType(fileExtension, inDirectory: nil) 135 | }.flatten()) 136 | 137 | for path in paths { 138 | if let 139 | certificateData = NSData(contentsOfFile: path), 140 | certificate = SecCertificateCreateWithData(nil, certificateData) 141 | { 142 | certificates.append(certificate) 143 | } 144 | } 145 | 146 | return certificates 147 | } 148 | 149 | /** 150 | Returns all public keys within the given bundle with a `.cer` file extension. 151 | 152 | - parameter bundle: The bundle to search for all `*.cer` files. 153 | 154 | - returns: All public keys within the given bundle. 155 | */ 156 | public static func publicKeysInBundle(bundle: NSBundle = NSBundle.mainBundle()) -> [SecKey] { 157 | var publicKeys: [SecKey] = [] 158 | 159 | for certificate in certificatesInBundle(bundle) { 160 | if let publicKey = publicKeyForCertificate(certificate) { 161 | publicKeys.append(publicKey) 162 | } 163 | } 164 | 165 | return publicKeys 166 | } 167 | 168 | // MARK: - Evaluation 169 | 170 | /** 171 | Evaluates whether the server trust is valid for the given host. 172 | 173 | - parameter serverTrust: The server trust to evaluate. 174 | - parameter host: The host of the challenge protection space. 175 | 176 | - returns: Whether the server trust is valid. 177 | */ 178 | public func evaluateServerTrust(serverTrust: SecTrust, isValidForHost host: String) -> Bool { 179 | var serverTrustIsValid = false 180 | 181 | switch self { 182 | case let .PerformDefaultEvaluation(validateHost): 183 | let policy = SecPolicyCreateSSL(true, validateHost ? host as CFString : nil) 184 | SecTrustSetPolicies(serverTrust, [policy]) 185 | 186 | serverTrustIsValid = trustIsValid(serverTrust) 187 | case let .PinCertificates(pinnedCertificates, validateCertificateChain, validateHost): 188 | if validateCertificateChain { 189 | let policy = SecPolicyCreateSSL(true, validateHost ? host as CFString : nil) 190 | SecTrustSetPolicies(serverTrust, [policy]) 191 | 192 | SecTrustSetAnchorCertificates(serverTrust, pinnedCertificates) 193 | SecTrustSetAnchorCertificatesOnly(serverTrust, true) 194 | 195 | serverTrustIsValid = trustIsValid(serverTrust) 196 | } else { 197 | let serverCertificatesDataArray = certificateDataForTrust(serverTrust) 198 | let pinnedCertificatesDataArray = certificateDataForCertificates(pinnedCertificates) 199 | 200 | outerLoop: for serverCertificateData in serverCertificatesDataArray { 201 | for pinnedCertificateData in pinnedCertificatesDataArray { 202 | if serverCertificateData.isEqualToData(pinnedCertificateData) { 203 | serverTrustIsValid = true 204 | break outerLoop 205 | } 206 | } 207 | } 208 | } 209 | case let .PinPublicKeys(pinnedPublicKeys, validateCertificateChain, validateHost): 210 | var certificateChainEvaluationPassed = true 211 | 212 | if validateCertificateChain { 213 | let policy = SecPolicyCreateSSL(true, validateHost ? host as CFString : nil) 214 | SecTrustSetPolicies(serverTrust, [policy]) 215 | 216 | certificateChainEvaluationPassed = trustIsValid(serverTrust) 217 | } 218 | 219 | if certificateChainEvaluationPassed { 220 | outerLoop: for serverPublicKey in ServerTrustPolicy.publicKeysForTrust(serverTrust) as [AnyObject] { 221 | for pinnedPublicKey in pinnedPublicKeys as [AnyObject] { 222 | if serverPublicKey.isEqual(pinnedPublicKey) { 223 | serverTrustIsValid = true 224 | break outerLoop 225 | } 226 | } 227 | } 228 | } 229 | case .DisableEvaluation: 230 | serverTrustIsValid = true 231 | case let .CustomEvaluation(closure): 232 | serverTrustIsValid = closure(serverTrust: serverTrust, host: host) 233 | } 234 | 235 | return serverTrustIsValid 236 | } 237 | 238 | // MARK: - Private - Trust Validation 239 | 240 | private func trustIsValid(trust: SecTrust) -> Bool { 241 | var isValid = false 242 | 243 | var result = SecTrustResultType(kSecTrustResultInvalid) 244 | let status = SecTrustEvaluate(trust, &result) 245 | 246 | if status == errSecSuccess { 247 | let unspecified = SecTrustResultType(kSecTrustResultUnspecified) 248 | let proceed = SecTrustResultType(kSecTrustResultProceed) 249 | 250 | isValid = result == unspecified || result == proceed 251 | } 252 | 253 | return isValid 254 | } 255 | 256 | // MARK: - Private - Certificate Data 257 | 258 | private func certificateDataForTrust(trust: SecTrust) -> [NSData] { 259 | var certificates: [SecCertificate] = [] 260 | 261 | for index in 0.. [NSData] { 271 | return certificates.map { SecCertificateCopyData($0) as NSData } 272 | } 273 | 274 | // MARK: - Private - Public Key Extraction 275 | 276 | private static func publicKeysForTrust(trust: SecTrust) -> [SecKey] { 277 | var publicKeys: [SecKey] = [] 278 | 279 | for index in 0.. SecKey? { 292 | var publicKey: SecKey? 293 | 294 | let policy = SecPolicyCreateBasicX509() 295 | var trust: SecTrust? 296 | let trustCreationStatus = SecTrustCreateWithCertificates(certificate, policy, &trust) 297 | 298 | if let trust = trust where trustCreationStatus == errSecSuccess { 299 | publicKey = SecTrustCopyPublicKey(trust) 300 | } 301 | 302 | return publicKey 303 | } 304 | } 305 | -------------------------------------------------------------------------------- /Pods/Alamofire/Source/Stream.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Stream.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 | #if !os(watchOS) 28 | 29 | @available(iOS 9.0, OSX 10.11, tvOS 9.0, *) 30 | extension Manager { 31 | private enum Streamable { 32 | case Stream(String, Int) 33 | case NetService(NSNetService) 34 | } 35 | 36 | private func stream(streamable: Streamable) -> Request { 37 | var streamTask: NSURLSessionStreamTask! 38 | 39 | switch streamable { 40 | case .Stream(let hostName, let port): 41 | dispatch_sync(queue) { 42 | streamTask = self.session.streamTaskWithHostName(hostName, port: port) 43 | } 44 | case .NetService(let netService): 45 | dispatch_sync(queue) { 46 | streamTask = self.session.streamTaskWithNetService(netService) 47 | } 48 | } 49 | 50 | let request = Request(session: session, task: streamTask) 51 | 52 | delegate[request.delegate.task] = request.delegate 53 | 54 | if startRequestsImmediately { 55 | request.resume() 56 | } 57 | 58 | return request 59 | } 60 | 61 | /** 62 | Creates a request for bidirectional streaming with the given hostname and port. 63 | 64 | - parameter hostName: The hostname of the server to connect to. 65 | - parameter port: The port of the server to connect to. 66 | 67 | :returns: The created stream request. 68 | */ 69 | public func stream(hostName hostName: String, port: Int) -> Request { 70 | return stream(.Stream(hostName, port)) 71 | } 72 | 73 | /** 74 | Creates a request for bidirectional streaming with the given `NSNetService`. 75 | 76 | - parameter netService: The net service used to identify the endpoint. 77 | 78 | - returns: The created stream request. 79 | */ 80 | public func stream(netService netService: NSNetService) -> Request { 81 | return stream(.NetService(netService)) 82 | } 83 | } 84 | 85 | // MARK: - 86 | 87 | @available(iOS 9.0, OSX 10.11, tvOS 9.0, *) 88 | extension Manager.SessionDelegate: NSURLSessionStreamDelegate { 89 | 90 | // MARK: Override Closures 91 | 92 | /// Overrides default behavior for NSURLSessionStreamDelegate method `URLSession:readClosedForStreamTask:`. 93 | public var streamTaskReadClosed: ((NSURLSession, NSURLSessionStreamTask) -> Void)? { 94 | get { 95 | return _streamTaskReadClosed as? (NSURLSession, NSURLSessionStreamTask) -> Void 96 | } 97 | set { 98 | _streamTaskReadClosed = newValue 99 | } 100 | } 101 | 102 | /// Overrides default behavior for NSURLSessionStreamDelegate method `URLSession:writeClosedForStreamTask:`. 103 | public var streamTaskWriteClosed: ((NSURLSession, NSURLSessionStreamTask) -> Void)? { 104 | get { 105 | return _streamTaskWriteClosed as? (NSURLSession, NSURLSessionStreamTask) -> Void 106 | } 107 | set { 108 | _streamTaskWriteClosed = newValue 109 | } 110 | } 111 | 112 | /// Overrides default behavior for NSURLSessionStreamDelegate method `URLSession:betterRouteDiscoveredForStreamTask:`. 113 | public var streamTaskBetterRouteDiscovered: ((NSURLSession, NSURLSessionStreamTask) -> Void)? { 114 | get { 115 | return _streamTaskBetterRouteDiscovered as? (NSURLSession, NSURLSessionStreamTask) -> Void 116 | } 117 | set { 118 | _streamTaskBetterRouteDiscovered = newValue 119 | } 120 | } 121 | 122 | /// Overrides default behavior for NSURLSessionStreamDelegate method `URLSession:streamTask:didBecomeInputStream:outputStream:`. 123 | public var streamTaskDidBecomeInputStream: ((NSURLSession, NSURLSessionStreamTask, NSInputStream, NSOutputStream) -> Void)? { 124 | get { 125 | return _streamTaskDidBecomeInputStream as? (NSURLSession, NSURLSessionStreamTask, NSInputStream, NSOutputStream) -> Void 126 | } 127 | set { 128 | _streamTaskDidBecomeInputStream = newValue 129 | } 130 | } 131 | 132 | // MARK: Delegate Methods 133 | 134 | /** 135 | Tells the delegate that the read side of the connection has been closed. 136 | 137 | - parameter session: The session. 138 | - parameter streamTask: The stream task. 139 | */ 140 | public func URLSession(session: NSURLSession, readClosedForStreamTask streamTask: NSURLSessionStreamTask) { 141 | streamTaskReadClosed?(session, streamTask) 142 | } 143 | 144 | /** 145 | Tells the delegate that the write side of the connection has been closed. 146 | 147 | - parameter session: The session. 148 | - parameter streamTask: The stream task. 149 | */ 150 | public func URLSession(session: NSURLSession, writeClosedForStreamTask streamTask: NSURLSessionStreamTask) { 151 | streamTaskWriteClosed?(session, streamTask) 152 | } 153 | 154 | /** 155 | Tells the delegate that the system has determined that a better route to the host is available. 156 | 157 | - parameter session: The session. 158 | - parameter streamTask: The stream task. 159 | */ 160 | public func URLSession(session: NSURLSession, betterRouteDiscoveredForStreamTask streamTask: NSURLSessionStreamTask) { 161 | streamTaskBetterRouteDiscovered?(session, streamTask) 162 | } 163 | 164 | /** 165 | Tells the delegate that the stream task has been completed and provides the unopened stream objects. 166 | 167 | - parameter session: The session. 168 | - parameter streamTask: The stream task. 169 | - parameter inputStream: The new input stream. 170 | - parameter outputStream: The new output stream. 171 | */ 172 | public func URLSession( 173 | session: NSURLSession, 174 | streamTask: NSURLSessionStreamTask, 175 | didBecomeInputStream inputStream: NSInputStream, 176 | outputStream: NSOutputStream) 177 | { 178 | streamTaskDidBecomeInputStream?(session, streamTask, inputStream, outputStream) 179 | } 180 | } 181 | 182 | #endif 183 | -------------------------------------------------------------------------------- /Pods/Alamofire/Source/Timeline.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Timeline.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 | /// Responsible for computing the timing metrics for the complete lifecycle of a `Request`. 28 | public struct Timeline { 29 | /// The time the request was initialized. 30 | public let requestStartTime: CFAbsoluteTime 31 | 32 | /// The time the first bytes were received from or sent to the server. 33 | public let initialResponseTime: CFAbsoluteTime 34 | 35 | /// The time when the request was completed. 36 | public let requestCompletedTime: CFAbsoluteTime 37 | 38 | /// The time when the response serialization was completed. 39 | public let serializationCompletedTime: CFAbsoluteTime 40 | 41 | /// The time interval in seconds from the time the request started to the initial response from the server. 42 | public let latency: NSTimeInterval 43 | 44 | /// The time interval in seconds from the time the request started to the time the request completed. 45 | public let requestDuration: NSTimeInterval 46 | 47 | /// The time interval in seconds from the time the request completed to the time response serialization completed. 48 | public let serializationDuration: NSTimeInterval 49 | 50 | /// The time interval in seconds from the time the request started to the time response serialization completed. 51 | public let totalDuration: NSTimeInterval 52 | 53 | /** 54 | Creates a new `Timeline` instance with the specified request times. 55 | 56 | - parameter requestStartTime: The time the request was initialized. Defaults to `0.0`. 57 | - parameter initialResponseTime: The time the first bytes were received from or sent to the server. 58 | Defaults to `0.0`. 59 | - parameter requestCompletedTime: The time when the request was completed. Defaults to `0.0`. 60 | - parameter serializationCompletedTime: The time when the response serialization was completed. Defaults 61 | to `0.0`. 62 | 63 | - returns: The new `Timeline` instance. 64 | */ 65 | public init( 66 | requestStartTime: CFAbsoluteTime = 0.0, 67 | initialResponseTime: CFAbsoluteTime = 0.0, 68 | requestCompletedTime: CFAbsoluteTime = 0.0, 69 | serializationCompletedTime: CFAbsoluteTime = 0.0) 70 | { 71 | self.requestStartTime = requestStartTime 72 | self.initialResponseTime = initialResponseTime 73 | self.requestCompletedTime = requestCompletedTime 74 | self.serializationCompletedTime = serializationCompletedTime 75 | 76 | self.latency = initialResponseTime - requestStartTime 77 | self.requestDuration = requestCompletedTime - requestStartTime 78 | self.serializationDuration = serializationCompletedTime - requestCompletedTime 79 | self.totalDuration = serializationCompletedTime - requestStartTime 80 | } 81 | } 82 | 83 | // MARK: - CustomStringConvertible 84 | 85 | extension Timeline: CustomStringConvertible { 86 | /// The textual representation used when written to an output stream, which includes the latency, the request 87 | /// duration and the total duration. 88 | public var description: String { 89 | let latency = String(format: "%.3f", self.latency) 90 | let requestDuration = String(format: "%.3f", self.requestDuration) 91 | let serializationDuration = String(format: "%.3f", self.serializationDuration) 92 | let totalDuration = String(format: "%.3f", self.totalDuration) 93 | 94 | let timings = [ 95 | "\"Latency\": \(latency) secs", 96 | "\"Request Duration\": \(requestDuration) secs", 97 | "\"Serialization Duration\": \(serializationDuration) secs", 98 | "\"Total Duration\": \(totalDuration) secs" 99 | ] 100 | 101 | return "Timeline: { \(timings.joinWithSeparator(", ")) }" 102 | } 103 | } 104 | 105 | // MARK: - CustomDebugStringConvertible 106 | 107 | extension Timeline: CustomDebugStringConvertible { 108 | /// The textual representation used when written to an output stream, which includes the request start time, the 109 | /// initial response time, the request completed time, the serialization completed time, the latency, the request 110 | /// duration and the total duration. 111 | public var debugDescription: String { 112 | let timings = [ 113 | "\"Request Start Time\": \(requestStartTime)", 114 | "\"Initial Response Time\": \(initialResponseTime)", 115 | "\"Request Completed Time\": \(requestCompletedTime)", 116 | "\"Serialization Completed Time\": \(serializationCompletedTime)", 117 | "\"Latency\": \(latency) secs", 118 | "\"Request Duration\": \(requestDuration) secs", 119 | "\"Serialization Duration\": \(serializationDuration) secs", 120 | "\"Total Duration\": \(totalDuration) secs" 121 | ] 122 | 123 | return "Timeline: { \(timings.joinWithSeparator(", ")) }" 124 | } 125 | } 126 | -------------------------------------------------------------------------------- /Pods/Alamofire/Source/Upload.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Upload.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 | extension Manager { 28 | private enum Uploadable { 29 | case Data(NSURLRequest, NSData) 30 | case File(NSURLRequest, NSURL) 31 | case Stream(NSURLRequest, NSInputStream) 32 | } 33 | 34 | private func upload(uploadable: Uploadable) -> Request { 35 | var uploadTask: NSURLSessionUploadTask! 36 | var HTTPBodyStream: NSInputStream? 37 | 38 | switch uploadable { 39 | case .Data(let request, let data): 40 | dispatch_sync(queue) { 41 | uploadTask = self.session.uploadTaskWithRequest(request, fromData: data) 42 | } 43 | case .File(let request, let fileURL): 44 | dispatch_sync(queue) { 45 | uploadTask = self.session.uploadTaskWithRequest(request, fromFile: fileURL) 46 | } 47 | case .Stream(let request, let stream): 48 | dispatch_sync(queue) { 49 | uploadTask = self.session.uploadTaskWithStreamedRequest(request) 50 | } 51 | 52 | HTTPBodyStream = stream 53 | } 54 | 55 | let request = Request(session: session, task: uploadTask) 56 | 57 | if HTTPBodyStream != nil { 58 | request.delegate.taskNeedNewBodyStream = { _, _ in 59 | return HTTPBodyStream 60 | } 61 | } 62 | 63 | delegate[request.delegate.task] = request.delegate 64 | 65 | if startRequestsImmediately { 66 | request.resume() 67 | } 68 | 69 | return request 70 | } 71 | 72 | // MARK: File 73 | 74 | /** 75 | Creates a request for uploading a file to the specified URL request. 76 | 77 | If `startRequestsImmediately` is `true`, the request will have `resume()` called before being returned. 78 | 79 | - parameter URLRequest: The URL request 80 | - parameter file: The file to upload 81 | 82 | - returns: The created upload request. 83 | */ 84 | public func upload(URLRequest: URLRequestConvertible, file: NSURL) -> Request { 85 | return upload(.File(URLRequest.URLRequest, file)) 86 | } 87 | 88 | /** 89 | Creates a request for uploading a file to the specified URL request. 90 | 91 | If `startRequestsImmediately` is `true`, the request will have `resume()` called before being returned. 92 | 93 | - parameter method: The HTTP method. 94 | - parameter URLString: The URL string. 95 | - parameter headers: The HTTP headers. `nil` by default. 96 | - parameter file: The file to upload 97 | 98 | - returns: The created upload request. 99 | */ 100 | public func upload( 101 | method: Method, 102 | _ URLString: URLStringConvertible, 103 | headers: [String: String]? = nil, 104 | file: NSURL) 105 | -> Request 106 | { 107 | let mutableURLRequest = URLRequest(method, URLString, headers: headers) 108 | return upload(mutableURLRequest, file: file) 109 | } 110 | 111 | // MARK: Data 112 | 113 | /** 114 | Creates a request for uploading data to the specified URL request. 115 | 116 | If `startRequestsImmediately` is `true`, the request will have `resume()` called before being returned. 117 | 118 | - parameter URLRequest: The URL request. 119 | - parameter data: The data to upload. 120 | 121 | - returns: The created upload request. 122 | */ 123 | public func upload(URLRequest: URLRequestConvertible, data: NSData) -> Request { 124 | return upload(.Data(URLRequest.URLRequest, data)) 125 | } 126 | 127 | /** 128 | Creates a request for uploading data to the specified URL request. 129 | 130 | If `startRequestsImmediately` is `true`, the request will have `resume()` called before being returned. 131 | 132 | - parameter method: The HTTP method. 133 | - parameter URLString: The URL string. 134 | - parameter headers: The HTTP headers. `nil` by default. 135 | - parameter data: The data to upload 136 | 137 | - returns: The created upload request. 138 | */ 139 | public func upload( 140 | method: Method, 141 | _ URLString: URLStringConvertible, 142 | headers: [String: String]? = nil, 143 | data: NSData) 144 | -> Request 145 | { 146 | let mutableURLRequest = URLRequest(method, URLString, headers: headers) 147 | 148 | return upload(mutableURLRequest, data: data) 149 | } 150 | 151 | // MARK: Stream 152 | 153 | /** 154 | Creates a request for uploading a stream to the specified URL request. 155 | 156 | If `startRequestsImmediately` is `true`, the request will have `resume()` called before being returned. 157 | 158 | - parameter URLRequest: The URL request. 159 | - parameter stream: The stream to upload. 160 | 161 | - returns: The created upload request. 162 | */ 163 | public func upload(URLRequest: URLRequestConvertible, stream: NSInputStream) -> Request { 164 | return upload(.Stream(URLRequest.URLRequest, stream)) 165 | } 166 | 167 | /** 168 | Creates a request for uploading a stream to the specified URL request. 169 | 170 | If `startRequestsImmediately` is `true`, the request will have `resume()` called before being returned. 171 | 172 | - parameter method: The HTTP method. 173 | - parameter URLString: The URL string. 174 | - parameter headers: The HTTP headers. `nil` by default. 175 | - parameter stream: The stream to upload. 176 | 177 | - returns: The created upload request. 178 | */ 179 | public func upload( 180 | method: Method, 181 | _ URLString: URLStringConvertible, 182 | headers: [String: String]? = nil, 183 | stream: NSInputStream) 184 | -> Request 185 | { 186 | let mutableURLRequest = URLRequest(method, URLString, headers: headers) 187 | 188 | return upload(mutableURLRequest, stream: stream) 189 | } 190 | 191 | // MARK: MultipartFormData 192 | 193 | /// Default memory threshold used when encoding `MultipartFormData`. 194 | public static let MultipartFormDataEncodingMemoryThreshold: UInt64 = 10 * 1024 * 1024 195 | 196 | /** 197 | Defines whether the `MultipartFormData` encoding was successful and contains result of the encoding as 198 | associated values. 199 | 200 | - Success: Represents a successful `MultipartFormData` encoding and contains the new `Request` along with 201 | streaming information. 202 | - Failure: Used to represent a failure in the `MultipartFormData` encoding and also contains the encoding 203 | error. 204 | */ 205 | public enum MultipartFormDataEncodingResult { 206 | case Success(request: Request, streamingFromDisk: Bool, streamFileURL: NSURL?) 207 | case Failure(ErrorType) 208 | } 209 | 210 | /** 211 | Encodes the `MultipartFormData` and creates a request to upload the result to the specified URL request. 212 | 213 | It is important to understand the memory implications of uploading `MultipartFormData`. If the cummulative 214 | payload is small, encoding the data in-memory and directly uploading to a server is the by far the most 215 | efficient approach. However, if the payload is too large, encoding the data in-memory could cause your app to 216 | be terminated. Larger payloads must first be written to disk using input and output streams to keep the memory 217 | footprint low, then the data can be uploaded as a stream from the resulting file. Streaming from disk MUST be 218 | used for larger payloads such as video content. 219 | 220 | The `encodingMemoryThreshold` parameter allows Alamofire to automatically determine whether to encode in-memory 221 | or stream from disk. If the content length of the `MultipartFormData` is below the `encodingMemoryThreshold`, 222 | encoding takes place in-memory. If the content length exceeds the threshold, the data is streamed to disk 223 | during the encoding process. Then the result is uploaded as data or as a stream depending on which encoding 224 | technique was used. 225 | 226 | If `startRequestsImmediately` is `true`, the request will have `resume()` called before being returned. 227 | 228 | - parameter method: The HTTP method. 229 | - parameter URLString: The URL string. 230 | - parameter headers: The HTTP headers. `nil` by default. 231 | - parameter multipartFormData: The closure used to append body parts to the `MultipartFormData`. 232 | - parameter encodingMemoryThreshold: The encoding memory threshold in bytes. 233 | `MultipartFormDataEncodingMemoryThreshold` by default. 234 | - parameter encodingCompletion: The closure called when the `MultipartFormData` encoding is complete. 235 | */ 236 | public func upload( 237 | method: Method, 238 | _ URLString: URLStringConvertible, 239 | headers: [String: String]? = nil, 240 | multipartFormData: MultipartFormData -> Void, 241 | encodingMemoryThreshold: UInt64 = Manager.MultipartFormDataEncodingMemoryThreshold, 242 | encodingCompletion: (MultipartFormDataEncodingResult -> Void)?) 243 | { 244 | let mutableURLRequest = URLRequest(method, URLString, headers: headers) 245 | 246 | return upload( 247 | mutableURLRequest, 248 | multipartFormData: multipartFormData, 249 | encodingMemoryThreshold: encodingMemoryThreshold, 250 | encodingCompletion: encodingCompletion 251 | ) 252 | } 253 | 254 | /** 255 | Encodes the `MultipartFormData` and creates a request to upload the result to the specified URL request. 256 | 257 | It is important to understand the memory implications of uploading `MultipartFormData`. If the cummulative 258 | payload is small, encoding the data in-memory and directly uploading to a server is the by far the most 259 | efficient approach. However, if the payload is too large, encoding the data in-memory could cause your app to 260 | be terminated. Larger payloads must first be written to disk using input and output streams to keep the memory 261 | footprint low, then the data can be uploaded as a stream from the resulting file. Streaming from disk MUST be 262 | used for larger payloads such as video content. 263 | 264 | The `encodingMemoryThreshold` parameter allows Alamofire to automatically determine whether to encode in-memory 265 | or stream from disk. If the content length of the `MultipartFormData` is below the `encodingMemoryThreshold`, 266 | encoding takes place in-memory. If the content length exceeds the threshold, the data is streamed to disk 267 | during the encoding process. Then the result is uploaded as data or as a stream depending on which encoding 268 | technique was used. 269 | 270 | If `startRequestsImmediately` is `true`, the request will have `resume()` called before being returned. 271 | 272 | - parameter URLRequest: The URL request. 273 | - parameter multipartFormData: The closure used to append body parts to the `MultipartFormData`. 274 | - parameter encodingMemoryThreshold: The encoding memory threshold in bytes. 275 | `MultipartFormDataEncodingMemoryThreshold` by default. 276 | - parameter encodingCompletion: The closure called when the `MultipartFormData` encoding is complete. 277 | */ 278 | public func upload( 279 | URLRequest: URLRequestConvertible, 280 | multipartFormData: MultipartFormData -> Void, 281 | encodingMemoryThreshold: UInt64 = Manager.MultipartFormDataEncodingMemoryThreshold, 282 | encodingCompletion: (MultipartFormDataEncodingResult -> Void)?) 283 | { 284 | dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)) { 285 | let formData = MultipartFormData() 286 | multipartFormData(formData) 287 | 288 | let URLRequestWithContentType = URLRequest.URLRequest 289 | URLRequestWithContentType.setValue(formData.contentType, forHTTPHeaderField: "Content-Type") 290 | 291 | let isBackgroundSession = self.session.configuration.identifier != nil 292 | 293 | if formData.contentLength < encodingMemoryThreshold && !isBackgroundSession { 294 | do { 295 | let data = try formData.encode() 296 | let encodingResult = MultipartFormDataEncodingResult.Success( 297 | request: self.upload(URLRequestWithContentType, data: data), 298 | streamingFromDisk: false, 299 | streamFileURL: nil 300 | ) 301 | 302 | dispatch_async(dispatch_get_main_queue()) { 303 | encodingCompletion?(encodingResult) 304 | } 305 | } catch { 306 | dispatch_async(dispatch_get_main_queue()) { 307 | encodingCompletion?(.Failure(error as NSError)) 308 | } 309 | } 310 | } else { 311 | let fileManager = NSFileManager.defaultManager() 312 | let tempDirectoryURL = NSURL(fileURLWithPath: NSTemporaryDirectory()) 313 | let directoryURL = tempDirectoryURL.URLByAppendingPathComponent("com.alamofire.manager/multipart.form.data") 314 | let fileName = NSUUID().UUIDString 315 | let fileURL = directoryURL.URLByAppendingPathComponent(fileName) 316 | 317 | do { 318 | try fileManager.createDirectoryAtURL(directoryURL, withIntermediateDirectories: true, attributes: nil) 319 | try formData.writeEncodedDataToDisk(fileURL) 320 | 321 | dispatch_async(dispatch_get_main_queue()) { 322 | let encodingResult = MultipartFormDataEncodingResult.Success( 323 | request: self.upload(URLRequestWithContentType, file: fileURL), 324 | streamingFromDisk: true, 325 | streamFileURL: fileURL 326 | ) 327 | encodingCompletion?(encodingResult) 328 | } 329 | } catch { 330 | dispatch_async(dispatch_get_main_queue()) { 331 | encodingCompletion?(.Failure(error as NSError)) 332 | } 333 | } 334 | } 335 | } 336 | } 337 | } 338 | 339 | // MARK: - 340 | 341 | extension Request { 342 | 343 | // MARK: - UploadTaskDelegate 344 | 345 | class UploadTaskDelegate: DataTaskDelegate { 346 | var uploadTask: NSURLSessionUploadTask? { return task as? NSURLSessionUploadTask } 347 | var uploadProgress: ((Int64, Int64, Int64) -> Void)! 348 | 349 | // MARK: - NSURLSessionTaskDelegate 350 | 351 | // MARK: Override Closures 352 | 353 | var taskDidSendBodyData: ((NSURLSession, NSURLSessionTask, Int64, Int64, Int64) -> Void)? 354 | 355 | // MARK: Delegate Methods 356 | 357 | func URLSession( 358 | session: NSURLSession, 359 | task: NSURLSessionTask, 360 | didSendBodyData bytesSent: Int64, 361 | totalBytesSent: Int64, 362 | totalBytesExpectedToSend: Int64) 363 | { 364 | if initialResponseTime == nil { initialResponseTime = CFAbsoluteTimeGetCurrent() } 365 | 366 | if let taskDidSendBodyData = taskDidSendBodyData { 367 | taskDidSendBodyData(session, task, bytesSent, totalBytesSent, totalBytesExpectedToSend) 368 | } else { 369 | progress.totalUnitCount = totalBytesExpectedToSend 370 | progress.completedUnitCount = totalBytesSent 371 | 372 | uploadProgress?(bytesSent, totalBytesSent, totalBytesExpectedToSend) 373 | } 374 | } 375 | } 376 | } 377 | -------------------------------------------------------------------------------- /Pods/Alamofire/Source/Validation.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Validation.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 | extension Request { 28 | 29 | /** 30 | Used to represent whether validation was successful or encountered an error resulting in a failure. 31 | 32 | - Success: The validation was successful. 33 | - Failure: The validation failed encountering the provided error. 34 | */ 35 | public enum ValidationResult { 36 | case Success 37 | case Failure(NSError) 38 | } 39 | 40 | /** 41 | A closure used to validate a request that takes a URL request and URL response, and returns whether the 42 | request was valid. 43 | */ 44 | public typealias Validation = (NSURLRequest?, NSHTTPURLResponse) -> ValidationResult 45 | 46 | /** 47 | Validates the request, using the specified closure. 48 | 49 | If validation fails, subsequent calls to response handlers will have an associated error. 50 | 51 | - parameter validation: A closure to validate the request. 52 | 53 | - returns: The request. 54 | */ 55 | public func validate(validation: Validation) -> Self { 56 | delegate.queue.addOperationWithBlock { 57 | if let 58 | response = self.response where self.delegate.error == nil, 59 | case let .Failure(error) = validation(self.request, response) 60 | { 61 | self.delegate.error = error 62 | } 63 | } 64 | 65 | return self 66 | } 67 | 68 | // MARK: - Status Code 69 | 70 | /** 71 | Validates that the response has a status code in the specified range. 72 | 73 | If validation fails, subsequent calls to response handlers will have an associated error. 74 | 75 | - parameter range: The range of acceptable status codes. 76 | 77 | - returns: The request. 78 | */ 79 | public func validate(statusCode acceptableStatusCode: S) -> Self { 80 | return validate { _, response in 81 | if acceptableStatusCode.contains(response.statusCode) { 82 | return .Success 83 | } else { 84 | let failureReason = "Response status code was unacceptable: \(response.statusCode)" 85 | 86 | let error = NSError( 87 | domain: Error.Domain, 88 | code: Error.Code.StatusCodeValidationFailed.rawValue, 89 | userInfo: [ 90 | NSLocalizedFailureReasonErrorKey: failureReason, 91 | Error.UserInfoKeys.StatusCode: response.statusCode 92 | ] 93 | ) 94 | 95 | return .Failure(error) 96 | } 97 | } 98 | } 99 | 100 | // MARK: - Content-Type 101 | 102 | private struct MIMEType { 103 | let type: String 104 | let subtype: String 105 | 106 | init?(_ string: String) { 107 | let components: [String] = { 108 | let stripped = string.stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceAndNewlineCharacterSet()) 109 | let split = stripped.substringToIndex(stripped.rangeOfString(";")?.startIndex ?? stripped.endIndex) 110 | return split.componentsSeparatedByString("/") 111 | }() 112 | 113 | if let 114 | type = components.first, 115 | subtype = components.last 116 | { 117 | self.type = type 118 | self.subtype = subtype 119 | } else { 120 | return nil 121 | } 122 | } 123 | 124 | func matches(MIME: MIMEType) -> Bool { 125 | switch (type, subtype) { 126 | case (MIME.type, MIME.subtype), (MIME.type, "*"), ("*", MIME.subtype), ("*", "*"): 127 | return true 128 | default: 129 | return false 130 | } 131 | } 132 | } 133 | 134 | /** 135 | Validates that the response has a content type in the specified array. 136 | 137 | If validation fails, subsequent calls to response handlers will have an associated error. 138 | 139 | - parameter contentType: The acceptable content types, which may specify wildcard types and/or subtypes. 140 | 141 | - returns: The request. 142 | */ 143 | public func validate(contentType acceptableContentTypes: S) -> Self { 144 | return validate { _, response in 145 | guard let validData = self.delegate.data where validData.length > 0 else { return .Success } 146 | 147 | if let 148 | responseContentType = response.MIMEType, 149 | responseMIMEType = MIMEType(responseContentType) 150 | { 151 | for contentType in acceptableContentTypes { 152 | if let acceptableMIMEType = MIMEType(contentType) where acceptableMIMEType.matches(responseMIMEType) { 153 | return .Success 154 | } 155 | } 156 | } else { 157 | for contentType in acceptableContentTypes { 158 | if let MIMEType = MIMEType(contentType) where MIMEType.type == "*" && MIMEType.subtype == "*" { 159 | return .Success 160 | } 161 | } 162 | } 163 | 164 | let contentType: String 165 | let failureReason: String 166 | 167 | if let responseContentType = response.MIMEType { 168 | contentType = responseContentType 169 | 170 | failureReason = ( 171 | "Response content type \"\(responseContentType)\" does not match any acceptable " + 172 | "content types: \(acceptableContentTypes)" 173 | ) 174 | } else { 175 | contentType = "" 176 | failureReason = "Response content type was missing and acceptable content type does not match \"*/*\"" 177 | } 178 | 179 | let error = NSError( 180 | domain: Error.Domain, 181 | code: Error.Code.ContentTypeValidationFailed.rawValue, 182 | userInfo: [ 183 | NSLocalizedFailureReasonErrorKey: failureReason, 184 | Error.UserInfoKeys.ContentType: contentType 185 | ] 186 | ) 187 | 188 | return .Failure(error) 189 | } 190 | } 191 | 192 | // MARK: - Automatic 193 | 194 | /** 195 | Validates that the response has a status code in the default acceptable range of 200...299, and that the content 196 | type matches any specified in the Accept HTTP header field. 197 | 198 | If validation fails, subsequent calls to response handlers will have an associated error. 199 | 200 | - returns: The request. 201 | */ 202 | public func validate() -> Self { 203 | let acceptableStatusCodes: Range = 200..<300 204 | let acceptableContentTypes: [String] = { 205 | if let accept = request?.valueForHTTPHeaderField("Accept") { 206 | return accept.componentsSeparatedByString(",") 207 | } 208 | 209 | return ["*/*"] 210 | }() 211 | 212 | return validate(statusCode: acceptableStatusCodes).validate(contentType: acceptableContentTypes) 213 | } 214 | } 215 | -------------------------------------------------------------------------------- /Pods/Manifest.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - Alamofire (3.4.0) 3 | 4 | DEPENDENCIES: 5 | - Alamofire (~> 3.4) 6 | 7 | SPEC CHECKSUMS: 8 | Alamofire: c19a627cefd6a95f840401c49ab1f124e07f54ee 9 | 10 | PODFILE CHECKSUM: cc3501dec68f096404d9552f1b571e2ba4c8ea11 11 | 12 | COCOAPODS: 1.0.0 13 | -------------------------------------------------------------------------------- /Pods/Pods.xcodeproj/xcuserdata/jtratta.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/jtratta.xcuserdatad/xcschemes/Pods-SwiftJSS.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/jtratta.xcuserdatad/xcschemes/Pods-SwiftJSSTests.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/jtratta.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | Alamofire.xcscheme 8 | 9 | isShown 10 | 11 | 12 | Pods-SwiftJSS.xcscheme 13 | 14 | isShown 15 | 16 | 17 | Pods-SwiftJSSTests.xcscheme 18 | 19 | isShown 20 | 21 | 22 | 23 | SuppressBuildableAutocreation 24 | 25 | 35C7EC7116FBBDF92898397993B6F1AB 26 | 27 | primary 28 | 29 | 30 | 441CA41994F6F6FBBFBF08F057CCB970 31 | 32 | primary 33 | 34 | 35 | 79C040AFDDCE1BCBF6D8B5EB0B85887F 36 | 37 | primary 38 | 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /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/Alamofire/Alamofire-prefix.pch: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #endif 4 | 5 | -------------------------------------------------------------------------------- /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/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/Alamofire/Alamofire.xcconfig: -------------------------------------------------------------------------------- 1 | CODE_SIGN_IDENTITY = 2 | CONFIGURATION_BUILD_DIR = $PODS_CONFIGURATION_BUILD_DIR/Alamofire 3 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 4 | HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Public" 5 | OTHER_SWIFT_FLAGS = $(inherited) "-D" "COCOAPODS" 6 | PODS_BUILD_DIR = $BUILD_DIR 7 | PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 8 | PODS_ROOT = ${SRCROOT} 9 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} 10 | SKIP_INSTALL = YES 11 | -------------------------------------------------------------------------------- /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.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-SwiftJSS/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-SwiftJSS/Pods-SwiftJSS-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 | Generated by CocoaPods - https://cocoapods.org 27 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-SwiftJSS/Pods-SwiftJSS-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 | Generated by CocoaPods - https://cocoapods.org 45 | Title 46 | 47 | Type 48 | PSGroupSpecifier 49 | 50 | 51 | StringsTable 52 | Acknowledgements 53 | Title 54 | Acknowledgements 55 | 56 | 57 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-SwiftJSS/Pods-SwiftJSS-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_Pods_SwiftJSS : NSObject 3 | @end 4 | @implementation PodsDummy_Pods_SwiftJSS 5 | @end 6 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-SwiftJSS/Pods-SwiftJSS-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 | fi 89 | if [[ "$CONFIGURATION" == "Release" ]]; then 90 | install_framework "$BUILT_PRODUCTS_DIR/Alamofire/Alamofire.framework" 91 | fi 92 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-SwiftJSS/Pods-SwiftJSS-resources.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | mkdir -p "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 5 | 6 | RESOURCES_TO_COPY=${PODS_ROOT}/resources-to-copy-${TARGETNAME}.txt 7 | > "$RESOURCES_TO_COPY" 8 | 9 | XCASSET_FILES=() 10 | 11 | case "${TARGETED_DEVICE_FAMILY}" in 12 | 1,2) 13 | TARGET_DEVICE_ARGS="--target-device ipad --target-device iphone" 14 | ;; 15 | 1) 16 | TARGET_DEVICE_ARGS="--target-device iphone" 17 | ;; 18 | 2) 19 | TARGET_DEVICE_ARGS="--target-device ipad" 20 | ;; 21 | *) 22 | TARGET_DEVICE_ARGS="--target-device mac" 23 | ;; 24 | esac 25 | 26 | realpath() { 27 | DIRECTORY="$(cd "${1%/*}" && pwd)" 28 | FILENAME="${1##*/}" 29 | echo "$DIRECTORY/$FILENAME" 30 | } 31 | 32 | install_resource() 33 | { 34 | if [[ "$1" = /* ]] ; then 35 | RESOURCE_PATH="$1" 36 | else 37 | RESOURCE_PATH="${PODS_ROOT}/$1" 38 | fi 39 | if [[ ! -e "$RESOURCE_PATH" ]] ; then 40 | cat << EOM 41 | error: Resource "$RESOURCE_PATH" not found. Run 'pod install' to update the copy resources script. 42 | EOM 43 | exit 1 44 | fi 45 | case $RESOURCE_PATH in 46 | *.storyboard) 47 | echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .storyboard`.storyboardc $RESOURCE_PATH --sdk ${SDKROOT} ${TARGET_DEVICE_ARGS}" 48 | ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .storyboard`.storyboardc" "$RESOURCE_PATH" --sdk "${SDKROOT}" ${TARGET_DEVICE_ARGS} 49 | ;; 50 | *.xib) 51 | echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .xib`.nib $RESOURCE_PATH --sdk ${SDKROOT}" 52 | ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .xib`.nib" "$RESOURCE_PATH" --sdk "${SDKROOT}" 53 | ;; 54 | *.framework) 55 | echo "mkdir -p ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 56 | mkdir -p "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 57 | echo "rsync -av $RESOURCE_PATH ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 58 | rsync -av "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 59 | ;; 60 | *.xcdatamodel) 61 | echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH"`.mom\"" 62 | xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodel`.mom" 63 | ;; 64 | *.xcdatamodeld) 65 | echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd\"" 66 | xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd" 67 | ;; 68 | *.xcmappingmodel) 69 | echo "xcrun mapc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm\"" 70 | xcrun mapc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm" 71 | ;; 72 | *.xcassets) 73 | ABSOLUTE_XCASSET_FILE=$(realpath "$RESOURCE_PATH") 74 | XCASSET_FILES+=("$ABSOLUTE_XCASSET_FILE") 75 | ;; 76 | *) 77 | echo "$RESOURCE_PATH" 78 | echo "$RESOURCE_PATH" >> "$RESOURCES_TO_COPY" 79 | ;; 80 | esac 81 | } 82 | 83 | mkdir -p "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 84 | rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 85 | if [[ "${ACTION}" == "install" ]] && [[ "${SKIP_INSTALL}" == "NO" ]]; then 86 | mkdir -p "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 87 | rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 88 | fi 89 | rm -f "$RESOURCES_TO_COPY" 90 | 91 | if [[ -n "${WRAPPER_EXTENSION}" ]] && [ "`xcrun --find actool`" ] && [ -n "$XCASSET_FILES" ] 92 | then 93 | # Find all other xcassets (this unfortunately includes those of path pods and other targets). 94 | OTHER_XCASSETS=$(find "$PWD" -iname "*.xcassets" -type d) 95 | while read line; do 96 | if [[ $line != "`realpath $PODS_ROOT`*" ]]; then 97 | XCASSET_FILES+=("$line") 98 | fi 99 | done <<<"$OTHER_XCASSETS" 100 | 101 | printf "%s\0" "${XCASSET_FILES[@]}" | xargs -0 xcrun actool --output-format human-readable-text --notices --warnings --platform "${PLATFORM_NAME}" --minimum-deployment-target "${!DEPLOYMENT_TARGET_SETTING_NAME}" ${TARGET_DEVICE_ARGS} --compress-pngs --compile "${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 102 | fi 103 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-SwiftJSS/Pods-SwiftJSS-umbrella.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | 4 | FOUNDATION_EXPORT double Pods_SwiftJSSVersionNumber; 5 | FOUNDATION_EXPORT const unsigned char Pods_SwiftJSSVersionString[]; 6 | 7 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-SwiftJSS/Pods-SwiftJSS.debug.xcconfig: -------------------------------------------------------------------------------- 1 | CODE_SIGN_IDENTITY = 2 | EMBEDDED_CONTENT_CONTAINS_SWIFT = YES 3 | FRAMEWORK_SEARCH_PATHS = $(inherited) "$PODS_CONFIGURATION_BUILD_DIR/Alamofire" 4 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 5 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/../Frameworks' '@loader_path/Frameworks' 6 | OTHER_CFLAGS = $(inherited) -iquote "$PODS_CONFIGURATION_BUILD_DIR/Alamofire/Alamofire.framework/Headers" 7 | OTHER_LDFLAGS = $(inherited) -framework "Alamofire" 8 | OTHER_SWIFT_FLAGS = $(inherited) "-D" "COCOAPODS" 9 | PODS_BUILD_DIR = $BUILD_DIR 10 | PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 11 | PODS_ROOT = ${SRCROOT}/Pods 12 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-SwiftJSS/Pods-SwiftJSS.modulemap: -------------------------------------------------------------------------------- 1 | framework module Pods_SwiftJSS { 2 | umbrella header "Pods-SwiftJSS-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-SwiftJSS/Pods-SwiftJSS.release.xcconfig: -------------------------------------------------------------------------------- 1 | CODE_SIGN_IDENTITY = 2 | EMBEDDED_CONTENT_CONTAINS_SWIFT = YES 3 | FRAMEWORK_SEARCH_PATHS = $(inherited) "$PODS_CONFIGURATION_BUILD_DIR/Alamofire" 4 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 5 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/../Frameworks' '@loader_path/Frameworks' 6 | OTHER_CFLAGS = $(inherited) -iquote "$PODS_CONFIGURATION_BUILD_DIR/Alamofire/Alamofire.framework/Headers" 7 | OTHER_LDFLAGS = $(inherited) -framework "Alamofire" 8 | OTHER_SWIFT_FLAGS = $(inherited) "-D" "COCOAPODS" 9 | PODS_BUILD_DIR = $BUILD_DIR 10 | PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 11 | PODS_ROOT = ${SRCROOT}/Pods 12 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-SwiftJSSTests/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-SwiftJSSTests/Pods-SwiftJSSTests-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-SwiftJSSTests/Pods-SwiftJSSTests-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-SwiftJSSTests/Pods-SwiftJSSTests-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_Pods_SwiftJSSTests : NSObject 3 | @end 4 | @implementation PodsDummy_Pods_SwiftJSSTests 5 | @end 6 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-SwiftJSSTests/Pods-SwiftJSSTests-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-SwiftJSSTests/Pods-SwiftJSSTests-resources.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | mkdir -p "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 5 | 6 | RESOURCES_TO_COPY=${PODS_ROOT}/resources-to-copy-${TARGETNAME}.txt 7 | > "$RESOURCES_TO_COPY" 8 | 9 | XCASSET_FILES=() 10 | 11 | case "${TARGETED_DEVICE_FAMILY}" in 12 | 1,2) 13 | TARGET_DEVICE_ARGS="--target-device ipad --target-device iphone" 14 | ;; 15 | 1) 16 | TARGET_DEVICE_ARGS="--target-device iphone" 17 | ;; 18 | 2) 19 | TARGET_DEVICE_ARGS="--target-device ipad" 20 | ;; 21 | *) 22 | TARGET_DEVICE_ARGS="--target-device mac" 23 | ;; 24 | esac 25 | 26 | realpath() { 27 | DIRECTORY="$(cd "${1%/*}" && pwd)" 28 | FILENAME="${1##*/}" 29 | echo "$DIRECTORY/$FILENAME" 30 | } 31 | 32 | install_resource() 33 | { 34 | if [[ "$1" = /* ]] ; then 35 | RESOURCE_PATH="$1" 36 | else 37 | RESOURCE_PATH="${PODS_ROOT}/$1" 38 | fi 39 | if [[ ! -e "$RESOURCE_PATH" ]] ; then 40 | cat << EOM 41 | error: Resource "$RESOURCE_PATH" not found. Run 'pod install' to update the copy resources script. 42 | EOM 43 | exit 1 44 | fi 45 | case $RESOURCE_PATH in 46 | *.storyboard) 47 | echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .storyboard`.storyboardc $RESOURCE_PATH --sdk ${SDKROOT} ${TARGET_DEVICE_ARGS}" 48 | ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .storyboard`.storyboardc" "$RESOURCE_PATH" --sdk "${SDKROOT}" ${TARGET_DEVICE_ARGS} 49 | ;; 50 | *.xib) 51 | echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .xib`.nib $RESOURCE_PATH --sdk ${SDKROOT}" 52 | ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .xib`.nib" "$RESOURCE_PATH" --sdk "${SDKROOT}" 53 | ;; 54 | *.framework) 55 | echo "mkdir -p ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 56 | mkdir -p "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 57 | echo "rsync -av $RESOURCE_PATH ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 58 | rsync -av "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 59 | ;; 60 | *.xcdatamodel) 61 | echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH"`.mom\"" 62 | xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodel`.mom" 63 | ;; 64 | *.xcdatamodeld) 65 | echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd\"" 66 | xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd" 67 | ;; 68 | *.xcmappingmodel) 69 | echo "xcrun mapc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm\"" 70 | xcrun mapc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm" 71 | ;; 72 | *.xcassets) 73 | ABSOLUTE_XCASSET_FILE=$(realpath "$RESOURCE_PATH") 74 | XCASSET_FILES+=("$ABSOLUTE_XCASSET_FILE") 75 | ;; 76 | *) 77 | echo "$RESOURCE_PATH" 78 | echo "$RESOURCE_PATH" >> "$RESOURCES_TO_COPY" 79 | ;; 80 | esac 81 | } 82 | 83 | mkdir -p "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 84 | rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 85 | if [[ "${ACTION}" == "install" ]] && [[ "${SKIP_INSTALL}" == "NO" ]]; then 86 | mkdir -p "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 87 | rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 88 | fi 89 | rm -f "$RESOURCES_TO_COPY" 90 | 91 | if [[ -n "${WRAPPER_EXTENSION}" ]] && [ "`xcrun --find actool`" ] && [ -n "$XCASSET_FILES" ] 92 | then 93 | # Find all other xcassets (this unfortunately includes those of path pods and other targets). 94 | OTHER_XCASSETS=$(find "$PWD" -iname "*.xcassets" -type d) 95 | while read line; do 96 | if [[ $line != "`realpath $PODS_ROOT`*" ]]; then 97 | XCASSET_FILES+=("$line") 98 | fi 99 | done <<<"$OTHER_XCASSETS" 100 | 101 | printf "%s\0" "${XCASSET_FILES[@]}" | xargs -0 xcrun actool --output-format human-readable-text --notices --warnings --platform "${PLATFORM_NAME}" --minimum-deployment-target "${!DEPLOYMENT_TARGET_SETTING_NAME}" ${TARGET_DEVICE_ARGS} --compress-pngs --compile "${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 102 | fi 103 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-SwiftJSSTests/Pods-SwiftJSSTests-umbrella.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | 4 | FOUNDATION_EXPORT double Pods_SwiftJSSTestsVersionNumber; 5 | FOUNDATION_EXPORT const unsigned char Pods_SwiftJSSTestsVersionString[]; 6 | 7 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-SwiftJSSTests/Pods-SwiftJSSTests.debug.xcconfig: -------------------------------------------------------------------------------- 1 | CODE_SIGN_IDENTITY = 2 | FRAMEWORK_SEARCH_PATHS = $(inherited) "$PODS_CONFIGURATION_BUILD_DIR/Alamofire" 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" 6 | PODS_BUILD_DIR = $BUILD_DIR 7 | PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 8 | PODS_ROOT = ${SRCROOT}/Pods 9 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-SwiftJSSTests/Pods-SwiftJSSTests.modulemap: -------------------------------------------------------------------------------- 1 | framework module Pods_SwiftJSSTests { 2 | umbrella header "Pods-SwiftJSSTests-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-SwiftJSSTests/Pods-SwiftJSSTests.release.xcconfig: -------------------------------------------------------------------------------- 1 | CODE_SIGN_IDENTITY = 2 | FRAMEWORK_SEARCH_PATHS = $(inherited) "$PODS_CONFIGURATION_BUILD_DIR/Alamofire" 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" 6 | PODS_BUILD_DIR = $BUILD_DIR 7 | PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 8 | PODS_ROOT = ${SRCROOT}/Pods 9 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SwiftJSS 2 | 3 | This is an example on how to leverage JAMFs Casper API using Swift in OSX. This is also an good example on how to leverage 4 | a REST API in iOS as well. 5 | 6 | 7 | 8 | ![alt tag](https://github.com/jason-tratta/SwiftJSS/blob/master/SwiftJSS/Screen%20Shot.png) 9 | -------------------------------------------------------------------------------- /SwiftJSS.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /SwiftJSS.xcodeproj/project.xcworkspace/xcuserdata/jtratta.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jason-tratta/SwiftJSS/a1a53b826b3377d7acbc98d191ad4b3fed0bdfb7/SwiftJSS.xcodeproj/project.xcworkspace/xcuserdata/jtratta.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /SwiftJSS.xcodeproj/xcuserdata/jtratta.xcuserdatad/xcschemes/SwiftJSS.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 33 | 39 | 40 | 41 | 42 | 43 | 49 | 50 | 51 | 52 | 53 | 54 | 64 | 66 | 72 | 73 | 74 | 75 | 76 | 77 | 83 | 85 | 91 | 92 | 93 | 94 | 96 | 97 | 100 | 101 | 102 | -------------------------------------------------------------------------------- /SwiftJSS.xcodeproj/xcuserdata/jtratta.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | SwiftJSS.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | 385734A31A9E299E006C3681 16 | 17 | primary 18 | 19 | 20 | 385734B51A9E299E006C3681 21 | 22 | primary 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /SwiftJSS.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /SwiftJSS.xcworkspace/xcuserdata/jtratta.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jason-tratta/SwiftJSS/a1a53b826b3377d7acbc98d191ad4b3fed0bdfb7/SwiftJSS.xcworkspace/xcuserdata/jtratta.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /SwiftJSS.xcworkspace/xcuserdata/jtratta.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | -------------------------------------------------------------------------------- /SwiftJSS/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // SwiftJSS 4 | // 5 | // Created by Tratta, Jason A on 2/25/15. 6 | // 7 | // The MIT License (MIT) 8 | // 9 | // Copyright (c) 2015 Jason Tratta 10 | // 11 | //Permission is hereby granted, free of charge, to any person obtaining a copy 12 | //of this software and associated documentation files (the "Software"), to deal 13 | //in the Software without restriction, including without limitation the rights 14 | //to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 15 | //copies of the Software, and to permit persons to whom the Software is 16 | //furnished to do so, subject to the following conditions: 17 | // 18 | //The above copyright notice and this permission notice shall be included in all 19 | //copies or substantial portions of the Software. 20 | // 21 | //THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 22 | //IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 23 | //FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 24 | //AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 25 | //LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 26 | //OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 27 | //SOFT 28 | 29 | 30 | import Cocoa 31 | 32 | @NSApplicationMain 33 | class AppDelegate: NSObject, NSApplicationDelegate { 34 | 35 | 36 | 37 | func applicationDidFinishLaunching(aNotification: NSNotification) { 38 | // Insert code here to initialize your application 39 | } 40 | 41 | func applicationWillTerminate(aNotification: NSNotification) { 42 | // Insert code here to tear down your application 43 | } 44 | 45 | 46 | } 47 | 48 | -------------------------------------------------------------------------------- /SwiftJSS/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "mac", 5 | "size" : "16x16", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "mac", 10 | "size" : "16x16", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "mac", 15 | "size" : "32x32", 16 | "scale" : "1x" 17 | }, 18 | { 19 | "idiom" : "mac", 20 | "size" : "32x32", 21 | "scale" : "2x" 22 | }, 23 | { 24 | "idiom" : "mac", 25 | "size" : "128x128", 26 | "scale" : "1x" 27 | }, 28 | { 29 | "idiom" : "mac", 30 | "size" : "128x128", 31 | "scale" : "2x" 32 | }, 33 | { 34 | "idiom" : "mac", 35 | "size" : "256x256", 36 | "scale" : "1x" 37 | }, 38 | { 39 | "idiom" : "mac", 40 | "size" : "256x256", 41 | "scale" : "2x" 42 | }, 43 | { 44 | "idiom" : "mac", 45 | "size" : "512x512", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "mac", 50 | "size" : "512x512", 51 | "scale" : "2x" 52 | } 53 | ], 54 | "info" : { 55 | "version" : 1, 56 | "author" : "xcode" 57 | } 58 | } -------------------------------------------------------------------------------- /SwiftJSS/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1 25 | LSMinimumSystemVersion 26 | $(MACOSX_DEPLOYMENT_TARGET) 27 | NSHumanReadableCopyright 28 | Copyright © 2015 Indiana University. All rights reserved. 29 | NSMainStoryboardFile 30 | Main 31 | NSPrincipalClass 32 | NSApplication 33 | 34 | 35 | -------------------------------------------------------------------------------- /SwiftJSS/Screen Shot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jason-tratta/SwiftJSS/a1a53b826b3377d7acbc98d191ad4b3fed0bdfb7/SwiftJSS/Screen Shot.png -------------------------------------------------------------------------------- /SwiftJSS/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // SwiftJSS 4 | // 5 | // Created by Tratta, Jason A on 2/13/15. 6 | // 7 | // The MIT License (MIT) 8 | // 9 | // Copyright (c) 2015 Jason Tratta 10 | // 11 | //Permission is hereby granted, free of charge, to any person obtaining a copy 12 | //of this software and associated documentation files (the "Software"), to deal 13 | //in the Software without restriction, including without limitation the rights 14 | //to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 15 | //copies of the Software, and to permit persons to whom the Software is 16 | //furnished to do so, subject to the following conditions: 17 | // 18 | //The above copyright notice and this permission notice shall be included in all 19 | //copies or substantial portions of the Software. 20 | // 21 | //THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 22 | //IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 23 | //FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 24 | //AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 25 | //LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 26 | //OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 27 | //SOFTWARE. 28 | // 29 | 30 | import Cocoa 31 | import Alamofire 32 | 33 | class ViewController: NSViewController, NSXMLParserDelegate { 34 | 35 | 36 | @IBOutlet weak var jssAddressTextField: NSTextField! 37 | @IBOutlet weak var usernameTextField: NSTextField! 38 | @IBOutlet weak var passwordSecureText: NSSecureTextField! 39 | @IBOutlet weak var testButton: NSButton! 40 | 41 | @IBOutlet weak var numberOfCPUsLabel: NSTextField! 42 | 43 | //Properties 44 | 45 | var computerArray: [String] = [String]() 46 | 47 | 48 | override func viewDidLoad() { 49 | super.viewDidLoad() 50 | 51 | 52 | 53 | // Do any additional setup after loading the view. 54 | } 55 | 56 | override var representedObject: AnyObject? { 57 | didSet { 58 | // Update the view, if already loaded. 59 | } 60 | } 61 | 62 | 63 | 64 | 65 | 66 | @IBAction func testJSS(sender: AnyObject) { 67 | 68 | 69 | 70 | let address = jssAddressTextField.stringValue 71 | let username = usernameTextField.stringValue 72 | let password = passwordSecureText.stringValue 73 | let thePath = "computers" 74 | 75 | 76 | let credential = NSURLCredential(user: username, password: password, persistence: .ForSession) 77 | 78 | 79 | let constructedAddress = address + "/JSSResource/" + thePath 80 | Alamofire.request(.GET, constructedAddress, parameters: ["application/xml": "Accept"]) 81 | .authenticate(usingCredential: credential) 82 | .responseData { response in 83 | debugPrint(response) 84 | 85 | let xmlParser = NSXMLParser(data: response.data!) 86 | xmlParser.delegate = self 87 | xmlParser.parse() 88 | 89 | } 90 | } 91 | 92 | 93 | 94 | 95 | func updateComputerCount() { 96 | 97 | let count = computerArray.count 98 | 99 | numberOfCPUsLabel.stringValue = String(count) 100 | 101 | } 102 | 103 | 104 | // MARK: Parser Methods 105 | 106 | func parser(parser: NSXMLParser, didStartElement elementName: String, namespaceURI: String?, qualifiedName qName: String?, attributes attributeDict: [String : String]) { 107 | 108 | 109 | 110 | if (elementName == "computer") { 111 | 112 | computerArray.append(elementName) 113 | 114 | } 115 | 116 | } 117 | 118 | 119 | 120 | 121 | func parserDidEndDocument(parser: NSXMLParser) { 122 | 123 | 124 | updateComputerCount() 125 | 126 | } 127 | 128 | 129 | 130 | 131 | 132 | } 133 | 134 | 135 | -------------------------------------------------------------------------------- /SwiftJSSTests/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 | -------------------------------------------------------------------------------- /SwiftJSSTests/SwiftJSSTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SwiftJSSTests.swift 3 | // SwiftJSSTests 4 | // 5 | // Created by Tratta, Jason A on 2/25/15. 6 | // Copyright (c) 2015 Indiana University. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | import XCTest 11 | 12 | class SwiftJSSTests: XCTestCase { 13 | 14 | override func setUp() { 15 | super.setUp() 16 | // Put setup code here. This method is called before the invocation of each test method in the class. 17 | } 18 | 19 | override func tearDown() { 20 | // Put teardown code here. This method is called after the invocation of each test method in the class. 21 | super.tearDown() 22 | } 23 | 24 | func testExample() { 25 | // This is an example of a functional test case. 26 | XCTAssert(true, "Pass") 27 | } 28 | 29 | func testPerformanceExample() { 30 | // This is an example of a performance test case. 31 | self.measureBlock() { 32 | // Put the code you want to measure the time of here. 33 | } 34 | } 35 | 36 | } 37 | --------------------------------------------------------------------------------