0

i've been working with swift app. im stuck at parsing multiple data as an array, here's my json

    {
"error":0,
"success":1,
"kode_keranjang":"2",
"kode_produk":"1",
"kode_pelanggan":"USR-6cs42",
"jumlah":"1",
"nama_produk":"MacBook 2015",
"gambar":"MacBook.jpg",
"harga":"2000000",
"message":"Berhasil"
}
{
"error":0,
"success":1,
"kode_keranjang":"3",
"kode_produk":"2",
"kode_pelanggan":"USR-6cs42",
"jumlah":"1",
"nama_produk":"iPhone 6s",
"gambar":"iPhone",
"harga":"12000000",
"message":"Berhasil"
}

how can i get nama_produk as an array in swift? so i can populate it in my tableview cell

here's my swift

        let myUrl = NSURL(string: "http://xxxxxxxx.com/produk.php");

    let request = NSMutableURLRequest(URL:myUrl!);

    request.HTTPMethod = "POST";// Compose a query string

    let postString = "produkid="+produkid!+"&kat="+kat!+"";

    request.HTTPBody = postString.dataUsingEncoding(NSUTF8StringEncoding);

    let task = NSURLSession.sharedSession().dataTaskWithRequest(request) {
        data, response, error in

        if error != nil
        {
            print("error=\(error)")
            return
        }

        // You can print out response object
        print("response = \(response)")

        // Print out response body
        let responseString = NSString(data: data!, encoding: NSUTF8StringEncoding)
        print("responseString = \(responseString)")

        //Let's convert response sent from a server side script to a NSDictionary object:
        do {
            let myJSON =  try NSJSONSerialization.JSONObjectWithData(data!, options: .MutableContainers) as? NSDictionary

            if let parseJSON = myJSON {

                // Now we can access value of First Name by its key
                let nama_produk = parseJSON["nama_produk"] as? NSArray
                let status = parseJSON["success"] as? Int
                if(status == 1){


                    print (nama_produk);
                }
                else{
                   // let statusnya = "error";
                    return;
                }

            }
        } catch {
            print(error)
        }
    }
    task.resume()

in this line

let nama_produk = parseJSON["nama_produk"] as? NSArray


print (nama_produk);

i create nama_produk as array, then i try print it, but it empty not showing data.

then i wanna add nama_produk array in my cell like this

var nama_produk_array = [""+nama_produk+""]
cell.namaproduk.text = nama_produk_array[indexPath.row]

how can i parse json into array?

please somebody

4
  • 1
    That's JSON isn't an array. Commented Sep 15, 2016 at 19:46
  • can i just use that json or i have to change the json? Commented Sep 15, 2016 at 19:52
  • 1
    What you have isn't valid JSON. JSON must have a single root level object, either an Array, or a Dictionary. What you have are multiple dictionaries. Perhaps you meant to enclose all those dictionaries in a root-level array? Commented Sep 15, 2016 at 21:53
  • dowtn voted: bad json AND there are I'd guess around 1000 answers on SO for this sort of issue -- a bit of searching and if not, at least a valid question helps :) Commented Sep 16, 2016 at 7:10

3 Answers 3

2

What you provided isn't valid JSON. You must have a singular top-level element. Perhaps you meant to put it an Array, like so:

[
    {
        "error": 0,
        "success": 1,
        "kode_keranjang": "2",
        "kode_produk": "1",
        "kode_pelanggan": "USR-6cs42",
        "jumlah": "1",
        "nama_produk": "MacBook 2015",
        "gambar": "MacBook.jpg",
        "harga": "2000000",
        "message": "Berhasil"
    } {
        "error": 0,
        "success": 1,
        "kode_keranjang": "3",
        "kode_produk": "2",
        "kode_pelanggan": "USR-6cs42",
        "jumlah": "1",
        "nama_produk": "iPhone 6s",
        "gambar": "iPhone",
        "harga": "12000000",
        "message": "Berhasil"
    }
]

Here's my improvement on serg_zhd's answer:

import Foundation

var jsonFragment1 =
"{\"error\":0,\"success\":1,\"kode_keranjang\":\"2\",\"kode_produk\":\"1\",\"kode_pelanggan\":\"USR-6cs42\",\"jumlah\":\"1\",\"nama_produk\":\"MacBook 2015\",\"gambar\":\"MacBook.jpg\",\"harga\":\"2000000\",\"message\":\"Berhasil\"}"
var jsonFragment2 =
"{\"error\":0,\"success\":1,\"kode_keranjang\":\"3\",\"kode_produk\":\"2\",\"kode_pelanggan\":\"USR-6cs42\",\"jumlah\":\"1\",\"nama_produk\":\"iPhone 6s\",\"gambar\":\"iPhone\",\"harga\":\"12000000\",\"message\":\"Berhasil\"}"
var jsonString = "[" + jsonFragment1 + "," + jsonFragment2 + "]"


