Reputation: 91
So I'm making a small app to update some data on a website that I'm hosting. I've never written anything in swift 3 so it's all a bit confusing to me.
Right now I'm pulling a list of names from the site to use in a picker, for obvious reasons I will edit the url for the service I'm using but all the code should be understandable.
I have this code that works on the emulator which I've set up to be the same model as my phone(6s), it will work in the emulator but when I try and test it on my phone it errors with ambiguous use of subscript(I'll indicate the line in the code)
import UIKit
class ViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource {
@IBOutlet weak var playerTextPicker: UITextField!
var pickOption = [String]()
let picker = UIPickerView()
override func viewDidLoad() {
super.viewDidLoad()
getPlayerJson()
picker.delegate = self
picker.dataSource = self
playerTextPicker.inputView = picker
}
public func numberOfComponents(in pickerView: UIPickerView) -> Int{
return 1
}
public func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int{
return pickOption.count
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
return pickOption[row]
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
playerTextPicker.text = pickOption[row]
self.view.endEditing(false)
}
func getPlayerJson(){
let players = [String]()
let url = URL(string: "http://www.test.com/test.php")
let task = URLSession.shared.dataTask(with: url!) { (data, response, error) in
if error != nil{
print("Error")
}
else{
if let myData = data{
do{
let jsonResult = try JSONSerialization.jsonObject(with: myData, options: JSONSerialization.ReadingOptions.mutableContainers) as AnyObject
var jsonElement: NSDictionary = NSDictionary()
for i in 0 ..< jsonResult.count
{
jsonElement = jsonResult[i] as! NSDictionary //ERRORS HERE
//the following insures none of the JsonElement values are nil through optional binding
if
let name = jsonElement["name"] as? String
{
self.pickOption.append(name)
}
}
}catch{
//print error
}
}
}
}
task.resume()
}
}
Upvotes: 0
Views: 687
Reputation: 52592
When you use Swift, you should really try to use Swift code. Your code isn't Swift, it's Objective-C trying to pretend it is Swift.
The mutableContainers option is nonsense and just slows your code down (use it when you understand what it does and you need it). Use [] instead.
Since you are not handling the case that JSONSerialization throws, just use try?
Cast the result of JSONSerialization to as? [Any].
Looping through an array: for (item in array) Getting a dictionary and checking that it worked instead of crashing:
if let dict = item as? [AnyHashable, Any] {
}
Upvotes: 1
Reputation: 93181
I don't know how the simulator allowed you to do this, but this line:
let jsonResult = try JSONSerialization.jsonObject(with: myData, options: JSONSerialization.ReadingOptions.mutableContainers) as AnyObject
A JSON object is either an array or a dictionary. AnyObject
is ambiguous. If you are sure that it's an array, cast it to [AnyObject]
:
let jsonResult = try JSONSerialization.jsonObject(with: myData, options: .mutableContainers) as! [AnyObject]
Upvotes: 1