Can't delete a Parse PFObject? - ios

I'm having trouble deleting an object... Confused why it can't find it because I am already collecting data from it from Parse to the user's device. I'm getting 2 error messages. One for the first deleteInBackground, and then again for deleteEventually:
1) Error: object not found for delete (Code: 101, Version: 1.2.19)
2) runEventually command failed. Error:Error Domain=Parse Code=101 "The operation couldn’t be completed. (Parse error 101.)" UserInfo=0x17d16150 {code=101, error=object not found for delete}
Here's my code on how I am deleting:
PFObject *parseMessage = [objects objectAtIndex:i];
SentMessage *newMessage = [[SentMessage alloc] initNew:parseMessage[#"senderEmail"] :parseMessage[#"senderName"] :Kjell.savedData.userEmail :Kjell.savedData.userDisplayName :parseMessage[#"message"]];
[newMessage setTimeReceived:[NSDate date]];
[newMessage setTimeSent:parseMessage[#"dateSent"]];
[[[Kjell.savedData.recentUserArray objectAtIndex:j] conversationArray] addObject:newMessage];
[parseMessage deleteInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
if (!succeeded)
{
[parseMessage deleteEventually];
}
}];
any help would be great.

Once ensured that object really exist server side, check if ACL is property set for it, so that current logged user ( client side ) can affect that object for edit or delete

Related

Google Drive on iOS and "invalid_grant"

I have an iOS app that uses Google Drive to sync some files. The app was working fine up until a couple of months ago (it uses iCloud by default for syncing so it wasn't until recently that I learned the Google Drive since was no longer working).
The error I'm getting is:
An error occurred: Error Domain=com.google.HTTPStatus Code=400 "(null)" UserInfo={json={
error = "invalid_grant";
}, data=<7b0a2020 22657272 6f722220 3a202269 6e76616c 69645f67 72616e74 220a7d>}
The OAuth part sets to be OK and I think I'm authorized to access the user's Google Drive. The error happens when I try to list the files at the top level to see if I need to create a special directory for my app.
- (void)createGoogleDocumentsDirIfNeeded:(id<GoogleServiceDelegate>)delegate
{
NSString *parentID = #"root";
GTLQueryDrive *query = [GTLQueryDrive queryForFilesList];
query.q = [NSString stringWithFormat:#"'%#' in parents and title = '%#' and trashed != true", parentID, APP_NAME];
[googleService executeQuery:query completionHandler:^(GTLServiceTicket *ticket,
GTLDriveFileList *files,
NSError *error)
{
if (error == nil)
{
if ( files.items.count == 0)
{
NSLog(#"Creating google documents dir: %#", APP_NAME);
[self createGoogleDocumentsDir:delegate];
}
else
{
GTLDriveFile *file = [files objectAtIndexedSubscript:0];
self.googleDocumentsID = file.identifier;
NSLog(#"Directory exists: %#; fileID = %#", APP_NAME, googleDocumentsID);
[delegate googleDocumentsDirCreated:YES];
}
}
else
{
NSLog(#"An error occurred: %#", error);
}
}];
}
The error is displayed in the last NSLog().
I'm pretty convinced that something has change on Google's side that is causing this. I've reverted to code to a point where I know it worked before and it is still failing.
Possibly I've made some change in our Google Developer's Console that is causing this, but I can't see what.
It is also the case that the Google API Dashboard still shows some successful accesses, so it seems this is not failing for everyone.
Any thoughts as to what could be going on? The "invalid_grant" error seems pretty generic and web searches show it happens in lots of situations. Any help would be appreciated.
As you say, there could be a variety of explanations.
Some to check are:-
has the user withdrawn his permission
are you using an expired refresh token
is the phone's clock accurate
Read https://developers.google.com/identity/protocols/OAuth2UserAgent
The URL used when authenticating a user is https://accounts.google.com/o/oauth2/v2/auth. This endpoint is accessible over SSL, and HTTP connections are refused.
Only for httpS connects for now

mailcore2 imap Error Domain=MCOErrorDomain Code=5

I in turn to the making relevant mailcore2 problems, based on past errors, and all of the share, or didn't find the solution to this problem below, so the problem I have encountered redistribution, also hope to get more help, thank you!
Mailcore2 using the code below:
self.imapSession = [[MCOIMAPSession alloc] init];
self.imapSession.hostname = hostname;
self.imapSession.port = 993;
self.imapSession.username = username;
self.imapSession.password = password;
if (oauth2Token != nil) {
self.imapSession.OAuth2Token = oauth2Token;
self.imapSession.authType = MCOAuthTypeXOAuth2;
}
self.imapSession.connectionType = MCOConnectionTypeTLS;
MasterViewController * __weak weakSelf = self;
self.imapSession.connectionLogger = ^(void * connectionID, MCOConnectionLogType type, NSData * data) {
#synchronized(weakSelf) {
if (type != MCOConnectionLogTypeSentPrivate) {
NSLog(#"event logged:%p %i withData: %#", connectionID, type, [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);
}
}
};
// Reset the inbox
self.messages = nil;
self.totalNumberOfInboxMessages = -1;
self.isLoading = NO;
self.messagePreviews = [NSMutableDictionary dictionary];
[self.tableView reloadData];
NSLog(#"checking account");
self.imapCheckOp = [self.imapSession checkAccountOperation];
[self.imapCheckOp start:^(NSError *error) {
MasterViewController *strongSelf = weakSelf;
NSLog(#"finished checking account.");
if (error == nil) {
[strongSelf loadLastNMessages:NUMBER_OF_MESSAGES_TO_LOAD];
} else {
NSLog(#"error loading account: %#", error);
}
strongSelf.imapCheckOp = nil;
}];
When I use iOS8.1 equipment, error message as follows, the console output:
checking account
2015-02-15 10:58:36.712 MailCoreTest[11971:2988194] event logged:0x166a4d50 0 withData: * OK [CAPABILITY IMAP4 IMAP4rev1 IDLE XAPPLEPUSHSERVICE ID UIDPLUS AUTH=LOGIN NAMESPACE] QQMail IMAP4Server ready
2015-02-15 10:58:36.821 MailCoreTest[11971:2988194] event logged:0x166a4d50 0 withData: (null)
2015-02-15 10:58:36.824 MailCoreTest[11971:2988128] finished checking account.
2015-02-15 10:58:36.825 MailCoreTest[11971:2988128] error loading account: Error Domain=MCOErrorDomain Code=5 "Unable to authenticate with the current session's credentials." UserInfo=0x16596ec0 {NSLocalizedDescription=Unable to authenticate with the current session's credentials.}
But when I use iOS8.0 devices, console to print the results are as follows:
checking account
2015-02-15 11:22:53.249 MailCoreTest[7853:1742121] finished checking account.
2015-02-15 11:22:53.249 MailCoreTest[7853:1742121] error loading account: Error Domain=MCOErrorDomain Code=1 "A stable connection to the server could not be established." UserInfo=0x17e50ab0 {NSLocalizedDescription=A stable connection to the server could not be established.}
Please help me, I contact with Objective - C time is short, but I must do my best to be aggressive, still hope to give a detailed solution, sincere thank you once again, hard work!
Yes its an authentication issue, I had same issue with my app but it was working fine before.
After I got this error, I checked my gmail account and there was an email from Google with subject "Suspicious Sign in prevented" and This sign in was of CA, USA. Actually My Application was under review so it was rejected for this reason.
Then I found that gmail is disabling unauthorised IPs.
You have to enable the 2 step verification for the gmail account to resolve this and generate an app specific password. Use that password in your app and It'll work fine.
Follow below google link to generate application specific password.
https://support.google.com/mail/answer/1173270?hl=en

Parse iOS: PFUser saveInBackgroundWithBlock does not return error when the save does not succeed

I am using anonymous users in parse and if they are not saved, I issue a network call to save them. The code for saving the user is as follows
PFUser* current = [PFUser currentUser];
if (!current.objectId) {
// The user is newly created, don't run any queries for them until they are saved.
[current saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
// We need a saved user to do stuff.
if (!succeeded) {
NSLog(#"Error saving user: %#", error);
} else {
NSLog(#"Saved anonymous user");
// ... load data
}
}];
return;
}
If I run this in the simulator with no internet connection, the save fails (clearly), but succeeded is true and error is nil, so my code goes into loading data even though the user was not saved. In fact the error gets logged in logs but isn't returned in the callback:
Error: Error
Domain=NSURLErrorDomain Code=-1009 "The Internet connection appears to
be offline." UserInfo=0x17aa1220
{NSErrorFailingURLStringKey=https://api.parse.com/2/user_signup_or_login,
NSErrorFailingURLKey=https://api.parse.com/2/user_signup_or_login,
NSLocalizedDescription=The Internet connection appears to be offline.,
NSUnderlyingError=0x1792c880 "The Internet connection appears to be
offline."} (Code: 100, Version: 1.2.20)
Is this a bug in the Parse API or am I not using something correctly?
It is not enough to just check the succeeded flag, you should also check the error.
If you are only going to check one of them, check the error.
The following is the pattern I would use:
if (succeeded && !error) {
// success!
} else {
// uh oh :(
}
You can handle the error in the else block by using kPFErrorConnectionFailed which checks for connection.
Example
else {
if(error.code == kPFErrorConnectionFailed)
{
// handle error
}
}
This was a bug which has now been fixed in the latest release of parse.

userInfo Keys used in Core Data Validation Errors Error

Trying to find out Core Data Errors Error, and looking inside userInfo in NSError returned by MOC's save method.
iphone-core-data-unresolved-error-while-saving
I am not able to make commends or raise questions due to my lack of points.
Can any one point out for me where following keys are defined in Apple Doc, NSValidationErrorObject, NSValidationErrorKey...etc?
My understanding is: if CoreData's Error code == NSValidationMultipleErrorsError, then NSError's userInfo(dictionary) will contain all detailed-single-error information, and all those detailed-single-error will be accessible from an Array stored under "NSDetailedErrorsKey" from userInfo.
I just don't see them (NSValidationErrorObject, NSValidationErrorKe...) in Core Data Constants Reference...??? Are they opaque ?
Thanks.
- (BOOL)saveData {
NSError *error;
if (![_sharedManagedObjectContext save:&error]) {
// If Cocoa generated the error...
NSString *message = nil;
if ([[error domain] isEqualToString:#"NSCocoaErrorDomain"]) {
// ...check whether there's an NSDetailedErrors array
NSDictionary *userInfo = [error userInfo];
if ([userInfo valueForKey:#"NSDetailedErrors"] != nil) {
// ...and loop through the array, if so.
NSArray *errors = [userInfo valueForKey:#"NSDetailedErrors"];
for (NSError *anError in errors) {
NSDictionary *subUserInfo = [anError userInfo];
subUserInfo = [anError userInfo];
// Granted, this indents the NSValidation keys rather a lot
// ...but it's a small loss to keep the code more readable.
NSLog(#"Core Data Save Error\n\n \
NSValidationErrorKey\n%#\n\n \
NSValidationErrorPredicate\n%#\n\n \
NSValidationErrorObject\n%#\n\n \
NSLocalizedDescription\n%#",
[subUserInfo valueForKey:#"NSValidationErrorKey"],
[subUserInfo valueForKey:#"NSValidationErrorPredicate"],
[subUserInfo valueForKey:#"NSValidationErrorObject"],
[subUserInfo valueForKey:#"NSLocalizedDescription"]);
}
}
// If there was no NSDetailedErrors array, print values directly
// from the top-level userInfo object. (Hint: all of these keys
// will have null values when you've got multiple errors sitting
// behind the NSDetailedErrors key.
else {
NSLog(#"Core Data Save Error\n\n \
NSValidationErrorKey\n%#\n\n \
NSValidationErrorPredicate\n%#\n\n \
NSValidationErrorObject\n%#\n\n \
NSLocalizedDescription\n%#",
[userInfo valueForKey:#"NSValidationErrorKey"],
[userInfo valueForKey:#"NSValidationErrorPredicate"],
[userInfo valueForKey:#"NSValidationErrorObject"],
[userInfo valueForKey:#"NSLocalizedDescription"]);
}
}
// Handle mine--or 3rd party-generated--errors
else {
NSLog(#"Custom Error: %#", [error localizedDescription]);
}
return NO;
}
return YES;
}
[1]: https://stackoverflow.com/questions/1283960/iphone-core-data-unresolved-error-while-saving
Following is the quoted from #quellish message, thanks #quellish!
Core Data validation errors are defined in CoreDataErrors.h. I am considering asking Apple to move that stuff out of core data and into Foundation, since Key Value Coding really "owns" validation. Validation errors should always have a errorCode value between NSValidationErrorMinimum and NSValidationErrorMaximum as well.
I have an example validation error that may be helpful to you.
Single validation error (only one property failed): Error Domain=NSCocoaErrorDomain Code=1560 "The operation couldn’t be completed. (Cocoa error 1560.)" UserInfo=0x2808ac0 {NSDetailedErrors=(
"Error Domain=NSCocoaErrorDomain Code=1670 \"Name must be John\" UserInfo=0x2805f30 {NSLocalizedDescription=Name must be John}",
"Error Domain=NSCocoaErrorDomain Code=1570 \"The operation couldn\U2019t be completed. (Cocoa error 1570.)\" UserInfo=0x28089c0 {NSValidationErrorObject=<Employee: 0xc003180> (entity: Employee; id: 0xc0031d0 <x-coredata:///Employee/t6FEF17D8-0306-4959-9BFB-4B806E6ED1302> ; da…
see full text
a multiple looks similar, with additional NSErrors in the array that is the value of the userInfo dictionary for the key NSDetailedErrorsKey.
Note that the top level NSError is a single error with the cocoa error domain and error code 1560. That is NSValidationMultipleErrorsError. That error should always contain additional errors under the NSDetailedErrorsKey.
hope that helps!

stackmob ios datastore http 401 error

I'm using the iOS DataStore API to upload data to StackMob. I get this error when I try to use my smclient initialized with my public key.
HTTP Code=401 "The operation couldn’t be completed. (HTTP error 401.)" UserInfo=0xa14dac0 {error=Insufficient authorization}
Sample code
[[self.smclient dataStore] createObject:eventDictObj
inSchema:#"EventSchema"
onSuccess:^(NSDictionary *object, NSString *schema)
{
NSLog(#"Created online event : %#", object);
successBlock();
}
onFailure:^(NSError *error, NSDictionary* object, NSString *schema)
{
failedBlock(error);
}];
And smclient is initialized as follows
self.smclient = [[SMClient alloc] initWithAPIVersion:#"0" publicKey:#"xxxxxxxxxx"];
For this use case I don't need to use the logged in user credentials to create this entry in StackMob
Make sure that the permissions are set to Open on your stack mob database.

Resources