cannot extract JSON - ios

Hello I am trying to extract a json. However I am getting an error saying Cannot convert value of type 'Data' to expected argument type 'NSData'. Is there something that I am doing wrong?
success: { (response) -> Void in
var dataStream: Data = Data.init(referencing: response!)
do {
let data = try JSONSerialization.jsonObject(with: dataStream, options: JSONSerialization.ReadingOptions.mutableContainers)as AnyObject
}catch{
}
if let id = response!["money"]as? String {
print(id)
}
}){ (error) -> Void in
print("error")
}
}
Update2
let request = Alamofire.request(apiUrl, method: .get)
request.responseJSON { response in
switch response.result
{
case .success:
success(response.result.value as AnyObject)
case .failure(let error):
failure(error as NSError)
}
}
}

Your problem is here
var dataStream: Data = Data.init(referencing: response!)
in Docs
init(referencing reference: NSData)
response should be of type NSData not Data , you may try
let responseDict = try JSONSerialization.jsonObject(with: data!, options: .allowFragments) as? [String:Any]
note cast to expected return whether it's dictionary or array
this
if let id = response!["money"]as? String {
print(id)
}
should be replaced with
if let id = responseDict!["money"]as? String {
print(id)
}
You can try Alamofire with SwiftyJson
Alamofire.request("https://yourlinkdownloadjson/abc").responseJSON { response in
debugPrint(response)
if let json = response.data {
let data = JSON(data: json)
print("data\(data["money"])")
}
}

Related

how to determine the specific 409 error from an AFError?

I have a method that returns a Single<(HTTPURLResponse, Any)> doing a call to a webservice.
This call returns an 409 for multiple reasons and this reason is passed as a JSON in the response.
I know the JSON is in the data attribute of the DataResponse object but I would like to have it in the AFError that I pass when an error occurs. I want to display the specific 409 error message related to the JSON response to the user to allow him understand what happened.
How could I do that ?
I searched for that in Stackoverflow and also on the github of Alamofire but couldn't find any help to my case.
return Single<(HTTPURLResponse, Any)>.create(subscribe: { single in
let request = self.sessionManager.request(completeURL, method: httpMethod, parameters: params, encoding: encoding, headers: headers)
request.validate().responseJSON(completionHandler: { (response) in
let result = response.result
switch result {
case let .success(value): single(.success((response.response!, value)))
case let .failure(error): single(.error(error))
}
})
return Disposables.create { request.cancel() }
})
I'm working with Alamofire 4.9.1
request.validate().responseJSON { (response) in
let statusCode = response.response?.statusCode ?? 0
guard statusCode != 409 else {
if let data = response.data, let errorJson = try? JSONSerialization.jsonObject(with: data, options: .mutableContainers) as? [String: Any] {
let errorMessage = errorJson["message"] as? String
let customError = CustomError(message: errorMessage)
single(.error(customError))
}
return
}
let result = response.result
switch result {
case let .success(value): single(.success((response.response!, value)))
case let .failure(error): single(.error(error))
}
}
I guess you can achieve your requirement by this way. create a custom Error class to pass the error to completion. dont forget to call completion if errorJson is not serialised.
class CustomError: Error {
var localizedDescription: String { message ?? "" }
var message: String?
init(message: String?) {
self.message = message
}
}

Convert decrypted string into JSON object

After decrypting my response from API i am getting a string "name:DM100, profile:[1,2,4,5]".
How can i convert this to a json object where name is string and profile is an array
i have tried using but getting nil
if let data = testString.data(using: .utf8) {
do {
return try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any]
} catch {
print("JSON Serialization Error :-> \(error.localizedDescription)")
}
}
return nil
}
Your JSON String is not valid. It should look like this:
let testString = "{\"name\":\"DM100\", \"profile\":[1,2,4,5]}"
if let data = testString.data(using: .utf8) {
do {
if let json = try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any] {
print(json["name"])
}
}
catch {
print(error.localizedDescription)
}
}
Start and end with curly braces {} and have double quotations around string keys and values.
You can use following code to get the output:
But String must have and valid JSON format first as follows:
let string = "{\"name\":\"DM100\", \"profile\":[1,2,4,5]}"
let data = string.data(using: .utf8)!
do {
if let jsonObj = try JSONSerialization.jsonObject(with: data, options : .allowFragments) as? Dictionary<String,Any> {
print(jsonObj)
} else {
print("JSON Error")
}
} catch let error as NSError {
print(error)
}

How to grab data from an API using Swift 4 and Alamofire

