Error on serializer JSON using Swift - AutoreleasingUnsafePointer (has 1 child) - ios

I was try parse a JSON online, but cannot read this how the types generally, how:
typealias JSON = AnyObject
typealias JSONDictionary = Dictionary<String, JSON>
typealias JSONArray = Array<JSON>
Never return this types, the JSON i read is:
json:
[
{
"id":72,
"name":"Batata Cremosa",
"time":"1:30 horas",
"rcp_img_file_name":"batata-cremosa.jpg"
},
{
"id":183,
"name":"Caldeirada de Peixes",
"time":"50 minutos",
"rcp_img_file_name":"caldeirada-peixes.jpg"
},
{
"id":76,
"name":"Batata com Cebola e Ervas",
"time":"10 minutos",
"rcp_img_file_name":"batata-cebola-ervas.jpg"
},
{
"id":56,
"name":"Arroz de forma",
"time":"25 minutos",
"rcp_img_file_name":"arroz-forma.jpg"
}]
The json is read and cast in a string how this in console:
in console(var jsonString):
(
{
id = 72;
name = "Batata Cremosa";
"rcp_img_file_name" = "batata-cremosa.jpg";
time = "1:30 horas";
},
{
id = 183;
name = "Caldeirada de Peixes";
"rcp_img_file_name" = "caldeirada-peixes.jpg";
time = "50 minutos";
},
{
id = 76;
name = "Batata com Cebola e Ervas";
"rcp_img_file_name" = "batata-cebola-ervas.jpg";
time = "10 minutos";
},
{
id = 463;
name = "Pat\U00ea de Frango F\U00e1cil";
"rcp_img_file_name" = "pate-frango-facil.jpg";
time = "30 minutos";
},
...
So, this is the func that dont read the JSON, by debug when have to choice around the Objects dont enter in anyone option:
parse function:
func JSONParseArray(jsonString: String) {
println(jsonString)
var data: NSData = jsonString.dataUsingEncoding(NSUTF8StringEncoding)
var error: AutoreleasingUnsafePointer<NSError?> = nil
let jsonObj: AnyObject? = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions(0),
error: error)
println("Error: \(error)")
if jsonObj is JSONDictionary {
println("0")
}
else if jsonObj is JSONArray {
println("1")
}
}
Dont return Array or Dictionary, in debug appear this below the json:
error returned:
Error: VSs26AutoreleasingUnsafePointer (has 1 child)
and when i debug the jsonObj this return nil
Please someone help, i search by hours by info, test many things but no one works for me, thanks much.

It is easier than you think:
var error: NSError?
let jsonObj: AnyObject? = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions(0),
error: &error)
Additionally there is the question of why the JSON is being passed in as a string and not data.
jsonObj is a bad name because once it is de-serialized it is going to be an Array, not JSON.

Related

How Fix Error Domain=NSCocoaErrorDomain Code=3840 "Invalid value around character 52."

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}

Swift-Can't convert core data to url parameters

I am trying to build a small app that track device location. So save the location into core data. But can't convert it to json for sending this information to server. I got following errors
2018-12-18 13:08:33.583580+0530 My App[6696:144278] [General] An uncaught exception was raised.
2018-12-18 13:08:33.583605+0530 My App[6696:144278] [General] Invalid type in JSON write (__NSDate).
2018-12-18 13:08:33.604814+0530 My App[6696:144278] [General] (
0 CoreFoundation 0x00007fff4af112db __exceptionPreprocess + 171 ........)
Loading data from core data
func loadingFromCoreData() -> [String:Dictionary<String,AnyObject>]
{
var locationsArray: [String:Dictionary<String,AnyObject>] = [:]
var count = 0
if let context = (NSApplication.shared.delegate as? AppDelegate)?.persistentContainer.viewContext {
do {
locationDataInstance = try context.fetch(LocationInformation.fetchRequest())
} catch {
}
}
print("IN Loading From database")
for locationDI in locationDataInstance {
var location_info: [String:AnyObject]=[:]
location_info["latitude"] = locationDI.latitude as AnyObject
location_info["longitude"] = locationDI.longitude as AnyObject
location_info["timestamp"] = locationDI.timestamp as AnyObject
locationsArray["\(count)"] = location_info
count = count + 1
}
return locationsArray
}
Dictionary to Json coversion
let parameters:Dictionary<String,AnyObject> = ["name":devicename as AnyObject,"loctioninfo":loadingFromCoreData() as AnyObject]
do {
let js = try JSONSerialization.data(withJSONObject: parameters, options: .prettyPrinted)
print(js)
} catch {
print(error.description)
}
The error is pretty clear: The type of timestamp is obviously Date and JSON does not support this type.
Add a computed property to convert the Date object to UNIX timestamp or date string for example
var unixTimeStamp : Double {
return timestamp.timeIntervalSince1970
}
And get rid of this ugly as AnyObject cast by declaring the dictionary as [String:Any]

