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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.