【问题标题】:How to parse JSON response from Alamofire API in Swift?如何在 Swift 中解析来自 Alamofire API 的 JSON 响应?
【发布时间】:2014-11-24 17:27:26
【问题描述】:

按照我编写的代码,我也收到了 JSON 格式的响应,但 JSON 的类型是“AnyObject”,我无法将其转换为数组以便我可以使用它。

Alamofire.request(.POST, "MY URL", parameters:parameters, encoding: .JSON) .responseJSON
{
    (request, response, JSON, error) in

    println(JSON?)
}

【问题讨论】:

  • 我没有否决您的问题,但我认为这是因为解析 JSON 的主题过于广泛,无法给出明确、直接的答案。试试这个名为 SwiftyJSON 的库。
  • @Isuru 没关系!我看过那个图书馆,但我正在使用 Alamofire!但是你能把你使用过 SwiftyJson 的示例代码发给我吗?那里的代码对我不起作用!
  • 我也使用 SwiftyJSON 和 Alamofire。我只是像这样let data = JSONValue(JSON!) 传递响应。然后我可以提取像data["Id"] 这样的值。 SwiftyJSON 文档提供了如何以所需类型检索这些值的示例。你到底得到了什么错误?

标签: ios json swift alamofire


【解决方案1】:

Swift 2.0 Alamofire 3.0 的答案实际上应该更像这样:

Alamofire.request(.POST, url, parameters: parameters, encoding:.JSON).responseJSON
{ response in switch response.result {
                case .Success(let JSON):
                    print("Success with JSON: \(JSON)")

                    let response = JSON as! NSDictionary

                    //example if there is an id
                    let userId = response.objectForKey("id")!

                case .Failure(let error):
                    print("Request failed with error: \(error)")
                }
    }

https://github.com/Alamofire/Alamofire/blob/master/Documentation/Alamofire%203.0%20Migration%20Guide.md

Alamofire 4.0 和 Swift 3.0 更新:

Alamofire.request(url, method: .post, parameters: parameters, encoding: JSONEncoding.default)
            .responseJSON { response in
                print(response)
//to get status code
                if let status = response.response?.statusCode {
                    switch(status){
                    case 201:
                        print("example success")
                    default:
                        print("error with response status: \(status)")
                    }
                }
//to get JSON return value
            if let result = response.result.value {
                let JSON = result as! NSDictionary
                print(JSON)
            }

        }

【讨论】:

  • 如何获得 JSON 的实际内容?这是什么类型的物体?设计和文档非常模糊,我无法弄清楚,也无法在互联网上找到任何示例......
  • 我在答案中添加了几行应该有帮助的内容。
  • @JosephGeraghty 具有编码参数会导致编译器告诉我有一个额外的参数调用...知道吗?
  • @jch-duran 不积极,但我隐约记得不久前遇到过类似的事情。我认为这与库未更新或可能与 swift 版本不同步有关。确保您使用的是最新版本可能会有所帮助
  • @AlexWorden 同意,这个页面帮助我回答了这些问题并提供了一个很好的解决方案:github.com/SwiftyJSON/SwiftyJSON
【解决方案2】:

如上所述,您可以使用 SwiftyJSON 库并像我在下面所做的那样获取您的值

Alamofire.request(.POST, "MY URL", parameters:parameters, encoding: .JSON) .responseJSON
{
    (request, response, data, error) in

var json = JSON(data: data!)

       println(json)   
       println(json["productList"][1])                 

}

我的 json 产品列表从脚本返回

{ "productList" :[

{"productName" : "PIZZA","id" : "1","productRate" : "120.00","productDescription" : "PIZZA AT 120Rs","productImage" : "uploads\/pizza.jpeg"},

{"productName" : "BURGER","id" : "2","productRate" : "100.00","productDescription" : "BURGER AT Rs 100","productImage" : "uploads/Burgers.jpg"}    
  ]
}

输出:

{
  "productName" : "BURGER",
  "id" : "2",
  "productRate" : "100.00",
  "productDescription" : "BURGER AT Rs 100",
  "productImage" : "uploads/Burgers.jpg"
}

