Parse local datastore doesn't work - Swift 2 - ios

I am currently using the latest version of Parse 1.14.2 and Bolts 1.8.4.Parse is implemented correctly and I have been using it for a long time now. The problem I'm facing now is when I try to use Parse's local datastore. I have the following code in my AppDelegate.swift:
Parse.enableLocalDatastore()
Parse.setApplicationId("ID",
clientKey: "Client_Key")
I have the following code to create and save a string named firstName in a class named contact:
let contact = PFObject(className: "contact")
contact["firstName"] = "Jack"
contact.pinInBackground()
Here is the code to retrieve objects from the created class:
let query = PFQuery(className: "contact")
query.fromLocalDatastore()
query.getFirstObjectInBackgroundWithBlock({ (object, error) -> Void in
if error == nil {
if let contact = object {
print(contact.objectForKey("firstName"))
}
}
})
I have added libsqlite3.dylib to my project. My app doesn't crash when I run this code but it simply gives me the following message when I try to retrieve objects:
2016-08-29 11:31:38.049 App_Demo[14436:3504319] [Bolts] Warning: `BFTask` caught an exception in the continuation block.
This behavior is discouraged and will be removed in a future release.
Caught Exception: Method requires Pinning enabled.
Can anyone help me to work around this issue? I am guessing the issue is that this version of Bolts cannot pin Parse objects in the background and I need to work my way around this bug. Any help would be appreciated as I have been stuck at this for a while and can't find too much info online.
Edited: I have tried downgrading Bolts, but then Parse downgrades with it in Cocoapod and it causes errors in Xcode.

it's not objectforkey.
You need to call object["UsedName"] "UsedName" being the key. Hope that helps.

Related

Swift migration: 'Notification' is ambiguous for type lookup in this context' in some places

I'm making a migration from Swift 2.3 to Swift 5 with a lot of pain and well, I'm ending the migration but I'm still getting an error in some places of the code:
Notification' is ambiguous for type lookup in this context
I recieved before this error but now I'm getting this in places like
var notifications = [Notification]
self.notifications = (sql.execute() as NSArray) as! [Notification]
and
func isAlreadyExists(notification: Notification) -> Bool {
I thought to change Notification name but the app is not mine and is big... very big and is not possible to do this and well, I don't know what to do.
Thanks in advance.
Edit:
Tried to do the same as suggested in How can I disambiguate a type and a module with the same name? but doing "import (class|struct|func|protocol|enum) Module.Symbol" desn't works (I see where Notification is in the project but doesn't work ProjectName.class).
Finally, it worked by changing the class name and adding it to a file called <Project_name>-Bridging-Header.
Doing this I could call the class with var example = <Project_name>.<className>

Parse 'Quick Start' with Swift - 'PFObject' does not have a member named 'subscript'

This is my first attempt with Parse on Swift, and I've followed the quick start guide on Parse's website as seen here: https://parse.com/apps/quickstart#parse_data/mobile/ios/swift/existing
Unfortunately I get this error, 'PFObject' does not have a member named 'subscript'. I have followed the example code and instructions exactly as they are written and have redone this several times but with the same result. I really fail to see where I've gone wrong with this particularly as it's straight off the site. I'm on Xcode 6.4 targeting iOS SDK 8.4 using version 1.8.3 of the Parse library.
This is the code on the ViewController in the viewDidLoad method (I have remembered to include import Parse)
let testObject = PFObject(className: "TestObject")
testObject["foo"] = "bar"
testObject.saveInBackgroundWithBlock { (success: Bool, error: NSError?) -> Void in
println("Object has been saved.")
}
and this is the code I've added to AppDelegate. Again, I have imported Parse and Bolts as specified in the guide. This is the only code I have changed, the rest is as a standard blank single-view application would be. I have redacted the application ID and client key.
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
Parse.enableLocalDatastore()
Parse.setApplicationId("-redacted-",
clientKey: "-redacted-")
PFAnalytics.trackAppOpenedWithLaunchOptions(launchOptions)
}
Any ideas as to how I might fix this or where I might have gone wrong?
You might wait for a better answer in which somebody explains swift unwrapping and optional types as it relates to parse objects (I wish I was qualified to give such an answer). In the meantime a quick fix is to bypass the object["foo"] sugar, and use the the functional form of property access, like object.objectForKey("foo").
I tried it and have the same result.
I also did try to do the
testObject.setValue("bar", forKey: "foo")
And same error occur. Seem like it is inserting "nil" instead of the value or object. I don't why.
What I can suggest though, is use the Objective-C files in Parse.com and then create a bridging header file.
Then do the code provided in Swift language - the one in the AppDelegate.swift and the one with the viewDidLoad.
The code should work.
I think there must be a problem/incompatibility with their new framework for the Swift Language . I'm not sure about it.
Incase the same error occurs, use the
testObject.setValue("bar", forKey: "foo")
in exchange with:
testObject["foo"] = "bar"
Though I read this...
I don't know if this is related to the problem here on their starter project:
'PFObject' does not have a member named 'subscript'

