I am having trouble with parsing json using alamofire (it is working fine using browser or postman),below is my code
Alamofire.request(.POST, reqStr.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLQueryAllowedCharacterSet())! , parameters: nil).responseJSON { response in
GMDCircleLoader.hideFromView(self.view, animated: false)
if let dict = response.result.value {
self.selectArray = dict as! NSArray as! [NSDictionary]
if self.selectArray.count == 0 {
}else{
self.selectProperty.hidden = false
}
}
}
i am getting below error Error Domain=NSCocoaErrorDomain Code=3840 "Invalid value around character 14." UserInfo={NSDebugDescription=Invalid value around character 14.}
and searched a lot some body suggested that use responseString instead of responseJSON, if i use responseString i am getting data but in string format like
"{"Properties":[{ "ID":"22", "post_title":"Test Property" },{ "ID":"24", "post_title":"TestProperty" }]}"
how can convert it to Dictionary i used below code
if let dict = response.result.value
self.resulArray = dict as! [NSDictionary];
BUt it is crashing.
1)is their any way to get the results using responseJSON.
2) if i use responseString how to get convert to dictinary.
thanks in advance , I am new in Swift i am using swift2.0.
Related
How to Convert this one. "{\n ID = \"d9a7c7bf-781d-47b3-bb4e-e1022ec4ce1b\";\n Name = Headquarters;\n}"; To this format {
"ID": "d9a7c7bf-781d-47b3-bb4e-e1022ec4ce1b",
"Name": "Headquarters"
}
if let jsonString = text as? String {
let objectData = jsonString.data(using: String.Encoding.utf8)
do {
let json = try JSONSerialization.jsonObject(with: objectData!, options: .allowFragments) as! [String:Any] //try JSONSerialization.jsonObject(with: objectData!, options: JSONSerialization.ReadingOptions.mutableContainers)
print(String(describing: json))
return json
} catch {
// Handle error
print(error)
}
}
Blockquote
First of all and already mentioned the string format is clearly not JSON.
It's the string format which is returned when calling the description property of a Foundation collection type (NSArray / NSDictionary).
For example a print statement calls description and this format appears also in output of Terminal.app.
However there is a solution: This string format is called openStep (an OpenStep / NeXt legacy format) and is available in PropertyListSerialization
This code reads the format:
let string = "{\n ID = \"d9a7c7bf-781d-47b3-bb4e-e1022ec4ce1b\";\n Name = Headquarters;\n}"
let data = Data(string.utf8)
do {
let dictionary = try PropertyListSerialization.propertyList(from: data, format: nil)
print(dictionary)
} catch { print(error) }
Note:
I'm pretty sure that the original data format is not openStep and somewhere you created the string unnecessarily with the String(describing initializer like in the question.
your json format is incorrect. If you try it with jsonformatter it will throw this error:
so first you need to replace ; with ,. The second is that Strings should be wrapped in double quotes, replace Name = Headquarters with Name = "Headquarters".
This is the right form
{\n ID = \"d9a7c7bf-781d-47b3-bb4e-e1022ec4ce1b\",
\n Name = "Headquarters"\n}
I am using SwiftyJson library for parsing my following json
{
"data": {
"id": "12345",
"messages": {
"message": "{\"data\":{\"msg\":\"HelloMsg\"}}"
}
}
}
I tried to use following code to get msg parameter
let json = JSON(data)
let msg = JSON(json["data"]["messages"]["message"])
msg["data"]["msg"].stringValue
However, I could not get the value of msg parameter. What shall I do to get HelloMsg?
The content of the "message" field is not parsed JSON, it's a JSON string.
Use SwiftyJSON's JSON(parseJSON:) initializer to accept a string as input and parse it as JSON:
let messages = json["data"]["messages"]["message"].stringValue
let innerJSON = JSON(parseJSON: messages)
let msg = innerJSON["data"]["msg"].stringValue // "HelloMsg"
The error occurs because JSON(...) is the wrong API to initialize and parse a SwiftyJSON object from a string.
You have to use this syntax:
let json = JSON(data)
let msg = JSON(parseJSON: json["data"]["messages"]["message"].stringValue)
msg["data"]["msg"].stringValue
From the documentation of init(_ object: Any):
note: this does not parse a String into JSON, instead use init(parseJSON: String)
Edit:
To test the code in a Playground
let str = """
{"data": {"id": "12345",
"messages": {
"message": "{\\"data\\":{\\"msg\\":\\"HelloMsg\\"}}"
}
}
}
"""
let data = Data(str.utf8)
let json = JSON(data)
let msg = JSON(parseJSON: json["data"]["messages"]["message"].stringValue)
msg["data"]["msg"].stringValue
The JSON as traditional literal string is
let str = "{\"data\": {\"id\": \"12345\",\"messages\": {\"message\": \"{\\\"data\\\":{\\\"msg\\\":\\\"HelloMsg\\\"}}\"}}}"
The messaage is a string. not a JSON. so SwiftyJson could not parse it. You will have to first parse that string and than get the message from that using JSONSerialization.jsonObject(with: Data, options: JSONSerialization.ReadingOptions).
You can refer to this answer to get the dictionary from that string: https://stackoverflow.com/a/30480777/7820107
Your second "message" key value is a String with a dictionary in JSON format, so you need to convert that string to JSON and access to ["data"]["msg"] then
Code
let json = JSON(data)
let msg = json["data"]["messages"]["message"]
let jsonFromString = JSON(data: msg.data(using: .utf8)!, options: JSONSerialization.ReadingOptions.allowFragments, error: nil)
debugPrint(jsonFromString["data"]["msg"])
Output
HelloMsg
This question already has answers here:
How do I decode HTML entities in Swift?
(23 answers)
Closed 5 years ago.
I'm using NSURLSession to communicate with a Webservice. However, in the JSON from Webservice I'm getting strings like this Biblotecas de cat& aacute;logos de Marcas i.e. Biblotecas de catálogos de Marcas. I need to get rid of the text cat& aacute;logos and get the original string. How can i do this.
I'm using this code for parsing the JSON.
guard let json = try JSONSerialization.jsonObject(with: data, options: []) as? [String:Any] else{
self.showalertview(messagestring: parseError)
return
}
The best way is to ask the owner of the webservice to send UTF-8 compliant text.
If this is not possible NSAttributedString can decode HTML entities in a very convenient way, this is a String extension adding the computed property htmlDecoded. As the conversion can fail for several reasons the return value is an optional:
extension String {
var htmlDecoded : String? {
guard let encodedString = self.data(using: .utf8) else { return nil }
let options : [String:Any] = [NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType,
NSCharacterEncodingDocumentAttribute: String.Encoding.utf8.rawValue]
return try? NSAttributedString(data: encodedString, options: options, documentAttributes: nil).string
}
}
And use it:
let string = "Biblotecas de catálogos de Marcas"
print(string.htmlDecoded) // "Biblotecas de catálogos de Marcas"
This is my code:
do {
if let json = try NSJSONSerialization.JSONObjectWithData(data!, options: []) as? NSDictionary {
print(json)
let success = json ["success"] as? Int
print("Success: \(success)")
And this is my output:
{
error = "Account does not exist, please create it!";
}
Success: nil
`
So, before let success = json ["success"] as? Int, everything works well, but why is my output after this line nil?
This is my php:
public function login($username,$password) {
$query = "Select * from users where username = '$username' and password = '$password'";
$result = mysqli_query($this->connection, $query);
if (mysqli_num_rows($result) > 0) {
$json['success'] = 'Welcome '. $username . '!';
echo json_encode($json);
mysqli_close($this->connection);
} else {
$json['error'] = 'Account does not exist, please create it!';
echo json_encode($json);
mysqli_close($this->connection);
}
let success = json ["success"] as? Int
When you use this line it will extract the value of the key "success". As your json response does not contain that field it sets nil in the success variable.
Along with the error key you will need to return the success key too.
Success is nil because key 'success' does not exist in the JSON.
X as? Int = try to make x an Int from X when possible. If not possible (because the value is nil or the value is not convertible to an Int), make it Nil. That's what the question mark does.
So, I would do this:
if let success = json ["success"] as? Int {
print("Success: \(success)")
} else {
// Failed
}
You could also change your PHP code to make sure it always returns the 'success' key. However, I would recommend to use the Swift code above since you are always safe then.
I am new to SwiftyJSON, and I'm having some trouble with it. I can get it to return the entire JSON file as a string, but the moment I try to parse it, I keep getting empty variables back, and I'm not sure what I'm doing wrong.
This is the formatting of my JSON file:
[
{
"entryID": 1,
"from": "String",
"to": "String",
"value": "String"
},
{
...
},
...
]
And this is roughly what I want to do with it (in quite inelegant code, I do apologise, I'm new to Swift):
for entry: JSON in indexJSON.arrayValue {
var vEntryID: Int
var vFrom: String
var vTo: String
var vValue: String
for (dictKey: String, dictVal: JSON) in entry.dictionaryValue {
if(dictKey=="entryID") {vEntryID = dictVal.intValue}
if(dictKey=="from") {vFrom = dictVal.stringValue}
if(dictKey=="to") {vTo = dictVal.stringValue}
if(dictKey=="value") {vValue = dictVal.stringValue}
}
someSwiftObject[vEntryID]["from"] = vFrom
someSwiftObject[vEntryID]["to"] = vTo
someSwiftObject[vEntryID]["value"] = vValue
}
However, this block never executes at all, because indexJSON.arrayValue is always empty.
When I try to run the following, it correctly prints the complete file contents to the console:
let indexJSON = JSON(content!)
println(indexJSON.stringValue)
But when I try to go deeper, to fetch any element, it returns nothing:
if(indexJSON.arrayValue.isEmpty==true) {println("indexJSON.arrayValue is Empty")}
if(indexJSON[0].arrayValue.isEmpty==true) {println("indexJSON[0].arrayValue is Empty")}
if(indexJSON[0].dictionaryValue.isEmpty==true) {println("indexJSON[0].dictionaryValue is Empty")}
if(indexJSON[0]["entryID"]==nil) {println("indexJSON[0][\"entryID\"].stringValue is Empty")}
Output:
indexJSON.arrayValue is Empty
indexJSON[0].arrayValue is Empty
indexJSON[0].dictionaryValue is Empty
indexJSON[0]["entryID"].stringValue is Empty
I'd be grateful for any help! What am I doing wrong?
I checked SwiftyJSON source code and I think I know where the problem is.
I suppose that you are using String to initialize the JSON object like this
let s = "{\"entryID\": 1,\"from\": \"String\",\"to\": \"String\",\"value\": \"String\"}"
let j = JSON(s)
In this case the JSON object is actuall given a type "String", not Array. That's why it's not iterable and its arrayValue is empty.
To do what you want to do, you need to initialize it with an Array object:
let arr = [
[
"entryID":1,
"from":"String",
"to":"String",
"value":"String",
]
]
let j2 = JSON(arr)
Now j2 is an array JSON object and iterable.
SwiftyJSON can only be initialized with NSData and object. So if you want to initialize it with a String you need to do this:
if let data = s.dataUsingEncoding(NSUTF8StringEncoding) {
let j = JSON(data:data)
println(j)
}
first of all, make sure the format of your json string is correct. in your question, your json string is a array, just format the string like this(the content is from my code):
let jsonStr = "[{\"name\": \"hangge\", \"age\": 100, \"phones\": [{\"name\": \"公司\",\"number\": \"123456\"}, {\"name\": \"家庭\",\"number\": \"001\"}]}, {\"name\": \"big boss\",\"age\": 1,\"phones\": [{ \"name\": \"公司\",\"number\": \"111111\"}]}]"
then you can use SwityJson to get the array object, like this:
let strData = jsonStr.data(using: String.Encoding.utf8, allowLossyConversion: false)
let json = JSON(data: strData!)
for object in json.arrayValue {
let name = object["name"].string
}
Take a look at the documentation here: https://github.com/lingoer/SwiftyJSON#loop
You are iterating it incorrectly. You should be iterating over the array with a for loop like this:
for (index: String, subJson: JSON) in json {
//Do something you want
}