Parsing JSON into swift predefined array - arrays

I am trying to get items from an api (JSON) and to parse it into a predefined swift array. I have searched and looked for hours but due to my lack of skills I wasn't able to find anything suitable my case.
My predefined array looks like this:
init?(participants: String, photoguest: UIImage?, photohome: UIImage?, time: String, stadium: String, channel: String)
the JSON structure is like this(entire json file):
{"gameId":"255","gameWeek":"17","gameDate":"2016-01-03","awayTeam":"SEA","homeTeam":"ARI","gameTimeET":"4:25 PM","tvStation":"FOX","winner":"SEA"}
My current code looks like this (Games is the class where I connect variables from array with table cell items):
var gameplan = [Games]()
func loadNFLgames(){
let apiURL = NSURL(string: "http://www.fantasyfootballnerd.com/service/schedule/json/test/")
let data: AnyObject? = NSData(contentsOfURL: apiURL!)
let homeTeam = (data as! NSDictionary)["homeTeam"] as! String
let awayTeam = (data as! NSDictionary)["awayTeam"] as! String
let gameDate = (data as! NSDictionary)["gameDate"] as! String
let gameTimeET = (data as! NSDictionary)["gameTimeET"] as! String
let tvStation = (data as! NSDictionary)["tvStation"] as! String
/*
for schleife mit API daten:
for gameWeek = currentWeek{ //every game where gameWeek matches currentWeek
*/
// create variables from api calls
let api_guest = awayTeam
let api_home = homeTeam
let api_tvhost = tvStation
let api_time = gameDate + ", " + gameTimeET + " ET" // convert gameDate to day e.g. SUN
let api_stadion = "N/A"
// prepare data for array
let gamedata = Games(participants: api_guest+" # "+api_home, photoguest: UIImage(named: api_guest), photohome: UIImage(named: api_home), time: api_time, stadium: api_stadion, channel: api_tvhost)!
// add data to array
gameplan.append(gamedata)
}
I am getting the following error:
Could not cast value of type '_NSInlineData' (0x1a0cfd428) to
'NSDictionary' (0x1a0cf3380).
EDIT: The error is being thrown here:
let homeTeam = (data as! NSDictionary)["homeTeam"] as! String
Your help is highly appreciated.
Thanks in advance!

hello your data variable doesn't contain the Json you r looking for. so you have to serialize it to json like alexander suggested but NSJSONSerialization can throw an error so we have tu put in in try
so your code will be something like this (i suggest always using dispatch_async to make it in background thread than use the completion closure to get your result)-->
func loadNFLgames(completionClosure: (result : [Games]) ->()){
let queue: dispatch_queue_t = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)
dispatch_async(queue, {
let URL = "http://www.fantasyfootballnerd.com/service/schedule/json/test/"
print(URL)
if let data = NSData(contentsOfURL: NSURL(string: URL)!){
if let JsonObject = try? NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers) as! NSMutableDictionary{
print(JsonObject)
//here you can loop through the JsonObject to get the data you are looking for
//when you get your array of Games just pass it the the completion closure like this
completionClosure(result: gameplan)
}
}
})
}
PS: please let me know if you need more help.

Your data variable is NSData type (not NSDictionary). You have to convert it in order to use it. Try something like that:
let decodedJson = NSJSONSerialization.JSONObjectWithData(data, options: nil) as! NSDictionary
And than you can use it like standard dictionary
let homeTeam = decodedJson["homeTeam"] as! String

Related

Swift 4: Filtering Array

