Filtering NSArray of dictionaries in Swift - ios

I have an array of dictionaries that was pulled from a RESTful API. I currently am trying to filter out the data as needed where the "domain" is equal to "youtube.com".
How can I filter this out? I've looked into
results.filter({
$0["domain"] != "youtube.com"
but not sure how to go deeper to get it to work.

Or, you can use Swift array, casting theJSON to [[String: AnyObject]] rather than NSMutableArray. Then, you don't have to cast results. And then you can use filter.
In Swift 1.2, that might be:
let task = session.dataTaskWithURL(url) { data, response, error in
if error != nil || data == nil {
print(error)
return
}
var parseError: NSError?
if let resultObject = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions(rawValue: 0), error: &parseError) as? [[String: AnyObject]] {
let results = resultObject.filter() { ($0["data"]?["domain"] as? String) != "youtube.com" }
dispatch_async(dispatch_get_main_queue()) {
// use results here
}
} else {
print(parseError)
return
}
}
task.resume()
Or, in Swift 2:
let task = session.dataTaskWithURL(url) { data, response, error in
guard data != nil && error == nil else {
print(error)
return
}
do {
let resultObject = try NSJSONSerialization.JSONObjectWithData(data!, options: []) as? [[String: AnyObject]]
let results = resultObject?.filter() { ($0["data"]?["domain"] as? String) != "youtube.com" }
dispatch_async(dispatch_get_main_queue()) {
// use results here
}
} catch let parseError {
print(parseError)
}
}
task.resume()}

use
func filteredArrayUsingPredicate(_ predicate: NSPredicate) -> [AnyObject]
to filter an NSArray instance.

Related

if condition in json response in swift ios

If server response is (result = "Account Exists") then i can do something. but when i compare the result it gives an error that "Binary operator '==' cannot be applied to operands of type 'Any' and 'String'".
let dataTask = session.dataTask(with: url!, completionHandler: { (data, response, error) -> Void in
do
{
let json = try JSONSerialization.jsonObject(with: data!, options: .allowFragments) as! NSDictionary
print("JSON : \(json)")
if let dataDic = json.value(forKey: "data")
{
print("dataDic: \(dataDic)")
if let Result = (dataDic as AnyObject).value(forKey: "Result")
{
print("Result: \(Result)")
if (Result ("Account Exists")) == 0
{
//... DO Something
}
}
}
}
catch
{
print("Catch exception")
}
})
dataTask.resume()
}
In pure swift way .. your "data" is an array and Top level json is Dictionary
do
{
let json = try JSONSerialization.jsonObject(with: data!, options: []) as! [String:Any]
if let data = json["data"] as? [[String:String]] {
if let resultString = data.first?["Result"] as? String{
if resultString == "Account Exists"{
//... DO Something
}
else if resultString == "Unauthorized Access" {
//... DO Something
}
}
}
}
catch{
print("Catch exception")
}
please update below in your code and check it
if (Result ("Account Exists") as! String) == "0"
{
//... DO Something
}
If your Result is a string, you need to unwrap it accordingly and then compare, you can implement the comparing while unwrapping itself, you can do something like
if let Result = (dataDic as AnyObject).value(forKey: "Result") as? String, Result == "Unauthorized Access"
{
print("Result: \(Result)")
// DO whatever you want here in case of Unauthorised access
}

how to access array inside json object in swift

