博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
iOS - Alamofire 网络请求
阅读量:7039 次
发布时间:2019-06-28

本文共 38512 字,大约阅读时间需要 128 分钟。

前言

  • Alamofire 是 Swift 语言的 HTTP 网络开发工具包,相当于 Swift 实现 AFNetworking 版本。当然,AFNetworking 非常稳定,在 Mac OSX 与 iOS 中也能像其他 Objective-C 代码一样用 Swift 编写。不过 Alamofire 更适合 Swift 语言风格习惯(Alamofire 与 AFNetworking 可以共存一个项目中,互不影响)。Alamofire 取名来源于 Alamo Fire flower。

  • Alamofire 的核心主要是试图简化 iOS 中 HTTP 网络连接,它通过使用 NSURLSession 以及 Foundation URL Loading System 来创建一个 Swift 本地的网络访问接口,从而实现令人难以置信效率的任务。

1、Alamofire

  • Alamofire 功能:

    • Chainable Request / Response methods
    • URL / JSON / plist Parameter Encoding
    • Upload File / Data / Stream
    • Download using Request or Resume data
    • Authentication with NSURLCredential
    • Progress Closure & NSProgress
    • cURL Debug Output
  • Alamofire 系统需求:

    Alamofire Version     |    Minimum iOS Target    |          Target Notes

    ------------------------|--------------------------|-------------------------------------------------------------------

    3.4.x | iOS 8.0+ | Xcode 7.3+ is required.
    3.1.4 -> 3.3.1 | iOS 8.0+ | Xcode 7.2+ is required.
    3.1.0 -> 3.1.3 | iOS 8.0+ | Xcode 7.1+ is required.
    2.0.0 -> 3.0.1 | iOS 8.0+ | Xcode 7.0+ is required.
    1.3.0 -> 1.3.1 | iOS 7.0+ | Xcode 6.4 is required.
    1.2.1 -> 1.2.3 | iOS 7.0+ | Xcode 6.3 is required.
    1.1.0 -> 1.2.0 | iOS 7.0+ | Xcode 6.1 is required.
    1.0.0 -> 1.0.1 | iOS 7.0+ | Xcode 6.0 is required. For Xcode 6.1, use the xcode-6.1 branch.

  • Alamofire 有许多让程序猿信服去使用它的理由。在 iOS 开发中,使用 NURLSession 是 HTTP 网络的未来趋势, 相比 NSURLConnection 来说,它的功能更加丰富:

    • 后台上传和下载
    • 暂停以及重新开始网络操作的能力
    • 可配置的容器(Container)
    • 子类和私有存储
    • 改进的认证处理
    • 对每个基础连接进行身份验证
    • 多种代理模式 -- NSURLConnection 拥有异步代码块的基本方法, 但是不能用它们的代理,NSURLSession 具有一种混合型的方法。
  • 对 AFNetworking 能做而 Alamofire 不能做的有以下几点:

    • UIKit 扩展
    • TLS 验证
    • NSOperation/NSURLConnection/AFURLConnectionOperation 调用
    • 多重 HTTP 网络请求构架

2、Alamofire 的添加

  • Github 网址:https://github.com/Alamofire/Alamofire

  • Alamofire 使用 ARC

  • Swift

    // 将第三方库文件复制到工程目录下    Alamofire           // 将第三方库文件中的 xcodeproj 添加到工程中    Alamofire.xcodeproj    // 在 TARGETS -> General -> Embedded Binaries 下添加静态库文件(添加上边的)    Alamofire.framework    // 添加头文件    import Alamofire

