AnyObject to string in swift - ios

I am stuck on this code! I want to remove the optionals what is the best way to do that?
I tried to change the AnyObject in to NSString but I don't know how.
What is the best way to do this?
And my second question is how do I store this in the core data? Is there a cool framework for this?
Alamofire.request(.GET, urlDb)
.responseJSON { (request, response, json, error) in
println(error)
//println(json)
if let contactGroups : AnyObject! = json{
//println("Contact groepen")
var contactGroups = contactGroups["contact_groups"] as NSArray
for cG in contactGroups {
println(cG["group_id"]!)
//println(cG["contact_id"]!)
}
}
if let contacts : AnyObject = json{
//println(contacts["contacts"])
println("Contacten")
var contacts = contacts["contacts"] as NSArray
for c in contacts{
println(c["id"])
println(c["name"])
}
}
}
This is the console log
nil
Optional(1)
Optional(2)
Contacten
Optional(1)
Optional(Dirk Sierd de Vries)
I hope you guys can help me with my school project :D

Modify for loop like below:
for c in contacts {
println(c["id"] as NSString)
println(c["name"] as NSString)
}
Explanation:
In Swift you have to specify object to specific type. If you not than it will by default showsOptional keyword. Here your dictionary key values are directly printed on log and you have not specified that which type of value stored in dictionary.
About Saving in Core Data:
No there isn't any cool framework which can save data into core data. You need to do it your self. Below link is best to follow to start learning this.
Swift + Core data

Related

How to model data from JSON array with no property name into swift so It can be parsed? SWIFT

Im stuck trying to model a JSON array which has no property name into my swift project with the goal of parsing the data and using it in my app. I know how to do this when there is a NAME for the array but I don't know how to make swift and this lackluster JSON understand each other. The path to the first "Company" in the JSON is "0.Company". The error I get is "Value of type 'WorkData' has no member '0'"
Im including pictures of my full project so it is easier to understand the structure of the code and what im trying to do. Please look at the picture for a clearer understanding I apologize if Im not explaining it well i'm new to programming.
import Foundation
class WorkData: Codable {
let WorkData: [WorkData]
let Company: String
let worklogDate: String
let issue: String
}
func parseData(jsonDataInput: Data) {
let decoder = JSONDecoder() // an object that decodes JSON data
do {
let decodedData = try decoder.decode(WorkData.self, from: jsonDataInput)
let Company = decodedData.0.Company
let worklogDate = decodedData.0.worklogDate
let issue = decodedData.0.issue
} catch {
print (error)
}
}
}
json
Trying to model JSON in Swift
Parsing JSON
You cannot start JSON with an array because JSON itself is an object {}
See example below:
{
"WorkData" : [
{"Company" : ""},
{"Company" : ""},
{"Company" : ""}
]
}
let decodedData = try decoder.decode(LocalizationsResponse.self, from: jsonDataInput)
decodedData will be an array

Swift 3: Array Value for key

