I keep getting an error of "ambiguous use of subscript," in my Swift code. I don't know what's causing this error. It just randomly popped up. Here's my code:
if let path = NSBundle.mainBundle().pathForResource("MusicQuestions", ofType: "plist") {
myQuestionsArray = NSArray(contentsOfFile: path)
}
var count:Int = 1
let currentQuestionDict = myQuestionsArray!.objectAtIndex(count)
if let button1Title = currentQuestionDict["choice1"] as? String {
button1.setTitle("\(button1Title)", forState: UIControlState.Normal)
}
if let button2Title = currentQuestionDict["choice2"] as? String {
button2.setTitle("\(button2Title)", forState: UIControlState.Normal)
}
if let button3Title = currentQuestionDict["choice3"] as? String {
button3.setTitle("\(button3Title)", forState: UIControlState.Normal)
}
if let button4Title = currentQuestionDict["choice4"] as? String {
button4.setTitle("\(button4Title)", forState: UIControlState.Normal)
}
if let question = currentQuestionDict["question"] as? String!{
questionLabel.text = "\(question)"
}
The problem is that you are using NSArray:
myQuestionsArray = NSArray(contentsOfFile: path)
This means that myQuestionArray is an NSArray. But an NSArray has no type information about its elements. Thus, when you get to this line:
let currentQuestionDict = myQuestionsArray!.objectAtIndex(count)
...Swift has no type information, and has to make currentQuestionDict an AnyObject. But you can't subscript an AnyObject, so expressions like currentQuestionDict["choice1"] cannot compile.
The solution is to use Swift types. If you know what currentQuestionDict really is, type it as that type. At the very least, since you seem to believe it is a dictionary, make it one; type it as [NSObject:AnyObject] (and more specific if possible). You can do this in several ways; one way is by casting when you create the variable:
let currentQuestionDict =
myQuestionsArray!.objectAtIndex(count) as! [NSObject:AnyObject]
In short, never use NSArray and NSDictionary if you can avoid it (and you can usually avoid it). If you receive one from Objective-C, type it as what it really is, so that Swift can work with it.
["Key"] has causing this error. New Swift update, you should use objectForKey to get your value. In you case just change the your code to ;
if let button1Title = currentQuestionDict.objectForKey("choice1") as? String {
button1.setTitle("\(button1Title)", forState: UIControlState.Normal)
}
This is the code I used to solve the error:
let cell:AddFriendTableViewCell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as! AddFriendTableViewCell
let itemSelection = items[indexPath.section] as! [AnyObject] //'items' is an array of NSMutableArrays, one array for each section
cell.label.text = itemSelection[indexPath.row] as? String
Hope this helps!
Related
I am getting a JSON from an API. So, I want to store a particular value with key SKU. So, what I did was:
var skuArr = [""]
{ (response, error) in
if (error != nil)
{
print("Error \(error.debugDescription)")
}
else
{
self.coinsArr = response.arrayObject as? Array<Dictionary<String, Any>>
for i in 0 ..< (self.coinsArr?.count)!
{
self.skuArr = [response[i]["sku"].rawValue as! String]
}
}
So, with this I am getting the array in skuArr, but when i is 0 I am getting ["a"], and when i is 1 I want it to be ["a","b"], but it gives ["b"] only and when the loop ends with only the last value and not with ["a","b","c","d"] which I want as the final result. How can I insert each of them in the Array?
First of all declare skuArr as empty string array.
var skuArr = [String]()
And this is Swift. There are better ways than ugly index based loops to extract data for example with map or compactMap
if let result = response.arrayObject as? Array<Dictionary<String, Any>> {
self.coinsArr = result
self.skuArr = result.compactMap{ $0["sku"] as? String }
}
And why is coinsArr declared as optional as you are going to force unwrap it anyway? It's highly recommended to use non-optional types as much as possible. Non-optionals can never cause a well-liked unexpected found nil crash
Don't use this:
self.skuArr = [response[i]["sku"].rawValue as! String]
As this will replace the previous value with new one.
Use .append to insert into array.
self.skuArr.append([response[i]["sku"].rawValue as! String])
EDIT
change your initialisation as below:
skuArr: [String] = []
I'm trying to cast a dictionary of [String:Bool] to an array of string.
my code is:
var action = [Nourishing:true, Radiance:true]
let actionArray = [action.keys.description] as? [String]
but the result comes out as:
["[\"Nourishing\", \"Radiance\"]"]
How do I fix this?
You should use this directly
let actionArray = Array(action.keys)
I have a Questions
I want to move Value in array to Variable
ex.
[1,2,3] = array
i want to get "1" to Variable
Var = 1 <= Which "1" is Value in array
My code :
//Loop For Seach Value
for result in 0...DataSearch.count-1 {
let Object = DataSearch[result] as! [String:AnyObject];
self.IDMachine_Array.append(Object["IDMac"] as! String!);
self.Password_Array.append(Object["password"] as! String!);
self.Conpassword_Array.append(Object["password_con"] as! String!);
self.Tel_Array.append(Object["Tel"] as! String!);
self.Email_Array.append(Object["Email"] as! String!);
self.Email = String(self.Email_Array);
}
I try Value Email = Email_Array
Result print :
[xxxx#xxxx.com]
but i want Result is :
xxxx#xxxx.com -> without []
Please Help me please.
Thank you.
Sorry if my solution is wrong.
Just get the first element from the array?
self.Email = self.EmailArray.first!
(this is the same as self.Email = self.EmailArray[0])
NB: first! or [0] will both crash if the array is empty. The original question uses as! so obviously just need this to work. However, if you wanted safety you would use something like
if let email as self.EmailArray.first {
self.Email = email
}
or
self.Email = self.EmailArray.first ?? "no email found"
When I try to run the code below on my iPhone, I get the following error
rrr.swift:356:72: Ambiguous use of 'subscript'
The strange thing is it happens only when I want to run the app on the phone, on the simulator however it works fine.
There are 3 lines which cause the error where. I noted them below in the code in capital letters.
I try to access properties in an array inside the JSON array, I suspect Im doing it the wrong way but have no idea how to fix it.
How can these properties be retrieved without the subscript error?
self.restApi.getSchoolDetails(schoolId) {responseObject, error in
// use responseObject and error here
self.schoolDetailsCollection = NSDictionary(dictionary: responseObject! as! [String : AnyObject])
print(self.schoolDetailsCollection)
if let response = responseObject as? NSDictionary {
//parse the response object
self.schoolDetailsList = (response as? NSDictionary)!
//assigning all values to shareData class
self.shareData.sco_id = response["result"]!["sco_id"] as!NSInteger
self.shareData.address = response["result"]!["address"] as!String
self.shareData.name = response["result"]!["name"] as! String
print("school name")
print(self.shareData.name)
self.shareData.intro = response["result"]!["intro"] as! String
self.shareData.sell_point = response["result"]!["sell_point"] as! String
self.shareData.city = response["result"]!["city"] as! String
self.shareData.cou_id = response["result"]!["cou_id"] as! String
//get images from the nested array in the json array
/THESE THREE LINES CAUSE THE ERROR SUBSRCIPT
self.shareData.image1 = response["result"]!["images"][0]! as! String
self.shareData.image2 = response["result"]!["images"]![1] as! String
self.shareData.image3 = response["result"]!["images"]![2] as! String
print(self.shareData.image1)
print(self.shareData.image2)
print(self.shareData.image3)
//open next controller after all info has been set correctly
//info is being passed by Singleton class Sharedata
if let COBezierDemoViewController = self.storyboard!.instantiateViewControllerWithIdentifier("COBezierDemoViewController") as? COBezierDemoViewController {
self.presentViewController(COBezierDemoViewController, animated: true, completion: nil)
}
}
}
}
The JSON file:
{
result = {
address = "223 Vincent St, West Perth WA 6005, Australia";
city = Perth;
"cou_id" = AU;
"cur_id" = "";
environment = R;
financed = "<null>";
images = (
"Phoenix_Academy_1.jpeg",
"Phoenix_Academy_3.jpeg",
"Phoenix_Academy_2.jpeg"
);
intro = "Our language school in Perth has a modern campus and a spacious garden. The language school is located 10 minutes north from the city center. You can reach the city center and the famous bea
As you hint that error in this line:
self.shareData.image1 = response["result"]!["images"][0]! as! String
Error:
Error is [0] subscript which you are implementing in AnyObject.
response["result"]!["images"] // this is returning Optional<AnyObject> which do not have subscript option.
Correct way should be this:
Downcast AnyObject as? [String] // this will either return nil or an Optional Array<String?> where String is image name.
Without downcasting, you will get error: Ambiguous use of subscript.
let images = response["result"]? ["images"] as? [String]
images?.flatMap({ $0 }).forEach {
print($0) // Phoenix_Academy_1.jpeg, Phoenix_Academy_3.jpeg, Phoenix_Academy_2.jpeg
}
I prepare a swift Array in my Watch Interface and send it to the iOS App:
#IBAction func buttonGeklickt() {
if WCSession.isSupported() {
let session = WCSession.defaultSession()
session.delegate = self
session.activateSession()
let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "hh:mm"
let datumString = dateFormatter.stringFromDate(NSDate())
var swiftArray = [String]()
swiftArray.append(datumString)
var swiftDict = ["a":swiftArray]
session.transferUserInfo(swiftDict)
}
so far so good, on the iOS App the dictionary arrives, but there seems to be something wrong with the Array in the Dictionary:
func session(session: WCSession, didReceiveUserInfo userInfo: [String : AnyObject]) {
print ("seems to be the same Dict = \(userInfo)")
if let vw = userInfo["a"] as? [String: String] {
print ("Never called! Here I would expect my array from the watch \(vw)")
}
}
I would expect and like vw to hold the same array as swiftArray in the watchApp. However it seems to be of type __NSCFArray:
screenshot
So what I'm doing wrong here?
I'm new to Swift, however I'm experienced with Objective C to solve actually every problem I faced in the past years, but this issue seems to be so basic and it's embarrassing that I'm not able to solve it on my own. So help is much appreciated
If I understand your code correctly, you are saving "a" as value of type [String]. But you are trying to read it as [String:String]. Instead of
if let vw = userInfo["a"] as? [String: String]
try
if let vw = userInfo["a"] as? [String]