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:
For Swift 4
I used @Passkit's logic but i had to update as per Swift 4
Step.1 Created extension for String Class
import UIKit
extension String
{
var parseJSONString: AnyObject?
{
let data = self.data(using: String.Encoding.utf8, allowLossyConversion: false)
if let jsonData = data
{
// Will return an object or nil if JSON decoding fails
do
{
let message = try JSONSerialization.jsonObject(with: jsonData, options:.mutableContainers)
if let jsonResult = message as? NSMutableArray
{
print(jsonResult)
return jsonResult //Will return the json array 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
}
}
}
Step.2 This is how I used in my view controller
var jsonString = "[\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 jsonString to jsonArray
let json: AnyObject? = jsonString.parseJSONString
print("Parsed JSON: \(json!)")
print("json[2]: \(json![2])")
All credit goes to original user, I just updated for latest swift version
Here's a sample for you to make things simpler and easier. My String data in my database is a JSON file that looks like this:
[{"stype":"noun","sdsc":"careless disregard for consequences","swds":"disregard, freedom, impulse, licentiousness, recklessness, spontaneity, thoughtlessness, uninhibitedness, unrestraint, wantonness, wildness","anwds":"restraint, self-restraint"},{"stype":"verb","sdsc":"leave behind, relinquish","swds":"abdicate, back out, bail out, bow out, chicken out, cop out, cut loose, desert, discard, discontinue, ditch, drop, drop out, duck, dump, dust, flake out, fly the coop, give up the ship, kiss goodbye, leave, leg it, let go, opt out, pull out, quit, run out on, screw, ship out, stop, storm out, surrender, take a powder, take a walk, throw over, vacate, walk out on, wash hands of, withdraw, yield","anwds":"adopt, advance, allow, assert, begin, cherish, come, continue, defend, favor, go, hold, keep, maintain, persevere, pursue, remain, retain, start, stay, support, uphold"},{"stype":"verb","sdsc":"leave in troubled state","swds":"back out, desert, disown, forsake, jilt, leave, leave behind, quit, reject, renounce, throw over, walk out on","anwds":"adopt, allow, approve, assert, cherish, come, continue, defend, favor, keep, pursue, retain, stay, support, uphold"}]
To load this JSON String Data, follow these simple Steps. First, create a class for my MoreData Object like this:
class MoreData {
public private(set) var stype : String
public private(set) var sdsc : String
public private(set) var swds : String
public private(set) var anwds : String
init( stype : String, sdsc : String, swds : String, anwds : String) {
self.stype = stype
self.sdsc = sdsc
self.swds = swds
self.anwds = anwds
}}
Second, create my String extension for my JSON String like this:
extension String {
func toJSON() -> Any? {
guard let data = self.data(using: .utf8, allowLossyConversion: false) else { return nil }
return try? JSONSerialization.jsonObject(with: data, options: .mutableContainers)
}}
Third, create My Srevices Class to handle my String Data like this:
class Services {
static let instance: Services = Services()
func loadMoreDataByString(byString: String) -> [MoreData]{
var myVariable = [MoreData]()
guard let ListOf = byString.toJSON() as? [[String: AnyObject]] else { return [] }
for object in ListOf {
let stype = object["stype"] as? String ?? ""
let sdsc = object["sdsc"] as? String ?? ""
let swds = object["swds"] as? String ?? ""
let anwds = object["anwds"] as? String ?? ""
let myMoreData = MoreData(stype : stype, sdsc : sdsc, swds : swds, anwds : anwds)
myVariable.append(myMoreData)
}
return myVariable
}}
Finally, call this Function from the View Controller to load data in the table view like this:
func handlingJsonStringData(){
moreData.removeAll(keepingCapacity: false)
moreData = Services.instance.loadMoreDataByString(byString: jsonString)
print(self.moreData.count)
tableView.reloadData()
}
It might be help someone. Similar example.
This is our Codable
class to bind data. You can easily create this class using SwiftyJsonAccelerator
class ModelPushNotificationFilesFile: Codable {
enum CodingKeys: String, CodingKey {
case url
case id
case fileExtension = "file_extension"
case name
}
var url: String?
var id: Int?
var fileExtension: String?
var name: String?
init (url: String?, id: Int?, fileExtension: String?, name: String?) {
self.url = url
self.id = id
self.fileExtension = fileExtension
self.name = name
}
required init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
url = try container.decodeIfPresent(String.self, forKey: .url)
id = try container.decodeIfPresent(Int.self, forKey: .id)
fileExtension = try container.decodeIfPresent(String.self, forKey: .fileExtension)
name = try container.decodeIfPresent(String.self, forKey: .name)
}
}
This is Json String
let jsonString = "[{\"name\":\"\",\"file_extension\":\"\",\"id\":10684,\"url\":\"https:\\/\\/homepages.cae.wisc.edu\\/~ece533\\/images\\/tulips.png\"},
{\"name\":\"\",\"file_extension\":\"\",\"id\":10684,\"url\":\"https:\\/\\/homepages.cae.wisc.edu\\/~ece533\\/images\\/arctichare.png\"},
{\"name\":\"\",\"file_extension\":\"\",\"id\":10684,\"url\":\"https:\\/\\/homepages.cae.wisc.edu\\/~ece533\\/images\\/serrano.png\"},
{\"name\":\"\",\"file_extension\":\"\",\"id\":10684,\"url\":\"https:\\/\\/homepages.cae.wisc.edu\\/~ece533\\/images\\/peppers.png\"},
{\"name\":\"\",\"file_extension\":\"\",\"id\":10684,\"url\":\"https:\\/\\/homepages.cae.wisc.edu\\/~ece533\\/images\\/pool.png\"}]"
Here we convert to swift object.
let jsonData = Data(jsonString.utf8)
let decoder = JSONDecoder()
do {
let fileArray = try decoder.decode([ModelPushNotificationFilesFile].self, from: jsonData)
print(fileArray)
print(fileArray[0].url)
} catch {
print(error.localizedDescription)
}
Use swiftyJson swiftyJson
platform :ios, '8.0'
use_frameworks!
target 'MyApp' do
pod 'SwiftyJSON', '~> 4.0'
end
Usage
import SwiftyJSON
let json = JSON(jsonObject)
let id = json["Id"].intValue
let name = json["Name"].stringValue
let lat = json["Latitude"].stringValue
let long = json["Longitude"].stringValue
let address = json["Address"].stringValue
print(id)
print(name)
print(lat)
print(long)
print(address)