New to swift, just trying to catch some data.
so here is my swift code i used
let url = Bundle.main.url(forResource: "kurdiebg", withExtension: "plist")!
do {
let data = try Data(contentsOf: url)
let dataArray = try PropertyListSerialization.propertyList(from: data, format: nil) as! [[String:String]]
// Bloody Error is this
let request = dataArray(value(forKey: "Key"))
print(dataArray.count)
} catch {
print("This error must not happen", error)
}
i am getting
Cannot call value of non-function type '[[String : String]]'
what exactly i am trying to do?
so i have this plist file and i want to allow users to search in it , i perform this via a button action with this code above, so if a user write abbey, it would get the kurdi meaning,
The error occurs because you are using wrong syntax.
dataArray is not a function, you probably mean
dataArray.value(forKey: "Key")
However using KVC methods like value(forKey is only useful if you know what KVC is and why you need KVC. In this case it's inappropriate.
dataArray – as the name implies – is an array which is subscripted by index so you can get for example the value for key english of the first item with
dataArray[0]["english"]
which is a synonym for
dataArray[0].object(forKey:"english")
Or if you want to find an item for a specific key
dataArray.first(where: { $0["english"] == "abbey"})

Get json results in NSuserDefault and display result for annotation in MapKit in Swift

I want to get result from json and save this result in NSUserDefault, after I want to use the json array saved in NSUserDefault to add multiple annotation on the MapKit.
Currently to get json result, I use this : ( Swift 2.x )
let defaults = NSUserDefaults.standardUserDefaults()
//Get user content//
let url = NSURL(string: "http://www.example.com/folder/coordonate.php")
let request = NSMutableURLRequest(URL: url!)
// modify the request as necessary, if necessary
let task = NSURLSession.sharedSession().dataTaskWithRequest(request) {
data, response, error in
if data == nil {
print("request failed \(error)")
return
}
do {
if let json = try NSJSONSerialization.JSONObjectWithData(data!, options: []) as? NSDictionary {
print(json)
// print : {tab = "[london,paris]";}
var test = json["tab"]
defaults.setObject(test, forKey: "annotation") as? NSArray
}
} catch {
print(error)
}
}
task.resume()
NSUserDefaults.standardUserDefaults().synchronize()
And to get the NSUserdefault in another view, I try this code :
let defaults = NSUserDefaults.standardUserDefaults()
let test = NSUserDefaults.standardUserDefaults().objectForKey("annotation") as! NSArray
map.addAnnotations(test as! [MKAnnotation])
print("We saved this data: \(test)")
//No print, error before
But I have an error when I try with this method.
Could not cast value of type '__NSCFString' (0x1971a3958) to 'NSArray' (0x1971a4308).
If the "tab" property JSON actually being returned is:
[london, paris]
Then the property is not an array. What you're looking for would be:
['london', 'paris']
But additionally I can tell you that even if the "tab" property is a properly formatted JSON array your code will fail when it attempts to convert it to [MKAnnotation] anyway. That's because iOS's JSON library does not know how to convert a generic NSArray into it's typed equivalent. The NSJSONSerialization documentation indicates all the types that JSON will convert to. Best case scenario the "tab" property is an array of items with the same structure as MKAnnotation and are being converted to an array of dictionaries that you will have to convert to MKAnnotation yourself. But the JSON provided currently evaluates as a string. With my suggested change it will instead evaluate to an array of strings- still not sufficient to create an MKAnnotation from.
Your JSON data has to be one of the valid NSUserDefault types (String, NSArray, NSDictionary, NSData).
The quickest fix would be to store the JSON in NSUserDefaults as the NSData that comes back from the server. Then deserialize the NSData on the reading of NSUserDefaults.
If storing a subset of the JSON from the server is really needed, I would use Dictionaries, Arrays and validate the data before storing it. As a general Swift rule, I avoid using NSDictionary and NSArray to ensure the types are what I expect and won't cause a runtime crash.
change your php code to
$results = Array("tab" => ["london","paris"]);
instead of
$results = Array("tab" => "[london,paris]");
p.s
if using php earlier than 5.5 (or 5.4 not quite remember) then use:
$results = Array("tab" => Array("london","paris"));
==========================
you are casting the setObject func to NSArray and not the test object
defaults.setObject(test, forKey: "annotation") as? NSArray
should be
if let arrayTest = test as? NSArray{
defaults.setObject(arrayTest, forKey: "annotation")
}

iOS 9 JSON Parsing loop

I'm creating an app that should retrieve some JSON from a database.
This is how my JSON looks:
[{"id":"1","longitude":"10","latitude":"10","visibility":"5","timestampAdded":"2015-10-01 15:01:39"},{"id":"2","longitude":"15","latitude":"15","visibility":"5","timestampAdded":"2015-10-01 15:06:25"}]
And this is the code i use:
if let jsonResult = JSON as? Array<Dictionary<String,String>> {
let longitudeValue = jsonResult[0]["longitude"]
let latitudeValue = jsonResult[0]["latitude"]
let visibilityValue = jsonResult[0]["visibility"]
print(longitudeValue!)
print(latitudeValue!)
print(visibilityValue!)
}
As you can see it only gets the first chunk from the JSON and if there are no JSON at all it will crash, but if i want it to count the amount and make an array out of it like this:
var longitudeArray = [10, 15]
var latitudeArray = [10, 15]
And so on...
I also need this to be apple watch compatible so i can't use SwiftyJSON.
What do i do? I really hope you can help me!
Thanks.
SOLVED!
Problems was solved by "Eric D."
This is the code:
do {
if let url = NSURL(string: "YOU URL HERE"),
let data = NSData(contentsOfURL: url),
let jsonResult = try NSJSONSerialization.JSONObjectWithData(data, options: []) as? [[String:AnyObject]] {
print(jsonResult)
let longitudeArray = jsonResult.flatMap { $0["longitude"] as? String }
let latitudeArray = jsonResult.flatMap { $0["latitude"] as? String }
print(longitudeArray)
print(latitudeArray)
}
} catch let error as NSError {
print(error.description)
}
Thank you soo much Eric!! :-)
You could use flatMap to get an array of your elements:
let longitudeArray = jsonResult.flatMap { $0["longitude"] as? String }
let latitudeArray = jsonResult.flatMap { $0["latitude"] as? String }
etc.
flatMap is like map but unwraps optionals, which is adequate because we need to safely cast the type of the object we get from each dictionary in the json array.
$0 represents the object in the current iteration of flatMap of the array it's applied to.
If you're currently using SwiftyJSON, then that would be:
let longitudeArray = jsonResult.flatMap { $1["longitude"].string }
let latitudeArray = jsonResult.flatMap { $1["latitude"].string }
because .string is SwiftyJSON's optional String value getter.
But as you said, you don't want to use it (anymore), so you need to use NSJSONSerialization to decode your JSON data, there's plenty of examples on the Web and on SO. Then you will be able to use my original answer.
You're already getting an array with all of the elements (not just the first one. you're simply only accessing the first one). jsonResult is an array of dictionaries. Each dictionary (in this case, based on the json you provided) contains these elements: id, longitude, latitude, visibility and timestampAdded. In order to access each of them, you can simply loop over jsonResult and access the i'th element (and not always the 0 element). This will also prevent the crash you're experiencing with the json is blank or invalid (since you'll only be going over the valid elements in jsonResult.
This will give you the flexibility to create the custom arrays you wish to create (in order to create an array of all of the longitudes, for example, you will simply add that element to the new array while looping over jsonResult). However, if you'd like to save yourself the trouble of manually building these arrays and assuming you have control over the json structure, I would recommend changing the received json to the relevant structure (a dictionary or arrays instead of an array of dictionaries), so it would better fit your needs and provide you the results in the relevant format right "out of the box".

iOS, Swift - JSON Response. VK SDK

I am using the VK SDK for iOS, and I need to take out the images URLs from JSON response from VK.
The response is look like this:
The actual response could be AnyObject OR String, and I only need the largest image URL (photo_1280) as string.
In the response comes 1-10 photos and which parameters I will need to change to get the particular photo like first or second and so on.
I'm using Swift in my project but can understand Objective-C.
JSON is just a format that lets you exchange information between languages (or objects).
You need to 'parse' the string into a JSON object. Its a little different for each language. For example on iOS I create my UI elements from a JSON file where I load the file and create a dictionary object from it. In your case you are doing it from a string. You need to turn that string into a valid object in your language. In Swift I prefer a Dictionary. So I use a typealias for that and cast the nsDictionary as that type of object.
Then to access objects, I access keys in the dictionary. In your case you would create a dictionary object too, and access the "attachments" object, which in your case is an array so you'll need to do extra processing on it to get each image (i.e. go through the array). This should get you going.
typealias Dict = Dictionary<String,AnyObject>
func loadDictionaryFromJSON(jsonString:String) -> Dict
{
var JSONData:NSData! = jsonString.dataUsingEncoding(NSUTF8StringEncoding)
var JSONError:NSError?
let swiftObject:AnyObject = NSJSONSerialization.JSONObjectWithData(JSONData, options: NSJSONReadingOptions.AllowFragments, error: &JSONError)!
if let nsDictionaryObject = swiftObject as? NSDictionary
{
if let dictionaryObject = nsDictionaryObject as Dictionary?
{
return dictionaryObject as Dict
}else
{
println("Error could not make dictionary from NSDictionary in \(self)")
}
}else
{
"Error could not make NSDictionary in \(self)"
}
println("Empty dictionary passed, fix it!")
return Dict()
}
Now to access things you just do
var objects:Dictionary<String,AnyObject> = loadDictionaryFromJSON("{"what":"ever"}")
var whatever = objects["what"]

Resources