2016-12-20 2 views
0

У меня есть json ниже, но не удается выяснить, как его разобрать в Swift 3. Мой код ниже. Json из API имеет корень массива. Я использую Xcode 8.2.1 с Swift 4 и Alamofire 4.0.Как разобрать этот json с Alamofire 4 в Swift 3?

["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 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) 
    } 
} 

Я попытался это let item = readableJSON["items"] as? [[String: Any]] как предложено here, но это не будет компилировать с ошибкой [String:Any] has no subscript и let item = readableJSON["items"] as? [String: Any]! компилирует с предупреждением Expression implicitly coerced from string но производит ноль. Размышление об этом json - это жизнь или смерть для меня.

+0

Исследование это: https://developer.apple.com/swift/blog/?id=37 – Moritz

+0

Я читал, что и, возможно, я Я просто тупой, но я не могу найти шаблон json, который соответствует моему, и через 2 дня я пришел сюда. – markhorrocks

+1

Вот подсказка (практически полное решение, на самом деле): «items» - это словарь, содержащий массив. Этот массив содержит словари. // Конец, сделано. – Moritz

ответ

0

Это функция разбора JSON я в конце концов придумал. Проблема для этих json-данных заключается в том, что это словарь внутри массива. Я noob и большинство ответов, и то, как я видел, не соответствовало бы моим данным 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! 
} 
2

ли что-то вроде

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

тогда вы будете иметь возможность получить доступ к элементам в этом словаре, как так:

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

Я пробовал использовать «index» или «price», но получил ошибку 'Could not cast value of type '__NSArrayM '(0x10c60ddb0) в' NSString '(0x10bc14c40) '. – markhorrocks

+1

ах, ну, похоже, вам нужно соответствовать вашему приведению к вашему типу. –

0

Alamofire Пример в Swift 3

1.First всех Использование двух cocoapods к вашему project.Use SwiftyJSON для разбора JSON

pod 'Alamofire' 
pod 'SwiftyJSON' 
  1. My Json находится ниже

    { "loginNodes": [{ "ErrorMessage": "Добро пожаловать в Alamofire", "имя": Энамул Хак, "ERRORCODE": "0", "фото": нулевой}]}

  2. It может быть сделано по-разному. Но я сделал это ниже. Обратите внимание, если вам не нужен какой-либо параметр для отправки сервера, тогда удалите параметр. Он может работать или получать метод. Вы можете использовать любой способ. Мой 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 
            } 
           } 
    
    
          } 
         } 
        } 
    
  3. Если Вы используете Как таблицы View или коллекции View или так далее, вы можете использовать, как это ..

  4. Объявляет массив

    вар arrRes = [Строка: AnyObject]

  5. Присвоить значение в массиве как

    , если ((responseDa ta.result.value!= Ноль)) {

      // 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() 
           } 
    
          } 
         } 
    
  6. В taleView, cellForRowAt indexPath, Просто используйте

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

Swift 3 Alamofire Пример в Swift 3

импорта UIKit импорта Alamofire импорта 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 
} 

}

Смежные вопросы