如何在 Swift 3 中使用 Alamofire 4 解析这个 json?

Posted

技术标签:

【中文标题】如何在 Swift 3 中使用 Alamofire 4 解析这个 json?【英文标题】:How to parse this json with Alamofire 4 in Swift 3? 【发布时间】:2016-12-20 16:02:40 【问题描述】:

我有下面的 json,但无法弄清楚如何在 Swift 3 中解析它。我的代码在下面。 API 中的 json 有一个数组根。我将 Xcode 8.2.1 与 Swift 4 和 Alamofire 4.0 一起使用。

["items": <__NSArrayM 0x608000248af0>(

    currency = USD;
    image = "https://cdn.myDomain.com/image.jpg";
    "item_title" = "Antique Table";
    "name:" = "";
    price = 675;
,

    currency = USD;
    image = "https://cdn.mydomain.com/image2.jpg";
    "name:" = "";
    price = 950;
...

这是我的代码。我试图从结果中获取一个数组 r 字典,但它总是为零。

Alamofire.request(myURL)
    .responseJSON(completionHandler: 
        response in
        self.parseData(JSONData: response.data!)
    )


func parseData(JSONData: Data) 

    do 
        let readableJSON = try JSONSerialization.jsonObject(with: JSONData, options:.mutableContainers) as! [String: Any] 
        print(readableJSON)               
    
    catch 
     print(error)
    

我已经按照建议的here 尝试了这个let item = readableJSON["items"] as? [[String: Any]],但它不会编译并出现错误[String:Any] has no subscriptlet item = readableJSON["items"] as? [String: Any]! 编译时出现警告Expression implicitly coerced from string 但产生零。解析这个 json 对我来说是生死攸关的事情。

【问题讨论】:

研究这个:developer.apple.com/swift/blog/?id=37 我读到了,也许我只是愚蠢,但我找不到与我匹配的 json 模式,两天后我来到了这里。 这里有一个提示(实际上几乎是一个完整的解决方案):“items”是一个包含数组的字典。该数组包含字典。 // 结束,完成。 我确实明白了很多,但仍然不足以让我找出有效的代码。我几乎记住了你链接的页面。 其中许多示例和我正在处理的项目使用 NSDictionary 但我想使用 [String: Any] 【参考方案1】:

做类似的事情

let responseJSON = response.result.value as! [String:AnyObject]

那么您将能够像这样访问该字典中的元素:

let infoElementString = responseJSON["infoElement"] as! String

【讨论】:

我尝试过使用“index”或“price”但得到错误Could not cast value of type '__NSArrayM' (0x10c60ddb0) to 'NSString' (0x10bc14c40) 啊,好吧,听起来你需要将你的演员阵容与你的类型相匹配。【参考方案2】:

这是我最终想出的解析 json 函数。这个 json 数据的问题在于它是一个数组内的字典。我是菜鸟,我看到的大多数答案和方法都不适合我的 json 数据。这是我最终想出的功能。

var myItems = [[String:Any]]()

然后在我的视图控制器类中

func loadMyItems() 

    Alamofire.request(myItemsURL)
        .responseJSON(completionHandler: 
            response in                
            self.parseData(JSONData: response.data!)

            self.collectionView.reloadData()                
        )


func parseData(JSONData: Data)         
        do                 
            let readableJSON = try JSONSerialization.jsonObject(with: JSONData, options:.allowFragments) as! [String: Any]

            let items = readableJSON["items"] as! [[String: Any]]

            self.myItems = items

                
        catch 
         print(error)
        



func collectionView(_ collectionView: UICollectionView,
                    cellForItemAt indexPath: IndexPath) -> UICollectionViewCell 

    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "myCell", for: indexPath) as? myCell

    let dictionary = myItems[indexPath.row] as [String:Any]
    if let item_title = dictionary["item_title"] as? String 
        cell!.textLabel.text = item_title
        print(item_title)
    

    return cell!

【讨论】:

【参考方案3】:

Swift 3 中的 Alamofire 示例

1.首先在你的项目中使用两个cocoapods。使用SwiftyJSON进行json解析

pod 'Alamofire'
pod 'SwiftyJSON'

    我的 Json 在下面

    "loginNodes":["errorMessage":"Welcome To Alamofire","name":Enamul Haque,"errorCode":"0","photo":null]

    它可以以不同的方式完成。但是我已经完成了以下方式。请注意,如果您不需要任何参数来发送服务器,请删除参数选项。它可以工作 post 或 get 方法。你可以使用任何方式。我的 Alamofire 代码在下面......这对我来说很好......

            Alamofire.request("http://era.com.bd/UserSignInSV", method: .post,parameters:["uname":txtUserId.text!,"pass":txtPassword.text!]).responseJSON(responseData) -> Void in
      if((responseData.result.value != nil))
    
       let jsonData = JSON(responseData.result.value)
    
            if let arrJSON = jsonData["loginNodes"].arrayObject 
             for index in 0...arrJSON.count-1 
              let aObject = arrJSON[index] as! [String : AnyObject]
              let errorCode = aObject["errorCode"] as? String;
              let errorMessage = aObject["errorMessage"] as? String;
                 if("0"==errorCode )
    
                            //Database Login Success Action
                        else
                            // //Database Login Fail Action
                        
                    
    
    
                
            
       
    

    如果你使用 Like table View 或 Collection View 等,你可以这样使用..

    声明一个数组

    var arrRes = [String:AnyObject]

    将值赋给数组

    if((responseData.result.value != nil))

                // let jsonData = JSON(responseData.result.value)                   
    
                if((responseData.result.value != nil))
                    let swiftyJsonVar = JSON(responseData.result.value!)
    
                    if let resData = swiftyJsonVar["loginNodes"].arrayObject 
                        self.arrRes = resData as! [[String:AnyObject]]
                    
    
                    if self.arrRes.count > 0 
                        self.tableView.reloadData()
                    
    
                
            
    

    在 taleView 中,cellForRowAt indexPath ,只要使用

      let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for:  indexPath) as! customCell
    cell.errorLabelName.text = arrRes[indexPath.row]["errorMessage"] as? String
    

