Warning inside code when updating Parse object - ios

I am using the following code to update a Parse object as button action:
-(IBAction)sendPressed:(id)sender
{
NSLog(#"boton subir cadena pulsado");
loadingSpinner.hidden = NO;
[loadingSpinner startAnimating];
//Upload a new picture
NSData *pictureData = UIImagePNGRepresentation(self.chainPhoto.image);
PFFile *file = [PFFile fileWithName:#"img" data:pictureData];
[file saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
if (succeeded){
NSLog(#"IMAGEN CARGADA");
PFQuery *query = [PFQuery queryWithClassName:#"cadenas"];
// Retrieve the object by id
[query getObjectInBackgroundWithId: chain.objectId block:^(PFObject *imageObject, NSError *error)
{
[imageObject setObject:file forKey:#"image"];
[imageObject setObject:self.commentTextField.text forKey:#"chain_name"];
[imageObject saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
if (succeeded){
//Go back to the wall
[self.navigationController popViewControllerAnimated:YES];
}
else{
NSString *errorString = [[error userInfo] objectForKey:#"error"];
[self showErrorView:errorString];
}
}];
}
ERROR HERE--> else
{
NSString *errorString = [[error userInfo] objectForKey:#"error"];
[self showErrorView:errorString];
}
}
[loadingSpinner stopAnimating];
//loadingSpinner.hidden = YES;
//self.commentTextField.text =#" ";
self.progress_block.hidden = YES;
// self.imageView.image = [UIImage imageNamed:#"no-image.jpg"];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Restaurant Chain changed with success"
message:#"You can now go back to the list."
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alert show];
} progressBlock:^(int percentDone) {
self.progress_block.hidden =NO;
self.progress_block.progress = (float) percentDone/100+progressValue;
}];
}
In the line that I have marked as ERROR HERE in the code, there is an error warning (Expected ":"), but I can't find out why.
Any help is welcome.

From the looks of it, you never closed the query bracket:
PFQuery getObjectInBackground.... {
but never closed it using the proper syntax or it looks like you have an extra bracket }. For better practice, you should use proper indentation with if statements or else complications can happen like this. You get lost in the code because you don't know where a statement begins or ends
You should close it after the else statement so:
} ERROR HERE--> else {
NSString *errorString = [[error userInfo] objectForKey:#"error"];
[self showErrorView:errorString];
//stop animating and other stuff
}
}];
I can't troubleshoot because i'm on my iPhone but I would suggest going back and using proper indentation so you can catch your culprit

Related

ERROR: _block_literal_generic or _block_invoke

I'm having an issue finding the source of this crash in my iOS app which has a core data model using iPhone app i am not able to login URl. I am using same code on iOS 7 its working but now I am trying to work on iOS 8.2.Have issue for _block_literal_generic
Block point is below As well check screen shot for block Error:---
[[NetwokManager sharedInstance] loginRequestEmail:userEmail andPassword:userPassword WithResponse:^(id responseObject, NSError *error) { if (!error) {
}
Using code is below:
-(void)sendLoginRequest
{
NSString *userEmail = [[NSUserDefaults standardUserDefaults] objectForKey:#"emailKey"];
NSString *userPassword = [[NSUserDefaults standardUserDefaults] objectForKey:#"passwordKey"];
NSLog(#"Email %#", userEmail);
NSLog(#"Password %#", userPassword);
NSString *mobileNo = [SCUserProfile currentUser].callerid;
NSLog(#"CallerID %#", mobileNo);
[[NetwokManager sharedInstance] loginRequestEmail:userEmail andPassword:userPassword WithResponse:^(id responseObject, NSError *error) {
if (!error) {
NSLog(#"responseString = %#", responseObject);
if (responseObject == nil)
{
NSLog(#"No data from server");
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"Error"
message:#"No data downloaded from server!"
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles: nil];
[alertView show];
}
NSDictionary *resposneDict = (NSDictionary*)responseObject;
NSString *success = [resposneDict valueForKey:#"success"];
if ([success isEqual:#"Authentication Failed"])
{
[self showAlertViewWithMessage:#"Authentication Failed"];
// [self sendLogoutRequest];
[[C2CallAppDelegate appDelegate] logoutUser];
}
else if ([success intValue] == 1)
{
amobilePayUserID = [resposneDict valueForKey:#"user_id"];
[[NSUserDefaults standardUserDefaults] setValue:amobilePayUserID forKey:#"AMobilePay_User_ID"];
NSLog(#"User Id is:= %#",amobilePayUserID);
}
else if ([success intValue] == 0)
{
//[self sendRegistrationRequest];
// [self sendLogoutRequest];
// [[C2CallAppDelegate appDelegate] logoutUser];
}
else
{
[self showAlertViewWithMessage:#"Unable to login AmobilePay"];
}
} else {
[self showAlertViewWithMessage:[error localizedDescription]];
}
}];
}
Crash in unknown region 2015-04-30 09:56:18.390 AmobipayMerchant[337:60b] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[MOC2CallEvent costs]: unrecognized selector sent to instance 0x16ef2dd0'
Somewhere in the code, you called costs to an instance of MOC2CallEvent. MOC2CallEvent has no method or property costs, so of course it will crash.

Terminating App - NSInvalidArgumentException

Crashing when running Parse Anypic code.
-(void)sendCommentButton:(id) sender {
NSString *trimmedComment = [commentTextView.text stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
if (trimmedComment.length != 0 && [self.photo objectForKey:kPAPPhotoUserKey]) {
PFObject *comment = [PFObject objectWithClassName:kPAPActivityClassKey];
[comment setObject:trimmedComment forKey:kPAPActivityContentKey]; // Set comment text
[comment setObject:[self.photo objectForKey:kPAPPhotoUserKey] forKey:kPAPActivityToUserKey]; // Set toUser
[comment setObject:[PFUser currentUser] forKey:kPAPActivityFromUserKey]; // Set fromUser
[comment setObject:kPAPActivityTypeComment forKey:kPAPActivityTypeKey];
[comment setObject:self.photo forKey:kPAPActivityPhotoKey];
[comment setObject:self.photoFile forKey:#"attachmentFile"];
PFACL *ACL = [PFACL ACLWithUser:[PFUser currentUser]];
[ACL setPublicReadAccess:YES];
[ACL setWriteAccess:YES forUser:[self.photo objectForKey:kPAPPhotoUserKey]];
comment.ACL = ACL;
[[PAPCache sharedCache] incrementCommentCountForPhoto:self.photo];
// Show HUD view
[MBProgressHUD showHUDAddedTo:self.view.superview animated:YES];
// If more than 5 seconds pass since we post a comment, stop waiting for the server to respond
NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:5.0f target:self selector:#selector(handleCommentTimeout:) userInfo:#{#"comment": comment} repeats:NO];
[comment saveEventually:^(BOOL succeeded, NSError *error) {
[timer invalidate];
if (error && error.code == kPFErrorObjectNotFound) {
[[PAPCache sharedCache] decrementCommentCountForPhoto:self.photo];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:NSLocalizedString(#"Could not post comment", nil) message:NSLocalizedString(#"This photo is no longer available", nil) delegate:nil cancelButtonTitle:nil otherButtonTitles:#"OK", nil];
[alert show];
[self.navigationController popViewControllerAnimated:YES];
}
[[NSNotificationCenter defaultCenter] postNotificationName:PAPPhotoDetailsViewControllerUserCommentedOnPhotoNotification object:self.photo userInfo:#{#"comments": #(self.objects.count + 1)}];
[MBProgressHUD hideHUDForView:self.view.superview animated:YES];
[self loadObjects];
}];
}
[self.commentTextView setText:#""];
[self.commentTextView resignFirstResponder];
if (self.photoFile != nil) {
self.photoFile = nil;
}
}
Picking an Image
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
NSLog(#"Hello");
UIImage *img = [info objectForKey:UIImagePickerControllerOriginalImage];
// JPEG to decrease file size and enable faster uploads & downloads
NSData *imageData = UIImageJPEGRepresentation(img, 0.8f);
self.photoFile = [PFFile fileWithData:imageData];
// Request a background execution task to allow us to finish uploading the photo even if the app is backgrounded
self.fileUploadBackgroundTaskId = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
[[UIApplication sharedApplication] endBackgroundTask:self.fileUploadBackgroundTaskId];
}];
NSLog(#"Requested background expiration task with id %lu for Anypic photo upload", (unsigned long)self.fileUploadBackgroundTaskId);
[self.photoFile saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
if (succeeded) {
NSLog(#"Photo uploaded successfully");
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Photo Uploaded"
message:#"successfully"
delegate:self
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alert show];
} else {
[[UIApplication sharedApplication] endBackgroundTask:self.fileUploadBackgroundTaskId];
}
}];
[self dismissViewControllerAnimated:YES completion:nil];
}
Question: Why is it crashing? I believe this is the code that is crashing it. What I did to crash it was not add an attachmentFile and just put a comment.
If you need more code or need any clarifications please comment down below
PFObject *comment = [PFObject objectWithClassName:kPAPActivityClassKey];
[comment setObject:trimmedComment forKey:kPAPActivityContentKey]; // Set comment text
[comment setObject:[self.photo objectForKey:kPAPPhotoUserKey] forKey:kPAPActivityToUserKey]; // Set toUser
[comment setObject:[PFUser currentUser] forKey:kPAPActivityFromUserKey]; // Set fromUser
[comment setObject:kPAPActivityTypeComment forKey:kPAPActivityTypeKey];
[comment setObject:self.photo forKey:kPAPActivityPhotoKey];
[comment setObject:self.photoFile forKey:#"attachmentFile"];
In one of these lines, you're passing nil to the first parameter of setObject:forKey. Add an Exception Breakpoint (in the breakpoints tab of left sidebar) and check which line it breaks on.

share image on twitter and get favourites list from iOS native app

I found many tutorials online how to share image on twitter from an iOS app. But i want to know 2 things about social sharing with twitter-
If i post an image on twitter via my app, Can i get image id from twitter in callback method/block? If yes then how?
If i fetch favourites of a user, is the response include text posted with that image? I checked for the same on twitter Rest API doc that there is a text property returned in the response.
Now my question is that if i post some text with image via my iOS app and later make this post favourite in twitter app and now i get my favourites list through twitter rest API in my app, does the text property in the response is same that i posted with my post?
Edit about #1 above:- from SLComposeViewControllerResult docs i found that completion handler return one of
typedef NS_ENUM (NSInteger,
SLComposeViewControllerResult ) {
SLComposeViewControllerResultCancelled,
SLComposeViewControllerResultDone
};
constant so there is no info about image just posted. Am i right? If not please give me some reference about how to get image id please.
Here I have customize alertView,NSLog,etc. You ignore that.
Here is the code to share to twitter by using STTwitter library
- (void)shareToTwitter
{
APP_DELEGATE.navController = self.navigationController;
NSString *strTwitterToken = [[NSUserDefaults standardUserDefaults] objectForKey:#"TwitterToken"];
NSString *strTwitterTokenSecret = [[NSUserDefaults standardUserDefaults] objectForKey:#"TwitterTokenSecret"];
if (strTwitterToken && strTwitterTokenSecret)
{
self.twitter = [STTwitterAPI twitterAPIWithOAuthConsumerKey:TwitterConsumerKey consumerSecret:TwitterSecretKey oauthToken:strTwitterToken oauthTokenSecret:strTwitterTokenSecret];
[self.twitter verifyCredentialsWithSuccessBlock:^(NSString *username) {
DLogs(#"Twitter User Name");
[self twitterMediaUpload];
} errorBlock:^(NSError *error) {
DLogs(#"-- error: %#", error);
[AppConstant showAutoDismissAlertWithMessage:[error localizedDescription] onView:self.view];
[self safariLoginTwitter];
}];
}
else
{
[self safariLoginTwitter];
}
}
-(void)safariLoginTwitter
{
// [APP_CONSTANT getNativeTwitterAccountAccessToken:^(id result) {
//
// }];
self.twitter = [STTwitterAPI twitterAPIWithOAuthConsumerKey:TwitterConsumerKey
consumerSecret:TwitterSecretKey];
[self.twitter postTokenRequest:^(NSURL *url, NSString *oauthToken) {
DLogs(#"-- url: %#", url);
DLogs(#"-- oauthToken: %#", oauthToken);
[[UIApplication sharedApplication] openURL:url];
} authenticateInsteadOfAuthorize:NO
forceLogin:#(YES)
screenName:nil
oauthCallback:#"myapp://twitter_access_tokens/"
errorBlock:^(NSError *error) {
DLogs(#"-- error: %#", error);
[AppConstant showAutoDismissAlertWithMessage:[error localizedDescription] onView:self.view];
}];
}
- (void)setOAuthToken:(NSString *)token oauthVerifier:(NSString *)verifier {
[self.twitter postAccessTokenRequestWithPIN:verifier successBlock:^(NSString *oauthToken, NSString *oauthTokenSecret, NSString *userID, NSString *screenName) {
DLogs(#"-- screenName: %#", screenName);
/*
At this point, the user can use the API and you can read his access tokens with:
_twitter.oauthAccessToken;
_twitter.oauthAccessTokenSecret;
You can store these tokens (in user default, or in keychain) so that the user doesn't need to authenticate again on next launches.
Next time, just instanciate STTwitter with the class method:
+[STTwitterAPI twitterAPIWithOAuthConsumerKey:consumerSecret:oauthToken:oauthTokenSecret:]
Don't forget to call the -[STTwitter verifyCredentialsWithSuccessBlock:errorBlock:] after that.
*/
[[NSUserDefaults standardUserDefaults] setObject:self.twitter.oauthAccessToken forKey:#"TwitterToken"];
[[NSUserDefaults standardUserDefaults] setObject:self.twitter.oauthAccessToken forKey:#"TwitterTokenSecret"];
[[NSUserDefaults standardUserDefaults] synchronize];
[self twitterMediaUpload];
} errorBlock:^(NSError *error) {
[AppConstant showAutoDismissAlertWithMessage:[error localizedDescription] onView:self.view];
DLogs(#"-- %#", [error localizedDescription]);
}];
}
-(void)twitterMediaUpload
{
// ProfileImageBO *objProfImg = nil;
//
// if ([self.objProfile.arrUserImages count]) {
// objProfImg = [self.objProfile.arrUserImages objectAtIndex:0];
// }
[APP_CONSTANT showLoaderWithTitle:#"posting" onView:self.view];
// NSURL *urlProfImg = [NSURL URLWithString:[objProfImg.imageUrl stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
NSURL *screenshotUrl = [self getScreenshotUrl];
[self.twitter postMediaUpload:screenshotUrl uploadProgressBlock:^(NSInteger bytesWritten, NSInteger totalBytesWritten, NSInteger totalBytesExpectedToWrite) {
DLogs(#"uploading");
} successBlock:^(NSDictionary *imageDictionary, NSString *mediaID, NSString *size) {
DLogs(#"imageDictionary = %#, mediaID = %#, size %#",imageDictionary.description,mediaID,size);
[self postToTheTwitterWithMediaId:mediaID];
} errorBlock:^(NSError *error) {
DLogs(#"Error in uploading media, try again ...");
[APP_CONSTANT hideLoader];
[AppConstant showAutoDismissAlertWithMessage:error.localizedDescription onView:self.view];
}];
}
-(void)postToTheTwitterWithMediaId:(NSString *)mediaID
{
NSString *msg = [NSString stringWithFormat:#"Check out My Profile"];
[self.twitter postStatusUpdate:msg inReplyToStatusID:nil mediaIDs:[NSArray arrayWithObject:mediaID] latitude:nil longitude:nil placeID:nil displayCoordinates:nil trimUser:nil successBlock:^(NSDictionary *status) {
DLogs(#"Description %#",status.description);
[self showNotificationToastWithMessage:TwitterPostSuccess];
[APP_CONSTANT hideLoader];
} errorBlock:^(NSError *error) {
DLogs(#"Twitter posting error %#",error.description);
[APP_CONSTANT hideLoader];
[AppConstant showAutoDismissAlertWithMessage:error.localizedDescription onView:self.view];
}];
}
For your second question: Yes, you will get the same text in the response
And This is the code to get favorite list
-(void)getFavListTwitter
{
[self.twitter getFavoritesListWithSuccessBlock:^(NSArray *statuses) {
DLogs(#"%#",statuses.description);
} errorBlock:^(NSError *error) {
DLogs(#"%#",error.description);
}];
}

Parse iOS PFTwitterUtils linkUser: doesn't do anything

So I am using Parse to link a user with their twitter account. In the app delegate I have the following:
[PFTwitterUtils initializeWithConsumerKey:CONSUMER_KEY consumerSecret:CONSUMER_SECRET];
Then the button which the user clicks to link the user to facebook calls the following:
-(IBAction)twitterConnectPressed{
NSLog(#"twitter");
[PFTwitterUtils linkUser:[PFUser currentUser] block:^(BOOL succeeded, NSError* error){
NSLog(#"haha");
if(succeeded){
UIAlertView* alert = [[UIAlertView alloc] initWithTitle:#"Done!" message:#"Connected with Twitter!" delegate:self cancelButtonTitle:#"okay" otherButtonTitles: nil];
[alert show];
self.fbButton.backgroundColor = [TGAPublic grey];
}else{
UIAlertView* alert = [[UIAlertView alloc] initWithTitle:#"Oops" message:error.userInfo[#"error"] delegate:self cancelButtonTitle:#"okay" otherButtonTitles: nil];
[alert show];
}
}];
}
However even though linkUser:block: is called it doesn't do anything at all. It doesn't create a pop up to log in to twitter like [PFFacebookUtils linkUser:] does and therefore doesn't end up calling the block either
PFTwitterUtils does not appear to handle all cases on iOS. In particular, if you do not have an account setup (Settings->Twitter) it does not fire up a web view and attempt to used web oauth. Conversely if you have multiple Twitter accounts configured (again in Settings) then it doesn't appear to fire up an action sheet to allow you to select which account you'd like to link.
There's a great tutorial on how to do these things which exposes an extension to PFFacebookUtils here: http://natashatherobot.com/ios-twitter-login-parse/
It does not do linking though, just login, but should be a good basis to add linking.
I've got similar problem with link/unlink methods for both PFFacebookUtils and PFTwitterUtils (v. 1.7.4).
The only way I managed to make it work was to replace them by, unfortunately, messing with internal Parse implementation of authData:
#import "TwitterAuthProvider.h"
#import "PFTwitterUtils.h"
#import "PFUser.h"
static NSString * const kTwitterKey = #"XXX";
static NSString * const kTwitterSecret = #"XXX";
#implementation TwitterAuthProvider
- (instancetype)init {
if ((self = [super init])) {
[PFTwitterUtils initializeWithConsumerKey:kTwitterKey consumerSecret:kTwitterSecret];
}
return self;
}
- (void)setAuthData:(id)twAuthData forUser:(PFUser *)user {
static NSString * const kParseAuthDataKey = #"authData";
static NSString * const kParseLinkedServiceNamesKey = #"linkedServiceNames";
static NSString * const kParseAuthProviderName = #"twitter";
NSMutableDictionary *authData = [[user valueForKey:kParseAuthDataKey] mutableCopy] ?: [NSMutableDictionary dictionary];
authData[kParseAuthProviderName] = twAuthData ?: [NSNull null];
[user setObject:authData forKey:kParseAuthDataKey];
[user setValue:authData forKey:kParseAuthDataKey];
NSMutableSet *linkedServices = [[user valueForKey:kParseLinkedServiceNamesKey] mutableCopy] ?: [NSMutableSet set];
if (twAuthData) {
[linkedServices addObject:kParseAuthProviderName];
} else {
[linkedServices removeObject:kParseAuthProviderName];
}
[user setValue:linkedServices forKey:kParseLinkedServiceNamesKey];
}
- (void)linkWithCompletion:(PFBooleanResultBlock)completion {
NSParameterAssert(completion != nil);
PFUser *user = [PFUser currentUser];
__weak typeof(self) weakSelf = self;
PF_Twitter *twitter = [PFTwitterUtils twitter];
[twitter authorizeWithSuccess:^(void) {
[weakSelf setAuthData:[self twitterAuthData] forUser:user];
[user saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
if (!succeeded) {
//revert
[weakSelf setAuthData:nil forUser:user];
}
completion(succeeded, error);
}];
} failure:^(NSError *error) {
completion(NO, error);
} cancel:^(void) {
completion(NO, nil);
}];
}
- (void)unlinkWithCompletion:(PFBooleanResultBlock)completion {
NSParameterAssert(completion != nil);
PFUser *user = [PFUser currentUser];
[self setAuthData:nil forUser:user];
[user saveInBackgroundWithBlock:completion];
}
- (NSDictionary *)twitterAuthData {
PF_Twitter *twitter = [PFTwitterUtils twitter];
return #{
#"auth_token" : twitter.authToken,
#"auth_token_secret": twitter.authTokenSecret,
#"consumer_key": kTwitterKey,
#"consumer_secret": kTwitterSecret,
#"id": twitter.userId,
#"screen_name": twitter.screenName,
};
}
#end

UITableViewController table won't refresh after deletion, but will refresh on viewWillAppear

I have a button for each cell, and once clicked it deletes each individual object from the Parse backend. I have it set to reloadData upon success in the block as seen here:
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
PFRelation *relation = [self.currentUser relationforKey:#"watching"];
[[relation query] findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
if (error) {
// There was an error
} else {
// NSLog(#"%#", objects);
self.watchingEvents = objects;
[self refreshTableView];
}
}];
}
-(IBAction) deleteButtonAction:(id) sender
{
[SVProgressHUD showWithStatus:#"Removing from Watch List..."];
PFRelation *relation = [self.currentUser relationforKey:#"watching"];
[relation removeObject:self.selectedEvent];
[self.currentUser saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
if (error)
{
NSString *errorString = [[error userInfo] objectForKey:#"error"];
UIAlertView *errorAlertView = [[UIAlertView alloc] initWithTitle:#"Error" message:errorString delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[errorAlertView show];
}
else
{
[SVProgressHUD showSuccessWithStatus:#"Removed from Watch List!"];
[self refreshTableView];
}
}];
}
-(void)refreshTableView
{
[self.tableView reloadData];
}
But it doesn't seem to update the tableView, the cell still shows up (even though it's gone because if I navigate away and open the view again the viewWillAppear gets called with the same reloadData function and the items gone like how it should be. So I know the functions working, since it's clearly working in viewWillAppear. Not sure why it's not working once the success of the block is run, as the alert runs fine as does any NSLog message I put in?
Change you refresh method to:
-(void)refreshTableView
{
dispatch_async(dispatch_get_main_queue(), ^{
[self.tableView reloadData];
});
}
you are deleting the data from the backend but you are not deleting that object from self.watchingEvents. and i think u must be using self.watchingEvents to populate the date in cellForRowAtindex of your table. Please delete that object from self.watchingEvents too on deletion and your problem should be solved.
You need to use [tableView beginUpdates] before you do delete, insert or move actions and then [tableView endUpdates] at the end.
- (void)beginUpdates;
- (void)endUpdates;
https://developer.apple.com/Library/ios/documentation/UIKit/Reference/UITableView_Class/Reference/Reference.html#//apple_ref/occ/instm/UITableView/beginUpdates

Resources