Can't access json object which is array inside json object
i want to access data from json object which have array inside array
and that json file is also uploaded
so pls can anyone check and help me how to get "weather.description"
data
override func viewDidLoad() {
super.viewDidLoad()
let url = URL(string: "http://api.openweathermap.org/data/2.5/weather?q=London,uk&appid=13ae70c6aefa867c44962edc13f94404")!
let task = URLSession.shared.dataTask(with: url) { (data, response, error) in
if error != nil {
print("some error occured")
} else {
if let urlContent = data {
do{
let jsonResult = try JSONSerialization.jsonObject(with: urlContent, options: JSONSerialization.ReadingOptions.mutableContainers)
let newValue = jsonResult as! NSDictionary
print(jsonResult)
let name = newValue["name"]
//Here i am getting name as variable value
//this is not working
let description = newValue["weather"]??[0]["description"]
//this is not working
let description = newValue["weather"]!![0]["description"]
print()
}catch {
print("JSON Preocessing failed")
}
}
}
}
task.resume()
}
I have edited your code a bit, and added a few comments. Basiclly, lets check for the types of your response structure, and get the desired value.
let url = URL(string: "http://api.openweathermap.org/data/2.5/weather?q=London,uk&appid=13ae70c6aefa867c44962edc13f94404")!
let task = URLSession.shared.dataTask(with: url) { (data, response, error) in
if error != nil {
print("some error occured")
} else {
if let urlContent = data {
do{
let jsonResult = try JSONSerialization.jsonObject(with: urlContent, options: JSONSerialization.ReadingOptions.mutableContainers)
// I would not recommend to use NSDictionary, try using Swift types instead
guard let newValue = jsonResult as? [String: Any] else {
print("invalid format")
return
}
// Check for the weather parameter as an array of dictionaries and than excess the first array's description
if let weather = newValue["weather"] as? [[String: Any]], let description = weather.first?["description"] as? String {
print(description)
}
}catch {
print("JSON Preocessing failed")
}
}
}
}
task.resume()

Json Serialisation Swift 3

I am trying to serialise the json in the code below, the logs print out the display names successfully but I get a crash with an error:
fatal error: unexpectedly found nil while unwrapping an Optional value
on the following lines:
print(item["display-name"]! as!String)
Blockquoteself.tableData.append(item["display-name"] as! String)
I can't seem to figure out why, any help much appreciated!
let url = NSURL(string: "https://www.asmserver.co.uk/sally/parsexml.php")!
let task = URLSession.shared.dataTask(with: url as URL) { (data, response, error) -> Void in
if let urlContent = data {
do {
if let jsonResult = try JSONSerialization.jsonObject(with: urlContent, options: []) as? [[String:AnyObject]] {
for item in jsonResult {
print(item["display-name"]! as!String)
self.tableData.append(item["display-name"] as! String)
}
}
} catch {
print("JSON serialization failed")
}
} else {
print("ERROR FOUND HERE")
}
DispatchQueue.main.async(execute: { () -> Void in
self.tableView.reloadData()
})
self.tableView.isUserInteractionEnabled = true
}
task.resume()
You should make sure that you really have a value before you use it and specially before using as!.
Do like this instead:
for item in jsonResult {
guard let name = item["display-name"] as? String else { continue }
print(name)
self.tableData.append(name)
}
If the guard succeeds then you have a value and can use the name variable. You can also add several conditions to the guard statement.
As an alternative to the guard statement, you could also use the similar if let construct:
if let item = item["display-name"] as? String {
print(item)
} else {
print("No display name")
}

Error while parsing JSON in swift 2.0

