Cannot pass JSON array to array - arrays

I am trying to pass my JSON array to an array called array so that I can then query the array with submission_id with value 27 to obtain the safety_rating_id, schedule_job_id, score and submission_id from this JSON https://codeshare.io/UqJMV but I'm being thrown this error
Cannot convert value of type '[JSON]' to expected argument type 'JSON'
Code to pass JSON to array:
var array: [JSON] = []
func getTask(onCompletion: () -> (), onError: ((NSError) -> ())? = nil) {
guard let endPoint = Data.sharedInstance.weeklyEndpoint
else { print("Empty endpoint"); return }
Alamofire.request(.GET, endPoint, encoding: .JSON)
.validate()
.responseJSON { response in
switch response.result {
case .Success:
if let value = response.result.value {
let json = JSON(value)
for (_,subJson):(String, JSON) in json {
if let date = subJson["start_date"].string{
self.date = date
}
if let building = subJson["building_name"].string{
self.building = building
}
if let jobId = subJson["schedule_job_id"].int {
self.jobIdArray.append(jobId)
}
if let tasks = subJson["tasks"].array{
Tasks.sharedInstance.datas = tasks
for building in tasks {
if let ratings = building["safety_ratings"].array{
print(ratings)
self.array.append(ratings)
}
}
}
}
onCompletion()
}
case .Failure(let error):
print("Request failed with error: \(error)")
onError?(error)
}
}
}

append() expects a single element (JSON), but ratings is an array ([JSON]).
That's what the error message says.
To append an array use appendContentsOf:
self.array.appendContentsOf(ratings)

Related

how convert JSON response to Array in swift?

func llamadaApiDos(postData: (Data),empresa: String,boundary: String) -> [String] {
var request = URLRequest(url: URL(string: "https://www.something.com")!,timeoutInterval: Double.infinity)
request.addValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")
request.httpMethod = "POST"
request.httpBody = postData
var success = false
var serviceResponse = [""]
let semaphore = DispatchSemaphore(value: 0)
let task = URLSession.shared.dataTask(with: request, completionHandler: { data, response, error in
if let error = error {
print("Error while trying to re-authenticate the user: \(error)")
} else if let response = response as? HTTPURLResponse,
300..<600 ~= response.statusCode {
print("Error while trying to re-authenticate the user, statusCode: \(response.statusCode)")
} else if let data = data {
let loginDataModel = try! JSONDecoder().decode(responseLogin.self,from: data)
serviceResponse = JSONDecoder.decode(loginDataModel)
success = true
}else{
success = true
}
semaphore.signal()
})
task.resume()
_ = semaphore.wait(timeout: DispatchTime.distantFuture)
if success
{
return serviceResponse
}else
{
return ["Error"]
}
}
Cannot assign value of type '(T.Type, Data) throws -> T' to type '[String]'
I need to convert the JSON response into an array that can be validated in another function, but I don't know what type of data I should return, I'm sorry if it's not well understood, my English isn't very good either.
To convert the JSON response to an array in Swift, you can use the JSONSerialization class to convert the response data to a dictionary, then access the array stored in the dictionary using the key for the array.
Here's an example:
let json = try JSONSerialization.jsonObject(with: data, options: [])
if let array = json["keyForArray"] as? [String] {
// Use the array here
}
In your code, you can use this approach to convert the JSON response to an array, then return the array from the llamadaApiDos function.
Here's how your function would look like with this change:
func llamadaApiDos(postData: (Data),empresa: String,boundary: String) -> [String] {
var request = URLRequest(url: URL(string: "https://www.something.com")!,timeoutInterval: Double.infinity)
request.addValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")
request.httpMethod = "POST"
request.httpBody = postData
var success = false
var serviceResponse = [""]
let semaphore = DispatchSemaphore(value: 0)
let task = URLSession.shared.dataTask(with: request, completionHandler: { data, response, error in
if let error = error {
print("Error while trying to re-authenticate the user: \(error)")
} else if let response = response as? HTTPURLResponse,
300..<600 ~= response.statusCode {
print("Error while trying to re-authenticate the user, statusCode: \(response.statusCode)")
} else if let data = data {
// Convert the JSON response to an array
let json = try JSONSerialization.jsonObject(with: data, options: [])
if let array = json["keyForArray"] as? [String] {
// Use the array here
serviceResponse = array
success = true
}
}else{
success = true
}
semaphore.signal()
})
task.resume()
_ = semaphore.wait(timeout: DispatchTime.distantFuture)
if success
{
return serviceResponse
}else
{
return ["Error"]
}
}

