Swift Error: Ambiguous reference to member 'subscript' - swift

I'm new to coding and picked up some open source project to get the idea.
I'm getting the error:
Ambiguous reference to member 'subscript'
in the code below:
let pictures = ( selectedRestaurant["Pictures"] as! NSArray ) // Error
let picture = ( pictures[zoomedPhotoIndex] as! NSDictionary )
let pictureURL = picture["url"] as! String
let imageURL = NSURL(string: pictureURL)
let urlRequest = NSURLRequest(URL: imageURL!)
NSURLConnection.sendAsynchronousRequest(urlRequest, queue: NSOperationQueue.mainQueue()) {
response, data, error in
if error == nil && data != nil {
self.imageView.image = UIImage(data: data!)
self.imageView.contentMode = UIViewContentMode.ScaleAspectFit
}
}

Just specify explicitly what is the type of pictures:
So instead of:
let pictures = selectedRestaurant["Pictures"] as! NSArray
Write:
let pictures: NSArray = selectedRestaurant["Pictures"] as! NSArray

For me the answer was to specifically state the type of array I was casting to:
if let foo = dictionary["bar"] as? [String]

It means that "Pictures" is not a valid subscript. It looks like you are creating a constant named pictures and you are trying to assign it a value of selectedRestaraunt["Pictures"] and then trying to cast it as an NSArray. If selectedrestaraunt is already an array, then what goes in the [] brackets after selectedRestaraunt should be an integer value which will refer to an index in the selectedRestaraunt array. Obviosuly "Pictures" is not an integer, it is a string.
If you are trying to access an array within an array. Meaning that Pictures is an array stored within the selectedRestarauntarray then you can access it by using selectedRestaraunt[index of Pictures array] where [index of pictures array] is an integer which is equal to the index number in which the Picutres array resides within the selectedRestaraunt array

I managed to get this error in a somewhat weird way. I had code like this:
cell.textLabel = anArrayOfStrings[indexPath.item].uppercased()
And I was stumped as to why it couldn't figure out that this was an array, even though I very clearly declared its type. I broke the line in two and finally got a helpful error message:
let name = anArrayOfStrings[indexPath.item].uppercased()
cell.textLabel = name
I was trying to assign a String to a UILabel, but somehow the point at which the type inference engine failed was at the subscript.
So my advice to anyone stumped by this is to try to break up your statement into bite-sized chunks that the Swift type inference engine can more easily digest.

As Eric and Eugene mentioned in their comments it is impossible to review the issue you are having without knowing the selectedRestaurant type. That is after all why you are getting the compiler ambiguity error.
I have to respectfully disagree with MikeG though. The problem is not one of a valid subscript. You'd be getting that kind of error, if for example you had a selectedRestaurant type of [NSNumber:AnyObject], where clearly String is no longer valid since the dictionary key could only be an NSNumber.

Related

How to get value of a NSSingleObjectArrayI

func responseDataHandler(data: NSDictionary) {
let temperature_c = data.value(forKeyPath: "data.current_condition.temp_C")
DispatchQueue.main.async{
self.Temperature.text = temperature_c as? String
}
}
I have the above code where I am accessing a weather API which returns data in the form of an NSDictionary to this function. I need to access the value in temperature_c which when I try to print it, it says that it is: Optional(<__NSSingleObjectArrayI 0x600002147fd0>(
25
)
). Temperature is the outlet for label on my storyboard which I want to take on the value of 25 however as written now, it doesn't work and I have tried everything to try and access the value in the Single Object Array but nothing is working. I found this stack overflow question that was similar but it doesn't work for my situation because I keep getting the error that temperature_c is of type any and doesn't have subscripts.
The issue is that you can't cast to String an array, you should try to convert it to [String]. So could change your code to:
self.Temperature.text = (temperature_c as? [String])?.first ?? "Not available"
Let's go step by step:
temperature_c as? [String] tries to convert the NSDictionary to a String array which is the expectable type.
Since the previous step may return nil we have to use optional chaining ?. If we got a valid array using first return the the arrays first element.
Since both previous steps can return nil we can use nil coalescing operator to return a default value. In this case I use "Not available" but you can set any value.
You could write it in a more verbose way like this:
var text2Display2 = "Not available"
if let theArray = temperature_c as? [String] {
if let element = theArray.first {
text2Display2 = element
}
}
self.Temperature.text = text2Display2

Variable used within its own initial value Swift 3