i am new to swift, currently practicing
here i have a plist file, which has an Array Of Dictionaries, each dictionary has one string, the plist has 3 records, it looks like this
item 0:
kurdi: Googlee
item 1:
kurdi: Yahooe
item 2:
kurdi: Binge
here's a image for the plist;
Screenshot 11:52AM
okay so the point is, when a user searches for oo for example two of the records contain oo, such as google and yahoo, i want to return an array of results,
for that case i used:
let path = Bundle.main.path(forResource:"hello", ofType: "plist")
let plistData = NSArray(contentsOfFile: path!)
let objCArray = NSMutableArray(array: plistData!)
if let swiftArray = objCArray as NSArray as? [String] {
let matchingTerms = swiftArray.filter({
$0.range(of: "oo", options: .caseInsensitive) != nil // here
})
print(matchingTerms)
}
but unfortunately, when i print matchingTerms it returns nil
..
thanks
If you are new to Swift please learn first not to use NSMutable... Foundation collection types in Swift at all. (The type dance NSArray -> NSMutableArray -> NSArray -> Array is awful). Use Swift native types. And instead of NSArray(contentsOfFile use PropertyListSerialization and the URL related API of Bundle.
All exclamation marks are intended as the file is required to exist in the bundle and the structure is well-known.
let url = Bundle.main.url(forResource:"hello", withExtension: "plist")!
let plistData = try! Data(contentsOf: url)
let swiftArray = try! PropertyListSerialization.propertyList(from: plistData, format: nil) as! [[String:String]]
let matchingTerms = swiftArray.filter({ $0["kurdi"]!.range(of: "oo", options: .caseInsensitive) != nil })
print(matchingTerms)
Cast swift array to [[String:Any]] not [String]. And in filter you need to check the value of the key kurdi. Try this.
if let swiftArray = objCArray as? [[String:Any]] {
let matchingTerms = swiftArray.filter { (($0["kurdi"] as? String) ?? "").range(of: "oo", options: .caseInsensitive) != nil }
print(matchingTerms)
}

how to access Array with key in swift4

I am very new to swift, I used to code in objective C, but Now I am facing alot of problems while development in Swift. Right now I have json file imported in project
let file = Bundle.main.url(forResource: "test", withExtension: "json")
do {
let data = try Data(contentsOf: file!)
//let json = try JSONSerialization.jsonObject(with: data, options: JSONSerialization.ReadingOptions.mutableContainers) as! NSDictionary
let json:NSArray = try (JSONSerialization.jsonObject(with: data, options:JSONSerialization.ReadingOptions.mutableContainers) as? NSArray)!
print(json[0])
} catch let error as NSError {
print("Failed to load: \(error.localizedDescription)")
}
It gives output like
{
Correct = 1;
EA = "50 Days ";
EB = "40 days";
EC = "90 days";
ED = "30 days";
}
And i Need to access only Content with key "EA".
previously with objective C, I used to access it like
[[json objectAtIndex:0] objectForKey:#"EA"]
Now when I am trying to access it like
json[0].objectForKey("EA") as? String
it says
Value of type 'Any' has no member 'objectForKey'
What should I do?
Swift 2
(json[0] as! NSDictionary).objectForKey("EA") as? String
Swift 3 & 4
(json[0] as! NSDictionary).object(forKey: "EA") as? String

How we can find an element from [AnyObject] type array in swift

I have [AnyObject] array
var updatedPos = [AnyObject]()
I am setting data in that according to my requirement like!
let para:NSMutableDictionary = NSMutableDictionary()
para.setValue(posId, forKey: "id")
para.setValue(posName, forKey: "job")
let jsonData = try! NSJSONSerialization.dataWithJSONObject(para, options: NSJSONWritingOptions())
let jsonString = NSString(data: jsonData, encoding: NSUTF8StringEncoding) as! String
self.updatedPos.append(jsonString)
Now in my code i have some requirement to remove the object from this array where id getting matched according to requirement Here is the code which i am trying to implement
for var i = 0; i < updatedPos.count; i++
{
let posItem = updatedPos[i]
print("Id=\(posItem)")
let pId = posItem["id"] as? String
print("secRId=\(pId)")
if removeId! == pId!
{
updatedPos.removeAtIndex(i)
}
}
Here print("Id=\(posItem)") give me output asId={"id":"51","job":"Programmer"} but here i am not able to access id from this object. here print("secRId=\(pId)") give me nil
First of all use native Swift collection types.
Second of all use types as specific as possible.
For example your [AnyObject] array can be also declared as an array of dictionaries [[String:AnyObject]]
var updatedPos = [[String:AnyObject]]()
Now create the dictionaries and add them to the array (in your example the dictionary is actually [String:String] but I keep the AnyObject values).
let para1 : [String:AnyObject] = ["id" : "51", "job" : "Programmer"]
let para2 : [String:AnyObject] = ["id" : "12", "job" : "Designer"]
updatedPos.append(para1)
updatedPos.append(para2)
If you want to remove an item by id use the filter function
let removeId = "12"
updatedPos = updatedPos.filter { $0["id"] as? String != removeId }
or alternatively
if let indexToDelete = updatedPos.indexOf{ $0["id"] as? String == removeId} {
updatedPos.removeAtIndex(indexToDelete)
}
The JSON serialization is not needed for the code you provided.
PS: Never write valueForKey: and setValue:forKey: unless you know exactly what it's doing.
After some little bit stuffs I have found the very easy and best solution for my question. And I want to do special thanks to #vadian. Because he teach me new thing here. Hey Thank you very much #vadian
Finally the answer is I had covert posItem in json Format for finding the id from Id={"id":"51","job":"Programmer"} this string
And the way is
let data = posItem.dataUsingEncoding(NSASCIIStringEncoding, allowLossyConversion: false)
do {
let json = try NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.MutableContainers)
if let dict = json as? [String: AnyObject] {
let id = dict["id"]
if removeId! == id! as! String
{
updatedLoc.removeAtIndex(i)
}
}
}
catch {
print(error)
}

Unable to add items to class Array

I am fetching data from JSON, and store inside in an NSArray. I've verified that I've successfully grab the data from JSON. The grabbed data will be stored into strings, then added into class array. However I get an error: "Thread: 6: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)"
var personList = [PersonTable]()
do {
let resultJSON = try NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions())
let resultArray = resultJSON as? NSArray
for jsonObjectString in resultArray! {
let name = jsonObjectString["Name"] as! String
let code = jsonObjectString["Code"] as! String
let description = jsonObjectString["Description"] as! String
self.personList[count].addPerson(Name, code: code, description: description)
count++
}
This is my class array in a separate swift file.
func addPerson(name: String, code: String, description: String){
self.name = name
self.code = code
self.description = description
}

Swift: Looping through a Dictionary Array

I'm struggling to loop through an array of dictionary values returned from a web service call.
I've implemented the following code and I seem to be encountering a crash on running.
I'd also like to store the results into a custom Struct. Really having difficulty achieving this and the answers on here so far haven't worked. Would be grateful if someone is able to help.
let nudgesURLString = "http://www.whatthefoot.co.uk/NUDGE/nudges.php"
let nudgesURL = NSURL(string: nudgesURLString)
let session = NSURLSession.sharedSession()
let task = session.dataTaskWithURL(nudgesURL!, completionHandler: {data, response, error -> Void in
if error != nil {
println(error)
} else {
let nudgesJSONResult = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: nil) as NSDictionary
let nudges: NSDictionary = nudgesJSONResult["nudges"] as NSDictionary
if let list = nudgesJSONResult["nudges"] as? [[String:String]] {
for nudgeDict in list {
let location = nudgeDict["location"]
println(location)
}
}
}
})
task.resume()
}
NOTICE
This answer was written using Swift 1.2 and as such, there may be some slight stylistic and syntax changes required for the answer to work depending on your current Swift system.
Answer -- Swift 1.2
This line is crashing your code:
let nudges: NSDictionary = nudgesJSONResult["nudges"] as NSDictionary
You're forcing a cast that Swift can't handle. You never make it to your for-loop.
Try changing your code to look more like this:
let nudgesURLString = "http://www.whatthefoot.co.uk/NUDGE/nudges.php"
let nudgesURL = NSURL(string: nudgesURLString)
let session = NSURLSession.sharedSession()
let task = session.dataTaskWithURL(nudgesURL!, completionHandler: {data, response, error -> Void in
if error != nil {
println(error)
} else {
let nudgesJSONResult = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: nil) as [String : AnyObject]
if let nudges = nudgesJSONResult["nudges"] as? [[String : String]] {
for nudge in nudges {
let location = nudge["location"]
println("Got location: \(location)")
println("Got full nudge: \(nudge)")
}
}
}
})
task.resume()
Thanks,
I created the following Struct which stored the data, and also lets me create dictionaries in the view controller for a particular index.
struct NudgesLibrary {
var location: NSArray?
var message: NSArray?
var priority: NSArray?
var date: NSArray?
var nudges: NSArray?
init(nudgesObject: AnyObject) {
nudges = (nudgesObject["nudges"] as NSArray)
if let nudges = nudgesObject["nudges"] as? NSArray {
location = (nudges.valueForKey("location") as NSArray)
message = (nudges.valueForKey("message") as NSArray)
priority = (nudges.valueForKey("priority") as NSArray)
date = (nudges.valueForKey("date") as NSArray)
}
}
}

Resources