3、Alamofire 的设置

  • Swift

    • 请求超时时间设置

      // 必须设置为全局的    var alamofireManager: Manager!    let config = NSURLSessionConfiguration.defaultSessionConfiguration()    config.timeoutIntervalForRequest = 5     // 秒    self.alamofireManager = Manager(configuration: config)    self.alamofireManager.request(.GET, "http://120.25.226.186:32812/video?type=JSON")
    • HTTP 方法(Medthods)

      Alamofire.Method enum 列表出在 RFC 2616 中定义的 HTTP 方法:        public enum Method: String {            case OPTIONS = "OPTIONS"            case GET = "GET"            case HEAD = "HEAD"            case POST = "POST"            case PUT = "PUT"            case PATCH = "PATCH"            case DELETE = "DELETE"            case TRACE = "TRACE"            case CONNECT = "CONNECT"        }    这些值可以作为 Alamofire.request 请求的第一个参数。    Alamofire.request(.POST, "https://httpbin.org/post")    Alamofire.request(.PUT, "https://httpbin.org/put")    Alamofire.request(.DELETE, "https://httpbin.org/delete")
    • 请求参数编码方式设置

      Alamofire 使用 Alamofire.ParameterEncoding 可以支持 URL query/URI form,JSON,PropertyList 方式编码参数。    enum ParameterEncoding {        case URL        case URLEncodedInURL        case JSON        case PropertyList(NSPropertyListFormat, NSPropertyListWriteOptions)        case Custom((URLRequestConvertible, [String : AnyObject]?) -> (NSMutableURLRequest, NSError?))        public func encode(URLRequest: URLRequestConvertible, parameters: [String : AnyObject]?) -> (NSMutableURLRequest, NSError?)        public func queryComponents(key: String, _ value: AnyObject) -> [(String, String)]        public func escape(string: String) -> String    }    // URL 形式参数编码        // 发送以下 HttpBody 内容: foo=bar&baz[]=a&baz[]=1&qux[x]=1&qux[y]=2&qux[z]=3        let urlStr:URLStringConvertible = "https://httpbin.org/post"        let parameters:[String: AnyObject]? = ["foo":"bar", "baz":["a", 1], "qux":["x":1, "y":2, "z":3]]        Alamofire.request(.POST, urlStr, parameters: parameters)        // 默认编码方式是 URL        Alamofire.request(.POST, urlStr, parameters: parameters, encoding: .URL)    // JSON 形式参数编码        // 发送以下 HttpBody 内容: {"foo":"bar", "baz":["a", 1], "qux":{"x":1, "y":2, "z":3}}        let urlStr:URLStringConvertible = "https://httpbin.org/post"        let parameters:[String: AnyObject]? = ["foo":"bar", "baz":["a", 1], "qux":["x":1, "y":2, "z":3]]        Alamofire.request(.POST, urlStr, parameters: parameters, encoding:.JSON)                            // URLRequest 请求编码        let url = NSURL(string: "https://httpbin.org/get")!        var urlRequest = NSMutableURLRequest(URL: url)        let param = ["foo": "bar"]        let encoding = Alamofire.ParameterEncoding.URL        (urlRequest, _) = encoding.encode(urlRequest, parameters: param)
    • 请求头设置

      let headers = ["User-Agent":"iPhone 6s Plus"]    Alamofire.request(.GET, "http://192.168.88.200:8080/MJServer/video?type=JSON", headers: headers)    // 不设置时为默认值    Alamofire.request(.GET, "http://192.168.88.200:8080/MJServer/video?type=JSON")
    • 请求数据响应格式设置

      Built-in Response Methods:        response()        responseData()        responseString(encoding:NSStringEncoding)        responseJSON(options:NSJSONReadingOptions)        responsePropertyList(options:NSPropertyListReadOptions)    可以同时响应多种格式数据。    // 响应 NSData 格式数据        Alamofire.request(.GET, "http://192.168.88.200:8080/MJServer/video?type=JSON")            .response { (request:NSURLRequest?, response:NSHTTPURLResponse?, responseData:NSData?, error:NSError?) in                /*                    网络请求结束,成功时 error == nil。请求返回的数据存在 responseData 中,为 NSData 格式。                */              }    // 响应 String 格式数据        Alamofire.request(.GET, "http://192.168.88.200:8080/MJServer/video?type=JSON")            .responseString { (response:Response
      ) in /* 网络请求结束,成功时 response.result.error == nil。请求返回的数据存在 response.result.value 中,为 String 格式。 或者成功时 response.result 的值为 .Success,失败时 response.result 的值为 .Failure。 */ response.request // original URL request response.response // URL response response.data // server data response.result // result of response serialization // 获取并判断结果值 if let string = response.result.value { } else { } // 判断结果值 if response.result.error == nil { } else { } // 判断结果值 switch response.result { case.Success(let value): case.Failure(let error): } } // 响应 JSON 格式数据 Alamofire.request(.GET, "http://192.168.88.200:8080/MJServer/video?type=JSON") .responseJSON { (response:Response
      ) in /* 网络请求结束,成功时 response.result.error == nil。请求返回的数据存在 response.result.value 中,为 JSON 格式。 或者成功时 response.result 的值为 .Success,失败时 response.result 的值为 .Failure。 */ } // 响应 PList 格式数据 Alamofire.request(.GET, "http://192.168.88.200:8080/MJServer/video?type=JSON") .responsePropertyList { (response:Response
      ) in /* 网络请求结束,成功时 response.result.error == nil。请求返回的数据存在 response.result.value 中,为 PList 格式。 或者成功时 response.result 的值为 .Success,失败时 response.result 的值为 .Failure。 */ } // 响应 多种格式 数据 Alamofire.request(.GET, "http://192.168.88.200:8080/MJServer/video?type=JSON") // 参数不使用时可以省略 .response { (_, _, responseData:NSData?, error:NSError?) in } .responseJSON { (response:Response
      ) in }
    • Request 请求创建方式

      // Manager 方式        // 必须设置为全局的        var alamofireManager: Manager!        self.alamofireManager = Manager(configuration: NSURLSessionConfiguration.defaultSessionConfiguration())        self.alamofireManager.request(.GET, "http://120.25.226.186:32812/video?type=JSON")    // Alamofire 方式,接收返回值        let request = Alamofire.request(.GET, "http://192.168.88.200:8080/MJServer/video?type=JSON")    // 不接收返回值,request 不带参数        Alamofire.request(.GET, "http://192.168.88.200:8080/MJServer/video?type=JSON")    // request 带参数        Alamofire.request(.GET, "http://192.168.88.200:8080/MJServer/video", parameters: ["type": "JSON"])    // request 带参数及参数编码方式        Alamofire.request(.GET, "http://192.168.88.200:8080/MJServer/video", parameters: ["type": "JSON"], encoding: .URL)    // request 带参数及请求头        Alamofire.request(.GET, "http://192.168.88.200:8080/MJServer/video", parameters: ["type": "JSON"],                                                                                encoding: .URL,                                                                                 headers: ["User-Agent":"iPhone 6s"])
    • 请求任务创建方式

      // 数据请求 request (GET/POST)        // Alamofire GET 方式            let urlStr:URLStringConvertible = "http://192.168.88.200:8080/MJServer/video?type=XML"            Alamofire.request(.GET, urlStr)        // Alamofire POST 方式            let urlStr:URLStringConvertible = "http://192.168.88.200:8080/MJServer/video"            Alamofire.request(.GET, urlStr, parameters: ["type": "XML"])        // Manager GET 方式            // 必须设置为全局的            var alamofireManager: Manager!            let urlStr:URLStringConvertible = "http://192.168.88.200:8080/MJServer/video?type=XML"            self.alamofireManager = Manager(configuration: NSURLSessionConfiguration.defaultSessionConfiguration())            self.alamofireManager.request(.GET, urlStr)        // Manager POST 方式            // 必须设置为全局的            var alamofireManager: Manager!            let urlStr:URLStringConvertible = "http://192.168.88.200:8080/MJServer/video"            self.alamofireManager = Manager(configuration: NSURLSessionConfiguration.defaultSessionConfiguration())            self.alamofireManager.request(.GET, urlStr, parameters: ["type": "XML"])    // 文件下载 download        // 指定文件路径方式            Alamofire.download(.GET, "http://120.25.226.186:32812/resources/videos/minion_01.mp4")                       { (temporaryURL:NSURL, response:NSHTTPURLResponse) -> NSURL in                /*                        设置文件下载路径,temporaryURL 是沙盒下的文件临时存储路径,下载完成后会被自动删除。response.suggestedFilename                     为服务器端文件名。此 block 在子线程中执行。                */                return documentsDirUrl            }                .progress { (bytesWrite:Int64, totalBytesWrite:Int64, totalBytesExpectedToWrite:Int64) in                    /*                        监听文件下载进度,此 block 在子线程中执行。                    */                }                .response { (_, _, _, error:NSError?) in                    /*                        网络请求结束,成功时 error == nil。在 Swift 中文件已经存在时,再次相同路径写入会失败。                    */                }        // 使用默认提供的下载路径方式            Alamofire.download(.GET, "http://120.25.226.186:32812/resources/videos/minion_01.mp4", destination: destination)                .progress { (bytesWrite:Int64, totalBytesWrite:Int64, totalBytesExpectedToWrite:Int64) in                    /*                        监听文件下载进度,此 block 在子线程中执行。                    */                }                .response { (_, _, _, error:NSError?) in                    /*                        网络请求结束,成功时 error == nil。在 Swift 中文件已经存在时,再次相同路径写入会失败。                    */                }        // 断点续传下载方式            let downloadRequest:Request = Alamofire.download(resumeData: resumeData,                                                             destination: { (temporaryURL:NSURL,                                                                                 response:NSHTTPURLResponse) -> NSURL in                /*                        设置文件下载路径,temporaryURL 是沙盒下的文件临时存储路径,下载完成后会被自动删除。response.suggestedFilename                     为服务器端文件名。此 block 在子线程中执行。                */                return documentsDirUrl            })                .progress { (bytesWrite:Int64, totalBytesWrite:Int64, totalBytesExpectedToWrite:Int64) in                    /*                        监听文件下载进度,此 block 在子线程中执行。                    */                }                .response { (_, _, data:NSData?, error:NSError?) in                    /*                        网络请求结束,成功时 error == nil。在 Swift 中文件已经存在时,再次相同路径写入会失败。                    */                }    // 文件上传 upload        // Data 形式上传            Alamofire.upload(.POST, "http://192.168.88.200:8080/MJServer/upload", headers: headers, data: formBody)                .progress { (bytesLoad:Int64, totalBytesLoad:Int64, totalBytesExpectedToLoad:Int64) in                    /*                        监听文件上传进度,此 block 在子线程中执行。                    */                }                .response { (_, _, responseData:NSData?, error:NSError?) in                    /*                        网络请求结束。                    */                }        // MultipartFormData 形式上传            Alamofire.upload(.POST, "http://192.168.88.200:8080/MJServer/upload",                                      multipartFormData: { (formData:MultipartFormData) in                /*                    添加参数。第一个参数是需要添加的参数内容值,第二个是后台规定的参数名。                    设置上传的文件。第一个参数是需要上传的文件路径,第二个是后台规定的参数名,第三个是上传后服务器端文件名称,第四个是文件类型。                */            }) { (encodingResult:Manager.MultipartFormDataEncodingResult) in                /*                    数据编码完成。                */                switch encodingResult {                // 编码成功                case .Success(let uploadRequest, _, _):                                                                                     uploadRequest                        .progress { (bytesLoad:Int64, totalBytesLoad:Int64, totalBytesExpectedToLoad:Int64) in                            /*                                监听文件上传进度,此 block 在子线程中执行。                            */                        }                        .response { (_, _, responseData:NSData?, error:NSError?) in                            /*                                网络请求结束。                            */                        }                // 编码失败                case .Failure(let error):                                                                                                   print(error)                }            }
    • 请求任务设置

      // 继续请求任务    downloadRequest.resume()    // 暂停请求任务    downloadRequest.suspend()    // 取消请求任务    downloadRequest.cancel()
    • 文件下载设置

      // 设置文件下载路径        let documentsDirUrl:NSURL = NSFileManager.defaultManager()                                                 .URLsForDirectory( .DocumentDirectory, inDomains: .UserDomainMask)[0]                                                 .URLByAppendingPathComponent(response.suggestedFilename!)        if NSFileManager.defaultManager().fileExistsAtPath(documentsDirUrl.path!) {            // 移除已经存在的文件,在 Swift 中文件已经存在时,再次相同路径写入会失败            try! NSFileManager.defaultManager().removeItemAtURL(documentsDirUrl)        }    // 设置文件默认下载路径        let destination = Alamofire.Request.suggestedDownloadDestination(directory: .DocumentDirectory, domain: .UserDomainMask)    // 监听文件下载进度        bytesWrite                  // 本次写入的大小        totalBytesWrite             // 已经写入的大小        totalBytesExpectedToWrite   // 总大小        // 设置下载进度条        let progressNum:NSNumber = NSNumber(float: Float(Double(totalBytesWrite)/Double(totalBytesExpectedToWrite)))        self.performSelectorOnMainThread(#selector(ViewController.refreshProgress(_:)), withObject: progressNum, waitUntilDone: true)
    • 文件上传设置

      // Data 形式上传        let boundary = "myBoundary"        // 设置请求头        /*            upload task 不会在请求头里添加 content-type (上传数据类型)字段,@"myBoundary" 为请求体边界,参数可以随便设置,但需一致        */        let headers = ["Content-Type":"multipart/form-data; charset=utf-8; boundary=\(boundary)"]        // 设置请求文件参数            let formBody = NSMutableData()            // 参数开始分割线            /*                每个参数开始前都需要加            */            formBody.appendData("--\(boundary)".dataUsingEncoding(NSUTF8StringEncoding)!)            formBody.appendData("\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)            // 参数            formBody.appendData("Content-Disposition: form-data; name=\"\("username")\"\r\n\r\n\("jhq")"                    .dataUsingEncoding(NSUTF8StringEncoding)!)            // username 是后台规定的参数名,jhq 是需要添加的参数内容值            formBody.appendData("\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)            // 文件开始分割线            /*                每个文件开始前都需要加            */            formBody.appendData("--\(boundary)".dataUsingEncoding(NSUTF8StringEncoding)!)            formBody.appendData("\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)            // 文件参数名            formBody.appendData("Content-Disposition: form-data; name=\"\("file")\"; filename=\"\("test.mp4")\""                    .dataUsingEncoding(NSUTF8StringEncoding)!)            // file 是后台规定的参数名,test.mp4 为上传后服务器端文件名称            formBody.appendData("\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)                                        // 文件的类型            formBody.appendData("Content-Type: mp4".dataUsingEncoding(NSUTF8StringEncoding)!)            formBody.appendData("\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)            formBody.appendData("\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)            // 待上传文件数据            /*                本地待上传的文件路径            */            formBody.appendData(NSData(contentsOfFile: NSBundle.mainBundle().pathForResource("minion", ofType: "mp4")!)!)            formBody.appendData("\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)            // 结束分割线标记            formBody.appendData("--\(boundary)--".dataUsingEncoding(NSUTF8StringEncoding)!)            formBody.appendData("\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)    // 指定文件路径形式上传    /*        public func appendBodyPart(fileURL fileURL: NSURL, name: String, fileName: String, mimeType: String);        第一个参数是需要上传的文件路径,第二个是后台规定的参数名,第三个是上传后服务器端文件名称,第四个是文件类型。    */    let fileUrl = NSBundle.mainBundle().URLForResource("HQ_0005", withExtension: "jpg")!    formData.appendBodyPart(fileURL: fileUrl, name: "file", fileName: "test.png", mimeType: "image/jpeg")    // 指定文件数据形式上传    /*        public func appendBodyPart(data data: NSData, name: String, fileName: String, mimeType: String);        第一个参数是需要上传的文件数据,第二个是后台规定的参数名,第三个是上传后服务器端文件名称,第四个是文件类型。    */    let fileData = NSData(contentsOfFile: NSBundle.mainBundle().pathForResource("minion", ofType: "mp4")!)    formData.appendBodyPart(data: fileData!, name: "file", fileName: "test.mp4", mimeType: "mp4")    // 添加参数    /*        public func appendBodyPart(data data: NSData, name: String);        第一个参数是需要添加的参数内容值,第二个是后台规定的参数名。    */    formData.appendBodyPart(data: "jhq".dataUsingEncoding(NSUTF8StringEncoding)!, name: "username")    // 监听文件上传进度    bytesLoad                   // 本次写入的大小    totalBytesLoad              // 已经写入的大小    totalBytesExpectedToLoad    // 总大小    let progressNum1:NSNumber = NSNumber(float: Float(Double(totalBytesLoad)/Double(totalBytesExpectedToLoad)))    self.performSelectorOnMainThread(#selector(ViewController.refreshProgress(_:)), withObject: progressNum1, waitUntilDone: true)