I am trying to download a list of articles and insert it into a table view. However I seem to be having an issue retrieving the JSON file and parsing it.
My code is as follows:
override func viewDidLoad() {
super.viewDidLoad()
self.downloadArticles()
self.tableView.reloadData()
}
func downloadArticles(){
var url: NSURL
url = NSURL(string: "https://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20feed%20where%20url=%27www.abc.net.au%2Fnews%2Ffeed%2F51120%2Frss.xml%27&format=json")!
print(url)
let task = NSURLSession.sharedSession().dataTaskWithURL(url){
(data, response, error) in
if (error != nil){
print("Error \(error)")
} else{
self.parseArticleJSON(data!)
}
self.syncCompleted = true
self.tableView.reloadData()
}
task.resume()
}
func parseArticleJSON(articleJSON:NSData)
{
do{
let result = try NSJSONSerialization.JSONObjectWithData(articleJSON, options: NSJSONReadingOptions.MutableContainers) as? NSArray
//let jsonData:NSArray = (try NSJSONSerialization.JSONObjectWithData(articleJSON, options:NSJSONReadingOptions.MutableContainers) as? NSArray)!
let newArticlesArray = result as NSArray!
//NSLog("Found \(newArticlesArray.count) new articles!")
for article in (newArticlesArray as NSArray as! [NSDictionary])
{
print (article.objectForKey("title")! as? String)
//let a = Article (t: <#T##String#>, da: <#T##String#>, de: <#T##String#>, i: <#T##NSURL#>)
//articlesArray.addObject(a);
}
}catch {
print("JSON Serialization error")
}
}
In the parseArticleJSON method (I know it is not all completely finished). I get the error at line:
for article in (newArticlesArray as NSArray as! [NSDictionary])
it says:
fatal error: unexpectedly found nil while unwrapping an Optional value
I have tried doing some research here on these forums, but I was unable to find any response that would be of help to me so I was wondering if somebody would be able to help me.
I need to use the native swift JSON methods to do all this.
Thanks in advance!
The JSON is much more nested:
typealias JSONDictionary = Dictionary<String,AnyObject>
func parseArticleJSON(articleJSON:NSData) {
do {
let jsonObject = try NSJSONSerialization.JSONObjectWithData(articleJSON, options: [])
if let jsonResult = jsonObject as? JSONDictionary,
query = jsonResult["query"] as? JSONDictionary,
results = query["results"] as? JSONDictionary,
newArticlesArray = results["item"] as? [JSONDictionary] {
for article in newArticlesArray {
print(article["title"] as! String)
}
}
} catch let error as NSError {
print(error)
}
}
For that deeply nested JSON it's recommended to use a library like SwiftyJSON.
Since the code is only reading the JSON object, the option MutableContainers is not needed at all and in Swift always use native collection types unless you have absolutely no choice.
try this code,
if let jsonObject: AnyObject = NSJSONSerialization.JSONObjectWithData(articleJSON, options: nil, error:&error) {
if let dict = jsonObject as? NSDictionary {
println(dict)
} else {
println("not a dictionary")
}
} else {
println("Could not parse JSON: \(error!)")
}
hope its helpful

Swift 2 - NSJSONSerialization.JSONObjectWithData Handling Error [duplicate]

This question already has answers here:
Correct handling of NSJSONSerialization (try catch) in Swift (2.0)?
(3 answers)
Closed 6 years ago.
I have a JSONParser, but unfortunately I couldn't adapt NSJSONSerialization.JSONObjectWithData(data, options: nil, error: &error) bit to Swift 2.0, so I am receiving error:
Extra argument 'error' in call
I found out that I can achieve this with do-try-catch, but I couldn't figure out how to adapt it in my case. Whatever I tried is just throwing another error.
class JSONParser {
let json: AnyObject?
var error: NSError?
init(data: NSData){ // ~this chunk~
self.json = NSJSONSerialization.JSONObjectWithData(data, options: nil, error: &error)
}
func array()->NSArray?{
if let jsonResponse: AnyObject = self.json{
return jsonResponse as? NSArray
}
return nil
}
func dictionary()->NSDictionary?{
if let jsonResponse: AnyObject = self.json{
return jsonResponse as? NSDictionary
}
return nil
}
}
swift3
NSJSONSerialization and its methods are modified, according to the Swift Documents.
do {
let JsonDict = try JSONSerialization.jsonObject(with: data, options: [])
// you can now use t with the right type
if let dictFromJSON = JsonDict as? [String:String]
{
// use dictFromJSON
}
} catch let error as NSError {
print(error)
}
Swift2
init(data: NSData){ // ~this chunk~
do {
self.json = try NSJSONSerialization.JSONObjectWithData(data, options: []) as! [String:AnyObject]
} catch {
print("error: \(error)")
self.json = nil
}
}
for more information tutorial1, tutorial2
var dataSource = [AnyObject]()
do { self.dataSource = try NSJSONSerialization.JSONObjectWithData(responseData, options: NSJSONReadingOptions.MutableLeaves) as! [AnyObject]
} catch let error as NSError {
print("Failed to load: \(error.localizedDescription)")
}
if self.dataSource.count != 0 {
dispatch_async(dispatch_get_main_queue()) {
self.sampleTableView.reloadData()
}
}

Resources