【讨论】:

  • 我在安装后尝试使用 SwiftyJson 的东西,但在 SwiftyJson 文件中出现了大约 300 个错误,有人遇到过这个问题吗? i',使用 Xcode 6.2 版、ios 8.1 版、cocoaPods 36,如 [github] (github.com/SwiftyJSON/SwiftyJSON) 文档中所述。
  • 老兄。有哪些错误?问一个单独的问题并提供一些细节。 SwiftyJSON 就像魔法一样美丽。尽可能使用它。
  • 确实应该将 json 字符串转换为具体的 swift 对象,以便您可以以自然的方式干净地使用它。通过字符串名称访问字段是荒谬的并且容易出错。
【解决方案3】:

Swift 3、Alamofire 4.4 和 SwiftyJSON:

Alamofire.request(url, method: .get)
  .responseJSON { response in
      if response.data != nil {
        let json = JSON(data: response.data!)
        let name = json["people"][0]["name"].string
        if name != nil {
          print(name!)
        }
      }
  }

这将解析这个 JSON 输入:

{
  people: [
    { name: 'John' },
    { name: 'Dave' }
  ]
}

【讨论】:

【解决方案4】:

我在 GitHub 上找到了 Swift2

的答案

https://github.com/Alamofire/Alamofire/issues/641

Alamofire.request(.GET, URLString, parameters: ["foo": "bar"])
    .responseJSON { request, response, result in
        switch result {
        case .Success(let JSON):
            print("Success with JSON: \(JSON)")

        case .Failure(let data, let error):
            print("Request failed with error: \(error)")

            if let data = data {
                print("Response data: \(NSString(data: data, encoding: NSUTF8StringEncoding)!)")
            }
        }
    }

【讨论】:

  • 这是 Swift 2.0 + Alamofire JSON 解析的正确版本。
  • 嗯,我仍然无法构建错误消息:'(_, _, _) -> Void' 不能转换为 'Response -> Void'
  • @alex 请参阅this answer 了解我用来解决它的方法。
  • 非常感谢!你不知道我尝试了多少东西来正确显示来自服务器的响应消息,救命恩人!
【解决方案5】:

我既不是 JSON 专家也不是 Swift 专家,但以下内容对我有用。 :) 我已经从我当前的应用程序中提取了代码,并且只将“MyLog 更改为 println”,并用空格缩进以使其显示为代码块(希望我没有破坏它)。

func getServerCourseVersion(){

    Alamofire.request(.GET,"\(PUBLIC_URL)/vtcver.php")
        .responseJSON { (_,_, JSON, _) in
          if let jsonResult = JSON as? Array<Dictionary<String,String>> {
            let courseName = jsonResult[0]["courseName"]
            let courseVersion = jsonResult[0]["courseVersion"]
            let courseZipFile = jsonResult[0]["courseZipFile"]

            println("JSON:    courseName: \(courseName)")
            println("JSON: courseVersion: \(courseVersion)")
            println("JSON: courseZipFile: \(courseZipFile)")

          }
      }
}

希望这会有所帮助。

编辑:

作为参考,这是我的 PHP 脚本返回的内容:

[{"courseName": "Training Title","courseVersion": "1.01","courseZipFile": "101/files.zip"}]

【讨论】:

  • 这应该是选择的答案,尽管您可能想要更新它,因为 Alamofire 已经稍微更新了他们的方法
【解决方案6】:

斯威夫特 5

class User: Decodable {

    var name: String
    var email: String
    var token: String

    enum CodingKeys: String, CodingKey {
        case name
        case email
        case token
    }

    public required init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        self.name = try container.decode(String.self, forKey: .name)
        self.email = try container.decode(String.self, forKey: .email)
        self.token = try container.decode(String.self, forKey: .token)
    }
}