4、Alamofire HTTP 认证

  • 支持以下几种认证:

    • HTTP Basic
    • HTTP Digest
    • Kerberos
    • NTLM
  • Swift

    // Http basic 方式认证        let user = "user"        let password = "password"        Alamofire.request(.GET, "https://httpbin.org/basic-auth/\(user)/\(password)")            .authenticate(user: user, password: password)    // NSURLCredential 方式认证        let user = "user"        let password = "password"        let credential = NSURLCredential(user: user, password: password, persistence: .ForSession)        Alamofire.request(.GET, "https://httpbin.org/basic-auth/\(user)/\(password)")            .authenticate(usingCredential: credential)    // headers 方式认证        let user = "user"        let password = "password"        let credentialData = "\(user):\(password)".dataUsingEncoding(NSUTF8StringEncoding)!        let base64Credentials = credentialData.base64EncodedStringWithOptions([])        let headers = ["Authorization": "Basic \(base64Credentials)"]        Alamofire.request(.GET, "https://httpbin.org/basic-auth/user/password", headers: headers)

5、Alamofire HTTP 响应状态信息识别

  • Swift

    • 手动识别

      /*            Alamofire 还提供了 HTTP 响应状态的判断识别,通过 validate 方法,对于在我们期望之外的 HTTP 响应状态信息,        Alamofire 会提供报错信息:    */    Alamofire.request(.GET, "https://httpbin.org/get", parameters: ["foo": "bar"])        .validate(statusCode: 200..<300)        .validate(contentType: ["application/json"])
    • 自动识别

      // validate 方法还提供自动识别机制,我们调用 validate 方法时不传入任何参数,则会自动认为 200…299 的状态吗为正常:    Alamofire.request(.GET, "https://httpbin.org/get", parameters: ["foo": "bar"])        .validate()

