damniatx
damniatx

Reputation: 234

Parse data from socket.io response swift

I have response from socket io library with response like this

socket.on("response-names") { data, ack in
    print(data)
}

can print this,

[{
    "person": [{
        "_id":"56512323212132",
        "name":"John Smith",
        "id":"0000001",
        "geolocation":{
             "latitude":5.12312323443,
             "longitude":101.12312464564354
        }
     }]
}]

How do you guys access the name, id and the geolocation(lat, long) in swift ?,

As far as I know the data is NSArray. but accessing is with data[0] will produce nil. but i can do data.count which will return with 1.

Thank you

Upvotes: 3

Views: 3168

Answers (3)

Wahab Khan Jadon
Wahab Khan Jadon

Reputation: 1196

I know it's a very old question but my answer may help someone ... In today's swift 5 it's very easy than before...

Create a SocketParser and use the below code to parse data...

class SocketParser {

    static func convert<T: Decodable>(data: Any) throws -> T {
        let jsonData = try JSONSerialization.data(withJSONObject: data)
        let decoder = JSONDecoder()
        do{
           let  _ = try decoder.decode(T.self, from: jsonData)
            
        }catch{
            createLog("CheckError \(error)")
        }
        return try decoder.decode(T.self, from: jsonData)
    }

}

Now Create a simple model for your JSON ... in you case as bellow...

import Foundation

// MARK: - WelcomeElement
struct WelcomeElement: Codable {
    let person: [Person]
}

// MARK: - Person
struct Person: Codable {
    let id, name, personID: String
    let geolocation: Geolocation

    enum CodingKeys: String, CodingKey {
        case id = "_id"
        case name
        case personID = "id"
        case geolocation
    }
}

// MARK: - Geolocation
struct Geolocation: Codable {
    let latitude, longitude: Double
}

It's time to use these in response as below...

socket.on("response-names") { data, ack in

    guard let data = data.first else{
       return
    }

if let response : WelcomeElement = try? SocketParser.convert(data: data) {
            print(responce)
}

Upvotes: 2

damniatx
damniatx

Reputation: 234

Finally i solved it, just for future reference for others. It looks like you need to know the type before you parsing it. and check it with print. and the debug code really helping, something like NSCFArray means your data as NSArray and try to read from that.

let dataArray = data as NSArray

let dataString = dataArray[0] as! String
let dataNewNow = dataString.data(using: String.Encoding.utf8, allowLossyConversion: false)!
do {
    let json = try NSJSONSerialization.JSONObjectWithData(dataNewNow, options: []) as! [String: AnyObject]

    let str = json["person"] as! NSArray
    let str2 = str[0] as! NSDictionary

    let personName = str2["name"] as! String
    let personId = str2["id"] as! String

    let personGeoLocation = str2["geolocation"] as! NSDictionary
    let personLatitude = personGeoLocation["latitude"] as! NSNumber
    let personLongitude = personGeoLocation["longitude"] as! NSNumber

    print("personName =", personName)
    print("personID =", personId)
    print("Person Latitude =", personLatitude)
    print("Person Longitude =", personLongitude)

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

Upvotes: 3

Teddy
Teddy

Reputation: 1

in my case this worked

let dataArray = data as NSArray
let dataString = dataArray[0] as! String
let dataNewNow = dataString.data(using: String.Encoding.utf8, allowLossyConversion: false)!
do {
    let json = try JSONSerialization.jsonObject(with: dataNewNow, options: []) as! [String: AnyObject]
    let nMsgType = json["msg_type"] as! String
    print(nMsgType)

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

Upvotes: 0

Related Questions