7

Xcode beta 6 has changed some of the Swift Language

Since ‘id’ now imports as ‘Any’ rather than ‘AnyObject’, you may see errors where you were previously performing dynamic lookup on ‘AnyObject’.

I have tried the fix to either cast to AnyObject explicitly before doing the dynamic lookup, or force cast to a specific object type

But am not sure I am doing it correctly - can someone help please here is original working code from Beta 5

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! SpecialCell
        let maindata = values[(indexPath as NSIndexPath).row]
        cell.name.text = maindata["name"] as? String
        cell.id.text = maindata["id"] as? String
        //team_id.text = maindata["team_id"] as? String

        return cell
    }

https://www.dropbox.com/s/ln0vx3b9rbywv83/Screen%20Shot%202016-08-18%20at%2014.32.23.png?dl=0

adamprocter
  • 856
  • 1
  • 15
  • 31

2 Answers2

7

According to the beta 6 release notes you have to (bridge) cast to AnyObject

cell.name.text = (maindata["name"] as AnyObject) as? String

or force cast

cell.name.text = maindata["name"] as! String

That's one more reason to prefer custom classes / structs with distinct property types over common dictionaries.

vadian
  • 274,689
  • 30
  • 353
  • 361
  • unfortunately even with either options they both produce the error Type Any has no subscript members still. – adamprocter Aug 18 '16 at 14:29
  • As my data is a JSON feed I was not sure how to use either a custom class or struct as you suggest ? – adamprocter Aug 18 '16 at 14:31
  • How is `values` declared? – vadian Aug 18 '16 at 14:31
  • values = try! JSONSerialization.jsonObject(with: data!, options: JSONSerialization.ReadingOptions.mutableContainers) as! NSMutableArray – adamprocter Aug 18 '16 at 14:31
  • **Do not** use `NSMutableArray` use at least a Swift `Array` `[[String:AnyObject]]` or `[[String:Any]]`. The declaration as `var` gives you mutability for free. – vadian Aug 18 '16 at 14:32
  • Thanks I think I was forced down the NSArray thing by mistake in the first instance.. so I can make values as var values:Any = [] but let maindata = values[(indexPath as NSIndexPath).row] - complains.... – adamprocter Aug 18 '16 at 14:37
  • I have to rewrite - values = try! JSONSerialization.jsonObject(with: data!, options: JSONSerialization.ReadingOptions.mutableContainers) as! NSMutableArray ? but not sure what – adamprocter Aug 18 '16 at 14:38
  • Please, please don't declare an obvious array simply as `Any`. That's the most unspecified type at all. Help the compiler then the compiler will help you. The JSON collection types are either dictionary `[String:AnyObject]` or array `[[String:AnyObject]]` (in Xcode 8 maybe `Any` for `AnyObject`), so cast the JSON serialization to `[[String:Any(Object)]]` – vadian Aug 18 '16 at 14:42
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/121267/discussion-between-adamprocter-and-vadian). – adamprocter Aug 18 '16 at 14:47
  • Vadian with this update the compiler says, "Method does not override any methods from its superclass". Then when I change the line to `override func awake(withContext context: Any?)` the error goes away. Is it ok to simply change it to `Any?`? – Edison Aug 20 '16 at 20:30
  • Yes, it is. All `AnyObject` types in parameters which represent `id` have been changed to `Any` – vadian Aug 20 '16 at 20:32
  • Thanks Vadian. Also I tried to find the same release notes [Release Notes](https://developer.apple.com/library/prerelease/content/navigation/#section=Resource%20Types&topic=Release%20Notes) but cannot find code changes. Do you have a link? – Edison Aug 20 '16 at 22:46
  • I guess the release notes of the beta versions are available only in a developer account. – vadian Aug 20 '16 at 22:47
0

I needed to make changes to my approach and ditch NSMutableArray (which I am pleased about)

so I declare the empty array as follows

var values = [[String:AnyObject]]()

and pop the data into it like so now

values = try! JSONSerialization.jsonObject(with: data!, options: JSONSerialization.ReadingOptions.mutableContainers) as! [[String : AnyObject]];

one other minor tweak

let maindata = values[(indexPath).row]

Job done -thanks @vadian for jumping to chat to help me understand his answer which is technically correct

adamprocter
  • 856
  • 1
  • 15
  • 31