Ambiguous use of Subscript in Swift 5? - ios

Does anyone know why I get this error?
func parseData(JSONData: Data){
do{
var readableJSON = try JSONSerialization.jsonObject(with: JSONData, options: .mutableContainers) as! JSONStandard
if let tracks = readableJSON["tracks"] as? JSONStandard{
if let items = tracks["items"]{
for i in 0..<items.count {
let item = items[i] as! JSONStandard //Here I get the error: Ambiguous use of 'subscript(_:)'
let name = item["name"]
names.append(name)

Change following
if let items = tracks["items"]
To
if let items = tracks["items"] as? [JSONSStandard]

Related

how to parse the data from web services and pass it to table view?

In this the web services i need to save and pass it to a table view how to implement this and the getting data also not possible from json and i need to display it on table view as mentioned below in image can anyone help me how to implement this or any suggestion also would be of great help
and my code is shown below
let url = "http://www.json-generator.com/api/json/get/cwqUAMjKGa?indent=2"
var detailsArray :[[String: AnyObject]] = []
var titleName = [String]()
var productName = [String]()
var children = [String]()
var childrenArray :[[String: AnyObject]] = []
var productsArray :[[String:AnyObject]] = []
var name = [String]()
func downloadJsonWithURL() {
let url = NSURL(string: self.url)
URLSession.shared.dataTask(with: (url as URL?)!, completionHandler: {(data, response, error) -> Void in
if let jsonObj = try? JSONSerialization.jsonObject(with: data!, options: .allowFragments) as? NSDictionary {
self.detailsArray = (jsonObj!.value(forKey: "data") as? [[String: AnyObject]])!
print(self.detailsArray)
for item in self.detailsArray{
if let detailDict = item as? NSDictionary {
if let name = detailDict.value(forKey: "name"){
self.titleName.append(name as! String)
print(self.productName)
}
self.childrenArray = (detailDict.value(forKey: "children") as? [[String : AnyObject]])!
for item in self.childrenArray {
if let detailDict = item as? NSDictionary {
if let name = detailDict.value(forKey: "name"){
self.productName.append(name as! String)
}
self.productsArray = (detailDict.value(forKey: "products") as? [[String : AnyObject]])!
for item in self.productsArray{
if let detailDict = item as? NSDictionary {
if let name = detailDict.value(forKey: "name"){
self.name.append(name as! String)
print(self.name)
}
}
}
}
}
}
}
OperationQueue.main.addOperation({
print(self.productName)
print(self.titleName)
print(self.name)
})
}
}).resume()
}

Not able to draw Polyline Google Maps : Swift 3

I am trying to draw route between two points but not able to do so beacuese there is nill value in my polypoints.
This is how I am doing it :
Parsing JSON :
if let json : [String:Any] = try JSONSerialization.jsonObject(with: data!, options: .allowFragments) as? [String: Any]{
if let routes = json["routes"] as? [Any]{
if let overview_polyline = routes[0] as?[String:Any]{
print("overview_polyline\(overview_polyline)")// Getting values till here
if let polyString = overview_polyline["points"] as? String{
//Call this method to draw path on map
self.showPath(polyStr: polyString)
}
}
}
}
Till polystring I am getting values but not getting any value for this line of code if let polyString = overview_polyline["points"] as? String.
Any idea why polyString is nil ?
I have gone through this link to clear the concepts still not able to implement it.
unexpectedly found nil while unwrapping an Optional value
I achieved this by modifying above code to this code. So to parse google api and create a polyline on map, you can use this code, written in swift 3.
if let json : [String:Any] = try JSONSerialization.jsonObject(with: data!, options: .allowFragments) as? [String: Any]{
let routes = json["routes"] as! NSArray;
print(routes)
self.mapView.clear()
OperationQueue.main.addOperation({
for route in routes {
let routeOverviewPolyline:NSDictionary = (route as! NSDictionary).value(forKey: "overview_polyline") as! NSDictionary
let points = routeOverviewPolyline.object(forKey: "points")
let path = GMSPath.init(fromEncodedPath: points! as! String)
let polyline = GMSPolyline.init(path: path)
polyline.strokeWidth = 3
polyline.map = self.mapView
}
})
}

GooglePlaces API Swift 3 Issue

I seem to have picked up a few errors since updating to swift 3
// Issue #1
let correctedAddress:String! = self.searchResults![(indexPath as NSIndexPath).row].addingPercentEncoding(withAllowedCharacters: CharacterSet.symbols)
print(correctedAddress)
let url = URL(string: "https://maps.googleapis.com/maps/api/geocode/json?address=\(correctedAddress)&sensor=false")
let task = URLSession.shared.dataTask(with: url!) {
data, response, error in
do {
if data != nil{
let dic = try JSONSerialization.jsonObject(with: data!, options: JSONSerialization.ReadingOptions.mutableLeaves) as! NSDictionary
// Issue #2
let results = dic["results"] as! [String: Any]
let geometry = results["geometry"] as! [String: Any]
let location = geometry["location"] as! [String: Any]
let lat = location["lat"] as! Double
let lon = location["lng"] as! Double
self.delegate.locateWithLongitude(lon, andLatitude: lat)
}
}
catch {
print("Error")
}
}
task.resume()
issue #1:
correctedAddress, as an example, returns value "%51%75%C3%A9%62%65%63%2C%20%43%61%6E%61%64%61". Nevertheless, for some reason the url constant returns nil and causes a crash.
I don't understand why it returns nil. I can replace correctedAddress inside the url with the value %51%75%C3%A9%62%65%63%2C%20%43%61%6E%61%64%61 so the full url is
let url = NSURL(string: "https://maps.googleapis.com/maps/api/geocode/json?address=%51%75%C3%A9%62%65%63%2C%20%43%61%6E%61%64%61&sensor=false") and it works fine.
issue #2:
It crashes just at let results to which i get back the error of Could not cast value of type '__NSArrayI' (0x108bb0c08) to 'NSDictionary' (0x108bb1108).
Try the below code for your Issue#2
let results = dic["results"] as! NSArray
for result in results {
let strObj = result as! NSDictionary
let geometry = strObj["geometry"] as! NSDictionary
let location = geometry["location"] as! NSDictionary
let lat = location["lat"] as! NSNumber
let lon = location["lng"] as! NSNumber
}
For issue#1, try the below code
let valueAtIndex = self.searchResults![(indexPath as NSIndexPath).row].addingPercentEncoding(withAllowedCharacters: CharacterSet.symbols)
guard let correctedAddress = valueAtIndex else { return }
let adrString:String = "https://maps.googleapis.com/maps/api/geocode/json?address=\(correctedAddress)&sensor=false"
let url:URL = URL(string: adrString)!

Swift 2 to Swift 3 migration: Ambiguous reference to member 'subscript'

I had a block of code parsing JSON from the youtube API. The JSON object received is stored in the dictionary and then a sub array of JSON objects items is stored in item. Xcode is giving me an error where it says: "items" is an ambiguous reference to member subscript for JSON and i for item[i].
I read through some posts on stack-overflow addressing similar issues where it said Swift 3 changed the type to [String: AnyObject] but that didn't work for me either.
do
{
let json = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as! Dictionary<NSObject, AnyObject>
//print(json)
let item: Array<Dictionary<NSObject,AnyObject>> = json["items"] as! Array<Dictionary<NSObject,AnyObject>>
for i in 0 ..< item.count
{
let snippetDict = (item[i] as Dictionary<NSObject, AnyObject>)["snippet"] as! Dictionary<NSObject, AnyObject>
// Initialize a new dictionary and store the data of interest.
var desiredVideoDict = Dictionary<NSObject, AnyObject>()
desiredVideoDict["title"] = snippetDict["title"]
desiredVideoDict["thumbnail"] = ((snippetDict["thumbnails"] as! Dictionary<NSObject, AnyObject>)["default"] as! Dictionary<NSObject, AnyObject>)["url"]
desiredVideoDict["videoID"] = (snippetDict["resourceId"] as! Dictionary<NSObject, AnyObject>)["videoId"]
// Append the desiredPlaylistItemDataDict dictionary to the videos array.
//self.videosArray.append(desiredPlaylistItemDataDict)
// Reload the tableview.
self.tblVideos.reloadData()
Thank you for your time and help.
The standard JSON dictionary has the type [String:Any] in Swift 3.
I recommend to use a type alias for better legibility.
typealias JSONObject = [String:Any]
Now you can write your code this way (I changed also the for loop syntax)
do
{
let json = try JSONSerialization.jsonObject(with: data!, options: []) as! JSONObject
//print(json)
let items = json["items"] as! Array<JSONObject>
for item in items
{
let snippetDict = item["snippet"] as! JSONObject
// Initialize a new dictionary and store the data of interest.
var desiredVideoDict = JSONObject()
desiredVideoDict["title"] = snippetDict["title"]
desiredVideoDict["thumbnail"] = ((snippetDict["thumbnails"] as! JSONObject)["default"] as! JSONObject)["url"]
desiredVideoDict["videoID"] = (snippetDict["resourceId"] as! JSONObject)["videoId"]
// Append the desiredPlaylistItemDataDict dictionary to the videos array.
//self.videosArray.append(desiredPlaylistItemDataDict)
// Reload the tableview.
}
self.tblVideos.reloadData()
...
mutableContainers is not needed at all.
This worked for me:
do
{
let json = try JSONSerialization.jsonObject(with: data , options: .mutableContainers) as! Dictionary<String, AnyObject>
//print(json)
let item = json["items"] as! Array<Dictionary<String,AnyObject>>
for i in 0 ..< item.count
{
let snippetDict = item[i]["snippet"] as! Dictionary<String, AnyObject>
// Initialize a new dictionary and store the data of interest.
var desiredVideoDict = Dictionary<String, AnyObject>()
desiredVideoDict["title"] = snippetDict["title"]
desiredVideoDict["thumbnail"] = ((snippetDict["thumbnails"] as! Dictionary<String, AnyObject>)["default"] as! Dictionary<String, AnyObject>)["url"]
desiredVideoDict["videoID"] = (snippetDict["resourceId"] as! Dictionary<String, AnyObject>)["videoId"]
// Reload the tableview.
self.tblVideos.reloadData()
}
}catch{
print("parse error")
}

Saving to Parse in a while loop swift

So I have a problem where I call save after putting some items in an object. I go to an API and I download some info and then I save it to another system for temporary use, however the .save() seems to only save 2 items, with no special pattern in which it selects. Can someone explain what the problem is?
let url = URL(string: link)
let spots = PFObject(className:"spot")
let task = URLSession.shared.dataTask(with: url!) { (data, response, error) in
if error != nil {
print(error)
}
else{
if let urlContent = data{
do{
let jsonResult = try JSONSerialization.jsonObject(with: urlContent, options: JSONSerialization.ReadingOptions.mutableContainers)
let results = (jsonResult as! NSDictionary)["results"]
let venueList = (results as! NSArray)
//print(jsonResult)
var i = 0
while i < venueList.count{
let venues = venueList[i] as! NSDictionary
let name = venues["name"] as! String
let geometry = venues["geometry"] as! NSDictionary
let location = geometry["location"] as! NSDictionary
let cLat = location["lat"] as! Double
let cLon = location["lng"] as! Double
let vPoint = PFGeoPoint(latitude: cLat, longitude: cLon)
//print(name," ", vPoint)
spots["venue"] = name
spots["name"] = vPoint
do{
try HotSpots.save()
print("Saved! ",name," ", vPoint)
}
catch{
print("Save Error")
}
i+=1
}
}
catch{
print("JSON Error")
}
}
}
}
task.resume()
}
The issue is that you're saving the two values always in the same PFObject instance.
Move the line let spots = PFObject(className:"spot") in the loop.
PS: Use Swift native types. For example this is more efficient
let location = geometry["location"] as! [String:Double]
let cLat = location["lat"]!
let cLon = location["lng"]!

Resources