UIApplication sharedApplication called twice - ios

I have a Subview that has a button, when tapped opens up the map and location. There is no error in code but once I get sent to Maps and get back to my app.. It opens Maps once again. So I guess the method is being called twice. How do I stop this?
- (void)openMaps:(UITapGestureRecognizer *)tapAddress{
PFQuery *query = [PFQuery queryWithClassName:#"outfitDay"];
[query getFirstObjectInBackgroundWithBlock:^(PFObject *object, NSError *error) {
if (!error) {
NSURL *mapUrl = [NSURL URLWithString:[NSString stringWithFormat:#"%#", [object objectForKey:#"map"]]];
if ([[UIApplication sharedApplication] canOpenURL:mapUrl]) {
[[UIApplication sharedApplication] openURL:mapUrl];
} else {
UIAlertView * alert = [[UIAlertView alloc]initWithTitle:nil message:#"Sin Servicio!" delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil, nil];
[alert show];
}
}
}];
}

Have you set a breakpoint or a log in your openMaps: method to make sure it's not accidentally getting called twice?
My next guess is that your query is returning a cache then performing the network request and returning that result. By default queries shouldn't return a cache, but I've seen the Parse SDK do some weird things in the past.
Try setting the cachePolicy on your query to kPFCachePolicyNetworkOnly.
query.cachePolicy = kPFCachePolicyNetworkOnly

Can you make sure that canOpenURL method does not also open if it can?

Related

Twitter login issue Parse.com iOS

I recently deleted all the multiple duplicate files from my mac and that messed up my xcode project. I had to import all the twitter frameworks again and had to delete the twitter run script for my app to work. Before my mess up everything worked fine.
Now everytime i login into with twitter this error comes up TWTRLogInButton was created with no completionBlock set
my code that worked perfectly:
- (IBAction)twlogin:(TWTRLogInButton *)sender {
[PFTwitterUtils logInWithBlock:^(PFUser *user, NSError *error) {
if (error) {
}
else {
PF_Twitter *twitter = [PFTwitterUtils twitter];
PFUser *user = [PFUser currentUser];
NSString *twitterScreenName = twitter.screenName;
[[PFUser currentUser] setObject:twitterScreenName forKey:#"username"];
[user saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error)
{
if (error)
{
UIAlertView *alertVeiw = [[UIAlertView alloc] initWithTitle:#"Sorry" message:[error.userInfo objectForKey:#"error"] delegate:nil cancelButtonTitle:nil otherButtonTitles:#"OK", nil];
[alertVeiw show];
}
else {
[[PFInstallation currentInstallation] setObject:[PFUser currentUser].objectId forKey:#"userId"];
[[PFInstallation currentInstallation] saveInBackground];
[self.navigationController popToRootViewControllerAnimated:NO];
}
}];
[self.navigationController popToRootViewControllerAnimated:NO];
}
}];
}
Please help me fix my issue.
It looks like there may be a bug in the Parse Twitter SDK. Many people are having this problem today. check this link https://developers.facebook.com/bugs/914545211986956/
You may be defining the button in the storyboard or xib file, and the completionBlock needs to be set programmatically. If you define it in the storyboard and your viewDidLoad, the app is probably presenting the button from the storyboard. So, in viewDidLoad, define it:
self.myTwitterLoginButton.logInCompletion = ^(TWTRSession *session, NSError *error) {
/* your code */
};
Edit:
In addition, don't hook up the twlogin action event in the storyboard. Your current action will end up in the completion block. Do hook the button up to an IBOutlet property and do not recreate it. In my code above, the IBOutlet is to myTwitterLoginButton.

Comparing an NSString to an NSArray from Parse.com (Obj-c)

I'm trying to compare an NSString to an NSArray from parse with an if statement. Here's what I tried:
-(void)queryParseMethod {
//PFQuery *query = [PFQuery queryWithClassName:classNameString];
PFQuery *query = [PFQuery queryWithClassName:#"SaveClass2"];
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
if (!error) {
_barcodeArray = [[NSArray alloc]initWithArray:objects];
//[_tableView reloadData];
}else{
NSLOG(#"ERROR");
}
}];
}
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
[self queryParseMethod];
NSIndexPath *indexPath;
int barcodInt = indexPath.row %1000000;
PFObject *barcodeObject = [_barcodeArray objectAtIndex:barcodInt];
NSArray *secondBarcodeArray;
secondBarcodeArray = [barcodeObject objectForKey:#"RNG1"];
if ([[secondBarcodeArray objectAtIndex:barcodInt] isEqualToString:_label.text]){
UIAlertView *alertView = [[UIAlertView alloc]initWithTitle:#"FOUND" message:#"THE BARCODE IS CORRECT!" delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil, nil];
[alertView show];
}else{
UIAlertView *alertView = [[UIAlertView alloc]initWithTitle:#"NOT FOUND" message:#"THE BARCODE IS INCORRECT!" delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil, nil];
[alertView show];
};
}
But it always displays the "NOT FOUND" alert View and I'm sure that the classes are right and the columns are also right but it wont work. Any help will be appreciated.
As long as your _barcodeArray is assigned in background thread (where, I believe runs findObjectsInBackgroundWithBlock:, at point where You're trying to get object barcodeObject from _barcodeArray latter is empty (it can be or can be not). You have classic race condition. If you really need to run this find objects block in background, you should consider using some sync mechanism - like dispatch_semaphore. Or, as I presume, you don't need to call findObjectsInBackgroundWithBlock: and use its synchronous counterpart instead, if present.
The blocks are asynchronous so you can't know when block will run on main thread.
I read your code and I found that you are fetching object asynchronously. It means execution wont wait for that method findObjectsInBackgroundWithBlock: to complete.
So the solution is use the synchronous versions of this methods like...
- (NSArray *)findObjects;
- (NSArray *)findObjects:(NSError **)error;
the above method stops the execution further util the findObject: method not get executed.
Use this
-(void)queryParseMethod {
PFQuery *query = [PFQuery queryWithClassName:#"SaveClass2"];
NSError *error = nil;
[query findObjects:&error] {
if (!error) {
_barcodeArray = [[NSArray alloc]initWithArray:objects];
} else {
//error
}
}
I hope this will work for you...good luck...!! :)

Optimize query for Mutual Friends using Parse

Currently, I am attempting to optimize my getMutualFriends method. When I open my 'Friends' view controller, I execute the getMutualFriends method for every friend the user currently has... Which is NOT optimal...but was the easiest solution...
Heres what I did:
[CBUtility queryForFriends:[PFUser currentUser] block:^(NSArray *friends, NSError *error) {
[self.friendsActivityIndicator stopAnimating];
if (error) {
[[[UIAlertView alloc] initWithTitle:#"Error"
message:[error localizedDescription]
delegate:nil cancelButtonTitle:#"Okay"
otherButtonTitles:nil]
show];
return;
}
if ([friends count] == 0 || !friends) {
[self.friendsTable addSubview:self.friendsEmptyView];
return;
}
self.friends = [NSMutableArray arrayWithArray:friends];
[self.friendsTable reloadData];
[self.friendsEmptyView removeFromSuperview];
int i = 0;
//
// THIS IS THE PART THAT SUCKS!!!
//
for (PFObject * friendObject in self.friends) {
[CBUtility queryForMutualFriends:[friendObject objectForKey:kCBFriendToUserKey] block:^(int mutualFriends, NSError *error) {
if (error) {
[[[UIAlertView alloc] initWithTitle:#"Error" message:[error localizedDescription] delegate:nil cancelButtonTitle:#"Okay" otherButtonTitles:nil] show];
return;
}
CBFriendsCell *cell = (CBFriendsCell *)[self.friendsTable cellForRowAtIndexPath:[NSIndexPath indexPathForRow:i inSection:0]];
[cell setMutualFriends:mutualFriends];
}];
i++;
}
}];
And heres what +(void)queryForMutualFriends looks like:
+ (void)queryForMutualFriends:(PFUser *)user block:(void (^)(int number, NSError *error))completionBlock
{
PFQuery *usersFriends = [PFQuery queryWithClassName:kCBFriendClassKey];
[usersFriends whereKey:kCBFriendFromUserKey equalTo:user];
[usersFriends whereKey:kCBFriendStatusKey equalTo:kCBFriendStatusFriendKey];
PFQuery *currentUsersFriends = [PFQuery queryWithClassName:kCBFriendClassKey];
[currentUsersFriends whereKey:kCBFriendFromUserKey equalTo:[PFUser currentUser]];
[currentUsersFriends whereKey:kCBFriendStatusKey equalTo:kCBFriendStatusFriendKey];
[currentUsersFriends whereKey:kCBFriendToUserKey matchesKey:kCBFriendToUserKey inQuery:usersFriends];
[currentUsersFriends countObjectsInBackgroundWithBlock:^(int number, NSError *error) {
if (!error) {
completionBlock(number, error);
return;
}
completionBlock(-1, error);
}];
}
So instead of running the loop and passing individual PFUser objects into the getMutualFriends method, I'd like to pass an array of friends into the method and return an array of dictionary objects whose keys are 'user' and 'count' with their respective values (e.g. #[#{#"user":somePFUser, #"count":5}, #{#"user":anotherPFUser, #"count":20}];
I mean, this works fine at the moment but takes up way too much API requests...
Anyone got ideas with how to setup the PFQuery?
EDIT:
Here was a link to a SQL query that solves the same problem
No apparently, you cannot... But you can limit the amount of times you query to the server by instead of querying for mutual friends when you retrieve the mutual friends like I did, you instead cache the results into memory...
I solved this issue by making the query in cellForIndexPath when setting a cells attributes. When the cell is loaded, I check cache first to see if the query has already been made, if it has then I get the cache data... If it hasn't then I make a query to the servers... Only issue I see is that it doesn't update... I figure I can clear cache every minute or so, so the user gets updated automatically instead of pressing a reload button.

Code stops when trying to save Parse.com object information to NSStrings

so I am making an app that searches for friends locations saved on parse.com. Before I begin, here is the method in question.
- (void)saveFriendLocationInfo {
PFQuery *query = [PFQuery queryWithClassName:#"Locations"];
[query orderByDescending:#"createdAt"];
[query whereKey:#"userString" equalTo:currentFriend];
[query getFirstObjectInBackgroundWithBlock:^(PFObject *parseCurrentFriend, NSError *error) {
if (!parseCurrentFriend) {
NSLog(#"The getFirstObject request failed.");
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"Uh oh..."
message:#"Looks like that user doesnt exist. Might want to double check that."
delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[self.navigationController popToRootViewControllerAnimated:YES];
[alertView show];
} else {
NSLog(#"ObjectID = %#", parseCurrentFriend.objectId);
parseCurrentFriend[#"title"] = friendTitle;
NSLog(#"Saved Title");
parseCurrentFriend[#"description"] = friendDescription;
NSLog(#"Saved Description");
parseCurrentFriend[#"latitude"] = friendLatitude;
NSLog(#"Saved Latitude");
parseCurrentFriend[#"longitude"] = friendLongitude;
NSLog(#"Saved Longitude");
}
}];
}
So this code all works fine at retrieving the required object. It reaches the NSLog line in the "else" statement where it is supposed to display the object ID. This displays the correct object id for the object that I am trying to receive. Now heres the weird part. The code seems to stop there. Nothing happens when trying to save the properties (title, description, lat, long) to the respective NSStrings; none of those other NSLog's below that are executed. But the weird thing is that there are no errors and the app keeps running as if that code below the first NSLog wasn't even there. Any insight into why this isn't working.
One problem you have is that you never save the object. After you modify all of the values, you need to save the PFObject.
[parseCurrentFriend saveInBackground];
Edit: Since you are trying to extract the values, then you'd need to do it like below.
friendTitle = parseCurrentFriend[#"title"];
friendDescription = parseCurrentFriend[#"description"];
friendLatitude = parseCurrentFriend[#"latitude"];
friendLongitude = parseCurrentFriend[#"longitude"];

Whats the reason for " FBSDKLog: -1059155737 is not a valid FBSessionLoginBehavior. Ignoring open call." issue?

Note:- dont direct me to the similar question, i have read them and tried using newer API from parse and facebook. but problem still persists.
It would be really helpful if someone point me in the right direction as to what might be the possible cause for this bug.
Are parse sdk and Facebook sdk not compatible any more?
i read post on this site saying issue fixed with updating parse sdk,but i m still having same issue with parse sdk 1.2.15, 1.2.16 and facebook 3.9, 3.10.
NOTE:- i can get my name,user_id,email after each time I logout and login again. but every time i hit run it shows me the above mentioned bug.
here is my code:-
-(void)viewWillAppear:(BOOL)animated
{
[[UIApplication sharedApplication]setStatusBarHidden:YES];
[PFFacebookUtils initializeFacebook];
[FBRequestConnection
startForMeWithCompletionHandler:^(FBRequestConnection *connection, id result, NSError *error) {
if (!error) {
userFBid = [(NSString *)[result objectForKey:#"id"] mutableCopy];
NSLog(#"user fb id %#",userFBid);
[self getNamePictureEmail];
}
}];
}
-(void)getNamePictureEmail
{
// GET NAME
NSString *nameURLString=[NSString stringWithFormat:#"https://graph.facebook.com/%#?fields=name",userFBid];
NSURL *url=[NSURL URLWithString:nameURLString];
NSData *data1=[NSData dataWithContentsOfURL:url];
// json parsing to convert json response returned by fb into dictionary
NSDictionary *allDataDictionary1=[NSJSONSerialization JSONObjectWithData:data1 options:0 error:nil];
fbUserName=[allDataDictionary1 objectForKey:#"name"];
NSLog(#"name %#",fbUserName);
[[FBRequest requestForMe]startWithCompletionHandler:^(FBRequestConnection *connection,
NSDictionary<FBGraphUser> *user,
NSError *error)
{
if (!error)
{
fbUSerEmail = [user objectForKey:#"email"];
NSLog(#"email %#",fbUSerEmail);
[self registerUser];
}
else
{
UIAlertView *alert = [[UIAlertView alloc]initWithTitle:#"Facebook Sync Error" message:#"Please try login again" delegate:self cancelButtonTitle:#"Ok" otherButtonTitles: nil];
[alert show];
}
}];
// GET PICTURE
NSString *pictureURLString=[NSString stringWithFormat:#"https://graph.facebook.com/%#/picture?type=normal",userFBid];
NSURL *PictureUrl1=[NSURL URLWithString:pictureURLString];
NSData *data3=[NSData dataWithContentsOfURL:PictureUrl1];
}
Finally!
just deleted the framework path under BUILD settings -->> Search Paths deleted and added parse and facebook sdk again. It works all fine now.
hope it helps to many trying to figure it out

Resources