Parse JsonArray response data - ios

I have an json array respone like this;
[
{
"id": 62,
"type_id": 1,
"coordinate": {
"x": 2273.73828125,
"y": 1568.015625000001
},
"name": "x"
},
{
"id": 57,
"type_id": 1,
"coordinate": {
"x": 1405,
"y": 343.99999999999704
},
"name": "y"
}
]
I use alomifere 5.2 to get response. How can I parse this data to get all values?

Alamofire.request("YOUR_URL", method:.post, parameters:params, encoding:URLEncoding.default, headers: nil).responseJSON { response in
switch(response.result)
{
case .success(_):
if response.result.value != nil
{
let arr :[[String:Any]] = response.result.value! as! [[String:Any]]
print(arr)
}
break
case .failure(_):
print(response.result.error)
break
}
}
Change successResponse as! [[string:Any]] (array of dictionary)

Related

Parsin JSON directory inside another directory

Alamofire.request("https://example.com/stories.php", method: .post, parameters: parameters).validate().responseJSON { response in
switch response.result {
case .success:
if let json = response.result.value {
let json2 = JSON(json)
for (_, subJSON): (String, JSON) in json2[0]["stories"] {
if let arr = subJSON["user"].dictionary {
let title = arr["name"]?.string
let id = arr["id"]?.int
let photo = arr["picture"]?.string
let rel1 = InboxStories(title: title!, storyID: id!, photo:photo!)
cell.arrayOfRels.append(rel1)
}
}
cell.getStoryDel()
}
case .failure(_):
print("hata")
}
}
JSON output
[{
"stories": [{
"id": "s1",
"last_updated": "1582543824",
"user": {
"id": "2",
"name": "testuser",
"picture": "https:\/\/example.com\/ios\/images\/profile_pic\/116534.jpg"
},
"snaps_count": "1",
"snaps": [{
"id": "c1",
"mime_type": "image",
"url": "chttps:\/\/example.com\/ios\/stories\/image\/3434.jpg",
"last_updated": "1582543824"
}]
}],
"count": 1
}]
I am trying to reach user key of stories.
It returns nil in my code. How can I parse it?
stories is also an array, please note the []
And it's pretty confusing to name a dictionary arr 😉
if let stories = json2.array?.first?["stories"].array {
for story in stories {
if let dict = story["user"].dictionary {
let title = dict["name"]!.stringValue
let id = dict["id"]!.stringValue
let photo = dict["picture"]!.stringValue
let rel1 = InboxStories(title: title, storyID: id, photo:photo)
cell.arrayOfRels.append(rel1)
}
}
}
And consider to use Decodable. It's built-in and more comfortable than SwiftyJSON

How can I post request with order of json in swift with alamofire?