【讨论】:

【参考方案4】:

斯威夫特 3 Swift 3 中的 Alamofire 示例

导入 UIKit 进口阿拉莫火 导入 SwiftyJSON

ViewController 类:UIViewController、UITableViewDelegate、UITableViewDataSource

var array = [[String:AnyObject]]()

@IBOutlet weak var tableview: UITableView!

override func viewDidLoad() 
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.

    Alamofire.request("http://www.designer321.com/johnsagar/plumbingapp/webservice/list_advertise.php?zip=123456").responseJSON  (responseData) -> Void in
        if((responseData.result.value) != nil)
        
            let swiftyJsonVar = JSON(responseData.result.value!)
            print("Main Responce")
            print(swiftyJsonVar)
       
        if let result = responseData.result.value
        
           if let Res = (result as AnyObject).value(forKey: "response") as? NSDictionary
            
                if let Hallo = (Res as AnyObject).value(forKey: "advertise_list") as? NSArray
                
                    print("-=-=-=-=-=-=-")
                    print(Hallo)

                    self.array = Hallo as! [[String:AnyObject]]
                    print(self.array)


                

            
            self.tableview.reloadData()
        


    





override func didReceiveMemoryWarning() 
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.



func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int

    return array.count


func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell

     let cell = tableView.dequeueReusableCell(withIdentifier: "TableViewCell", for: indexPath) as! TableViewCell

    var dict = array[indexPath.row]
    cell.lbl1.text = dict["address"] as? String
    cell.lbl2.text = dict["ad_created_date"] as? String
    cell.lbl3.text = dict["phone_number"] as? String
    cell.lbl4.text = dict["id"] as? String
    cell.lbl5.text = dict["ad_zip"] as? String

    let imageUrlString = dict["ad_path"]
    let imageUrl:URL = URL(string: imageUrlString as! String)!
    let imageData:NSData = NSData(contentsOf: imageUrl)!
    cell.img.image = UIImage(data: imageData as Data)



    return cell


func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat

    return 100

【讨论】:

以上是关于如何在 Swift 3 中使用 Alamofire 4 解析这个 json?的主要内容,如果未能解决你的问题,请参考以下文章

Alamofire 4 请求返回 NSArray,无法弄清楚如何在 Swift 3 中使用 SwiftyJSON 进行解析

如何使用 Alamofire 在 Xcode 8 Swift 3.0 中获取特定的 JSON?

如何使用 Swift 3 将单例与 Alamofire 一起使用?

如何在 swift 3 中使用 Alamofire 制作和发送字典数组(JSON 格式)发送到服务器

如何使用 alamofire 在 swift 3 中处理字符串响应

如何使用 Alamofire 5.0.0-beta.3 (Swift 5) 上传图片(多部分)