how to get value from response in swift which returns [String:AnyObject] Swift4

in my Api call i getting response in [String : AnyObject] format from this i need to get few elements and store it on Array how to achieve this in Swift4 here my sample response could help how to get values from my response
My Sample Response :
["result": valid: (
{
id = 1;
"name" = "Alen"
},
{
id = 12;
"name" = "Peter"
},
{
id = 14;
"name" = "John"
},
{
id = 16;
"name" = "Ema"
},
{
id = 19;
"name" = "Shane"
},
{
id = 211;
"name" = "Mia"
}
)]
From this response i need to get all "name" values in array how to acheive this in swift 4
You can use swiftyJSON for seperate "name" from the response
let jsonData = JSON(data : data)
data - response of your api
then use forloop for adding name data in array
Hope so, this will help you.
struct Details{
let Name : String
}
And where you are getting result from server, use this code and after that your name values will be in Result Array.
var RecordsArr = [Details]()
let Result = recordJSON.value(forKey: "result") as? [NSDictionary]
for item in Result {
let id_records = Details(Name: item[“name”]! as! String)
RecordsArr.append(id_records)
}
Let me tell, if you have any problem.

Get value of json response swift

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.

RestKit relationships not mapping when manually mapping JSON object

I am following some suggested posts on how to map incoming JSON data directly using RKMapperOperation. My entity object is being created in the data store, but without the proper relationships. Interestingly, if I create an object directly using the Core Data methods after I've already mapping incoming JSON (via websockets), the operation seems to "flesh" out my relationships in the incorrect entity.
To sum the order:
JSON data comes into app through a websocket connection
I map it using the below code, but the relationships aren't mapped
I save some other record in the same entity using a locally created (not RestKit) object with Core Data.
My object mapped from JSON now has its relationships attached!
Here is the JSON data:
{
"checkin": {
"session_id": 1,
"attendee_id": 70,
"source": "list",
"created_at": "2015-03-26 11:53:08",
"cache_id": "9234d700852df5c7402b87adf6ecfc19",
"checkout": "0",
"updated_at": "2015-03-27 03:53:09",
"id": 359
}
}
Here is my mapping function
func mapEntityFromJson(JSONString: String, key: String, mapping: RKEntityMapping!) -> NSManagedObject? {
let MIMEType = "application/json"
var error: NSError? = nil
let data = JSONString.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)
let jsonDictionary: NSDictionary = NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.MutableContainers, error: &error) as NSDictionary
let parsedData: AnyObject! = RKMIMETypeSerialization.objectFromData(data, MIMEType: MIMEType, error: &error)
if (parsedData == nil && error != nil) {
// Parser error...
return nil
}
let mappingsDictionary = [ key: mapping ]
let mappingDS = RKManagedObjectMappingOperationDataSource(managedObjectContext: self.objectStore.persistentStoreManagedObjectContext, cache: self.objectStore.managedObjectCache)
let mapper = RKMapperOperation(representation: parsedData, mappingsDictionary: mappingsDictionary)
mapper.mappingOperationDataSource = mappingDS
var mappingError: NSError? = nil
let isMapped = mapper.execute(&mappingError)
if (isMapped && mappingError == nil) {
// Trying to save twice per some other example
self.objectStore.persistentStoreManagedObjectContext.save(&error)
self.objectStore.persistentStoreManagedObjectContext.saveToPersistentStore(&error)
let result = mapper.mappingResult.firstObject() as NSManagedObject
return result
}
return nil
}
Here is the relationship mapping I'm passing to this function:
func checkinMapping() -> RKEntityMapping {
let checkinMapping = RKEntityMapping(forEntityForName: "Checkin", inManagedObjectStore: objectStore)
let checkinDictionary = ["source": "source", "checkout": "checkout", "cache_id": "cacheId", "attendee_id": "attendeeId", "session_id": "sessionId"]
checkinMapping.addAttributeMappingsFromDictionary(baseRecordDictionary)
checkinMapping.addAttributeMappingsFromDictionary(checkinDictionary)
checkinMapping.addConnectionForRelationship("attendee", connectedBy: ["attendeeId": "id"])
checkinMapping.addConnectionForRelationship("session", connectedBy: ["sessionId": "id"])
checkinMapping.identificationAttributes = ["cacheId"]
checkinMapping.setDefaultValueForMissingAttributes = true
return checkinMapping
}
Here is how the function gets called when the websocket subscription is notified:
let jsonString = "<the JSON data per above>"
let mappingResult = self.mapEntityFromJson(jsonString, key: "checkin", mapping: self.checkinMapping())
The attendee_id and session_id values should be establishing a relationship with Attendee and Session entities, but when I look at the sqlite data underlying Core Data the relationship columns are blank even though the incoming attendeeId and sessionId fields get mapped. Once I make the other save locally then those relationship columns get mapped.
Any thoughts?
EDIT:
I should add that when a checkin is mapped from a full RestKit call like .getObject or as the result of .postObject then the mapping works with no issues. It is only in the manual mapping I have here that it seems to fall apart.
Here is the final solution which involved much help from #wain and a key point from another post about needing to make the operationQueue wait until all operations are finished or else the mapping process hadn't finished mapping the relationships. So my NSManagedObject was returning with no relationships connected. The combination of a private child context for proper concurrency and saving of data along with the waiting issue fixed the problem. Here is the final mapping code:
func mapEntityFromJson(JSONString: String, key: String, mapping: RKEntityMapping!) -> NSManagedObject? {
let MIMEType = "application/json"
var error: NSError? = nil
let data = JSONString.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)
let jsonDictionary: NSDictionary = NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.MutableContainers, error: &error) as NSDictionary
let parsedData: AnyObject! = RKMIMETypeSerialization.objectFromData(data, MIMEType: MIMEType, error: &error)
if (parsedData == nil && error != nil) {
// Parser error...
return nil
}
let mapperContext = self.objectStore.newChildManagedObjectContextWithConcurrencyType(NSManagedObjectContextConcurrencyType.PrivateQueueConcurrencyType, tracksChanges: true)
let mappingsDictionary = [ key: mapping ]
let mappingDS = RKManagedObjectMappingOperationDataSource(managedObjectContext: mapperContext, cache: self.objectStore.managedObjectCache)
var mappingResult: RKMappingResult? = nil
var result: NSManagedObject? = nil
let mapper = RKMapperOperation(representation: parsedData, mappingsDictionary: mappingsDictionary)
mappingDS.operationQueue = self.operationQueue
mappingDS.parentOperation = mapper
mapper.mappingOperationDataSource = mappingDS
var mappingError: NSError? = nil
let isMapped = mapper.execute(&mappingError)
// Necessary to wait for relationships to map.
if self.operationQueue!.operationCount > 0 {
self.operationQueue!.waitUntilAllOperationsAreFinished()
}
if (isMapped && mappingError == nil) {
mapperContext.saveToPersistentStore(&error)
mappingResult = mapper.mappingResult
}
if mappingResult != nil {
result = mappingResult!.firstObject() as? NSManagedObject
}
return result
}
For now we're leaving it with the in-memory cache and don't see the duplicates issue others reported.

Resources