I need a payment method for my app and I have to post a request with JSON data for communicate with API. Everything seem correct to me. I can't find any bug in my code but I assume that JSON not post in order. Is this important? Because response said failure but I can't find anything else. If JSON order is important how can I make it? I'm new in swift please help me.
Here my code:
func mainRequestForPayment() {
)
let headers: HTTPHeaders = [
"accept": "application/json",
"content-type": "application/json",
"authorization": "\(self.authValue)",
"x-iyzi-rnd": "\(self.randomString)",
"cache-control": "no-cache"
]
let url = "MY_URL"
let parameters: [String: Any] = [
"locale": "tr",
"conversationId": "123456789",
"price": "1.1",
"paidPrice": "1.1",
"installment": 1,
"paymentChannel": "WEB",
"basketId": "B67832",
"paymentGroup": "PRODUCT",
"paymentCard": [
"cardHolderName": "CARD_HOLDER_NAME",
"cardNumber": "CARD_NUMBER",
"expireYear": "CARD_YEAR",
"expireMonth": "01",
"cvc": "123",
"registerCard": 0
],
"buyer": [
"id": "BY789",
"name": "John",
"surname": "Doe",
"identityNumber": "74300864791",
"email": "email#email.com",
"gsmNumber": "+905350000000",
"registrationAddress": "Nidakule Göztepe, Merdivenköy Mah. Bora Sok. No:1",
"city": "Istanbul",
"country": "Turkey",
"zipCode": "34732",
"ip": "85.34.78.112"
],
"shippingAddress": [
"address": "Nidakule Göztepe, Merdivenköy Mah. Bora Sok. No:1",
"zipCode": "34742",
"contactName": "Jane Doe",
"city": "Istanbul",
"country": "Turkey"
],
"billingAddress": [
"address": "Nidakule Göztepe, Merdivenköy Mah. Bora Sok. No:1",
"zipCode": "34742",
"contactName": "Jane Doe",
"city": "Istanbul",
"country": "Turkey"
],
"basketItems": [
[
"id": "BI101",
"price": "0.3",
"name": "Binocular",
"category1": "Collectibles",
"category2": "Accessories",
"itemType": "PHYSICAL"
],
[
"id": "BI102",
"price": "0.5",
"name": "Game code",
"category1": "Game",
"category2": "Online Game Items",
"itemType": "VIRTUAL"
],
[
"id": "BI103",
"price": "0.2",
"name": "Usb",
"category1": "Electronics",
"category2": "Usb / Cable",
"itemType": "PHYSICAL"
]
],
"currency": "TRY"
]
Alamofire.request(url, method: .post, parameters: parameters , encoding: JSONEncoding.default, headers: headers)
.responseJSON { (response) in
print(parameters)
switch response.result {
case .success(let value):
let swiftyJson = JSON(value)
print ("return as JSON using swiftyJson is: \(swiftyJson)")
case .failure(let error):
print ("error: \(error)")
}
}
}
Where is my fault I can't see? And again is there any way to make order in post request? Thanks all.
I get that response:
return as JSON using swiftyJson is: {
"conversationId" : "123456789",
"locale" : "tr",
"errorCode" : "1000",
"status" : "failure",
"systemTime" : 1579858355103,
"errorMessage" : "Invalid signature"
}
JSON order isn't typically important, as the JSON spec doesn't define it as a requirement for JSON objects, but some poorly engineered backends do require it. You really need to check the requirements of the backend you're communicating with.
Additionally, Swift's Dictionary type is arbitrarily ordered, and that order may change between runs of your app as well as between versions of Swift used to compile your code.
Finally, Swift's JSONEncoder, and Apple's JSONSerialization type both offer no way to require strict ordering. At most, JSONSerialization offers the .sortedKeys option, which will give you a guaranteed (alphabetical) order, but it may not be the order you declared your parameters in. Using an alternate Encoder, if you have Codable types (which I recommend instead of SwiftyJSON), may give you a better guarantee of order, but you should only really care if it's a requirement of your backend.
As an aside, I suggest you use the static HTTPHeader properties for your HTTPHeaders value, instead of using raw strings, it's much more convenient. For example:
let headers: HTTPHeaders = [.accept("application/json"),
.contentType("application/json")]
Use this class
//////////////////////////////////////////////
import Foundation
import UIKit
import Alamofire
class ServicesClass_New : NSObject
{
var delegate : ServicesClassDelegate!
typealias CompletionBlock = (_ result : Dictionary<String, Any>?, _ error : Error?) -> Void
typealias CompletionDataBlock = (_ result : Data?) -> Void
typealias ProgressBlock = (_ progressData : Progress) -> Void
//MARK: Shared Instance
static let sharedInstance : ServicesClass = {
let instance = ServicesClass()
return instance
}()
static func getDataFromURlWith(url:String,parameters:Dictionary<String, Any>?, requestName:String,completionBlock : #escaping CompletionBlock)
{
print("net available")
Alamofire.request(url, method: .get, parameters: parameters, encoding: URLEncoding.default, headers: nil).responseJSON { (response) in
switch(response.result) {
case .success(_):
if let data = response.result.value
{
//print(response.result.value!)
//print(data)
var dic : Dictionary<String,Any> = Dictionary()
if data as? Array<Dictionary<String,Any>> != nil
{
dic["data"] = data as? Array<Dictionary<String,Any>>
completionBlock(dic,nil)
}
else
{
completionBlock(data as? Dictionary<String,Any>,nil)
}
}
break
case .failure(_):
print(response.result.error!)
completionBlock(nil ,response.result.error!)
break
}
}
}
static func postDataFromURL(url:String,parameters:Dictionary<String, Any>?, requestName:String,completionBlock : #escaping CompletionBlock)
{
print("net available")
//application/json
//multipart/form-data
let hders : HTTPHeaders = [ "Content-Type" : "application/json"] as [String : String]
Alamofire.request(url, method: .post, parameters: parameters, encoding: JSONEncoding.default, headers: hders).responseJSON { response in
switch(response.result) {
case .success(_):
if let dict = response.result.value
{
let data = dict as! Dictionary<String,Any>
// print(response.result.value!)
// print(data)
completionBlock(data as Dictionary,nil)
}
break
case .failure(let error):
print((error as NSError).localizedDescription)
completionBlock(nil ,response.result.error!)
print("\(error.localizedDescription)")
break
}
}
}
static func downloadFile(strUrl : String, progressBlock : #escaping ProgressBlock, completionBlock : #escaping CompletionDataBlock)
{
let utilityQueue = DispatchQueue.global(qos: .utility)
Alamofire.request(URL.init(string: strUrl)!).downloadProgress(queue: utilityQueue, closure: { (progress) in
progressBlock(progress)
})
.responseData { (response) in
if let data = response.result.value
{
completionBlock(data)
}
else
{
completionBlock(nil)
}
}
}
static func uploadData(url:String,parameters:Dictionary<String, Any>,requestName:String,arrImg:[UIImage],arrVideos:[URL],completionBlock : #escaping CompletionBlock)
{
print("net available")
let hders = [
"Content-Type": "application/json"
]
Alamofire.upload(multipartFormData:
{
MultipartFormData in
for img in arrImg
{
let imageData = UIImageJPEGRepresentation(img , 0.8)!
MultipartFormData.append(imageData, withName: "image" , fileName:"file\(index).jpg", mimeType:"image/jpeg")
}
index = 0
for video in arrVideos
{
index = index + 1
var videoData : Data = Data()
do
{
videoData = try Data.init(contentsOf: URL.init(fileURLWithPath: video.path))
MultipartFormData.append(videoData, withName: "video", fileName:"file\(index).mp4",mimeType: "video/mp4")
}
catch
{
}
}
for (key, value) in parameters
{
MultipartFormData.append((value as! String).data(using: String.Encoding.utf8)!, withName: key)
}
}, to:url,method:.post,headers:hders, encodingCompletion: {
encodingResult in
//["content-type" : "application/json"]
switch encodingResult
{
case .success(let upload, _, _):
print("image uploaded")
upload.responseJSON { response in
if let JSON = response.result.value
{
print("JSON: \(JSON)")
}
if let dict = response.result.value
{
let data = dict as! Dictionary<String,Any>
print(response.result.value!)
print(data)
completionBlock(data as Dictionary,nil)
}
}
break
case .failure(let encodingError):
completionBlock(nil ,encodingError)
break
}
} )
}
}
/// call protocals where you want to call API.
//There is multiple Methods like : GET, POST
....

Create extension in Swift 5 for Dictonary[String:Any]

I want to create extension for Dictionary [String:Any] which is received from API Response.
Right Now I am doing below way
I have created func getDataFromJson this is working fine, Please let me know how to do that.
func getDataFromJson(json: AnyObject) -> Data?{
do {
print("json = \(json)")
return try JSONSerialization.data(withJSONObject: json, options: JSONSerialization.WritingOptions.prettyPrinted)
} catch let myJSONError {
print("\n\n\nError => getDataFromJson => \(myJSONError)")
}
return nil;
}
This is my response and I want to "data" to Data
{
"status": true,
"message": "Country List",
"data": [
{
"id": 1,
"name": “ABC”,
"code": "A",
"phone_code": "+91”,
"flag": "country-flags/-shiny.png"
},
{
"id": 2,
"name": “ZYX”,
"code": “Z”,
"phone_code": "+1”,
"flag": "country-flags/-shiny.png"
}
]
}
I want to get data this way jsonResponse["data"].retriveData()
Here is a simple function that encodes the dictionary, the function throws any error so it can be properly handled. Since JSONSerialization.data(withJSONObject: takes an Any parameter this function can also be implemented for an array etc
extension Dictionary {
func retriveData() throws -> Data {
return try JSONSerialization.data(withJSONObject: self)
}
}
Simple example
let dict = ["abc": 123, "def": 456]
do {
let data = try dict.retriveData()
let result = try JSONDecoder().decode([String:Int].self, from:data)
print(result)
} catch {
print(error)
}
Another way is to use Result if you're on Swift 5 (shortened after comment from vadian)
extension Dictionary {
func retriveData() -> Result<Data, Error> {
return Result { try JSONSerialization.data(withJSONObject: self) }
}
}
and an example
let result = try dict.retriveData()
switch result {
case .success(let data):
let dictionary = try JSONDecoder().decode([String:Int].self, from:data)
print(dictionary)
case .failure(let error):
print(error)
}
a copy of your function transposed to an extension can be
extension Dictionary {
func retriveData() -> Data? {
do {
return try JSONSerialization.data(withJSONObject: self, options: .prettyPrinted)
} catch let myJSONError {
print("\n\n\nError => getDataFromJson => \(myJSONError)")
}
return nil
}
}
Correct json
{
"status": true,
"message": "Country List",
"data": [
{
"id": 1,
"name": "ABC",
"code": "A",
"phone_code": "+91",
"flag": "country-flags/-shiny.png"
},
{
"id": 2,
"name": "ZYX",
"code": "Z",
"phone_code": "+1",
"flag": "country-flags/-shiny.png"
}
]
}
Model
struct Datum: Codable {
let id: Int
let name, code, phoneCode, flag: String
}
Decoding data only
let str = """
{
"status": true,
"message": "Country List",
"data": [{
"id": 1,
"name": "ABC",
"code": "A",
"phone_code": "+91",
"flag": "country-flags/-shiny.png"
},
{
"id": 2,
"name": "ZYX",
"code": "Z",
"phone_code": "+1",
"flag": "country-flags/-shiny.png"
}
]
}
"""
do {
let dic = try JSONSerialization.jsonObject(with: Data(str.utf8)) as! [String:Any]
let content = try JSONSerialization.data(withJSONObject: dic["data"])
let dec = JSONDecoder()
dec.keyDecodingStrategy = .convertFromSnakeCase
let res = try dec.decode([Datum].self, from: content)
print(res)
}
catch {
print(error)
}
Please try this
// Response Dictionary
let jsonResponse : [String:Any] = ["data":["key1":"value1",
"key2":"value2",
"key3":"value3",
"key4":"value4"]]
// check dictionary contains value for key "data"
if let dataDict = jsonResponse["data"] as? [String:Any] {
// convert dictionary to data
let jsonData = dataDict.retriveData()
print("Json Data :- ", jsonData != nil ? "Success" : "Data is nil")
}
// Dictionary exxtension for converting dictionary to json data
extension Dictionary {
func retriveData() -> Data? {
do {
print("json = \(self)")
return try JSONSerialization.data(withJSONObject: self, options: JSONSerialization.WritingOptions.prettyPrinted)
} catch let myJSONError {
print("\n\n\nError => getDataFromJson => \(myJSONError)")
}
return nil;
}
}

swift getting all values of a dictionary and passing to viewcontroller using almaofire

Hi have an application which collects data from an api and I use Alamofire and swiftyJSON. the current challenge I am facing now is that I have different dictionaries in one array and I want to be able to retun back specific items in the dictionary. this is the array I am working with
Json
[
{
"images": [
{
"id": 8,
"original": "http://127.0.0.1:8000/media/images/products/2018/05/f3.jpg",
"caption": "",
"display_order": 0,
"date_created": "2018-05-26T17:24:34.762848Z",
"product": 13
},
{
"id": 9,
"original": "http://127.0.0.1:8000/media/images/products/2018/05/f5.jpg",
"caption": "",
"display_order": 1,
"date_created": "2018-05-26T17:24:34.815214Z",
"product": 13
},
{
"id": 10,
"original": "http://127.0.0.1:8000/media/images/products/2018/05/f2.jpg",
"caption": "",
"display_order": 2,
"date_created": "2018-05-26T17:25:19.117271Z",
"product": 13
},
{
"id": 11,
"original": "http://127.0.0.1:8000/media/images/products/2018/05/f4.jpg",
"caption": "",
"display_order": 3,
"date_created": "2018-05-26T17:25:19.155159Z",
"product": 13
}
]
}
]
get a single image is like this
Alamofire.request(URL, method: .get, parameters: nil, encoding: JSONEncoding.default, headers: HEADER).responseJSON { (response) in
if response.result.error == nil {
guard let data = response.data else {return}
do {
if let json = try JSON(data: data).array {
for item in json {
let images = item["images"][0]["original"].stringValue
....
this returns only the indexed image.[0] if it is set to [1] it returns the indexed image at 1.
how do I return all the images so that I can loop through all and display in a collection view controller. more codes would be supplied on request.
You can dit it Like that :
if let json = try? JSON(data: data).arrayValue {
for item in json {
let imagesList = item["images"].arrayValue
let imagesURL = imagesList.map {$0["original"].string}.compactMap({$0})
if imagesURL.count > 0{
print( imagesURL[0])
}
}
}
Or:
do {
let json = try JSON(data: data).array
json?.forEach({ (item) in
let imagesList = item["images"].arrayValue
let imagesURL = imagesList.map {$0["original"].string}.compactMap({$0})
if imagesURL.count > 0{
print( imagesURL[0])
}
})
} catch {
print(error.localizedDescription)
}

swift parsing desc and parsing selected element

Swift parsing desc and parsing selected element. I want to parse desc and after parsing desc parse desc content. thanks swift parsing desc and parsing selected element.
I have tried different methods. Does anyone have an idea on how we can make it possible? I tried the following code:
**Code for getting the data**
func demoApi1() {
Alamofire.request("", method: .get, parameters: nil, encoding: JSONEncoding.default, headers: nil).responseJSON { (response:DataResponse<Any>) in
switch(response.result) {
case .success(_):
guard let json = response.result.value as! [[String:Any]]? else{ return}
print("Ang Response: , \(json)")
for item in json {
self.getAllDetail.append(item )
if let desc = item["dec"] as? String {
self.titleArray.append(desc)
print("motherfucker:" , self.titleArray)
}
}
if !self.getAllDetail.isEmpty{
DispatchQueue.main.async {
}
}
break
case .failure(_):
print("Error")
break
}
}
}
Response:
Ang Response [["status": {
name = ongoing;
}, "sched": 2018-04-10T14:22:00+08:00, "desc": asdasdasdsa, "id": 224, "reward": 1.00, "parent": das, "child": dasdas, "date_created": 2018-04-19T15:54:24.657644+08:00, "name": sad, "occurrence": {
name = once;
}, "type": , "date_modified": 2018-04-19T15:54:24.703520+08:00], ["status": {
name = ongoing;
}, "sched": 2018-04-19T15:54:24.657644+08:00, "desc": {
"questions" : [
{
"b" : 2,
"a" : 1
},
{
"b" : 3,
"a" : 2
},
{
"b" : 2,
"a" : 8
},
{
"b" : 9,
"a" : 7
},
{
"b" : 3,
"a" : 6
}
],
"operation" : "addition"
}, "id": 226, "reward": 1.00, "parent": shit, "child": , "date_created": 2018-04-23T14:16:35.739436+08:00, "name": chorename, "occurrence": {
name = once;
}, "type": homework, "date_modified": 2018-04-23T14:16:35.790237+08:00]]
String to Dictionary:
func stringToDictionary(_ strToJSON : String)-> [String:Any]{
print("JsonString:\(strToJSON)")
let data = strToJSON.data(using: .utf8)
var dict = [String:Any]()
do {
dict = try JSONSerialization.jsonObject(with: data!) as! [String:Any]
return dict
}
catch let error as NSError {
print("Error is:\(error)")
}
return dict
}
Use it like this:
let dictConv = stringToDictionary("your_string")
print(dictConv)

Resources