Reputation: 77641
I wrote a function to call some cloud code last night and it was working fine.
Now, when I run the same code I get a crash at...
#2 0x000000010e3e28f4 in -[PFNoObjectEncodingStrategy encodeRelatedObject:] at /Users/nlutsenko/src/parse/ios-client/Parse/Internal/PFObjectEncodingStrategy.m:17
I've never seen this crash before though.
My cloud code call is...
- (void)getFollowStats
{
[PFCloud callFunctionInBackground:@"followStats" withParameters:@{@"user": self.user} block:^(NSDictionary *result, NSError *error) {
if (error) {
NSLog(@"Error! %@ : %@", error, error.userInfo);
} else {
}
}];
}
And the crash is happening because of the @{@"user": self.user}
parameter. If I remove the user object then it doesn't crash. But this was working fine last night.
The entire call stack
#0 0x00000001119a3b8a in objc_exception_throw ()
#1 0x0000000111d0ae6d in +[NSException raise:format:] ()
#2 0x000000010e3e28f4 in -[PFNoObjectEncodingStrategy encodeRelatedObject:] at /Users/nlutsenko/src/parse/ios-client/Parse/Internal/PFObjectEncodingStrategy.m:17
#3 0x000000010e428520 in +[PFInternalUtils encodeObject:withObjectEncoder:] at /Users/nlutsenko/src/parse/ios-client/Parse/Internal/PFInternalUtils.m:456
#4 0x000000010e428b63 in +[PFInternalUtils encodeObject:withObjectEncoder:] at /Users/nlutsenko/src/parse/ios-client/Parse/Internal/PFInternalUtils.m:513
#5 0x000000010e42c675 in +[PFCloud callFunctionInBackground:withParameters:] at /Users/nlutsenko/src/parse/ios-client/Parse/PFCloud.m:29
#6 0x000000010e42c9c2 in +[PFCloud callFunctionInBackground:withParameters:block:] at /Users/nlutsenko/src/parse/ios-client/Parse/PFCloud.m:56
#7 0x000000010e392712 in -[CCAccountDataSource getFollowStats] at /Users/oliverfoggin/Documents/emojicate/Emojicate/Account View/Account Data Source/CCAccountDataSource.m:48
#8 0x000000010e3922cc in -[CCAccountDataSource fetchUserDetails] at /Users/oliverfoggin/Documents/emojicate/Emojicate/Account View/Account Data Source/CCAccountDataSource.m:27
#9 0x000000010e36bb9f in -[CCAccountViewController viewDidLoad] at /Users/oliverfoggin/Documents/emojicate/Emojicate/Account View/CCAccountViewController.m:86
#10 0x0000000110353a90 in -[UIViewController loadViewIfRequired] ()
#11 0x0000000110353c8e in -[UIViewController view] ()
#12 0x0000000110377507 in -[UINavigationController _startCustomTransition:] ()
#13 0x00000001103833fe in -[UINavigationController _startDeferredTransitionIfNeeded:] ()
#14 0x0000000110383f47 in -[UINavigationController __viewWillLayoutSubviews] ()
#15 0x00000001104c9509 in -[UILayoutContainerView layoutSubviews] ()
#16 0x0000000121ef6a5e in -[UILayoutContainerViewAccessibility layoutSubviews] ()
#17 0x00000001102a7973 in -[UIView(CALayerDelegate) layoutSublayersOfLayer:] ()
#18 0x000000010ff3bde8 in -[CALayer layoutSublayers] ()
#19 0x000000010ff30a0e in CA::Layer::layout_if_needed(CA::Transaction*) ()
#20 0x000000010ff3087e in CA::Layer::layout_and_display_if_needed(CA::Transaction*) ()
#21 0x000000010fe9e63e in CA::Context::commit_transaction(CA::Transaction*) ()
#22 0x000000010fe9f74a in CA::Transaction::commit() ()
#23 0x000000010fe9fdb5 in CA::Transaction::observer_callback(__CFRunLoopObserver*, unsigned long, void*) ()
#24 0x0000000111c3fdc7 in __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ ()
#25 0x0000000111c3fd20 in __CFRunLoopDoObservers ()
#26 0x0000000111c35b53 in __CFRunLoopRun ()
#27 0x0000000111c35486 in CFRunLoopRunSpecific ()
#28 0x0000000112e9d9f0 in GSEventRunModal ()
#29 0x000000011022e420 in UIApplicationMain ()
#30 0x000000010e3970c3 in main at /Users/oliverfoggin/Documents/appName/appName/main.m:16
#31 0x0000000112237145 in start ()
The parameters dictionary
I split out the parameters dictionary into a var and logged it and this is what I got...
{
user = "
<PFUser: 0x7blahblha0, objectId: blahblah, localId: (null)>
{
authData = {
facebook = {
"access_token" = blahblahblahblah;
"expiration_date" = "2016-11-19T09:32:19.434Z";
id = 1234567;
};
};
avatar = "<PFFile: 0x7fc1b1c3ffb0>";
canonicalName = "oliver foggin";
emoji = "<PFFile: 0x7fc1b1c41170>";
fbId = 723405322;
friendIds = (
8765586,
23452345,
2345123
);
fullName = "Oliver Foggin";
onboardComplete = 1;
username = blahblahblahblah;
}";
}
I have removed all secure info from this and changed the ID numbers.
The bit that I added yesterday is the friendIds
array. But that was added yesterday morning and this code was working at 18:10 last night.
OK, WTF? This is just weird
I replaced the parameters code with this...
NSMutableDictionary *parameters = [NSMutableDictionary dictionary];
if (self.user) {
parameters[@"user"] = [PFObject objectWithoutDataWithClassName:@"_User" objectId:self.user.objectId];
}
So now it isn't even using the user object it's creating a fake "User" object with the object ID.
The parameters dictionary looks like this...
{
user = "<PFUser: 0x7fd770cc1020, objectId: ez0KCzD6Th, localId: (null)> {\n}";
}
And I still get the same crash.
Upvotes: 1
Views: 267
Reputation: 351
I don't think you can currently pass PFObjects as parameters to cloud functions. The NoObjectEncodingStrategy (an internal implementation detail that you're seeing in the call stack) is explicitly forbidding this. The exception should have an error message to that effect.
Instead, you should pass the object id of any objects you want in your cloud functions, and look them up server-side if necessary.
The reasoning here is that there is no standard format (e.g. if you look at the REST API for Parse) for objects with pending changes or unsaved objects, so there are many cases where passing a PFObject would have undefined or at least unexpected behavior. That may one day change, but it is a restriction that was intended to avoid confusion.
Upvotes: 3