6、Alamofire Timeline

  • Swift

    /*            Alamofire collects timings throughout the lifecycle of a Request and creates a Timeline object         exposed as a property on a Response.    */    Alamofire.request(.GET, "http://192.168.88.200:8080/MJServer/video", parameters: ["type": "JSON"])        .validate()        .responseJSON { response in        print(response.timeline)    }    The above reports the following Timeline info:        Latency: 0.428 seconds        Request Duration: 0.428 seconds        Serialization Duration: 0.001 seconds        Total Duration: 0.429 seconds

7、Alamofire 调试打印

  • Swift

    // GET print        let request = Alamofire.request(.GET, "http://192.168.88.200:8080/MJServer/video?type=JSON")        print(request)        // 打印输出 GET http://192.168.88.200:8080/MJServer/video?type=JSON    // POST print        let request = Alamofire.request(.POST, "http://192.168.88.200:8080/MJServer/video", parameters: ["type":"JSON"])        print(request)        // 打印输出 POST http://192.168.88.200:8080/MJServer/video    // GET debugprint        let request = Alamofire.request(.GET, "http://192.168.88.200:8080/MJServer/video?type=JSON")        debugPrint(request)        // 打印输出 curl 信息        $ curl -i \            -H "User-Agent: SwiftAlamofire/com.qianqianstudio.SwiftAlamofire (1; OS Version 9.3 (Build 13E230))" \            -H "Accept-Language: zh-Hans-US;q=1.0, en-US;q=0.9" \            -H "Accept-Encoding: gzip;q=1.0, compress;q=0.5" \                "http://192.168.88.200:8080/MJServer/video?type=JSON"