func parse(JSON json: String) throws -> [String]? {
    guard let data = json.data(using: .utf8) else { return nil }

    guard let rootArray = try JSONSerialization.jsonObject(with: data, options : []) as? [[String: Any]]
    else { return nil }

    return rootArray
        .filter{ $0["success"] as? Int == 1}
        .map{ $0["nama_produk"] as! String }
}

if let devices = try parse(JSON: jsonString) {
    print(devices)
}
else {
    print("error parsing the json")
}

You can try it here.

Sign up to request clarification or add additional context in comments.

5 Comments

In above coding, Your JSON array is also invalid format
@MohanSingh Can you please elaborate?
See it on JSON array above your codes. Comma is missing between two dictionaries. it makes Json is invalid.
@MohanSingh the comma is there... In the definition of jsonString
Yep. I mentioned array is not in the codes. okay Thank you :)
2

As far as i can understand you have an array of dictionaries and want to extract nama_produk fields into the array. Here is the safe way to do it in Swift 3, Xcode 8:

var jsonString1 =
"{\"error\":0,\"success\":1,\"kode_keranjang\":\"2\",\"kode_produk\":\"1\",\"kode_pelanggan\":\"USR-6cs42\",\"jumlah\":\"1\",\"nama_produk\":\"MacBook 2015\",\"gambar\":\"MacBook.jpg\",\"harga\":\"2000000\",\"message\":\"Berhasil\"}"
var jsonString2 =
"{\"error\":0,\"success\":1,\"kode_keranjang\":\"3\",\"kode_produk\":\"2\",\"kode_pelanggan\":\"USR-6cs42\",\"jumlah\":\"1\",\"nama_produk\":\"iPhone 6s\",\"gambar\":\"iPhone\",\"harga\":\"12000000\",\"message\":\"Berhasil\"}"
var jsonString = "[" + jsonString1 + "," + jsonString2 + "]"

var data = jsonString.data(using: .utf8)!
do {
    if let json = try JSONSerialization.jsonObject(with: data, options : .allowFragments) as? [Dictionary<String,Any>]
    {
        let array = json
           .filter{ $0["success"] as? Int == 1}
           .flatMap{$0["nama_produk"] as? String}
        print(array) // ==> ["MacBook 2015", "iPhone 6s"]
    } else {
        print("bad json")
    }
} catch let error as NSError {
    print(error)
}

jsonString is possible json => the array of 2 dictionaries jsonString1 and jsonString2

flatMap takes care of a failed casts of $0["nama_produk"] to String, that may unnecessary hide the problem of json you received, so you might consider using .map{ $0["nama_produk"] as! String } as Alexander suggested

9 Comments

You can just use map to do with
What do you mean by to do with map? Like replace json for-loop with map closure? Or make Decodable struct to map json values to the corresponding properties?
Better use flatMap as it takes care of nil values rootArray.flatMap{$0["nama_produk"] as? String}
down voted: inelegant and not 'swiftly' .. we should make use HOF like map and stuff like you said in your comment :D
Reversed vote. It was mainly because u started with "the swift 3 way or the like.
|
0
struct Product: Decodable {
    let namaProduk: String?
}

let JSON: String = """
[{
    "error": 0,
    "success": 1,
    "kode_keranjang": "2",
    "kode_produk": "1",
    "kode_pelanggan": "USR-6cs42",
    "jumlah": "1",
    "nama_produk": "MacBook 2015",
    "gambar": "MacBook.jpg",
    "harga": "2000000",
    "message": "Berhasil"
},
{
    "error": 0,
    "success": 1,
    "kode_keranjang": "3",
    "kode_produk": "2",
    "kode_pelanggan": "USR-6cs42",
    "jumlah": "1",
    "nama_produk": "iPhone 6s",
    "gambar": "iPhone",
    "harga": "12000000",
    "message": "Berhasil"
}]
"""

if let jsonData = JSON.data(using: .utf8) {

    let decoder = JSONDecoder()
    decoder.keyDecodingStrategy = .convertFromSnakeCase

    do {
        let products: [Product] = try decoder.decode([Product].self, from: jsonData)
        let namaProduks: [String] = products.compactMap { $0.namaProduk }
        print(namaProduks) // ["MacBook 2015", "iPhone 6s"]
    } catch {
        print(error) // handle the error
    }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.