使用 Alamofire 在 Swift 中调用 API?

Posted

技术标签:

【中文标题】使用 Alamofire 在 Swift 中调用 API?【英文标题】:Api Calling in Swift with Alamofire? 【发布时间】:2017-12-24 21:35:22 【问题描述】:

下面是我用于 API 调用的代码,这里有任何其他方法可以减少所有视图控制器的代码。我可以创建一个 alamofire API 调用的模型类吗?

 func ForgotPasswordServiceCall()  
    
    
    let params = [
        "email":EmailTextField.text!,
        ]
    
    let strUrl = "forgotPassword?"
    
    PKHUD.sharedHUD.contentView = PKHUDProgressView()
    PKHUD.sharedHUD.show()
    
    Alamofire.request(strUrl, method: .post, parameters: params, encoding: URLEncoding.httpBody)
        .responseJSON response in
            
            PKHUD.sharedHUD.hide()
            if((response.result.value) != nil)
            
                let swiftyJsonVar = JSON(response.result.value!)
                
                if let resData = swiftyJsonVar.dictionaryObject
                
                    
                    if(resData["status"] as! String == "success")
                    
                      //self.arrData = resData["result"] as! [[String:String]]
                      //self.arrData = resData["result"] as! [NSDictionary]
                     //cel.text=self.arrData[indexPath.row].object(forKey:""] 
                     //as! NSString)as String 
                    else
                    
                
            
            else
            
            
    

【问题讨论】:

“减少代码”是什么意思? 我不认为你可以让它更小,但如果你要从不同的视图控制器调用它,你可以创建一个调用的结构单例并为函数创建一个完成处理程序,然后从其他视图控制器调用它。 【参考方案1】:

您肯定可以为所有视图控制器减少代码 -

    创建一个处理所有 REST API 请求(GET、POST、PUT 等)的基类。 为 JSON 对象创建模型类。

让我给你一个例子 -

基类 -

class WebServiceHandler : NSObject 


override init() 
    // perform some initialization here




func processSingleRecord() -> Bool 
    return false


func getWebServiceUrl() -> String
    return ""

func DisplayNetworkAvailabilityMessage()-> String
    return "network failed"


func fetchDataFromWebServicePost<T: Mappable>(_ parameters: Dictionary<String , AnyObject>, closure:@escaping (_ response: T) -> Void) 

    let url = getWebServiceUrl()
     Alamofire.request(url, method: .post, parameters: parameters, headers: nil).responseJSON  (response:DataResponse<Any>) in
            print(response.request)  // original URL request
            print(response.response) // URL response
            //                print(response.data)     // server data
            print("Result",response.result)   // result of response serialization
            print("parameters = \(parameters)")
            if let JSON = response.result.value 
                print("JSON: \(JSON)")
            
            SVProgressHUD.dismiss()
            switch response.result 
            case .success(_):
                if response.response?.statusCode == 200 || response.response?.statusCode == 201 
                    var user = Mapper<T>().map(JSONObject: response.result.value)
                    if self.processSingleRecord() == true 
                        user = Mapper<T>().map(JSONObject: (response.result.value as! NSArray).object(at: 0))
                    
                    closure(user! )
                
                else if response.response?.statusCode == 0

                
                else  
                    if let _ = response.result.value as? Error 
                    
                
            case .failure(let error):
                debugPrint("getEvents error: \(error)")
                SVProgressHUD.dismiss()
            
        .responseString  response in
            //                print("Success: \(response.result.isSuccess)")
            //                print("Response String: \(response.result.value)")
    
 

单个 api 的模型类 -

    class DeviceTokenDataHandler : WebServiceHandler
  

    override func getWebServiceUrl() -> String
        return ApiLinks.sharedInstance.deviceTokenLink()
    

    override func DisplayNetworkAvailabilityMessage()-> String
        return "Check your internet connection"
        


定义所有 api 链接的 ApiLinks 类 -

import Foundation
class ApiLinks : NSObject 

    var prod = Bool()
    var dev = Bool()
    var httpPart = "http://"

    var localHost = "put your base url here"
    var prodHost = "put your base url here"


    var apiExtension = ""//".php" for php apisf
    var separater = "/"
    var host = String()

    static let sharedInstance = ApiLinks()

    //handle the dev or prod modes    
    func setTheProdStatus(_ prodVaule : Bool) 
        prod = prodVaule
        if(prod) 
            host = prodHost
         else 
            host = localHost
        
    

    let deviceToken = "updatedevicetoken" // your api name here
    func deviceTokenLink() -> String 
        return "\(httpPart)\(host)\(separater)\(deviceToken)\(apiExtension)"


响应模型类 -

    import ObjectMapper
import AlamofireObjectMapper
class DeviceTokenResponse: Mappable 
    var user_id: Int?
    var message: String?
    var status: String?
    required init?(map: Map)

    

    func mapping(map: Map) 
        user_id <- map["user_id"]
        message <- map["message"]
        status <- map["status"]
    

现在这就是你如何从 viewcontroller 调用 api -

func updateDeviceToken()         
        let anotherWebServiceHandler = DeviceTokenDataHandler.init()
        anotherWebServiceHandler.fetchDataFromWebServicePost(["app_type":"user" as AnyObject], closure:  (response:SignUpResponse) -> Void in
            print(response.message);
        )
    

【讨论】:

哇,这工作真有魅力,是的,我正在寻找这个模型类。

以上是关于使用 Alamofire 在 Swift 中调用 API?的主要内容,如果未能解决你的问题,请参考以下文章

Alamofire Swift 3.0 调用中的额外参数

将 Alamofire 调用包装到 Swift 中的自定义对象中?

如何使用参数 swift 3.0 Alamofire 4.0 调用邮政服务?

无法从 Alamofire 的 Swift 3 中的 Web 服务的 PATCH API 调用中获得响应

表视图数据未在 Alamofire 发布请求调用 swift 3 中显示

Swift 3.0 迁移后的 Alamofire 错误:“调用中的额外参数”(请求方法)