8、Alamofire 网络连接状态检查

  • Swift

    网络连接状态:        public enum NetworkReachabilityStatus {            case Unknown            网络状态未知            case NotReachable       无网络连接            case Reachable(Alamofire.NetworkReachabilityManager.ConnectionType)        }        public enum ConnectionType {            case EthernetOrWiFi     WiFi 网络            case WWAN               无线网络(蜂窝移动网络)        }    let manager = NetworkReachabilityManager()    // 监听网络状态闭包    manager?.listener = { status in        /*            开启网络状态监听后,只要网络状态发生改变就会调用该闭包代码段。        */        print("Network Status Changed: \(status)")    }    // 开启监听网络状态    manager?.startListening()    // 关闭网络状态监听    manager?.stopListening()    // 获取网络连接状态    let status = manager?.networkReachabilityStatus    // 判断网络是否连接    let isReachable:Bool? = manager?.isReachable    // 判断 WiFi 是否连接    let isReachableOnEthernetOrWiFi:Bool? = manager?.isReachableOnEthernetOrWiFi    // 判断 无线网络 是否连接    let isReachableOnWWAN:Bool? = manager?.isReachableOnWWAN

9、Alamofire 异步 GET 数据请求

  • Swift

    // Alamofire 方式        let urlStr:URLStringConvertible = "http://192.168.88.200:8080/MJServer/video?type=XML"        Alamofire.request(.GET, urlStr)            .response { (request:NSURLRequest?, response:NSHTTPURLResponse?, responseData:NSData?, error:NSError?) in                /*                    网络请求结束,成功时 error == nil。请求返回的数据存在 responseData 中,为 NSData 格式。                */            }    // Manager 方式        // 必须设置为全局的        var alamofireManager: Manager!        let urlStr:URLStringConvertible = "http://192.168.88.200:8080/MJServer/video?type=XML"        self.alamofireManager = Manager(configuration: NSURLSessionConfiguration.defaultSessionConfiguration())        self.alamofireManager.request(.GET, urlStr)            .response { (request:NSURLRequest?, response:NSHTTPURLResponse?, responseData:NSData?, error:NSError?) in                /*                    网络请求结束,成功时 error == nil。请求返回的数据存在 responseData 中,为 NSData 格式。                */            }

