JSONSerialization did't serialised data as server send - ios

JSONSerialization didn't serialise data as server send. It reverses turn the data. I use data filter API from backend. its send the accurate data, I've also checked in postman and android side but iOS code changes the response.
do {
if let json = try JSONSerialization.jsonObject(with: usableData, options: .mutableLeaves) as? [String: Any] {
}
} catch let error {
OperationQueue.main.addOperation() {
SVProgressHUD.dismiss()
}
}
But if i convert the data into string then its shows correct. WHY?
var jsonString : String?
jsonString = String.init(data: data, encoding: String.Encoding.utf8)

Finally, I've got the solution. Server sends the data more than 100 keys in dictionary which is incorrect form, with this format our json serialisation could not able to serialised the data as we got from server.so we have decided to change the structure from dictionary to Array.
Incorrect form
1025{
id:1025
name:xyz
area:23123
}
1026{
id:1026
name:xyz
area:23123
}
1027{
id:1027
name:xyz
area:23123
}
Correct Form
[
id:1025
name:xyz
area:23123
,
id:1026
name:xyz
area:23123
,
id:1027
name:xyz
area:23123
]

Related

Alamofire.uploadmultipartFormData with JSONEncoding.default (Swift)

i have to send photo and json to server.
my json is :
{"anticorona":"Anti_Covid","time":"Time","navigateds":[{"collection_public_key":"Origin_Station.collection_public_key","station_public_key":"Origin_Station.public_key"},{"station_public_key":"Des_Station.public_key","collection_public_key":"Des_Station.collection_public_key"}],"seats":"Seats","date":"Date"}
how can i send this json with Alamofire.uploadmultipartFormData
i know i can use encoding: JSONEncoding.default in Alamofire.request but can in use JSONEncoding.default when use Alamofire.uploadmultipartFormData?
thanks
You seem to be new and it would be nice if you could perhaps add some code you have tried in future questions of yours. Anyways, as far as I can see this should be possible in the following way. I am assuming the key "navigateds" remains the same. Otherwise you could also check if the value (in the for-in-loop) is an array, too:
// set parameters for request
let antiCoronaParameters: Parameters = [
"anticorona" : "Anti_Covid",
"time":"Time",
"navigateds":[
["collection_public_key":"Origin_Station.collection_public_key", "station_public_key":"Origin_Station.public_key"],
["station_public_key":"Des_Station.public_key", "collection_public_key":"Des_Station.collection_public_key"]
],
"seats":"Seats",
"date":"Date"
]
let upload = AF.upload(multipartFormData: { (formData) in
// I would append file data here first
for (key, value) in antiCoronaParameters {
if key == "navigateds" {
do {
let arrayData = try JSONSerialization.data(withJSONObject: value, options: .prettyPrinted)
formData.append(arrayData, withName: key)
} catch {
print("could not append array, failed with error:", error)
}
} else if let string = value as? String, let stringData = string.data(using: String.Encoding.utf8, allowLossyConversion: false) {
formData.append(stringData, withName: key)
} else {
print("could not append some data in parameters")
}
}
}, to: "https://www.yourURLhere.com/link.php", method: .post).validate()
upload.responseString { (responseString) in
print(responseString)
}
This answer is based on this question. In the future, I would recommend trying lots of keywords relating to your question. Initially, searching for questions will consume more time but you will get the hang of it soon enough I'm sure. Just keep trying a little more next time maybe ;)
However, as you already mentioned there's another way, too, and I prepared it for you if you would like to check it out. You essentially mentioned it already and I'd always prefer it over the upload unless there's a very good reason:
// set parameters for request
let antiCoronaParameters: Parameters = [
"anticorona" : "Anti_Covid",
"time":"Time",
"navigateds":[
["collection_public_key":"Origin_Station.collection_public_key", "station_public_key":"Origin_Station.public_key"],
["station_public_key":"Des_Station.public_key", "collection_public_key":"Des_Station.collection_public_key"]
],
"seats":"Seats",
"date":"Date"
]
// request with json encoded parameters (e.g. sending to php)
let antiCoronaRequest = AF.request("https://www.yourURLhere.com/link.php", method: .post, parameters: antiCoronaParameters, encoding: JSONEncoding.default).validate()
antiCoronaRequest.responseString(completionHandler: { (response) in
print(response)
})
Hit me up if you have any questions.

How could I "force" all properties in a struct? To be able to send them to an API?

