I try to compile on device but i get this error. Any help?. In the simulator works perfectly.
I get an ambiguous use of subscript error in the following code and was hoping somebody else has encountered this and know the fix.
case .Success:
if response.response?.statusCode == 200 {
print ("Respuesta 200")
if let value = response.result.value {
let respuestaJSON = JSON(value)
let objsonUSUARIOS = respuestaJSON["d"].object
let arrayUsuarios = objsonUSUARIOS["results"]!
//print ("Usuarios: ",String(arrayUsuarios))
for i in 0 ..< arrayUsuarios!.count{
let boletines = boletinJSON()
if let item = arrayUsuarios![i] as? [String: AnyObject]{
)
if let person = item["Title"] as? String
{
boletines.name = person
}
if let person = item["Portada"] as? String
{
boletines.imagen = person
}
if let person = item["Created"] as? String
{
boletines.fecha = person
}
if let person = item["AttachmentFiles"] as? [String: AnyObject] {
if let itemAttach = person["__deferred"] as? [String: AnyObject]{
if let itemdeferred = itemAttach["uri"] as? String {
boletines.urldescarga = itemdeferred
}
}
}
self.boletin.append(boletines)
self.view.hideToastActivity()
}
}
}
self.tableView.reloadData()
// self.view.hideToastActivity()
}
Inform the compiler what the intermediary object objsonUSUARIOS is of type
let objsonUSUARIOS = respuestaJSON["d"].object
After the above statement, the compiler does not know what kind of object he is dealing with. So make sure that you can actually do all the casting as below
let objsonUSUARIOS = respuestaJSON["d"].object as! Dictionary
let arrayUsuarios = objsonUSUARIOS["results"]! as! Array
The problem is that you have not specified the type of object arrayUsuarios is Array, so try to explicit type cast the arrayUsuarios Array
let arrayUsuarios = objsonUSUARIOS["results"] as! [[String: AnyObject]]
Related
I want to parse JSON in UICollectionviewCell. I have a collectionViewController with two UICollectionviewCell. In collectionViewController first cell made to background scrolling and in the second I want to parse JSON. There is no error in the code, this is my JSON code.
var oCategoryFilter: CategoryFilter? {
didSet {
if let name = oCategoryFilter?.totalItem {
totalItemLabel.text = name
}
appsCollectionView.reloadData()
}
}
var arrProduct: [Product]?
func getPropductListByCategory(){
let category_id:String;
category_id = "21"
let url = URL(string: UtilityController.BASE_URL+"/products/"+category_id)
URLSession.shared.dataTask(with:url!) { (urlContent, response, error) in
if error != nil {
print(error)
}
else {
do {
let json = try JSONSerialization.jsonObject(with: urlContent!) as! [String:Any]
print(json)
let items = json["categories"] as? [[String: Any]] ?? []
items.forEach { item in
let oProduct = Product()
//oProduct.id = item["id"] as? String
oProduct.image = item["image"] as? String
oProduct.name = item["name"] as? String
oProduct.ar_name = item["ar_name"] as? String
//oProduct.description = item["description"] as? String
oProduct.ar_description = item["ar_description"] as? String
oProduct.price = item["price"] as? String
oProduct.quantity = item["quantity"] as? String
oProduct.is_featured = item["is_featured"] as? String
oProduct.seller_id = item["seller_id"] as? String
oProduct.payment_required = item["payment_required"] as? String
oProduct.is_editors_choice = item["is_editors_choice"] as? String
oProduct.created_at = item["created_at"] as? String
oProduct.updated_at = item["updated_at"] as? String
self.arrProduct?.append(oProduct)
}
print(url)
} catch let error as NSError {
print(error)
}
}
DispatchQueue.main.async(execute: {
self.appsCollectionView.reloadData()
})
}.resume()
}
When are you calling your functions ? You should call the method in the CollectionView, when it is loading every cell, but doing that is really bad, because each time you will scroll or reload your CollectionView it will parse again.
You should parse in a special class, call by the collection view and this last send the parse object to the cell.
I have JSON
http://maps.googleapis.com/maps/api/directions/json?&origin=28.594517,77.049112&destination=28.654109,77.34395&travelMode=DRIVING&provideRouteAlternatives=false&sensor=false
I want to access all the values in distance which is in steps.
Here is my code
class Router {
var getValue = Double()
func downloadData(complete: downloadComplete) {
let currentURL = URL(string:getURL)!
Alamofire.request(currentURL).responseJSON { (responseJSON) in
let result = responseJSON
// print(result)
if let dict = result.value as? Dictionary<String,AnyObject>{
if let routes = dict["routes"] as? [Dictionary<String, AnyObject>]{
if let legs = routes[0]["legs"] as? [Dictionary<String, AnyObject>]{
if let steps = legs[0]["steps"] as? [Dictionary<String, AnyObject>]{
for index in steps{
if let distance = steps["distance"] as? Dictionary<String,AnyObject>{
if let value = distance["value"] as? Double{
self.getValue = self.getValue + value
print(self.getValue)
}
}
}
}
}
}
}
}
complete()
}
I am getting error in:
if let distance = steps["distance"] as? Dictionary<String,AnyObject>{
which says:
Cannot subscript a value of type '[Dictionary]' with an index of type string
How can I access this?
You are trying to access the value of an array of dictionaries by key. You should change steps["distance"] to index["distance"].
if let distance = index["distance"] as? Dictionary<String,AnyObject>{
if let value = distance["value"] as? Double{
self.getValue = self.getValue + value
print(self.getValue)
}
}
The error is clear.
steps["distance"] is an array of dictionaries, which can be accessed like steps[0],steps[1].
You need to change following line
if let distance = steps["distance"] as? Dictionary<String,AnyObject>
to
if let distance = index["distance"] as? Dictionary<String,AnyObject>
I'm looking to try and reference all "titles" within this json (link here) in xcode 8. The issue is there's an object and array that need to be referenced (i believe) before I can pull the title data, and I'm not sure how to do that.
So far this is what i've got:
func fetchFeed(){
let urlRequest = URLRequest(url: URL(string: "http://itunes.apple.com/us/rss/topalbums/limit=10/json")!)
let task = URLSession.shared.dataTask(with: urlRequest) { (data,response,error) in
if error != nil {
print(error)
return
}
self.artists = [Artist]()
do {
let json = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as! [String : AnyObject]
if let feedFromJson = json["feed"]?["entry"] as? [[String : AnyObject]] {
for feedFromJson in feedsFromJson {
let feed = Feed()
if let entry = feedFromJson["entry"] as? String, let author = feedFromJson["domain"] as? String {
feed.entry = entry
article.headline = title
}
self.articles?.append(article)
}
}
DispatchQueue.main.async {
self.tableview.reloadData()
And thank you for your help in advance!
I'm working hard to try to understand what you need. If you want to get an Article array where the headline is the title label for the entry, here is how I cheated it out.
func articles(from json: Any?) -> [Article] {
guard let json = json as? NSDictionary, let entries = json.value(forKeyPath: "feed.entry") as? [NSDictionary] else {
return []
}
return entries.flatMap { entry in
guard let title = entry.value(forKeyPath: "title.label") as? String else {
return nil
}
var article = Article()
article.headline = title
return article
}
}
you call it as such
self.articles = articles(from: json)
NSDictionary has the method value(forKeyPath:) that is near magic. Calling json.value(forKeyPath: "feed.entry") returns an array of dictionaries. Each dictionary is an "entry" object in the json. Next, I map each entry to call entry.value(forKeyPath: "title.label") which returns a string.
If this is something more than a quick solution, then I would consider adding SwiftyJSON to your project.
func articles(from json: Any?) -> [Article] {
return JSON(json)["feed"]["entry"].arrayValue.flatMap { entry in
guard let title = entry["title"]["label"].string else {
return nil
}
var article = Article()
article.headline = title
return article
}
}
There is two kinds of titles.
the "feed" and the "entry".
if let entry = feedFromJson["entry"] as? String, let author = feedFromJson["domain"] as? String {
The practice of iOS is not this.
feedFromJson["entry"] is nil ,not a string . I guess you try to get the "feed" title.
if let entry = (json["feed"] as Dictionary)?["title"]
To get the "entry" title. Just traverse the array, and get the title.
let titleDict = feedFromJson["title"] as? Dictionary
let title = titleDict["title"] as? String
article.headline = title
Better to know the structure of the JSON data.
It's too quick.
if let feedFromJson = json["feed"]?["entry"] as? [[String :
AnyObject]] {
You should step by step.
if let feedFromJson = (json["feed"] as Dictionary)?["entry"] as? [[String : AnyObject]] {
My other question was marked as being identical to another but it didn't answer the problem I was having.
Here is the code:
if status == "OK" {
self.selectedRoute = (dictionary["routes"] as! Array<Dictionary<NSObject, AnyObject>>)[0]
self.overviewPolyline = self.selectedRoute["overview_polyline"] as! Dictionary<NSObject, AnyObject>
let legs = self.selectedRoute["legs"] as! Array<Dictionary<NSObject, AnyObject>>
let steps = legs[0]["steps"]!
for i in 0...steps.count - 1 {
let step_coordinate = steps[i]["start_location"]!
print(step_coordinate!["lat"]!!)
}
}
The print statement gives this result
40.7609205
40.7640121
40.7595325
40.7501637
40.7481923
40.7393448
40.7252038
40.7225337
40.718295
but if I swap the print statement out to grab the values and put them in an array I get the fatal error: found nil.
Can someone explain why this is the case? How can I grab these values if not through a for loop?
Here's a cleaner version of your code.
Rules:
Don't force unwrap anything!
Optionally cast values coming from [NSObject: AnyObject] lookups.
Use guard statements and if let to safely unwrap optionals.
Don't index arrays that might be empty without checking first.
if status == "OK" {
guard let routes = dictionary["routes"] as? [[NSObject: AnyObject]] else { return }
self.selectedRoute = routes.first ?? [:]
self.overviewPolyline = self.selectedRoute["overview_polyline"] as? [NSObject: AnyObject] ?? [:]
guard let legs = self.selectedRoute["legs"] as? [[NSObject: AnyObject]] else { return }
let firstleg = legs.first ?? [:]
guard let steps = firstleg["steps"] as? [[NSObject: AnyObject]] else { return }
for step in steps {
if let step_coordinate = step["start_location"] as? [NSObject: AnyObject] {
if let lat = step_coordinate["lat"] as? Double {
print(lat)
// append lat to array of lats
lats.append(lat)
}
}
}
}
I am trying to get data from Firebase, I have tried like this:
FIREBASE_REF.childByAppendingPath("tasks").observeEventType(.Value, withBlock: { (snapshot) -> Void in
print(snapshot.value)
self.tasks = [Task]()
var task = Task()
let data = snapshot.value as! NSDictionary
let tasksFromServer = data.allValues as! [NSDictionary]
for taskFromServer in tasksFromServer {
task.description = taskFromServer.objectForKey("description") as! String
task.startTime = taskFromServer.objectForKey("startTime") as! String
task.endTime = taskFromServer.objectForKey("endTime") as! String
task.progress = taskFromServer.objectForKey("progress") as! Int
let priorityTemp = taskFromServer.objectForKey("priority") as! Int
switch priorityTemp {
case 0: task.priority = .Low
case 1: task.priority = .Medium
case 2: task.priority = .High
default: break
}
task.assignee = taskFromServer.objectForKey("assignee") as! String
self.tasks.append(task)
}
MBProgressHUD.hideAllHUDsForView(self.view, animated: true)
self.tableView.reloadData()
}
but it shows error in this line:
let data = snapshot.value as! NSDictionary
It says: Could not cast value of type '__NSArrayM' (0x10ebfc8d8) to 'NSDictionary' (0x10ebfcd60).
My data from Firebase like this:
But in other side, I use another code in another ViewController to get users name and role from Firebase, it works.
FIREBASE_REF.childByAppendingPath("users").observeEventType(.Value, withBlock: { (snapshot) -> Void in
self.names = []
self.roles = []
let data = snapshot.value as! NSDictionary
let employees = data.allValues as! [NSDictionary]
for employee in employees {
let name = (employee.objectForKey("firstName") as! String) + " " + (employee.objectForKey("lastName") as! String)
self.names.append(name)
let role = employee.objectForKey("position") as! String
self.roles.append(role)
}
MBProgressHUD.hideAllHUDsForView(self.view, animated: true)
self.collectionView.reloadData()
})
But why the first code always crash.
Any helps would be appreciated. Thanks.
Firebase transforms your dictionary object to an array if more than 50% of keys are between 0 and maximum key (exactly your case with one zero element).
https://www.firebase.com/docs/ios/guide/understanding-data.html#section-arrays-in-firebase