Simple and clean way to convert JSON string to Object in Swift

前端 未结 16 1057
挽巷
挽巷 2020-11-28 23:27

I have been searching for days to convert a fairly simple JSON string to an object type in Swift but with no avail.

Here is the code for web service call:



        
相关标签:
16条回答
  • 2020-11-29 00:09

    For iOS 10 & Swift 3, using Alamofire & Gloss:

    Alamofire.request("http://localhost:8080/category/en").responseJSON { response in
    
    if let data = response.data {
    
        if let categories = [Category].from(data: response.data) {
    
            self.categories = categories
    
            self.categoryCollectionView.reloadData()
        } else {
    
            print("Casting error")
        }
      } else {
    
        print("Data is null")
      }
    }
    

    and here is the Category class

    import Gloss
    
    struct Category: Decodable {
    
        let categoryId: Int?
        let name: String?
        let image: String?
    
        init?(json: JSON) {
            self.categoryId = "categoryId" <~~ json
            self.name = "name" <~~ json
            self.image = "image" <~~ json
        }
    }
    

    IMO, this is by far the most elegant solution.

    0 讨论(0)
  • 2020-11-29 00:13

    Using SwiftyJSON library, you could make it like

    if let path : String = Bundle.main.path(forResource: "tiles", ofType: "json") {
        if let data = NSData(contentsOfFile: path) {
            let optData = try? JSON(data: data as Data)
            guard let json = optData else {
                return
            }
            for (_, object) in json {
                let name = object["name"].stringValue
                print(name)
            }
        }
    } 
    
    0 讨论(0)
  • 2020-11-29 00:14

    Swift 4 parses JSON much more elegantly. Just adopt the codable protocol for your structure as per this simplified example:

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

    To parse the JSON array, you tell the decoder what the objects of the data array are

    let parsedData = decoder.decode([Business].self, from: data)
    

    Here's a full working example:

    import Foundation
    
    struct Business: Codable {
        let id: Int
        let name: String
    }
    
    // Generating the example JSON data: 
    let originalObjects = [Business(id: 0, name: "A"), Business(id: 1, name: "B")]
    let encoder = JSONEncoder()
    let data = try! encoder.encode(originalObjects)
    
    // Parsing the data: 
    let decoder = JSONDecoder()
    let parsedData = try! decoder.decode([Business].self, from: data)
    

    For more background, check out this excellent guide.

    0 讨论(0)
  • 2020-11-29 00:14

    I like RDC's response, but why limit the JSON returned to have only arrays at the top level? I needed to allow a dictionary at the top level, so I modified it thus:

    extension String
    {
        var parseJSONString: AnyObject?
        {
            let data = self.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)
    
            if let jsonData = data
            {
                // Will return an object or nil if JSON decoding fails
                do
                {
                    let message = try NSJSONSerialization.JSONObjectWithData(jsonData, options:.MutableContainers)
                    if let jsonResult = message as? NSMutableArray {
                        return jsonResult //Will return the json array output
                    } else if let jsonResult = message as? NSMutableDictionary {
                        return jsonResult //Will return the json dictionary output
                    } else {
                        return nil
                    }
                }
                catch let error as NSError
                {
                    print("An error occurred: \(error)")
                    return nil
                }
            }
            else
            {
                // Lossless conversion of the string was not possible
                return nil
            }
        }
    
    0 讨论(0)
  • 2020-11-29 00:15
    let jsonString = "{\"id\":123,\"Name\":\"Munish\"}"
    

    Convert String to NSData

     var data: NSData =jsonString.dataUsingEncoding(NSUTF8StringEncoding)!
    
     var error: NSError?
    

    Convert NSData to AnyObject

    var jsonObject: AnyObject? = NSJSONSerialization.JSONObjectWithData(data,     options: NSJSONReadingOptions.allZeros, error: &error)
    
    println("Error: \\(error)")
    
    let id = (jsonObject as! NSDictionary)["id"] as! Int
    
    let name = (jsonObject as! NSDictionary)["name"] as! String
    
    println("Id: \\(id)")
    
    println("Name: \\(name)")
    
    0 讨论(0)
  • 2020-11-29 00:16

    Here are some tips how to begin with simple example.

    Consider you have following JSON Array String (similar to yours) like:

     var list:Array<Business> = []
    
      // left only 2 fields for demo
      struct Business {
        var id : Int = 0
        var name = ""               
     }
    
     var jsonStringAsArray = "[\n" +
            "{\n" +
            "\"id\":72,\n" +
            "\"name\":\"Batata Cremosa\",\n" +            
            "},\n" +
            "{\n" +
            "\"id\":183,\n" +
            "\"name\":\"Caldeirada de Peixes\",\n" +            
            "},\n" +
            "{\n" +
            "\"id\":76,\n" +
            "\"name\":\"Batata com Cebola e Ervas\",\n" +            
            "},\n" +
            "{\n" +
            "\"id\":56,\n" +
            "\"name\":\"Arroz de forma\",\n" +            
        "}]"
    
    
            // convert String to NSData
            var data: NSData = jsonStringAsArray.dataUsingEncoding(NSUTF8StringEncoding)!
            var error: NSError?
    
            // convert NSData to 'AnyObject'
            let anyObj: AnyObject? = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions(0),
                error: &error)
            println("Error: \(error)")
    
         // convert 'AnyObject' to Array<Business>
         list = self.parseJson(anyObj!)
    
         //===============
    
        func parseJson(anyObj:AnyObject) -> Array<Business>{
    
            var list:Array<Business> = []
    
             if  anyObj is Array<AnyObject> {
    
                var b:Business = Business()
    
                for json in anyObj as Array<AnyObject>{
                 b.name = (json["name"] as AnyObject? as? String) ?? "" // to get rid of null
                 b.id  =  (json["id"]  as AnyObject? as? Int) ?? 0                 
    
                   list.append(b)
                }// for
    
            } // if
    
          return list
    
        }//func    
    

    [EDIT]

    To get rid of null changed to:

    b.name = (json["name"] as AnyObject? as? String) ?? ""
    b.id  =  (json["id"]  as AnyObject? as? Int) ?? 0 
    

    See also Reference of Coalescing Operator (aka ??)

    Hope it will help you to sort things out,

    0 讨论(0)
提交回复
热议问题