I want to know how can I force all the properties from this struct to be able to send a POST request to our API?
First of all. I need all those optional properties because I make a GET request, I receive all those documents, I process the data, I add the file property (which is an object) then I need to send all those documents back to our server with a file added.
We have our Document
struct Document: Codable {
let allowedFormats: [String]?
let processWhereApply: [String]?
let isRequired: Bool?
let id, key, title, description: String?
var file: File?
// More properties
}
But it fails every time, because I'm not sending a string for example. I'm sending an Optional<String>
Is there anyway possible I can "force" all those properties to send them back? without like writting 25 lines of guard let var = var else { return } ?
I'm sending the POST request with the parameters like this
let params = [
"userId": userId,
"groupId": groupId,
"fileDocuments": documents! //sends all properties optional
] as [String: Any]
Api().saveDocuments(params: params)
I'm assuming that you are sending the data back as Json. In that case just use the Json encode method to convert the struct to Json which can be sent as a POST request. Json encode will deal with the null value issue by setting a corresponding value to the key in your json if the value exists and not creating the key if it doesn't exist.
For example just to get the json:
let doc1 = Document(!here you will be initialising variables!)
// below gives you json as data
let json = try! JSONEncoder().encode(doc1)
// if you want your json as string
let str = String(decoding: json, as: UTF8.self)
Here is an example making an alamofire POST request. In the case of alamofire it automatically encodes your struct as long as it conforms to Codable:
let doc1 = Document(!here you will be initialising variables!)
AF.request("https://yoururl.com",method: .post,parameters: doc1, encoder: JSONParameterEncoder.default).responseJSON { response in
switch response.result {
case .success(let json):
print("good response")
break
case .failure(let error):
print("bad response"
}
}

use of "po" to get data from server response in console log

i know this is very basic question that i am gonna ask but i need to ask how can i access data which is dictionary that is getting from server.
here is my response
JSON: {
message = "The email must be a valid email address.";}
now i want to do "po" in console log so what to write after in po statement
Thanks
All you need type
po yourResponseAsDictionary["message"]
UPDATED
Sorry I was thinking you already converted it.
If you are not using anything like SwiftyJSON or ObjectMapper to parse your json data then you can do just the following.
But I would recommend to use some lib to convert response directly to your model
let yourResponseFromNetwork = "{ \"country_code\" : \"+9\", \"user_id\" : 123456}"
if let data = yourResponseFromNetwork.data(using: String.Encoding.utf8) {
do {
if let dic = try JSONSerialization.jsonObject(with: data, options: .mutableContainers) as? [String:Any] {
let countryCode = dic["country_code"]
let userId = dic["user_id"]
}
} catch {
print("Error occurred")
}
}

How to remove xml tags before send to the json parser in swift

I want to use JSON data in my app. So I am using this webservice calling method to convert my json data to an array.
func getData(path: String, completion: (dataArray: NSArray)->()) {
let semaphore = dispatch_semaphore_create(0)
// var datalistArray = NSArray()
let baseUrl = NSBundle.mainBundle().infoDictionary!["BaseURL"] as! String
let fullUrl = "\(baseUrl)\(path)"
print("FULL URL-----HTTPClient \(fullUrl)")
guard let endpoint = NSURL(string:fullUrl) else {
print("Error creating endpoint")
return
}
let request = NSMutableURLRequest(URL: endpoint)
NSURLSession.sharedSession().dataTaskWithRequest(request,completionHandler: {(data,response,error) in
do {
guard let data = data else {
throw JSONError.NoData
}
guard let json = try NSJSONSerialization.JSONObjectWithData(data, options: []) as? NSArray else {//NSJSONReadingOptions.AllowFragments
throw JSONError.ConversionFailed
}
print(json)
if let data_list:NSArray = json {
completion(dataArray: data_list)
dispatch_semaphore_signal(semaphore);
}
}catch let error as JSONError {
print(error.rawValue)
} catch let error as NSError {
print(error.debugDescription)
}
}) .resume()
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
}
But now my service sending json data within xml tags like <string xmlns="http://tempuri.org/">json data</string so I am getting an exception when I try to convert my json data. The exception is this.
Error Domain=NSCocoaErrorDomain Code=3840 "Invalid value around character 0." UserInfo={NSDebugDescription=Invalid value around character 0.}
What should I change in my code to remove those tags before sending to json parser?
Please help me.
Thanks
I think your response that you get from server is in xml format not in json. If it is in xml format then you must do xml parsing instead of json parsing.
NSJSONSerialization.JSONObjectWithData is json parsing that give json object from data (data in json format).
But if you getting response in xml format from server then you should use NSXMLParser to parse the data.
If you don't have much idea about it then you can refer tutorial like
XML Parsing using NSXMLParse in Swift by The appguruz or can use third party libraries.

parse string and send as Json in swift

I have real big problem finding the right code which helps me to parse String to JSON and then send to external server. I'm using xCode 6.1, so some ways of parsing won't work for me, like SwiftyJSON.
On internet i only can find the way to send String , but not JSON, or if i found something it won't work.
I'm beginner in iOS and it would really help me if someone can explain me how to do it.
Thank you a lot.
If you have JSON String convert to NSData object.Check the data object before sending to an external server if data is valid JSON format or not by using NSJSONSerialization.I am giving sample code to how can check JSON Data valid or not.
suppose you String is like this,
let jsonString = "{\"device\":\"iPhone 6\",\"OS\":\"iOS 9\",\"name\":\"Apple\"}"
let data = jsonString.dataUsingEncoding(NSUTF8StringEncoding)
do {
let responseData = try NSJSONSerialization.JSONObjectWithData(data!, options: .AllowFragments)
if responseData != nil { // valid JSON
//Now pass data object to server
}
} catch {
NSLog("ERROR when parse JSON")
}

Resources