Parse.com PFQuery & Cache crash my app - parse-platform

Hello everyone I am using parse.com In my app .
To get SOME data and run a PFQuery In research I added also
[userQuery setCachePolicy:kPFCachePolicyCacheThenNetwork];
So far so good , but when you run the ' application crash and do not understand why ... If I remove the search function of the cache in the app does not crash .
Someone can ' help me understand a thing happens ?
This is my query
PFQuery *userQuery = [PFUser query];
[userQuery whereKey:kUNIUserLastNameKey equalTo:[currentUser objectForKey:kUNIUserLastNameKey]];
[userQuery setCachePolicy:kPFCachePolicyCacheThenNetwork];
[userQuery findObjectsInBackgroundWithBlock:^(NSArray * _Nullable objects, NSError * _Nullable error) {
if (!error) {
NSMutableArray *nameArray = [[NSMutableArray alloc] init];
for (PFObject *object in objects) {
[nameArray addObject:object];
NSString *welcome = [NSString stringWithFormat:#"welcome %#!", [object objectForKey:kUNIUserLastNameKey]];
}
}
}];

Related

PFUser Query Contraint

This is my current query:
[PFQuery *userQuery = [PFUser query];
[userQuery whereKey:#"phone" containedIn:phones];
[userQuery findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
if (!error) {
// The find succeeded.
self.contactsWithApp = objects;
[self.tableView reloadData];
} else {
// Log details of the failure
NSLog(#"Error: %# %#", error, [error userInfo]);
}
}];
I am searching for users according to an array composed of phone number strings. The key 'phone' in my User class contains a phone number string for each user. Why is this not working?
Try using this instead. This is assuming that the class you are querying in Parse is called User.
Replace your line of:
PFQuery *userQuery = [PFUser query];
With this:
PFQuery *userQuery = [PFQuery queryWithClassName:#"_User"];
Final code:
PFQuery *userQuery = [PFQuery queryWithClassName:#"_User"];
[userQuery whereKey:#"phone" containedIn:phones];
[userQuery findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
if (!error) {
// The find succeeded.
self.contactsWithApp = objects;
[self.tableView reloadData];
} else {
// Log details of the failure
NSLog(#"Error: %# %#", error, [error userInfo]);
}
}];
I'm pretty sure that this question isn't actual anymore. But I faced with the same problem and want to share with solution. Most likely that you have got JSON response, and your 'phone' in phones - is NSNumber type. To query from Parse with containedIn: array must be with objects of type NSString.

Send email from iOS app using SendGrid

I am trying to to use mail api from sendgrid.com but everytime it finishes with failure block.
Also I don't understand how to send the image as an attachment in the email. Can anybody tell me whats wrong in below code & how can I send image ? I am using below code for now
-(void)sendEmail
{
NSMutableDictionary *params = [[NSMutableDictionary alloc]init];
[params setValue:#"username" forKey:#"api_user"];
[params setValue:#"sdsfddf23423" forKey:#"api_key"];
[params setValue:#"test#gmail.com" forKey:#"to"];
[params setValue:#"test user" forKey:#"toname"];
[params setValue:#"Test SendGrid" forKey:#"subject"];
[params setValue:#"Test SendGrid from iOS app" forKey:#"text"];
[params setValue:#"noreply#gmail.com" forKey:#"from"];
NSURL *url = [NSURL URLWithString:#"https://sendgrid.com/api"];
AFHTTPClient *client = [[AFHTTPClient alloc] initWithBaseURL: url];
NSMutableURLRequest *request = [client requestWithMethod:POST path:#"/mail.send.json" parameters:params];
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject)
{
NSDictionary *response = [NSJSONSerialization JSONObjectWithData:responseObject options:0 error:nil];
DLog(#"Get latest product info response : %#", response);
NSLog(#"Success");
} failure: ^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Failure");
}];
[operation start];
}
Thanks in advance.
Update
I made some changes in code & now I can send the email successfully as below
-(void)sendEmailWithoutImage
{
NSDictionary *parameters = #{#"api_user": #"username",
#"api_key": #"sdsfddf23423",
#"subject":#"Test SendGrid",
#"from":#"noreply#gmail.com",
#"to":#"test#gmail.com",
#"text":#"Test SendGrid from iOS app"};
[[MyAPIClient sharedAPIClient] POST:#"mail.send.json" parameters:parameters success:^(NSURLSessionDataTask *task, id responseObject)
{
NSLog(#"Success::responseObject : %#", responseObject);
} failure:^(NSURLSessionDataTask *task, NSError *error) {
NSLog(#"Error::Mail response : %#", error);
}];
}
But when I try to send the image as attachment then it result in 400 bad request. So I think there is some error in my file uploading block. Here is my code
-(void)sendEmailWithImage
{
NSDictionary *parameters = #{#"api_user": #"username",
#"api_key": #"sdsfddf23423",
#"subject":#"Test SendGrid",
#"from":#"noreply#gmail.com",
#"to":#"test#gmail.com",
#"text":#"Test SendGrid from iOS app"};
[[MyAPIClient sharedAPIClient] POST:#"mail.send.json" parameters:parameters constructingBodyWithBlock:^(id<AFMultipartFormData> formData)
{
UIImage *image = [UIImage imageNamed:#"redWine.png"];
NSData *imageToUpload = UIImagePNGRepresentation(image);
[formData appendPartWithFileData:imageToUpload name:#"files" fileName:[NSString stringWithFormat:#"%#",#"abc.png"] mimeType:#"image/png"];
}
success:^(NSURLSessionDataTask *task, id responseObject)
{
NSLog(#"Success::responseObject : %#", responseObject);
}
failure:^(NSURLSessionDataTask *task, NSError *error)
{
NSLog(#"Error::Mail response : %#", error);
}];
}
Can you anybody tell me whats going wrong while uploading the image ?
Thanks
Just modified your code a little. It looks like there was an issue with the parameters being sent and the URL path.
Also since you are already using AFNetworking to make your POST request, you can follow their docs and example on how to send a photo over here: http://cocoadocs.org/docsets/AFNetworking/2.0.1/
NSDictionary *parameters = #{#"api_user": #"username",
#"api_key": #"sdsfddf23423",
#"Test SendGrid":#"test",
#"from":#"noreply#gmail.com",
#"to":#"test#gmail.com",
#"text":#"Test SendGrid from iOS app"};
NSURL *url = [NSURL URLWithString:#"https://sendgrid.com/api/"];
AFHTTPClient *client = [[AFHTTPClient alloc] initWithBaseURL: url];
NSMutableURLRequest *request = [client requestWithMethod:#"POST" path:#"mail.send.json" parameters:parameters];
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject)
{
NSDictionary *response = [NSJSONSerialization JSONObjectWithData:responseObject options:0 error:nil];
// DLog(#"Get latest product info response : %#", response);
NSLog(#"Success: %#", response);
} failure: ^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"%#",error);
}];
[operation start];
Update**
Created a Sendgrid-ios library to make it easier to send an email and photo attachment.
//create Email Object
gridmail *msg = [gridmail user:#"username" andPass:#"password"];
//set parameters
msg.to = #"foo#bar.com";
msg.subject = #"subject goes here";
msg.from = #"me#bar.com";
msg.text = #"hello world";
msg.html = #"<h1>hello world!</h1>";
//Image attachment
[msg attachImage:self.photo];
//Send email through Web API Transport
[msg sendWithWeb];

how could i integrate via me social site into iphone app

hi i want to integrate Via Me social site into my iphone app,i googled but didn't find any samples.
The basic process is as follows:
Create a custom URL scheme for your app. Via Me will use this after the user has been authenticated, to return to your app. In my example, I created one called "robviame://"
Register your app at http://via.me/developers. This will give you a client id and a client secret:
When you want to authenticate the user, you call:
NSString *redirectUri = [[self redirectURI] stringByAddingPercentEscapesForURLParameterUsingEncoding:NSUTF8StringEncoding];
NSString *urlString = [NSString stringWithFormat:#"https://api.via.me/oauth/authorize/?client_id=%#&redirect_uri=%#&response_type=code", kClientID, redirectUri];
NSURL *url = [NSURL URLWithString:urlString];
[[UIApplication sharedApplication] openURL:url];
What that will do is fire up your web browser and give the user a chance to log on and grant permissions to your app. When user finishes that process, because you've defined your custom URL scheme, it will call the following method in your app delegate:
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
{
// do whatever you want here to parse the code provided back to the app
}
for example, I'll call a handler for my Via Me response:
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
{
ViaMeManager *viaMeManager = [ViaMeManager sharedManager];
if ([[url host] isEqualToString:viaMeManager.host])
{
[viaMeManager handleViaMeResponse:[self parseQueryString:[url query]]];
return YES;
}
return NO;
}
// convert the query string into a dictionary
- (NSDictionary *)parseQueryString:(NSString *)query
{
NSMutableDictionary *dictionary = [[NSMutableDictionary alloc] init];
NSArray *queryParameters = [query componentsSeparatedByString:#"&"];
for (NSString *queryParameter in queryParameters) {
NSArray *elements = [queryParameter componentsSeparatedByString:#"="];
NSString *key = [elements[0] stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSString *value = [elements[1] stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
value = [[value componentsSeparatedByString:#"+"] componentsJoinedByString:#" "];
[dictionary setObject:value forKey:key];
}
return dictionary;
}
That handler might, for example, save the code and then request the access token:
- (void)handleViaMeResponse:(NSDictionary *)parameters
{
self.code = parameters[#"code"];
if (self.code)
{
// save the code
[[NSUserDefaults standardUserDefaults] setValue:self.code forKey:kViaMeUserDefaultKeyCode];
[[NSUserDefaults standardUserDefaults] synchronize];
// now let's authenticate the user and get an access key
[self requestToken];
}
else
{
NSLog(#"%s: parameters = %#", __FUNCTION__, parameters);
NSString *errorCode = parameters[#"error"];
if ([errorCode isEqualToString:#"access_denied"])
{
[[[UIAlertView alloc] initWithTitle:nil
message:#"Via Me functions will not be enabled because you did not authorize this app"
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil] show];
}
else
{
[[[UIAlertView alloc] initWithTitle:nil
message:#"Unknown Via Me authorization error"
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil] show];
}
}
}
and the code to retrieve the token might look like:
- (void)requestToken
{
NSURL *url = [NSURL URLWithString:#"https://api.via.me/oauth/access_token"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[request setHTTPMethod:#"POST"];
NSDictionary *paramsDictionary = #{#"client_id" : kClientID,
#"client_secret" : kClientSecret,
#"grant_type" : #"authorization_code",
#"redirect_uri" : [self redirectURI],
#"code" : self.code,
#"response_type" : #"token"
};
NSMutableArray *paramsArray = [NSMutableArray array];
[paramsDictionary enumerateKeysAndObjectsUsingBlock:^(NSString *key, NSString *obj, BOOL *stop) {
[paramsArray addObject:[NSString stringWithFormat:#"%#=%#", key, [obj stringByAddingPercentEscapesForURLParameterUsingEncoding:NSUTF8StringEncoding]]];
}];
NSData *paramsData = [[paramsArray componentsJoinedByString:#"&"] dataUsingEncoding:NSUTF8StringEncoding];
[request setHTTPBody:paramsData];
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
[NSURLConnection sendAsynchronousRequest:request queue:queue completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
if (error)
{
NSLog(#"%s: NSURLConnection error = %#", __FUNCTION__, error);
return;
}
NSError *parseError;
id results = [NSJSONSerialization JSONObjectWithData:data options:0 error:&parseError];
if (parseError)
{
NSLog(#"%s: NSJSONSerialization error = %#", __FUNCTION__, parseError);
return;
}
self.accessToken = results[#"access_token"];
if (self.accessToken)
{
[[NSUserDefaults standardUserDefaults] setValue:self.accessToken forKey:kViaMeUserDefaultKeyAccessToken];
[[NSUserDefaults standardUserDefaults] synchronize];
}
}];
}
Hopefully this will be enough to get you going. This is described in greater detail at the http://via.me/developers page.

Why does my code break for one call to this method, but not another?

I have a Mac application that is supposed to fetch Twitter followers and friends for a given username and then, in turn, ask Twitter for the user NAMES for each of those returned UserIDs. As you can see below, I have a method that will call the Twitter API to get friends/followers (which works fine). It is the userNameForUserID:delegate: method that is causing me problems. I used to do these requests synchronously and return the NSString for the username right then. That (now commented out) line always broke, so I tried doing it with an NSURLConnection asynchronously. Still doesn't work. I don't understand why
[[NSString alloc] initWithContentsOfURL:...] works for the fetchFollowers... method, but not when I do it the EXACT SAME way in the other...
I put a break point on the line that used to alloc init the NSString with contents of URL, and when I step into it, it doesn't break, return, throw an exception, crash...nothing. It's as if that line just got stepped over (but my application is still blocked.
Any ideas? Much appreciated!
NSString * const GET_FOLLOWERS = #"https://api.twitter.com/1/followers/ids.json?cursor=-1&screen_name=";
NSString * const GET_FRIENDS = #"https://api.twitter.com/1/friends/ids.json?cursor=-1&screen_name=";
NSString * const GET_USER_INFO = #"https://api.twitter.com/1/users/show.json?user_id=";
#implementation TwitterAPI
+ (void)userNameForUserID:(NSNumber *)userID delegate:(id<UserNameDelegate>)delegate
{
NSURL *url = [NSURL URLWithString:[GET_USER_INFO stringByAppendingString:[userID stringValue]]];
// NSString *JSON = [[NSString alloc] initWithContentsOfURL:url encoding:NSUTF8StringEncoding error:&error];
NSURLRequest *req = [NSURLRequest requestWithURL:url];
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
[NSURLConnection sendAsynchronousRequest:req queue:queue completionHandler:^(NSURLResponse *urlResponse, NSData *data, NSError *error) {
[delegate addUserNameToArray:data];
}];
}
+ (NSArray *)fetchFollowersWithUserName:(NSString *)userName
{
NSURL *url = [NSURL URLWithString:[GET_FOLLOWERS stringByAppendingString:userName]];
NSArray *followerIDs;
NSString *JSON = [[NSString alloc] initWithContentsOfURL:url encoding:NSASCIIStringEncoding error:nil];
if ([JSON rangeOfString:#"error"].location == NSNotFound)
followerIDs = [[JSON JSONValue] valueForKey:#"ids"];
return followerIDs;
}

How to optimize a UILocalNotification process

I'm trying to send multiple localNofications using a fetch request on an entity
And though this code works fine
NSFetchRequest *myRequest = [[NSFetchRequest alloc] init];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"active == YES"];
[myRequest setEntity:[NSEntityDescription entityForName:#"Entry" inManagedObjectContext:managedObjectContext]];
[myRequest setPredicate:predicate];
NSError *error = nil;
NSArray *fetchedObjects = [self.managedObjectContext executeFetchRequest: myRequest error: &error];
if (fetchedObjects == nil){
// Deal with error...
}
// We fill the NSMutableArray with the values of the fetch
self.activeList = [[NSMutableArray alloc] initWithArray:[fetchedObjects valueForKey:#"textbody"]];
[self scheduleAlarms:[self.activeList objectAtIndex:0]];
[fetchedObjects release]; //this line crashes the app
1) if I release fetchedObjects, the app crashes. Aren't I supposed to release it ?
2) Could I use the localNotif.userinfo to optimize the code instead of calling a method to schedule each localNotification with the strings in my activeList ? I can't figure out how to do it.
Thanks,
Mike
1) executeFetchRequest returns an autoreleased NSArray, you don't need to release it manually
2) not clear what do you want to optimize...

Resources