Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

'PFObject' does not have a member named 'subscript'

I understand, this particular error was already posted here and there and the code is somewhat basic, but I myself still unable to figure this one out & I need advice.

The thing is when I add the first two lines of code provided on parse.com for saving objects

var gameScore = PFObject(className:"GameScore")
gameScore["score"] = 1337

I get the following error for the second line:

'PFObject' does not have a member named 'subscript'

I'm on Xcode 6.3 beta 2. All required libraries are linked with binary, <Parse/Parse.h> imported via BridgeHeader.

What syntax should I use?

like image 464
IT Gypsy Avatar asked Mar 09 '15 22:03

IT Gypsy


2 Answers

This is happening due to the 1.6.4 version of the parse sdk which added Objective-C Nullability Annotations to the framework. In particular the file Parse/PFObject.h defines:

- (PF_NULLABLE_S id)objectForKeyedSubscript:(NSString *)key;

which is causing the Swift compile error. Removing the PF_NULLABLE_S fixes the problem.

On the other hand it seems correct that an object for a keyed subscript might be nil, so I suspect this is a Swift bug...

like image 102
kashif Avatar answered Nov 01 '22 08:11

kashif


The problem seems to be the changed method signature, as kashif suggested. Swift doesn't seem to be able to bridge to the Objective-C method because the signature no longer matches the subscript method names.

Workaround 1

You can work around this without modifying the framework by calling the subscript method directly, instead of using the [] operator:

Instead of using the instruction below for getting the value of a particular key:

let str = user["key-name"] as? Bool

Please use the following instruction:

let str = user.objectForKey("key-name") as? Bool

and

Instead of using the instruction below for setting the value of a particular key:

user["key-name"] = "Bla bla"

Please use the following instruction:

user.setObject("Bla bla", forKey: "key-name")

Workaround 2

Another solution is to add an extension on PFObject that implements the subscript member and calls setValue:forKey::

extension PFObject {
  subscript(index: String) -> AnyObject? {
    get {
      return self.valueForKey(index)
    }
    set(newValue) {
      if let newValue: AnyObject = newValue {
        self.setValue(newValue, forKey: index)
      }
    }
  }
}

Note that this second workaround isn't entirely safe, since I'm not sure how Parse actually implements the subscript methods (maybe they do more than just calling setValue:forKey - it has worked in my simple test cases, so it seems like a valid workaround until this is fixed in Parse/Swift.

like image 6
Ben-G Avatar answered Nov 01 '22 07:11

Ben-G