How to get value from json in iOS Swift?

I have JSON with dynamic data of all key values. Right now I am trying to get value by finding "type = object" if an object exists then in values I will check the contentType exists in values.
How to find the value matched inside JSON and convert it into an array?
Here is my code:
switch response.result {
case .success:
guard let data = response.value else {
return
}
if let JSON = response.value {
let json = JSON as? [String: AnyObject]
print("json view docue",json)
if let castedDict = json as? [String: String] {
print("Converted successfully: \(castedDict)")
} else {
print("Failed to cast the dictionary")
}
let vc = self.stringify(json: json)
print("new json converted into string:::", vc.count)
}
self.view.removeLoading()
case .failure(let error):
print("Error:", error)
self.view.removeLoading()
}
Here is my JSON:
{
image1: {
type = Object;
value = "{\"contentType\":\"image/jpeg\",\"url\":\"https://www.pexels.com/photo/neon-advertisement-on-library-glass-wall-9832438/",\"fileName\":\"9832438.jpg\"}";
valueInfo = {
objectTypeName = "com.google.gson.JsonObject";
serializationDataFormat = "application/json";
};
},
image2: {
type = Object;
value = "{\"contentType\":\"image/jpeg\",\"url\":\"https://www.pexels.com/photo/neon-advertisement-on-library-glass-wall-9832438/",\"fileName\":\"9832438.jpg\"}";
valueInfo = {
objectTypeName = "com.google.gson.JsonObject";
serializationDataFormat = "application/json";
};
}
}
Any much appreciated pls...

How to convert json array to objects array Alamofire?

I have such array in from api:
[{
data = "";
datetime = "23.07.2020 12:09";
id = 340593;
status = "My current task is";
},...]
I have created such struct:
struct RemarksModel {
let id:Int
let status,datetime:String
let data:String?
}
And here I make request:
AF.request(URLRequest(url:Pathes.init(endpoint: "notepad/\(noteModel?.id ?? 0)/documentation").resourseUrl),
interceptor: CallInterceptor.init(method:HTTPMethod.get)).responseJSON(completionHandler: { (response) in
print(response.description)
switch response.result{
case .success(let array):
let remarksData = array as? [RemarksModel]
let json = response.data as? [RemarksModel]
print(json?.count)
// if remarksData?.count ?? 1 > 0{
// self.remarksArray += remarksData!
// self.tableView.reloadData()
// }
case .failure(let error):
print(error.localizedDescription)
}
})
the problem is that I can't convert this array to array of my model objects. when I try to add all received data to array my app crashes because my array is nil, despite of json in logs. Maybe I have to use another way of converting received json array to objects array?
You can use directly .responseDecodable function instead of .responseData or .responseJSON after confirming RemarksModel to Codable (or just Decodable) protocol
.responseDecodable(of: [RemarksModel].self, queue: .main, decoder: JSONDecoder()) { (response) in
switch response.result {
case let .success(data):
// success
print(data)
case let .failure(error):
// error
print(error.localizedDescription)
}
}
You can add Codable protocol to RemarksModel and use .responseData instead of .responseJSON
.responseData { response in
switch response.result {
case let .success(data):
do {
let result = try JSONDecoder().decode([RemarksModel].self, from: data)
// success
} catch {
print("decoding error:\n\(error)")
// error
}
case let .failure(error):
// error
}
}

Extracting JSON Data -