I'm trying to get data from an API with no documentation.
My code is
let URL_MAIN = "http://evarsity.srmuniv.ac.in/srmswi/usermanager/youLogin.jsp"
let URL_ATTENDANCE = "http://evarsity.srmuniv.ac.in/srmswi/resource/StudentDetailsResources.jsp?resourceid=7"
let URL_TIMETABLE = "http://evarsity.srmuniv.ac.in/srmswi/resource/StudentDetailsResources.jsp?resourceid=5"
func getData(url: String) {
Alamofire.request(url, method: .get)
.responseData { response in
if response.result.isSuccess {
print("Sucess! Got the data")
guard let data = response.result.value else { return }
print(data)
} else {
print("Error: \(String(describing: response.result.error))")
}
}
I am getting the response as 51406 bytes.
I need to get the actual data in either JSON or some other format. Here is the api link for python
https://github.com/arjunmahishi/srm-erp-api/blob/master/erp.py
Convert your responseData to a dictionary using the function i provided below and then parse the data accordingly.Here, i m getting a JSON response in the form of a dictionary.
let strResponse = "\(responseString.value!)"
let arr = strResponse.components(separatedBy: "\n")
let dict = convertStringToDictionary(str:(arr.last ?? "")!)
self.Message = dict?["message"] as! String
let responseStatus = dict?["status"] as! NSString
public func convertStringToDictionary(str:String) -> [String: Any]? {
if let data = str.data(using: .utf8) {
do {
return try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any]
} catch {
print(error.localizedDescription)
}
}
return nil
}

Use Type T as parameter in completion handler

I have written a function for a URL request. This contains a completion handler that returns a dictionary of [String: AnyObject] that is fetched from the URL.
The code for this is:
func getDataAsyncFromURLRequest(url: NSURL, completion: ([String : AnyObject]) -> ()) {
let request = NSMutableURLRequest(URL: url)
let session = NSURLSession.sharedSession()
let task = session.dataTaskWithRequest(request) { (data, response, error) -> Void in
if error != nil {
print("error=\(error)")
return
}
else {
let datastring = NSString(data: data!, encoding: NSUTF8StringEncoding)
if let data = datastring!.dataUsingEncoding(NSUTF8StringEncoding) {
do {
let json = try NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions()) as! [String : AnyObject]
completion(json)
} catch {
print("json error: \(error)")
}
}
}
}
task.resume()
}
In some cases, however, I will receive an array of [String : AnyObject] and not the dictionary. So instead of making a duplicate function that takes the array of dictionaries as parameter for the completion handler, I though it was possible to do like this
func getDataAsyncFromURLRequest<T>(url: NSURL, completion: (T) -> ()) {
// code here
}
... and then do like this let json = try NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions()) as! T, but that gives me this error: Cannot invoke 'getDataAsyncFromURLRequest' with an argument list of type '(NSURL, completion: (_) -> ())'
What would be the best way to make the completion handler accept a parameter with a type decided at runtime, if possible at all?
It's very easy why don't you use AnyObject
func getDataAsyncFromURLRequest(url: NSURL, completion: (AnyObject) -> ()) {
let request = NSMutableURLRequest(URL: url)
let session = NSURLSession.sharedSession()
let task = session.dataTaskWithRequest(request) { (data, response, error) -> Void in
if error != nil {
print("error=\(error)")
return
}
else {
let datastring = NSString(data: data!, encoding: NSUTF8StringEncoding)
if let data = datastring!.dataUsingEncoding(NSUTF8StringEncoding) {
do {
let json = try NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions())
completion(json)
} catch {
print("json error: \(error)")
}
}
}
}
task.resume()
}
And result of JSONObjectWithData can be [AnyObject] (Array) or [String:AnyObject] and tree of those items.
So after got result, you can also check type of result in completion block
Like this
if result is [String:AnyObject]
...
else if result is [AnyObject]
...
else
//throw error : because then it is not JSON

Swift 2 error, converting to JSON

Ive been having an error with swift 2, its so simple but i cant get it
Here's the code before I started updating it for Swift 2:
func updateWeatherInfo(latitude: CLLocationDegrees, longitude: CLLocationDegrees) {
let url = "http://api.openweathermap.org/data/2.5/forecast"
let params = ["lat":latitude, "lon":longitude]
println(params)
Alamofire.request(.GET, url, parameters: params)
.responseJSON { (request, response, json, error) in
if(error != nil) {
println("Error: \(error)")
println(request)
println(response)
self.loading.text = "Internet appears down!"
}
else {
println("Success: \(url)")
println(request)
var json = JSON(json!)
self.updateUISuccess(json)
}
}
}
here's the line throwing error:
let json = JSON(json)
Here's the whole func after i started
func updateWeatherInfo(latitude: CLLocationDegrees, longitude: CLLocationDegrees) {
let url = "http://api.openweathermap.org/data/2.5/forecast"
let params = ["lat":latitude, "lon":longitude]
print(params)
Alamofire.request(.GET, url, parameters: params)
.responseJSON { (request, response, json) in
print("Success: \(url)")
print(request)
let json = JSON(json)
self.updateUISuccess(json!)
}
}
updateUISuccess requires a JSON value, but at the moment I have a (Request )
heres the error description
After a suggestion I tried this:
.Success(let data):
let data_ar = data as! JSON // or NSDictionary or NSString
self.updateUISuccess(data_ar)
case .Failure(let data, let error):
print("Request failed with error: \(error)")
}
but the app crashes at let data_ar = data as! JSON // or NSDictionary or NSString
The variable json looks like an enum value. Try this:
switch json {
case .Success(let data):
let data_ar = data as! NSArray // or NSDictionary or NSString
case .Failure(let data, let error):
print("Request failed with error: \(error)")
}

Resources