10、Alamofire 文件下载

  • 支持的类型:

    • Request
    • Resume Data
  • 默认支持后台方式下载

  • Swift

    • 指定文件路径方式

      // 目标路径闭包展开    Alamofire.download(.GET, "http://120.25.226.186:32812/resources/videos/minion_01.mp4")                       { (temporaryURL:NSURL, response:NSHTTPURLResponse) -> NSURL in        /*                设置文件下载路径,temporaryURL 是沙盒下的文件临时存储路径,下载完成后会被自动删除。response.suggestedFilename             为服务器端文件名。此 block 在子线程中执行。        */        let documentsDirUrl:NSURL = NSFileManager.defaultManager()                                                 .URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask)[0]                                                 .URLByAppendingPathComponent(response.suggestedFilename!)        if NSFileManager.defaultManager().fileExistsAtPath(documentsDirUrl.path!) {            // 移除已经存在的文件,在 Swift 中文件已经存在时,再次相同路径写入会失败            try! NSFileManager.defaultManager().removeItemAtURL(documentsDirUrl)                        }           return documentsDirUrl    }        .progress { (bytesWrite:Int64, totalBytesWrite:Int64, totalBytesExpectedToWrite:Int64) in            /*                监听文件下载进度,此 block 在子线程中执行。            */            // 设置下载进度条             let progressNum:NSNumber = NSNumber(float: Float(Double(totalBytesWrite)/Double(totalBytesExpectedToWrite)))            self.performSelectorOnMainThread(#selector(ViewController.refreshProgress(_:)), withObject: progressNum, waitUntilDone: true)        }        .response { (_, _, _, error:NSError?) in            /*                网络请求结束,成功时 error == nil。在 Swift 中文件已经存在时,再次相同路径写入会失败。            */          }
    • 使用默认提供的下载路径方式

      // 目标路径闭包        // 设置文件的默认下载路径        let destination = Alamofire.Request.suggestedDownloadDestination(directory: .DocumentDirectory, domain: .UserDomainMask)        Alamofire.download(.GET, "http://120.25.226.186:32812/resources/videos/minion_01.mp4", destination: destination)            .progress { (bytesWrite:Int64, totalBytesWrite:Int64, totalBytesExpectedToWrite:Int64) in                /*                    监听文件下载进度,此 block 在子线程中执行。                */                // 设置下载进度条                let progressNum:NSNumber = NSNumber(float: Float(Double(totalBytesWrite)/Double(totalBytesExpectedToWrite)))                self.performSelectorOnMainThread(#selector(ViewController.refreshProgress(_:)),                                       withObject: progressNum,                                    waitUntilDone: true)            }            .response { (_, _, _, error:NSError?) in                /*                    网络请求结束,成功时 error == nil。在 Swift 中文件已经存在时,再次相同路径写入会失败。                */            }
    • 断点续传下载方式

      // 使用断点下载需要之前下载的临时文件存在,才能继续下载。    var downloadRequest:Request!    var resumeData:NSData!    // 开始下载        let resumeTmpPath = NSSearchPathForDirectoriesInDomains(.CachesDirectory, .UserDomainMask, true)[0] + "/resumeData.tmp"        // 判断断点保存的文件是否存在        if NSFileManager.defaultManager().fileExistsAtPath(resumeTmpPath) {            // 断点开始下载            // 读取断点保存的数据            self.resumeData = NSData(contentsOfFile: resumeTmpPath)            self.downloadRequest = Alamofire.download(resumeData: self.resumeData, destination:                                              { (temporaryURL:NSURL, response:NSHTTPURLResponse) -> NSURL in            let documentsDirUrl:NSURL = NSFileManager.defaultManager()                                                     .URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask)[0]                                                     .URLByAppendingPathComponent(response.suggestedFilename!)                                   if NSFileManager.defaultManager().fileExistsAtPath(documentsDirUrl.path!) {                    try! NSFileManager.defaultManager().removeItemAtURL(documentsDirUrl)                }                return documentsDirUrl            })            .progress { (bytesWrite:Int64, totalBytesWrite:Int64, totalBytesExpectedToWrite:Int64) in                let progressNum:NSNumber = NSNumber(float: Float(Double(totalBytesWrite)/Double(totalBytesExpectedToWrite)))                self.performSelectorOnMainThread(#selector(ViewController.refreshProgress(_:)),                                       withObject: progressNum,                                    waitUntilDone: true)                }                .response { (_, _, data:NSData?, error:NSError?) in                if error == nil {                    // 删除断点下载缓存文件                    let resumeTmpPath = NSSearchPathForDirectoriesInDomains(.CachesDirectory,                                                                             .UserDomainMask,                                                                             true)[0]                                                                           + "/resumeData.tmp"                    if NSFileManager.defaultManager().fileExistsAtPath(resumeTmpPath) {                        try! NSFileManager.defaultManager().removeItemAtPath(resumeTmpPath)                    }                } else {                    // 下载的临时文件不存在处理                    if error?.localizedFailureReason == "No such file or directory" {                            let resumeTmpPath = NSSearchPathForDirectoriesInDomains(.CachesDirectory,                                                                                     .UserDomainMask,                                                                                     true)[0]                                                                                  + "/resumeData.tmp"                            if NSFileManager.defaultManager().fileExistsAtPath(resumeTmpPath) {                                // 删除断点下载缓存文件,否则继续断点下载会报错                                try! NSFileManager.defaultManager().removeItemAtPath(resumeTmpPath)                            }                           }                    }                }        } else {            // 重新开始下载            self.resumeData = NSData()            self.downloadRequest = Alamofire.download(.GET, "http://120.25.226.186:32812/resources/videos/minion_01.mp4")                                                      { (temporaryURL:NSURL, response: NSHTTPURLResponse) -> NSURL in                let documentsDirUrl:NSURL = NSFileManager.defaultManager()                                                         .URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask)[0]                                                         .URLByAppendingPathComponent(response.suggestedFilename!)                    if NSFileManager.defaultManager().fileExistsAtPath(documentsDirUrl.path!) {                        try! NSFileManager.defaultManager().removeItemAtURL(documentsDirUrl)                    }                    return documentsDirUrl            }                .progress { (bytesWrite:Int64, totalBytesWrite:Int64, totalBytesExpectedToWrite:Int64) in                    let progressNum:NSNumber = NSNumber(float: Float(Double(totalBytesWrite)/Double(totalBytesExpectedToWrite)))                    self.performSelectorOnMainThread(#selector(ViewController.refreshProgress(_:)),                                           withObject: progressNum,                                        waitUntilDone: true)                }                .response { (_, _, data:NSData?, error:NSError?) in                    if error == nil {                    } else {                        // 停止下载处理                        if error!.code == NSURLErrorCancelled {                            if data != nil {                                // 意外终止的话,把已下载的数据储存起来                                self.resumeData = data                                let resumeTmpPath = NSSearchPathForDirectoriesInDomains(.CachesDirectory,                                                                                         .UserDomainMask,                                                                                         true)[0]                                                                                       + "/resumeData.tmp"                                self.resumeData.writeToFile(resumeTmpPath, atomically: true)                            }                        } else {                    }                }            }        }    // 暂停下载        self.downloadRequest.suspend()    // 继续下载        self.downloadRequest.resume()    // 停止下载        self.downloadRequest.cancel()

