How to change an NSData to an NSDictionary or JSON - ios

I have a swift app that calls api and recieves back a JSON.
self.get(url).responseJSON { (response) -> Void in
self.notify(FetchCompletion, response: response.response, result: response.result)
print("response: ")
print(response.response)
print("data: ")
let dataExample = response.data
print(dataExample)
let dictionary:NSDictionary? = NSKeyedUnarchiver.unarchiveObjectWithData(dataExample!)! as? NSDictionary
}
And it prints out:
...
data:
Optional(<7b227374 61747573 223a2234 3034222c 22657272 6f72223a 224e6f74 20466f75 6e64227d>)
fatal error: unexpectedly found nil while unwrapping an Optional value
I want to just print out the data is some readable form by converting to a dictionary.
EDIT 1
My get() function is defined as such:
func get(path: String) -> Request {
return self.get(path, data: NSDictionary())
}
EDIT 2
I am using
import UIKit
import Alamofire
import SwiftyJSON
EDIT 3
I attempted to follow the example here:How to parse JSON in Swift using NSURLSession
But get the error "unresolved identifier 'JSONSerialization'"
EDIT 4 / probable answer
var newdata = JSON(data: dataExample!)
print(newdata)
outputted:
{
"status" : "404",
"error" : "Not Found"
}
I believe that this is a json and I am properly printing the readable data, so i believe this is the answer. I was led to this by the comment suggesting to use swiftJSON

A very standard way to convert to JSON from NSData, feel free to ask a question
self.get(url).responseJSON { (response) -> Void in
self.notify(FetchCompletion, response: response.response, result: response.result)
print("response: ")
print(response.response)
print("data: ")
let dataExample = response.data
print(dataExample)
do {
let dictionary = try NSJSONSerialization.JSONObjectWithData(dataExample!, options: NSJSONReadingOptions()) as! NSDictionary
}
catch {
// catch error.
}
}

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
}
}

Swift 3 - issue to create easy request method POST (URLRequestVonvertible)

