Swift Alamofire简单使用

SPM依赖

https://github.com/Alamofire/Alamofire

GET请求

在某些特殊情况下需要做无参无处理的请求,那么其使用就十分简单:

Alamofire.AF.request("https://ww.baidu.com")

当然有时候可能附加参数:

Alamofire.AF.request("https://ww.baidu.com", parameters: ["id":"2014"])

正常状态下是这样的:
(注意GET请求尽量不要拼接url,一方面是url太长太繁琐后期修改十分麻烦,另一方面是get的url参数不支持中文编码,springboot后端环境)

func getRequest(){
    let url = "http://www.baidu.com"
    Alamofire.AF.request(url).responseJSON { (response) in
        switch response.result {
        case .success(let json):
            print(json)
            // Success in request and do a async or sync(NOT UI) task here.
            break
        case .failure(let error):
            print("error:\(error)")
            break
        }
    }
}

说明:老版本的Alamofire写法似乎不兼容,新版本需要在Alamofire后面加上".AF",即Alamofire.AF.request()。闭包里面捕获返回的数据。成功请求和失败请求均各有一种情况,在各个情况里面判断即可。

POST请求

func postRequest(){
    let url = "http://test.shop.com/user?login"
    Alamofire.AF.request(url, method: .post, parameters: ["name":"jack","password":"123456"]).responseJSON { (response) in
        switch response.result {
        case .success(let json):
            print(json)
            break
        case .failure(let error):
            print("error:\(error)")
            break
        }
    }
}

说明:写法和闭包及返回类型与GET一样。不同的是POST请求多了键值对,request()这个方法第三个参数可以看出,数组里面存放的就是。

判断网络状态:

Alamofire自带网络状态判断类,这个方法只能调用一次进行判断。

        let networker = NetworkReachabilityManager(host: "https://ww.baidu.com")
        networker?.startListening() { status in
            print("------> NETWORK STATUS: \(status)")
            if status == .reachable(.ethernetOrWiFi) {
                print("------> WIFI")
            } else if status == .reachable(.cellular) {
                print("------> CELLULAR")
            } else if status == .notReachable {
                print("------> ANAVIABLE NETWORK")
            } else {
                print("------> UNKNOWN")
            }

上传

上传支持的类型包括File、Data、Stream、MultipartFormData。

Stream类型:

        let fileURL = Bundle.main.url(forResource: "tylor", withExtension: "zip")
         
        Alamofire.AF.upload(fileURL!, to: "http://test.com/upload")
            .uploadProgress { progress in // UI Thread.
     		    print("------> CURRENT PROG: \(progress.fractionCompleted)")
        }
            .responseJSON { response in
                debugPrint(response)
        }

工具类

这里定义了一个简单的工具类,可以直接调用该类进行访问。

结构体里面是两种常用的请求方式,是为get和post。请求结束后该方法会自动将结果回调出去。

import Foundation
import Alamofire
import UIKit

enum MethodType {
    case get
    case post
}

class AlamofireUtil{
    class func requestData(_ type : MethodType, URLString : String, parameters : [String : Any]? = nil, finishedCallback :  @escaping (_ result : Any) -> ()) {
        
        let method = type == .get ? HTTPMethod.get : HTTPMethod.post
        
        Alamofire.AF.request(URLString, method: method, parameters: parameters).responseJSON { (response) in
               
            switch response.result {
            case .success(let json):
                finishedCallback(json)
                break
            case .failure(let error):
                print("error:\(error)")
                break
            }
            
        }
    }
}

使用:

            AlamofireUtil.requestData(.get, URLString: "\(URLManager.getURL(type: "login"))\(loginView.accountTextField.text!)/\(loginView.passwordTextField.text!)") { result in
                let jsonData = JSON(result)
                // JSON数据解析并更新UI
            }

封装

自己的小示例用上述写法没任何文通,然而有时需要对第三方库进行封装以减少这些库对项目的侵入性,使用Protocol与闭包是个很好的选择。
Protocol

import Foundation
import SwiftyJSON

protocol NetworkUtil {
    static func postRequest(URLString: String, parameters : [String : Any]?, callback: @escaping (_ result: Any) -> ())
    static func getRequest(URLString: String, parameters : [String : Any]?,callback: @escaping (_ result: Any) -> ())
}

AlamofireLayer

import Foundation
import Alamofire

enum MethodType {
    case get
    case post
}

class AlamofireLayer{
    class func requestData(_ type : MethodType, URLString : String, parameters : [String : Any]? = nil, finishedCallback :  @escaping (_ result : Any) -> ()) {
        
        let method = type == .get ? HTTPMethod.get : HTTPMethod.post
        
        Alamofire.AF.request(URLString, method: method, parameters: parameters).responseJSON { (response) in
            switch response.result {
            case .success(let json):
                finishedCallback(json)
                break
            case .failure(let error):
                print("error:\(error)")
                break
            }
        }
    }

}

Impl

import Foundation
import SwiftyJSON

class NetworkImpl: NetworkUtil{
    
    static func getRequest(URLString: String, parameters: [String : Any]?, callback: @escaping (Any) -> ()) {
        AlamofireLayer.requestData(MethodType.get, URLString: URLString, parameters: parameters) { result in
            callback(result)
        }
    }
    
    public static func postRequest(URLString: String, parameters: [String : Any]?, callback: @escaping (Any) -> ()) {
        AlamofireLayer.requestData(MethodType.post, URLString: URLString, parameters: parameters) { result in
            callback(result)
        }
    }
  
}

使用

        NetworkImpl.getRequest(URLString: "http:example.com", parameters: ["id": requestTrackId!]) { (response) in
            let jsonData = JSON(response)
            
            print("------> RAW DATA:\(jsonData)")

        }

这样以来,每次调用时就是用接口,底层网络请求框架改变时只需改变底层与实现层即可,做到了“避免牵一发而动全身”这种效果。

后记:如何回到主线程?

Alamofire的request是在子线程里面的,但请求结果是回到了主线程,也就是说,可以在数据解析后直接进行UI更新。

你可能感兴趣的:(iOS,http,ios,swift,xcode)