11、Alamofire 异步 POST 数据请求

  • Swift

    • Alamofire 方式

      let urlStr:URLStringConvertible = "http://192.168.88.200:8080/MJServer/video"    let parameters:[String: AnyObject]? = ["type":"XML"]    Alamofire.request(.POST, urlStr, parameters: parameters)        .response { (request:NSURLRequest?, response:NSHTTPURLResponse?, responseData:NSData?, error:NSError?) in            /*                网络请求结束,成功时 error == nil。请求返回的数据存在 responseData 中,为 NSData 格式。            */          }
    • Manager 方式

      // 必须设置为全局的    var alamofireManager: Manager!    let urlStr:URLStringConvertible = "http://192.168.88.200:8080/MJServer/video"    let parameters:[String: AnyObject]? = ["type":"XML"]    self.alamofireManager = Manager(configuration: NSURLSessionConfiguration.defaultSessionConfiguration())    self.alamofireManager.request(.POST, urlStr, parameters: parameters)        .response { (request:NSURLRequest?, response:NSHTTPURLResponse?, responseData:NSData?, error:NSError?) in            /*                网络请求结束,成功时 error == nil。请求返回的数据存在 responseData 中,为 NSData 格式。            */          }

12、Alamofire 文件上传

  • 支持的类型:

    • File
    • Data
    • Stream
    • MultipartFormData
  • Swift

    • Data 形式上传

      let boundary = "myBoundary"    // 设置请求头    /*        upload task 不会在请求头里添加 content-type (上传数据类型)字段,@"myBoundary" 为请求体边界,参数可以随便设置,但需一致    */    let headers = ["Content-Type":"multipart/form-data; charset=utf-8; boundary=\(boundary)"]    // 设置请求文件参数        let formBody = NSMutableData()        // 参数开始分割线        /*            每个参数开始前都需要加        */        formBody.appendData("--\(boundary)".dataUsingEncoding(NSUTF8StringEncoding)!)        formBody.appendData("\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)        // 参数        /*            username 是后台规定的参数名,jhq 是需要添加的参数内容值        */        formBody.appendData("Content-Disposition: form-data; name=\"\("username")\"\r\n\r\n\("jhq")"                .dataUsingEncoding(NSUTF8StringEncoding)!)        formBody.appendData("\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)        // 文件开始分割线        /*            每个文件开始前都需要加        */        formBody.appendData("--\(boundary)".dataUsingEncoding(NSUTF8StringEncoding)!)        formBody.appendData("\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)        // 文件参数名        /*            file 是后台规定的参数名,test.mp4 为上传后服务器端文件名称        */        formBody.appendData("Content-Disposition: form-data; name=\"\("file")\"; filename=\"\("test.mp4")\""                .dataUsingEncoding(NSUTF8StringEncoding)!)        formBody.appendData("\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)        // 文件的类型        formBody.appendData("Content-Type: mp4".dataUsingEncoding(NSUTF8StringEncoding)!)        formBody.appendData("\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)        formBody.appendData("\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)        // 待上传文件数据        /*            本地待上传的文件路径        */        formBody.appendData(NSData(contentsOfFile: NSBundle.mainBundle().pathForResource("minion", ofType: "mp4")!)!)        formBody.appendData("\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)        // 结束分割线标记        formBody.appendData("--\(boundary)--".dataUsingEncoding(NSUTF8StringEncoding)!)        formBody.appendData("\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)    Alamofire.upload(.POST, "http://192.168.88.200:8080/MJServer/upload", headers: headers, data: formBody)        .progress { (bytesLoad:Int64, totalBytesLoad:Int64, totalBytesExpectedToLoad:Int64) in            /*                监听文件上传进度,此 block 在子线程中执行。            */            let progressNum:NSNumber = NSNumber(float: Float(Double(totalBytesLoad)/Double(totalBytesExpectedToLoad)))            self.performSelectorOnMainThread(#selector(ViewController.refreshProgress(_:)), withObject: progressNum, waitUntilDone: true)        }        .response { (_, _, responseData:NSData?, error:NSError?) in            /*                网络请求结束。            */          }
    • MultipartFormData 形式上传

      Alamofire.upload(.POST, "http://192.168.88.200:8080/MJServer/upload",                             multipartFormData: { (formData:MultipartFormData) in        /*            添加参数。第一个参数是需要添加的参数内容值,第二个是后台规定的参数名。            设置上传的文件。第一个参数是需要上传的文件路径,第二个是后台规定的参数名,第三个是上传后服务器端文件名称,第四个是文件类型。        */        // 添加参数            formData.appendBodyPart(data: "jhq".dataUsingEncoding(NSUTF8StringEncoding)!, name: "username")        // 指定文件路径形式上传            let fileUrl = NSBundle.mainBundle().URLForResource("HQ_0005", withExtension: "jpg")!            formData.appendBodyPart(fileURL: fileUrl, name: "file", fileName: "test.png", mimeType: "image/jpeg")        // 指定文件数据形式上传            let fileData = NSData(contentsOfFile: NSBundle.mainBundle().pathForResource("minion", ofType: "mp4")!)            formData.appendBodyPart(data: fileData!, name: "file", fileName: "test.mp4", mimeType: "mp4")    }) { (encodingResult:Manager.MultipartFormDataEncodingResult) in        /*            数据编码完成。        */        switch encodingResult {            // 编码成功            case .Success(let uploadRequest, _, _):                uploadRequest                    .progress { (bytesLoad:Int64, totalBytesLoad:Int64, totalBytesExpectedToLoad:Int64) in                    /*                        监听文件上传进度,此 block 在子线程中执行。                    */                    let progressNum:NSNumber = NSNumber(float: Float(Double(totalBytesLoad)/Double(totalBytesExpectedToLoad)))                    self.performSelectorOnMainThread(#selector(ViewController.refreshProgress(_:)),                                           withObject: progressNum,                                        waitUntilDone: true)                }                .response { (_, _, responseData:NSData?, error:NSError?) in                    /*                        网络请求结束。                    */                  }            // 编码失败            case .Failure(let error):                print(error)        }    }

转载地址:http://xtxal.baihongyu.com/

你可能感兴趣的文章
PHP5中的stdClass
查看>>
IntelliJ IDEA Community Edition 14.1.4下使用 Apache-Subversion搭建代码管理环境
查看>>
四种可变交流swap方法
查看>>
Lucene中的 Query对象
查看>>
二分基础
查看>>
物流英语
查看>>
[iOS]iOS8可用的识别用户方式(idfa、UUID、idfv)
查看>>
hdu1507--二分图最大匹配
查看>>
【数据结构与算法】二叉树深度遍历(递归)
查看>>
iOS开发--基于AFNetWorking3.0的图片缓存分析
查看>>
使用jqMobi开发app基础:弹出内容的设计
查看>>
3.Java集合总结系列:Set接口及其实现
查看>>
ExtJs之Element.select函数
查看>>
驱动程序调试方法之printk——自制proc文件(一)
查看>>
Swift 可选类型-备
查看>>
使用开源软件的原因
查看>>
数据结构和算法 – 10.集合
查看>>
关于新版SDK报错You need to use a Theme.AppCompat theme的两种解决办法
查看>>
微信热门话题榜要上线了?腾讯微博的变身?
查看>>
Android 初阶自定义 View 字符头像
查看>>