I am developing an application with Swift 3.0 and IOS 10 in Xcode 8.3.2. But I have a problem when I try to retrieve the JSON from this APIRest (http://schematic-ipsum.herokuapp.com/). What is the problem? Or how you would make the call. If you need more information regarding the code, tell me, but basically, I just want to make a call to that page to recover the biography.
enter image description here
My code is this:
import AlamofireDomain
import Alamofire
import ObjectMapper
class AuthorDAO : SimpleDAO {
func getBiography(_ parameters: Dictionary<String, Int>,
callbackFuncionOK: #escaping
(PropertiesAuthorModel)->(),
callbackFunctionERROR: #escaping (Int,NSError)->()) {
let ulr = NSURL( string: "http://schematic-ipsum.herokuapp.com/" as String)
let request = NSMutableURLRequest(url: ulr! as URL)
request.httpMethod = "POST"
request.setValue("application/json", forHTTPHeaderField: "Constent-Type")
let data = try! JSONSerialization.data(withJSONObject: parameters, options: JSONSerialization.WritingOptions.prettyPrinted)
let json = NSString(data: data, encoding: String.Encoding.utf8.rawValue)
if let json = json {
print(json)
}
request.httpBody = json!.data(using: String.Encoding.utf8.rawValue)
Alamofire.request(request as URLRequest)
.responseJSON { response in
if response.result.isSuccess{
if let status = response.response?.statusCode {
switch(status){
//MARK: CONTROL ON DIFERENTS KINDS OF RESPONSES ON SERVER
case 200:
if let value = response.result.value {
let biographyResponse = Mapper<PropertiesAuthorModel>().map(JSONObject: value)
callbackFuncionOK(biographyResponse!)
}
//case 400: {} ..., case 404: {} ...
default:
break
}
}
}
//MARK: ERROR ON SERVER
else {
var statusCode = -1
if let _response = response.response {
statusCode = _response.statusCode
}
var nsError: NSError = NSError(domain: Constants.UNKNOWN_HTTP_ERROR_MSG,
code: Constants.UNKNOWN_HTTP_ERROR_ID,
userInfo: nil)
if let _error = response.result.error {
nsError = _error as NSError
}
callbackFunctionERROR(statusCode,nsError)
}
}
}
And the error is: "Error Domain=Alamofire.AFError Code=4 "JSON could not be serialized because of error: The data couldn’t be read because it isn’t in the correct format." 400"
The problem is that it does not enter into the "if response.result.isSuccess {" because the result of the response is "nil" and goes directly to the "else". Showing the error that I have commented. Can it be because I have to send the JSON format in the httpBody request? How can I do it?
Your question should be more clear. "What is the problem?" isn't possible to answer without more information.
To issue HTTP request, take a look at Alamofire, an HTTP networking library written in Swift: https://github.com/Alamofire/Alamofire
Alamofire.request("https://httpbin.org/get").responseJSON { response in
print(response.request) // original URL request
print(response.response) // HTTP URL response
print(response.data) // server data
print(response.result) // result of response serialization
if let JSON = response.result.value {
print("JSON: \(JSON)")
}
}

How can I print the json content of the response from post request in Alamofire in swift?

Ok, so I'm using alamofire and the parameters I'm passing are valid. Here is the code so far:
Alamofire.request(.POST, "http://mywebservice.com", parameters: myparameters)
.response { (request, response, data, error) in
if(error != nil){
print("error= \(error)")
}else{
print("there was no error so far ")
print(data)
var json = JSON(data!)
print(json) //prints unknown
print(json["id"]) //prints null
}
}
}
I tried different things but so far nothing worked. I'm using alamofire and swiftyjson, the response json that comes from webservice is:
{
"id": "432532gdsg",
"username": "gsdgsdg"
}
and I want to print both values separately in case of success. How can I do it?
Your issue comes from this line:
var json = JSON(data!)
The JSON() initializer from SwiftyJSON can take several type of inputs.
When you don't specify the type in the init, SwiftyJSON tries to infer the type itself.
Unfortunately it sometimes fails silently because it will have misinterpreted the input.
So, when using SwiftyJSON with NSData, the solution is to specify the "data:" parameter for the JSON initializer:
var json = JSON(data: data!)
Try this
Alamofire.request(.POST, "http://mywebservice.com", parameters : myparameters , encoding : .JSON )
.responseData{ response in
let json = JSON(data.response.result.value!)
print(json)
let id=json["id"]
let username=json["username"]
print(id)
print(username)
}

Alamofire request coming up nil

I'm developing an iOS app which user WebServices and I find Alamofire just perfect for what I'm doing but I'm having a problem; the app asks the user to login which is an Alamofire call and does it just fine.
The problem is, it has to create a collection view based on the content of another Alamofire request but is always nil.
func getJSON(URLToRequest: String) -> JSON {
let comp:String = (prefs.valueForKey("COMPANY") as? String)!
let params = ["company":comp]
var json:JSON!
let request = Alamofire.request(.POST, URLToRequest, parameters: params).responseJSON {
response in
switch response.result {
case .Success:
if let value = response.result.value {
json = JSON(value)
}
default:
json = JSON("");
}
}
debugPrint(request.response)
return json;
}
The same codeblock works perfect for the Login but doesn't in this case BTW the debug Print always print nil
You're trying to access to request.response before it has been set, remember that Alamofire works asynchronously, so you have to return in your case the JSON using closures, but remember that Alamofire also returns an error, so I strongly recommend use the following code instead:
func getJSON(URLToRequest: String, completionHandler: (inner: () throws -> JSON?) -> ()) {
let comp:String = (prefs.valueForKey("COMPANY") as? String)!
let params = ["company":comp]
let request = Alamofire.request(.POST, URLToRequest, parameters: params).responseJSON {
response in
// JSON to return
var json : JSON?
switch response.result {
case .Success:
if let value = response.result.value {
json = JSON(value)
}
completionHandler(inner: { return json })
case .Failure(let error):
completionHandler(inner: { throw error })
}
}
The trick is that the getJSON function takes an additional closure called 'inner' of the type () throws -> JSON?. This closure will either provide the result of the computation, or it will throw. The closure itself is being constructed during the computation by one of two means:
In case of an error: inner: {throw error}
In case of success: inner: {return json}
And then you can call it like in this way:
self.getJSON("urlTORequest") { (inner: () throws -> JSON?) -> Void in
do {
let result = try inner()
} catch let error {
print(error)
}
}
I hope this help you.

cannot parse json using swift in iOS

I'm trying to get value from json but it is giving this error
type of expression is ambiguous without more context
My ViewController code is
Alamofire.request(.GET, "http://resturl.com/rest/loginuser",
parameters: ["password":uPwd,"username": uEmail,], encoding: .JSON).responseJSON() {
(request,response, data,error) in
let jsonData = NSJSONSerialization.JSONObjectWithData(data, options: nil, error: &error) as? NSDictionary // it is giving error here
if let parseJson=jsonData{
var result:String=parseJson[""] as String!;
}
}
I've searched internet but couldn't find any appropriate solution. Please guide me with this
Alamofire.request(.GET, "http://resturl.com/rest/loginuser",
parameters: ["password":uPwd,"username": uEmail,], encoding: .JSON)
.responseJSON { _, _, JSON, _ in
if let parseJson=JSON{
println(parseJson)
}
}
First thing the data will return in json format. So don't need to convert it in json format. So please use my code. Hope it will help you.
Second thing remove last semicolon(, ) which is extra in this line.
["password":uPwd,"username": uEmail,]
Alamofire.request(.GET, "http://resturl.com/rest/loginuser",
parameters: ["password": uPwd,"username": uEmail], encoding: .JSON).responseJSON() {
(request,response, data,error) in
if let jsonData : NSDictionary = data as! [NSDictionary : AnyObject]{
// do stuff over here
}
else{
println(data)
println(error)
}
}

Resources