XCode7 Core Data: Fetch for objects etc

I created an iOS8 application and updated it to XCode7. I have a couple of problems after I recreated the NSManagedObject.
First I get an error, if I fetch for contacts and iterate over them:
let contacts = try self.managedObjectContext.executeFetchRequest(request) as! [Contact]
for contact in contacts{
//--> EXC_BAD_INSTRUCION
}
Contact is my NSManagedObject. I do not get any compiler error or warning.
Second: I get this warning:
CoreData: warning: Unable to load class named 'MyAppName.Contact' for entity 'Contact'. Class not found, using default NSManagedObject instead.
What can cause this? The #objc(Contact) in Contact has already been generated bei XCode and now I can't set the className MyAppName.Contact in CoreData-editor. Any suggestion?
Finally found it. All the other tips are not working, because Apple has changed it with XCode7.
Now XCode creates #(Classname) in the NSManagedSubclass. This needs to be commented out (beta1 and beta2). Then XCode can find your class.

Parse SDK and Swift: Incorrect argument label in call PFObject 'withoutDataWithObjectId'

I subclass PFObject exactly as described here.
Then I create a new instance of the subclassed object without data, but since Swift 1.2 I get an error (It did work perfectly before):
var test = Armor(withoutDataWithObjectId: "1234567890")
-> Xcode complains:
"Incorrect argument label in call (have 'withoutDataWithObjectId:',
expected: 'className:')"
Why className? It should get the class name from the class function parseClassName
And I can under no circumstances create a new object with objectId but no data (which I MUST have to fetch it from the local datastore)
This is super annoying as my app doesn't compile any longer.
Update to the newest Parse SDK, available here.
The issue is caused due to necessary adaptions in the Parse SDK after the Swift language update. This issue also occurs with the most recent update to Swift 2.2. The newest (as of today) Parse SDK release 1.13.0 already fixes this.
UPDATE
Parse iOS SDK 1.13.0 has a typo and the function PFUser(withoutDataWithObjectId:) is called PFUser(outDataWithObjectId:). So upgrading the Parse SDK alone does solve this. Until this is fixed a temporary workaround would be to extend PFObject with a convenience initializer. To do this add a new Swift file to your project and insert this:
import Parse
extension PFObject {
convenience init(withoutDataWithObjectId objectId: String?) {
self.init(outDataWithObjectId: objectId)
}
}
It may be a little late to answer this question.
I use swift 1.2, and v 1.7.5 Parse SDK, and it works totally fine.
however, make sure you have define objective-c bridging header in "build setting".
and try to run it, even though there may reports some error

'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?
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...
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.
I've successfully run your exact code.
First, make sure you are indeed saving the object in the background, after you set the new value:
gameScore.save()
I would double check for misspellings in the class name and subclass; if they are incorrect, it will not work.
If that's not the problem, verify in Parse that the "score" subclass is set to be a number. If you accidentally set it to be a string, setting it as an integer will not work.
If these suggestions have not hit the solution, then I'm not sure what the problem is. Hope I helped.
I encountered a similar error with Parse 1.6.4 and 1.6.5 in the PFConstants.h header file with method parameters.
Xcode 6.3 beta 4 has a note in the "New in..." section regarding nullability operators.
Moving the nullability operator between the pointer operator and the variable name seems to comply/compile.
Changing:
PF_NULLABLE_S NSError *error
to:
NSError * PF_NULLABLE_S error
(i.e., NSError* __nullable error)
... resolved the compiler error.
This also worked for block parameters defined with id. So...
PF_NULLABLE_S id object
becomes:
id PF_NULLABLE_S object
In the above case, perhaps:
- (id PF_NULLABLE_S)objectForKeyedSubscript:(NSString *)key;
I.e., the nullability operator is after the pointer type.
I know its been a while but I encountered a similar problem when I was starting my first Parse application with SDK version 1.9.1.
The Quickstart guide had the code below as an example as to how to save values:
let testObject = PFObject(className: "TestObject")
testObject["foo"] = "bar"
testObject.saveInBackgroundWithBlock { (success: Bool, error: NSError?) -> Void in
println("Object has been saved.")
}
But, the line testObject["foo"] = "bar" returned the error 'PFObject' does not have a member named 'subscript'. I was able to work around the problem by changing the line to testObject.setValue("bar", forKey: "foo"). (As suggested by a tutorial video on YouTube: https://www.youtube.com/watch?v=Q6kTw_cK3zY)

Resources