Alamofire API

    Alamofire.request("url.endpoint/path", method: .get, parameters: params, encoding: URLEncoding.queryString, headers: nil)
     .validate()
     .responseJSON { response in

        switch (response.result) {

            case .success( _):

            do {
                let users = try JSONDecoder().decode([User].self, from: response.data!)
                print(users)

            } catch let error as NSError {
                print("Failed to load: \(error.localizedDescription)")
            }

             case .failure(let error):
                print("Request error: \(error.localizedDescription)")
         }

【讨论】:

  • 如果您有Decodable 类型,您应该使用responseDecodable,而不是responseJSON
【解决方案7】:

斯威夫特 3

pod 'Alamofire', '~> 4.4'
pod 'SwiftyJSON'

File json format:
{
    "codeAd": {
        "dateExpire": "2017/12/11",
        "codeRemoveAd":"1231243134"
        }
}

import Alamofire
import SwiftyJSON
    private func downloadJson() {
        Alamofire.request("https://yourlinkdownloadjson/abc").responseJSON { response in
            debugPrint(response)

            if let json = response.data {
                let data = JSON(data: json)
                print("data\(data["codeAd"]["dateExpire"])")
                print("data\(data["codeAd"]["codeRemoveAd"])")
            }
        }
    }

【讨论】:

    【解决方案8】:

    这是使用 Xcode 10.1 和 Swift 4 构建的

    “Alamofire”(4.8.1) 和“SwiftyJSON”(4.2.0) 的完美组合。首先你应该安装两个 pod

    pod 'Alamofire'pod 'SwiftyJSON'

    JSON 格式的服务器响应:

    {
      "args": {}, 
      "headers": {
        "Accept": "*/*", 
        "Accept-Encoding": "gzip;q=1.0, compress;q=0.5", 
        "Accept-Language": "en;q=1.0", 
        "Host": "httpbin.org", 
        "User-Agent": "AlamoFire TEST/1.0 (com.ighost.AlamoFire-TEST; build:1; iOS 12.1.0) Alamofire/4.8.1"
      }, 
      "origin": "200.55.140.181, 200.55.140.181", 
      "url": "https://httpbin.org/get"
    }
    

    在这种情况下,我想打印“主机”信息:“主机”:“httpbin.org”

    Alamofire.request("https://httpbin.org/get").validate().responseJSON { response in
            switch response.result {
            case .success:
                print("Validation Successful)")
    
                if let json = response.data {
                    do{
                        let data = try JSON(data: json)
                        let str = data["headers"]["Host"]
                        print("DATA PARSED: \(str)")
                    }
                    catch{
                    print("JSON Error")
                    }
    
                }
            case .failure(let error):
                print(error)
            }
        }
    

    保持冷静和快乐的代码?

    【讨论】:

    • 谢谢。我已经使用并重新格式化以适应我的项目需求,我可以保证这仍然适用于 Swift 5。
    【解决方案9】:

    我找到了一种将 response.result.value(在 Alamofire responseJSON 闭包内)转换为我在我的应用程序中使用的 JSON 格式的方法。

    我正在使用 Alamofire 3 和 Swift 2.2。

    这是我使用的代码:

        Alamofire.request(.POST, requestString,
                          parameters: parameters,
                          encoding: .JSON,
                          headers: headers).validate(statusCode: 200..<303)
                                           .validate(contentType: ["application/json"])
                                           .responseJSON { (response) in
            NSLog("response = \(response)")
    
            switch response.result {
            case .Success:
                guard let resultValue = response.result.value else {
                    NSLog("Result value in response is nil")
                    completionHandler(response: nil)
                    return
                }
    
                let responseJSON = JSON(resultValue)
    
                // I do any processing this function needs to do with the JSON here
    
                // Here I call a completionHandler I wrote for the success case
            break
            case .Failure(let error):
                NSLog("Error result: \(error)")
                // Here I call a completionHandler I wrote for the failure case
                return
            }
    

    【讨论】:

      【解决方案10】:

      我通常在 iOS 中使用Gloss 库来序列化或反序列化 JSON。例如,我有如下所示的 JSON:

      {"ABDC":[{"AB":"qwerty","CD":"uiop"}],[{"AB":"12334","CD":"asdf"}]}
      

      首先,我在 Gloss 结构中对 JSON 数组进行建模:

      Struct Struct_Name: Decodable {
         let IJ: String?
         let KL: String?
         init?(json: JSON){
             self.IJ = "AB" <~~ json
             self.KL = "CD" <~~ json
         }
      }
      

      然后在 Alamofire responseJSON 中,我执行以下操作:

      Alamofire.request(url, method: .get, paramters: parametersURL).validate(contentType: ["application/json"]).responseJSON{ response in
       switch response.result{
         case .success (let data):
          guard let value = data as? JSON,
             let eventsArrayJSON = value["ABDC"] as? [JSON]
          else { fatalError() }
          let struct_name = [Struct_Name].from(jsonArray: eventsArrayJSON)//the JSON deserialization is done here, after this line you can do anything with your JSON
          for i in 0 ..< Int((struct_name?.count)!) {
             print((struct_name?[i].IJ!)!)
             print((struct_name?[i].KL!)!)
          }
          break
      
         case .failure(let error):
          print("Error: \(error)")
          break
       }
      }
      

      上面代码的输出:

      qwerty
      uiop
      1234
      asdf
      

      【讨论】:

        【解决方案11】:

        在 swift 5 中,我们确实喜欢使用 typealias 来完成。 Typlealias 只是用来清理代码而已。

        typealias response = (Bool,Any?)->()
        
        
        static func postCall(_ url : String, param : [String : Any],completion : @escaping response){
            Alamofire.request(url, method: .post, parameters: param, encoding: JSONEncoding.default, headers: [:]).responseJSON { (response) in
        
                switch response.result {
                   case .success(let JSON):
                       print("\n\n Success value and JSON: \(JSON)")
        
                   case .failure(let error):
                       print("\n\n Request failed with error: \(error)")
        
                   }
            }
        }
        

        【讨论】:

          【解决方案12】:

          简单的答案是让 AlamoFire 直接进行解码。

          令人惊讶的是,您没有使用 .responseJSON,因为它返回一个无类型的 json 对象

          相反,您将对象设为可解码 - 并要求 AF 直接对它们进行解码

          我的 json 响应包含一个 Account 对象数组。我只关心 id 和 name 键(虽然还有更多)

          struct Account:Codable {
              let id:Int
              let name:String
          }
          

          那么简单

              AF.request(url,
                         method: .get)
                  .responseDecodable(of:[Account].self) { response in
                      switch response.result {
                      case .success:
                          switch response.response?.statusCode {
                          case 200:
                              //response.value is of type [Account]
                          default:
                              //handle other cases
                          }
                      case let .failure(error):
                          //probably the decoding failed because your json doesn't match the expected format
                      }
                  }
          

          【讨论】:

            【解决方案13】:
            let semaphore = DispatchSemaphore (value: 0)
            
                    var request = URLRequest(url: URL(string: Constant.localBaseurl2 + "compID")!,timeoutInterval: Double.infinity)
                                        request.httpMethod = "GET"
                                        let task = URLSession.shared.dataTask(with: request) { data, response, error in
                                            if let response = response {
                                            let nsHTTPResponse = response as! HTTPURLResponse
                                            print(nsHTTPResponse)
                                                      
                                            }
                                            if let error = error {
                                            print ("\(error)")
                                                return
                                             }
                                            
                                            if let data = data {
                                                DispatchQueue.main.async {
                                                    
                                                    let decoder = JSONDecoder()
                                                    decoder.keyDecodingStrategy = .convertFromSnakeCase//or any other Decoder\
                                                    
                                                    do{
                                                        
                                                        let jsonDecoder = JSONDecoder()
                                                        let memberRecord = try jsonDecoder.decode(COMPLAINTSVC.GetComplaints.self, from: data)
                                                        print(memberRecord.message)
                                                     
                                                        for detailData in memberRecord.message{
                                                            print(detailData)
                                                            
                                                            
                                                            
                                                            
                                                        
                                                        }
                                                        
                                                        
                                                        
                                                    }catch{
                                                        
                                                        print(error.localizedDescription)
                                                    }
                                                    
                                                  
                                                    
                                                }
                                         
                                            }
                                          
                                          semaphore.signal()
                                        }
            
                                        task.resume()
                                        semaphore.wait()
            

            }

            【讨论】:

            • OP 询问的是 Alamofire,而不是 URLRequest,所以这是题外话。此外,您的答案包含不相关的元素,似乎只是从现有代码库中随机复制的。请编辑并使其具体到这个问题。谢谢。
            【解决方案14】:
             pod 'Alamofire'
             pod 'SwiftyJSON'
             pod 'ReachabilitySwift'
            
            
            
            import UIKit
            import Alamofire
            import SwiftyJSON
            import SystemConfiguration
            
            class WebServiceHelper: NSObject {
            
                typealias SuccessHandler = (JSON) -> Void
                typealias FailureHandler = (Error) -> Void
            
                // MARK: - Internet Connectivity
            
                class func isConnectedToNetwork() -> Bool {
            
                    var zeroAddress = sockaddr_in()
                    zeroAddress.sin_len = UInt8(MemoryLayout<sockaddr_in>.size)
                    zeroAddress.sin_family = sa_family_t(AF_INET)
            
                    guard let defaultRouteReachability = withUnsafePointer(to: &zeroAddress, {
                        $0.withMemoryRebound(to: sockaddr.self, capacity: 1) {
                            SCNetworkReachabilityCreateWithAddress(nil, $0)
                        }
                    }) else {
                        return false
                    }
            
                    var flags: SCNetworkReachabilityFlags = []
                    if !SCNetworkReachabilityGetFlags(defaultRouteReachability, &flags) {
                        return false
                    }
            
                    let isReachable = flags.contains(.reachable)
                    let needsConnection = flags.contains(.connectionRequired)
            
                    return (isReachable && !needsConnection)
                }
            
                // MARK: - Helper Methods
            
                class func getWebServiceCall(_ strURL : String, isShowLoader : Bool, success : @escaping SuccessHandler, failure : @escaping FailureHandler)
                {
                    if isConnectedToNetwork() {
            
                        print(strURL)
            
                        if isShowLoader == true {
            
                            AppDelegate.getDelegate().showLoader()
                        }
            
                        Alamofire.request(strURL).responseJSON { (resObj) -> Void in
            
                            print(resObj)
            
                            if resObj.result.isSuccess {
                                let resJson = JSON(resObj.result.value!)
            
                                if isShowLoader == true {
                                    AppDelegate.getDelegate().dismissLoader()
                                }
            
                                debugPrint(resJson)
                                success(resJson)
                            }
                            if resObj.result.isFailure {
                                let error : Error = resObj.result.error!
            
                                if isShowLoader == true {
                                    AppDelegate.getDelegate().dismissLoader()
                                }
                                debugPrint(error)
                                failure(error)
                            }
                        }
                    }else {
            
            
                        CommonMethods.showAlertWithError("", strMessage: Messages.NO_NETWORK, withTarget: (AppDelegate.getDelegate().window!.rootViewController)!)
                    }
                }
            
                class func getWebServiceCall(_ strURL : String, params : [String : AnyObject]?, isShowLoader : Bool, success : @escaping SuccessHandler,  failure :@escaping FailureHandler){
                    if isConnectedToNetwork() {
            
                        if isShowLoader == true {
                            AppDelegate.getDelegate().showLoader()
                        }
            
            
                        Alamofire.request(strURL, method: .get, parameters: params, encoding: JSONEncoding.default, headers: nil).responseJSON(completionHandler: {(resObj) -> Void in
            
                            print(resObj)
            
                            if resObj.result.isSuccess {
                                let resJson = JSON(resObj.result.value!)
            
                                if isShowLoader == true {
                                    AppDelegate.getDelegate().dismissLoader()
                                }
            
                                success(resJson)
                            }
                            if resObj.result.isFailure {
                                let error : Error = resObj.result.error!
            
                                if isShowLoader == true {
                                    AppDelegate.getDelegate().dismissLoader()
                                }
            
                                failure(error)
                            }
            
                        })
                    }
                else {
            
                        CommonMethods.showAlertWithError("", strMessage: Messages.NO_NETWORK, withTarget: (AppDelegate.getDelegate().window!.rootViewController)!)
                }
            
                }
            
            
            
                class func postWebServiceCall(_ strURL : String, params : [String : AnyObject]?, isShowLoader : Bool, success : @escaping SuccessHandler, failure :@escaping FailureHandler)
                {
                    if isConnectedToNetwork()
                    {
            
                        if isShowLoader == true
                        {
                            AppDelegate.getDelegate().showLoader()
                        }
            
                        Alamofire.request(strURL, method: .post, parameters: params, encoding: JSONEncoding.default, headers: nil).responseJSON(completionHandler: {(resObj) -> Void in
            
                            print(resObj)
            
                            if resObj.result.isSuccess
                            {
                                let resJson = JSON(resObj.result.value!)
            
                                if isShowLoader == true
                                {
                                    AppDelegate.getDelegate().dismissLoader()
                                }
            
                                success(resJson)
                            }
            
                            if resObj.result.isFailure
                            {
                                let error : Error = resObj.result.error!
            
                                if isShowLoader == true
                                {
                                    AppDelegate.getDelegate().dismissLoader()
                                }
            
                                failure(error)
                            }
                        })
                    }else {
                        CommonMethods.showAlertWithError("", strMessage: Messages.NO_NETWORK, withTarget: (AppDelegate.getDelegate().window!.rootViewController)!)
                    }
                }
            
            
                class func postWebServiceCallWithImage(_ strURL : String, image : UIImage!, strImageParam : String, params : [String : AnyObject]?, isShowLoader : Bool, success : @escaping SuccessHandler, failure : @escaping FailureHandler)
                {
                    if isConnectedToNetwork() {
                        if isShowLoader == true
                        {
                            AppDelegate.getDelegate().showLoader()
                        }
            
                        Alamofire.upload(
                            multipartFormData: { multipartFormData in
                                if let imageData = UIImageJPEGRepresentation(image, 0.5) {
                                    multipartFormData.append(imageData, withName: "Image.jpg")
                                }
            
                                for (key, value) in params! {
            
                                    let data = value as! String
            
                                    multipartFormData.append(data.data(using: String.Encoding.utf8)!, withName: key)
                                    print(multipartFormData)
                                }
                            },
                            to: strURL,
                            encodingCompletion: { encodingResult in
                                switch encodingResult {
                                case .success(let upload, _, _):
                                    upload.responseJSON { response in
                                        debugPrint(response)
                                        //let datastring = String(data: response, encoding: String.Encoding.utf8)
                                       // print(datastring)
                                    }
                                case .failure(let encodingError):
                                    print(encodingError)
                                    if isShowLoader == true
                                    {
                                        AppDelegate.getDelegate().dismissLoader()
                                    }
            
                                    let error : NSError = encodingError as NSError
                                    failure(error)
                                }
            
                                switch encodingResult {
                                case .success(let upload, _, _):
                                    upload.responseJSON { (response) -> Void in
            
                                        if response.result.isSuccess
                                        {
                                            let resJson = JSON(response.result.value!)
            
                                            if isShowLoader == true
                                            {
                                                AppDelegate.getDelegate().dismissLoader()
                                            }
            
                                            success(resJson)
                                        }
            
                                        if response.result.isFailure
                                        {
                                            let error : Error = response.result.error! as Error
            
                                            if isShowLoader == true
                                            {
                                                AppDelegate.getDelegate().dismissLoader()
                                            }
            
                                            failure(error)
                                        }
            
                                    }
                                case .failure(let encodingError):
                                    if isShowLoader == true
                                    {
                                        AppDelegate.getDelegate().dismissLoader()
                                    }
            
                                    let error : NSError = encodingError as NSError
                                    failure(error)
                                }
                            }
                        )
                    }
                    else
                    {
                        CommonMethods.showAlertWithError("", strMessage: Messages.NO_NETWORK, withTarget: (AppDelegate.getDelegate().window!.rootViewController)!)
                    }
                }
            
            }
            
            
            ==================================
            
            
            Call Method
            
            
            let aParams : [String : String] = [
                            "ReqCode" : Constants.kRequestCodeLogin,
                            ]
            
                        WebServiceHelper.postWebServiceCall(Constants.BaseURL, params: aParams as [String : AnyObject]?, isShowLoader: true, success: { (responceObj) in
            
            
                            if "\(responceObj["RespCode"])" != "1"
                            {
                                let alert = UIAlertController(title: Constants.kAppName, message: "\(responceObj["RespMsg"])", preferredStyle: UIAlertControllerStyle.alert)
                                let OKAction = UIAlertAction(title: "OK", style: .default) { (action:UIAlertAction!) in
                                }
                                alert.addAction(OKAction)
                                self.present(alert, animated: true, completion: nil)
                            }
                            else
                            {
                                let aParams : [String : String] = [
                                    "Password" : self.dictAddLogin[AddLoginConstants.kPassword]!,
                                    ]
                                CommonMethods.saveCustomObject(aParams as AnyObject?, key: Constants.kLoginData)
            
                            }
                            }, failure:
                            { (error) in
            
                                CommonMethods.showAlertWithError(Constants.kALERT_TITLE_Error, strMessage: error.localizedDescription,withTarget: (AppDelegate.getDelegate().window!.rootViewController)!)
                        })
                    }
            

            【讨论】:

            • 对所有这些代码的解释会很有帮助。
            猜你喜欢
            • 1970-01-01
            • 2021-08-10
            • 2021-07-22
            • 1970-01-01
            • 1970-01-01
            • 2016-07-12
            • 2020-08-26
            • 1970-01-01
            相关资源
            最近更新 更多