I have the following JSON data structure being pulled from FBSDKGraphRequest.
data = (
{
id = "<USER_ID_GOES_HERE>";
name = "Tom Jones";
picture = {
data = {
"is_silhouette" = 0;
url = "<USER_IMAGE_URL_GOES_HERE>";
};
};
},
{
id = "<USER_ID_GOES_HERE>";
name = "Tom Jones";
picture = {
data = {
"is_silhouette" = 0;
url = "<USER_IMAGE_URL_GOES_HERE>";
};
};
},
{
id = "<USER_ID_GOES_HERE>";
name = "Tom Jones";
picture = {
data = {
"is_silhouette" = 0;
url = "<USER_IMAGE_URL_GOES_HERE>";
};
};
},
I want to extract the data and place it into an array. I am having difficulty with the first "data" key.
Heres my FBSDKGR:
let params = ["fields": "name, picture.type(large)"]
let request = FBSDKGraphRequest(graphPath: "me/taggable_friends", parameters: params)
request!.start { (connection, result, error) -> Void in
if error != nil {
print("There is some error getting friends", error!)
}
else if result != nil {
print("Here is the result", result!)
With an extra dependency, if you don't mind.
import SwiftyJSON
let json = JSON(result) // after you get result from FBSDKGR
let data = json["data"].array
for (index, _) in data.enumerated() {
if let id = json["data", index, "id"].int {
// add to your array
if let name = json["data", index, "name"].string {
// continue nesting...
}
}
}
As your JSOND dta is array of dictionary so , we can cast the result by the following way . First of all we will take two array , one is for names list and other is for picture details . here picture details array is array of dictionary . let's go for code
var namesArray = [String]()
var ImageDetailsArrayDict= [[String :AnyObject]]()
let params = ["fields": "name, picture.type(large)"]
let request = FBSDKGraphRequest(graphPath: "me/taggable_friends", parameters: params)
request!.start { (connection, result, error) -> Void in
if error != nil {
print("There is some error getting friends", error!)
}
else if result != nil {
print("Here is the result", result!)
if let response = result["data"] as? [[String :AnyObject]] {
for i in 0..<response.count {
namesArray.append(response[i]["name"] as! String)
ImageDetailsArrayDict.append(response[i]["picture"])
}
}
}
}
Now , we have two array . so we can easily populate it in the tableView .
Good luck .

error in FOR IN loop

I am trying to run the below function for the array quandlURLs in a for in loop. I am getting an error in line "loadDataFromURL", saying :can not convert value of type [String] to expected argument of type 'Sting'. Can somebody please tell me what I am missing here. Thanks!!
class func getDataFromQuandlWithSuccess(success: ((Quandl: NSData!) -> Void)) {
let quandlGold = "https://www.quandl.com/api/v3/datasets/LBMA/GOLD.json?auth_token=xyzDP7Cj-2F_Jss7sYHf&rows=1"
quandlURLs = [quandlGold, quandlSilver,quandlPlatinum,quandlPalladium]
var index: Int
var urlData = [String]()
for index in quandlURLs {
loadDataFromURL(NSURL(string: quandlURLs[index])!, completion:{(data, error) -> Void in
//2
if let urlData[index] = data {
//3
success(Quandl: urlData[index])
//below worked and showed raw data
//print("Successful \(urlData)")
}
})
}
}
here is the loadDataFromURL function
class func loadDataFromURL(url: NSURL, completion:(data: NSData?, error: NSError?) -> Void) {
let session = NSURLSession.sharedSession()
// Use NSURLSession to get data from an NSURL
let loadDataTask = session.dataTaskWithURL(url, completionHandler: { (data: NSData?, response: NSURLResponse?, error: NSError?) -> Void in
if let responseError = error {
completion(data: nil, error: responseError)
} else if let httpResponse = response as? NSHTTPURLResponse {
if httpResponse.statusCode != 200 {
let statusError = NSError(domain:"com.raywenderlich", code:httpResponse.statusCode, userInfo:[NSLocalizedDescriptionKey : "HTTP status code has unexpected value."])
completion(data: nil, error: statusError)
} else {
completion(data: data, error: nil)
}
}
})
loadDataTask.resume()
}
}
All you need to do here is change for index in quandlURLs to for index in 0..<quandlURLs.count
There was also an issue with if let urlData[index] = data, because you can't use optional binding with an array, you need to define a new value, so go if let urlDataEntry = data, in which case your urlIndex array should be of type NSData.
You also don't need the var index: Int line. Int is inferred when using the for in loop on the ..< function that creates an Int array, and the index variable is usable throughout the for loop.
For example:
class func getDataFromQuandlWithSuccess(success: ((Quandl: NSData!) -> Void)) {
let quandlGold = "https://www.quandl.com/api/v3/datasets/LBMA/GOLD.json?auth_token=xyzDP7Cj-2F_Jss7sYHf&rows=1"
quandlURLs = [quandlGold, quandlSilver,quandlPlatinum,quandlPalladium]
var urlData = [NSData]()
for index in 0..<quandlURLs.count {
loadDataFromURL(NSURL(string: quandlURLs[index])!, completion:{(data, error) -> Void in
//2
if let urlDataEntry = data {
//3
urlData[index] = urlDataEntry
success(Quandl: urlDataEntry)
//below worked and showed raw data
//print("Successful \(urlData)")
}
})
}
}

Resources