Swift 4: Filtering Array - arrays

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)
}

Related

Save and Append an Array in UserDefaults from ImagePickerControllerImageURL in Swift

I'm having an issue saving and retrieving an array in UserDefaults from UIImagePickerControllerImageURL. I can get the array after synchronizing, but I am unable to retrieve it. myArray is empty.
The testImage.image does get the image, no problems there.
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
let imageURL: URL = info[UIImagePickerControllerImageURL] as! URL
//test that imagepicker is actually getting the image
let imageData: NSData = try! NSData(contentsOf: imageURL)
let cvImage = UIImage(data:imageData as Data)
testImage.image = cvImage
//Save array to UserDefaults and add picked image url to the array
let usD = UserDefaults.standard
var array: NSMutableArray = []
usD.set(array, forKey: "WeatherArray")
array.add(imageURL)
usD.synchronize()
print ("array is \(array)")
let myArray = usD.stringArray(forKey:"WeatherArray") ?? [String]()
print ("myArray is \(myArray)")
picker.dismiss(animated: true, completion: nil)
}
There are many issue here.
Do not use NSData, use Data.
Do not use NSMutableArray, use a Swift array.
You can get the UIImage directly from the info dictionary`.
You can't store URLs in UserDefaults.
You save array to UserDefaults before you update the array with the new URL.
You create a new array instead of getting the current array from UserDefaults.
You needlessly call synchronize.
You needlessly specify the type for most of your variables.
Here is your code updated to fix all of these issues:
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
if let image = info[UIImagePickerControllerOriginalImage] as? UIImage {
testImage.image = image
}
if let imageURL = info[UIImagePickerControllerImageURL] as? URL {
//Save array to UserDefaults and add picked image url to the array
let usD = UserDefaults.standard
var urls = usD.stringArray(forKey: "WeatherArray") ?? []
urls.append(imageURL.absoluteString)
usD.set(urls, forKey: "WeatherArray")
}
picker.dismiss(animated: true, completion: nil)
}
Note that this saves an array of strings representing each URL. Later on, when you access these strings, if you want a URL, you need to use URL(string: arrayElement).

ios swfit - assign list of AnyObject to dictionary key

so i want to assign a list of AnyObject to a key of a dictionary with the structure [String:AnyObject]
here is my code:
let list = try JSONSerialization.jsonObject(with: newData, options: .allowFragments) as! [AnyObject]
let parsedResult = [String:AnyObject]()
parsedResult["dataList"] = list
callback(false, parsedResult)
im parsing data from an http request. i get this error:
Cannot assign value of type [AnyObject] to type AnyObject?
isn't a list of AnyObject, still an object?
Change:
let parsedResult = [String:AnyObject]()
To:
var parsedResult: [String: Any] = [ : ]
And by the way declare parsedResult as var to be able to do parsedResult["dataList"] = list.
For your other issue that you placed a comment on, do this instead:
if let account = data?["account"] as? [String: Any], let accountKey = account["key"] as? Int { ... }

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)
}

Parsing JSON into swift predefined array

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

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