I try to convert my code to swift 3 an I have spent hours on the following error:
Type 'Any' has no subscript members
Here's was my original code:
let data: AnyObject = user.object(forKey: "profilePicture")![0]
I looked at the answers here but I'm still stuck. (I do programming as a hobby, I'm not a pro :/)
I've try that:
let object = object.object(forKey: "profilePicture") as? NSDictionary
let data: AnyObject = object![0] as AnyObject
But now I get this error:
Variable used within its own initial value
Second issue: Use always a different variable name as the method name, basically use more descriptive names than object anyway.
First issue: Tell the compiler the type of the value for profilePicture, apparently an array.
if let profilePictures = user["profilePicture"] as? [[String:Any]], !profilePictures.isEmpty {
let data = profilePictures[0]
}
However, the array might contain Data objects, if so use
if let profilePictures = user["profilePicture"] as? [Data], !profilePictures.isEmpty {
let data = profilePictures[0]
}
Or – what the key implies – the value for profilePicture is a single object, who knows (but you ...)
And finally, as always, don't use NSArray / NSDictionary in Swift.

Found nil for optional value?

I just can not figure this out :
print(module)
print(Globals.sharedInstance.dataModuleName)
let kind:NSString = module[Globals.sharedInstance.dataModuleName] as! NSString
Will print this, and then crash for a strange reason:
( //dic print
{
meta = no;
module = IN;
subject = LT;
variable = A2;
}
)
module // print the right field we are looking for inside the dictionary .
fatal error: unexpectedly found nil while unwrapping an Optional value
But you can see that module is a valid dictionary and also dataModuleName.
Crashing on the line let kind. What's wrong with it ?
Your module is Array of Dictionary not directly Dictionary, so you need to first access its first object then the module key like this
let kind:String = module[0][Globals.sharedInstance.dataModuleName] as! String
Note: One sugeestion, in swift use String instead of NSString
Also you can use if let and guard with initializtion to avoid crash.

CoreData: Loading Integers out of a File

I got following code to load the data stored:
func loadLevel(){
let appDel:AppDelegate = (UIApplication.sharedApplication().delegate as! AppDelegate)
let context:NSManagedObjectContext = appDel.managedObjectContext
let request = NSFetchRequest(entityName: "Level")
request.returnsObjectsAsFaults = false
do{
let results:NSInteger = try context.executeFetchRequest(request)
level = results
}catch{
print("Error")
}
}
In the line where I am trying to store the data in the variabel results I get following error:
Cannot convert value of type '[AnyObject]' to specified type 'NSInteger' (aka 'Int')
I do know that I am not doing the error handling correct and as it should be. Thats the 'second step' on my list. Hopefully you can help me on my first problem.
The executeFetchRequest returns an array of results, because fetches can and usually do return more than one result. These results can be of different types depending on how the fetch request was configured. So the return type is [AnyObject].
You're attempting to assign the result of the fetch to a single NSInteger. You can't just assign an array of AnyObject like that. Your results will be zero or more instances of your Level instance, either instances of NSManagedObject or instances of a custom subclass you've configured for the entity.
What you should do is:
Change results to be of type [AnyObject]
Look through this array to find instances of Level
Get integer values from whichever attribute of Level contains the integer that you need.

Dictionary Values in Swift

I am trying to access values I've set in a Swift dictionary. The dictionary has a String for the keys and values. My intent is to use the dictionary to set a string variable as I work through a series of URLs. In Objective-C I understand how this works. I have a string property called currentFeed that I pass the value of the dictionary to.
self.currentFeed = [NSString stringWithString: [self.URLDictionary objectForKey: #"FLO Cycling"]];
In Swift I am having a difficult time with this. I tried the following code and receive an error message.
self.currentFeed = self.URLDictionary["FLO Cycling"]
Error Message: "Cannot subscript a value of type '[String:String]' with an index of type 'String'.
For reference the dictionary was created in Swift in the following way. The constants were created with lets.
let kFLOCyclingURL = "http://flocycling.blogspot.com/feeds/posts/default?alt=rss"
let kTriathleteURL = "http://triathlon.competitor.com/feed"
let kVeloNewsURL = "http://velonews.competitor.com/feed"
let kCyclingNewsURL = "http://feeds.feedburner.com/cyclingnews/news?format=xml"
let kRoadBikeActionURL = "http://www.roadbikeaction.com/news/rss.aspx"
let kIronmanURL = "http://feeds.ironman.com/ironman/topstories"
The items were added to the dictionary with keys.
let URLTempDictionary = ["FLO Cycling" : kFLOCyclingURL, "Triathlete" : kTriathleteURL, "Velo News" : kVeloNewsURL, "Cycling News" : kCyclingNewsURL, "Road Bike Action" : kRoadBikeActionURL, "Ironman" : kIronmanURL]
Thanks for any help.
Take care,
Jon
This compiles fine for me. The only thing I noticed was that your dictionary is named URLTempDictionary and you're accessing URLDictionary. :)
Option a (safest, most robust)
if let dict = self.URLDictionary
{
self.currentFeed = dict["FLO Cycling"]
}
Option b (use with caution, possible runtime error)
self.currentFeed = dict!["FLO Cycling"]