PushMeBaby does not work ! - iphone

I am trying to send push notification via PushMeBaby app according to [this tutorial ,][1] but I don't know why it does not work ! I install iPusher App from itunes and worked fine ! here is my code :
- (id)init {
self = [super init];
if(self != nil) {
self.deviceToken = #"5ce090e5 78d38a8a 149dbe46 cbe87e2e dc6c6d2a 4b97e3b7 a5d3f4c2 b09faad2";
self.payload = #"{\"aps\":{\"alert\":\"You got a new message!\",\"badge\":5,\"sound\":\"beep.wav\"},\"acme1\":\"bar\",\"acme2\":42}";
self.certificate = [[NSBundle mainBundle]
pathForResource:#"aps_developer_identity" ofType:#"cer"];
}
return self;
}
URBan AirShip code :
(void)application:(UIApplication*)application
didRegisterForRemoteNotificationsWithDeviceToken:(NSData*)deviceToken
{
// TODO: Pass the token to our server
// Convert the token to a hex string and make sure it's all caps
NSMutableString *tokenString = [NSMutableString stringWithString:[[deviceToken description] uppercaseString]];
[tokenString replaceOccurrencesOfString:#"<" withString:#"" options:0 range:NSMakeRange(0, tokenString.length)];
[tokenString replaceOccurrencesOfString:#">" withString:#"" options:0 range:NSMakeRange(0, tokenString.length)];
[tokenString replaceOccurrencesOfString:#" " withString:#"" options:0 range:NSMakeRange(0, tokenString.length)];
// Create the NSURL for the request
NSString *urlFormat = #"https://go.urbanairship.com/api/device_tokens/%#";
NSURL *registrationURL = [NSURL URLWithString:[NSString stringWithFormat:
urlFormat, tokenString]];
// Create the registration request
NSMutableURLRequest *registrationRequest = [[NSMutableURLRequest alloc]
initWithURL:registrationURL];
[registrationRequest setHTTPMethod:#"PUT"];
// And fire it off
NSURLConnection *connection = [NSURLConnection connectionWithRequest:registrationRequest
delegate:self];
[connection start];
NSLog(#"We successfully registered for push notifications");
}
- (void)application:(UIApplication*)application didFailToRegisterForRemoteNotificationsWithError:(NSError*)error
{
// Inform the user that registration failed
NSString* failureMessage = #"There was an error while trying to / register for push notifications.";
UIAlertView* failureAlert = [[UIAlertView alloc] initWithTitle:#"Error"
message:failureMessage
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[failureAlert show];
[failureAlert release];
}
- (void)connection:(NSURLConnection *)connection
didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
{
// Check for previous failures
if ([challenge previousFailureCount] > 0)
{
// We've already tried - something is wrong with our credentials
NSLog(#"Urban Airship credentials invalid");
return;
}
// Send our Urban Airship credentials
NSURLCredential *airshipCredentials = [NSURLCredential credentialWithUser:#"<GY__T8X4Rg6onkJSO8o0Bg>"
password:#"<Z_fhEasrQ6emwFcWMyiKrA>"
persistence:NSURLCredentialPersistenceNone];
[[challenge sender] useCredential:airshipCredentials
forAuthenticationChallenge:challenge];
}

I have read through the tutorial you've followed on mobiforge and it is wrong on so many levels!
If you want to use Push Notifications, then there really is no better way than to use Urban Airship
Here are a pair of tutorials which will get you up and running using Urban Airship: Part 1 & Part 2 (I can also verify these work properly as I have followed them many times)
If you would like avoid using a third party and instead have access to your own PHP capable server then here is another pair of tutorials which will help you get setup: Part 1 & Part 2

Related

iphone - return fbid to use it in json web service to receive data

I've been looking around, saw similar posts, but nothing like this that could give me answers. This is my setup and flow of the app:
User has to login via Facebook, using Facebook Graph. LoginView is presented modally, non animated
When user logins I can retrieve FBID and I use this fbid to send it to my web service (REST)
Web service gets the FBID from the NSURL and matches it with database to retrieve other user info
Using JSONserialization i parse the JSON received from web service and display it in the view
PROBLEM: Everything returns NULL except FBID that I get from Facebook. BUT, if I logout from Facebook and then login, that's when it works.
Here is my code:
viewDidAppear method:
-(void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:NO];
if (FBSession.activeSession.isOpen) {
[self populateUserDetails];
}
//Connect to WebService
NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:#"http://atnightcorp.com/api/member/id/%#/format/json", fbid]];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
[NSURLConnection connectionWithRequest:request delegate:self];
NSArray *pics = [member valueForKeyPath:#"photos"];
NSString *picCount = [NSString stringWithFormat:#"%d", [pics count]];
[photosCount setTitle:picCount forState:UIControlStateNormal];
NSLog(#"PHOTO: %#", picCount);
NSLog(#"FB: %#", fbid);
}
I tried putting NSURL request and connection code in viewDidLoad, but then I don't get anything back.
My NSURLConnection methods:
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
data = [[NSMutableData alloc]init];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)theData
{
[data appendData:theData];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
member = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:nil];
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
UIAlertView *errorView = [[UIAlertView alloc]initWithTitle:#"Error" message:#"The download could not complete. Please make sure you are connected to internet" delegate:nil cancelButtonTitle:#"Dismiss" otherButtonTitles:nil];
[errorView show];
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
}
The populateUserDetails method that you have seen above:
- (void)populateUserDetails
{
if (FBSession.activeSession.isOpen) {
[[FBRequest requestForMe] startWithCompletionHandler:
^(FBRequestConnection *connection,
NSDictionary<FBGraphUser> *user,
NSError *error) {
if (!error) {
self.userProfileImage.profileID = user.id;
self.navigationItem.title = user.name;
self.fbid = user.id;
}
}];
}
}
This method basically sets the FBID once user is logged in. Other important things you should know that could help you understand my project:
FBID is set as NSString property in my .H file
All facebook connect thing goes on in AppDelegate
I need to dynamically set the NSURL after I find out who the user is.
if I manually input FBID in NSURL, then it works.
everything should be executed when user logins, I think that the timing of retrieving fbid and receiving data from web service is wrong but I can't get to fix it.
IF you need anything else, I will elaborate more and post more code if needed. -
PLEASE HELP as I've been looking for answers for last 3 days.
Your problem is that the populateUserDetails is called and it returns without waiting the code to be executed (because it's an async task with a completition handler, and when you call the NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:#"http://atnightcorp.com/api/member/id/%#/format/json", fbid]]; for the first time, the fbid is nuil or not set properly (also you should use self.fbid not fbid since fbid is a property).
So you should try to move the whole code that is handling the request from viewDidAppear into a separate method and you should call that method from startWithCompletionHandler after you set the line with self.fbid = user.id
Also call [super viewDidAppear:animated]; not with NO param (this won't solve your problem but this is the right way to do it)

Programmatically tap on HTML href in order to update app

I'm planning updates for an enterprise app with ad-hoc distribution.
For updates, Apple recommends having the user visit an HTML page and tap on a link:
href="itms-services://?action=download-manifest&url=http://example.com/
manifest.plist"
See http://help.apple.com/iosdeployment-apps/#app43ad871e
I don't want to do this. I want the app to programmatically check for updates on launch and alert the user with a UIAlertView that an update is available.
Here's what I have so far in application didFinishLaunching. The complicated plist parsing comes from the structure of an example plist found here: http://help.apple.com/iosdeployment-apps/#app43ad78b3
NSLog(#"checking for update");
NSData *plistData = [NSData dataWithContentsOfURL:[NSURL URLWithString:#"http://example.com/MyApp.plist"]];
if (plistData) {
NSLog(#"finished checking for update");
NSError *error;
NSPropertyListFormat format;
NSDictionary *plist = [NSPropertyListSerialization propertyListWithData:plistData options:NSPropertyListImmutable format:&format error:&error];
if (plist) {
NSArray *items = [plist valueForKey:#"items"];
NSDictionary *dictionary;
if ([items count] > 0) {
dictionary = [items objectAtIndex:0];
}
NSDictionary *metaData = [dictionary objectForKey:#"metadata"];
float currentVersion = [[[[NSBundle mainBundle] infoDictionary] objectForKey:#"CFBundleVersion"] floatValue];
float newVersion = [[metaData objectForKey:#"bundle-version"] floatValue];
NSLog(#"newVersion: %f, currentVersion: %f", newVersion, currentVersion);
if (newVersion > currentVersion) {
NSLog(#"A new update is available");
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Update available" message:#"A new update is available." delegate:self cancelButtonTitle:#"Cancel" otherButtonTitles:#"UPDATE", nil];
[alert show];
}
}
}
Then I have my UIAlertView delegate method:
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
if (buttonIndex == 1) {
NSLog(#"downloading full update");
UIWebView *webView = [[UIWebView alloc] init];
[webView loadRequest:[[NSURLRequest alloc] initWithURL:[NSURL URLWithString:#"itms-services://?action=download-manifest&url=http://example.com/MyApp.plist"] cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:10.0]];
}
}
A few things:
I know [alert show] shouldn't be called in application didFinish, but I'll change it later.
I don't know how quickly plistData will be downloaded and how this download affects the app.
More importantly, my alert view delegate method doesn't work, and the update doesn't download. Even when I introduce webView with #property (nonatomic, strong) UIWebView *webView, the method doesn't do anything.
I think Dropbox has the MIME configured properly because I can download the .ipa through google Chrome.
So what I really need is a way using NSURLConnection (NSURLRequest etc.) to replicate the act of a user tapping on an HTML href. After that I think the full update will occur.
You can open a URL automatically using
[[UIApplication sharedApplication] openURL:...];
I don't know if it works for itms-services: urls, but it works for other bespoke URL schemes like tel:, fb: etc. so it should do unless Apple have specifically blocked it.

NSURLRequest converting NSData to an array

I need to convert data received from the web via an array in a PHP script into an array that I can pull values out of. Here's my code!
-(void)connectionDidFinishLoading:(NSURLConnection *)connection{
//NSString *payloadAsString = [NSString stringWithUTF8String:[receivedData bytes]];
NSArray *payloadAsString = [NSKeyedUnarchiver unarchiveObjectWithData:receivedData];
[payloadAsString finishEncoding];
verified = [payloadAsString objectAtIndex:0];
NSLog(#"logging");
//NSString *no = [[NSString alloc] init stringWithCString:verified];
NSLog(#"%#", verified);
if([verified isEqualToString:#"admin"]){
NSLog(#"test admin");
[self performSelector:#selector(changeViewAdmin) withObject:nil afterDelay:0.05];
}
if([verified isEqualToString:#"user"]){
NSLog(#"test user");
[self performSelector:#selector(changeView) withObject:nil afterDelay:0.05];
}
if([verified isEqualToString:#"No"]){
NSLog(#"test no");
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Error"
message:#"Invalid UserName/Password combination!"
delegate:self
cancelButtonTitle:#"Okay"
otherButtonTitles:nil];
[alert show];
[alert release];
}
[payloadAsString release];
//NSLog(#"%#", verified);
// INSERT GOOGLE MAPS URL REQUEST HERE
/*if(requestType == 1){
NSString* addressText = payloadAsString;
// URL encode the spaces
addressText = [addressText stringByAddingPercentEscapesUsingEncoding: NSASCIIStringEncoding];
NSString* urlText = [NSString stringWithFormat:#"http://maps.google.com/maps?q=%#", addressText];
// lets throw this text on the log so we can view the url in the event we have an issue
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:urlText]];
// */
//
//}
[connection release];
self.receivedData = nil;
}
Unfortunately, my console returns null and asks if I've put the -finishencoding method in. Question is, if that's correct, where would I do so?
PS: Another question, is if I'm retrieving an array of data from a database, is a PHP script the best way to go? Thank you.
1) Of all this code the only string relevant to your question is
NSArray *payloadAsString = [NSKeyedUnarchiver unarchiveObjectWithData:receivedData];
I really doubt that PHP script returns you data in NSKeyedUnarchiver-compatible format. I believe the only reason you don't get NSInvalidArgumentException exception from this method is that receivedData is nil (did you initialize it anywhere?). Try to make a string from what you receive like this
[[[NSString alloc] initWithData:receivedData encoding:NSUTF8StringEncoding] autorelease]
and log it. From this I hope it will be clear how to parse response.
2) Do not name NSArray instances like 'blahBlahString'. Strings and arrays are completely different.
NSKeyedUnarchiver can only unarchive instances which are produced by instances of the NSKeyedArchiver class.
https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSKeyedUnarchiver_Class/index.html

How to show an alert when the server is not working properly?

I am getting list using url by doing parsing it using xml parser. sometimes the server is not working properly. then how to give an alert when server is not working properly. I have given the code below
-(NSMutableArray*)getCustomerList:(NSString *)count category:(NSString *)aCategory alphabetic:(NSString *)alphabeticValue favorite:(NSString *)isFavoriteString
{
[self updateStatus];
if (internetConnectionStatus == NotReachable)
{
UIAlertView *reachbleAlert = [[UIAlertView alloc] initWithTitle:#"message"
message: #"No network available alert"
delegate:self
cancelButtonTitle:#"Ok"
otherButtonTitles: nil];
[reachbleAlert show];
[reachbleAlert release];
return 0;
}
else
{
NSString *urlString=#"http:getCustomerList.jsp";
urlString = [urlString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
[dataParser parseXMLFileAtURL:[NSURL URLWithString:urlString]];
NSMutableArray *list =[dataParser getCustomerListFromParser];
printf("\n url for Customer List%s",[urlString UTF8String]);
printf("\n Customer List %d",[list count]);
return list;
}
}
I am sending parameter to url to return repctive list when it returns zero I am dispalying alert in view controller.
but when server is not working properly then how to display this alert.
Please help me out of this.
Thank you,
Madan mohan.
In my opinion :
First perform the request operation to the server for any response.
Secondly Catch the the response received in a BOOL variable .
Finally when your BOOL variable is TRUE perform the desired operation [Such as parsing..]
Otherwise just show an alert message with a proper error message.
I'm sure there's a perfectly nice way to do it with parseXMLFileAtURL. I don't that way.
What I do know is if you use the excellent ASIHTTPRequest library to make an asynchronous request, all of that stuff is taken care of for you. You create two delegate methods, RequestFinished and RequestFailed, and one of them will be called when the result is clear.
In RequestFinished you'd parse the string portion of the response object.
In RequestFailed you'd display the alert and then decide how to proceed from there.
for this u create the asynchronous request usingNSURLRequest
NSURL *theURL=[[NSURL alloc]initWithString:#"**YOUR URL**"];
NSMutableURLRequest *theRequest = [[NSMutableURLRequest alloc] initWithURL:theURL];
[theRequest setTimeoutInterval:150];
[theURL release];
mURLConnection=[[NSURLConnection alloc]initWithRequest:theRequest delegate:self];
[theRequest release]
and then in their delegate method
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
if (mResultData == nil) //mResultData is NSData(member variable)
mResultData = [[NSMutableData alloc] init];
[mResultData setLength: 0];
}
-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
[mResultData appendData:data];
}
// this method calls if their is any problem from server side
-(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
[mResultData release];
mResultData = nil;
[mURLConnection release];
mURLConnection = nil;
//here the show the error
UIAlertView *theAlert=[[UIAlertView alloc]initWithTitle:kAlertTitle message:[error localizedDescription] delegate:nil cancelButtonTitle:#"Ok" otherButtonTitles:nil];
[theAlert show];
[theAlert release];
}
(void)connectionDidFinishLoading:(NSURLConnection *)connection
{
//here u could send mResulData for parsing
// create NSXMLParser
}

Using Google Reader API and OAuth in iPhone app

I want to make an app that uses on the Google Reader API. But I'm finding out that there isn't an offical API for it - is there a problem using the unofficial API, in terms of App Store guidelines/approval? Would other apps (Reeder, etc) use this?
Also what is the best method for logging in? Is OAuth the preffered method? Is using Janrain a good idea?
Frankly Apple doesn't care if you use Google's unofficial API.
I worked for a customer on a RSS reader app that used Google Reader for syncing. We didn't use OAuth but the standard HTTP login which returns you a cookie where you'll have to extract a token from to use in consecutive calls to the various reader URLs.
I can post you the login code from my (old) proof of concept app.
It uses ASIHTTP and some custom string categories. The idea is to send a login request, get the response and extract the session ID/auth code from the response's cookie header. Then you can use that session ID/auth code for consecutive calls.
#pragma mark -
#pragma mark login
//this is your sessionID token you get from the login
//use this in consecutive calls to google reader
//this method returns you the header string you have to add to your request
//[request addRequestHeader: #"Cookie" value: [self sidHeader]];
- (NSString *) sidHeader
{
return [NSString stringWithFormat: #"SID=%#", [self sid]];
}
- (NSString *) authHeader
{
return [NSString stringWithFormat: #"GoogleLogin auth=%#",[self auth]];
}
//login to your google account and get the session ID
- (void) login
{
NSString *username = #"my.googlelogin#gmail.com";
NSString *password = #"mypassword123";
NSString *loginUrl = #"https://www.google.com/accounts/ClientLogin?client=NNW-Mac";
NSString *source = #"NNW-Mac"; //let's fake NetNewsWire
NSString *continueUrl = #"http://www.google.com";
ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:[NSURL URLWithString: loginUrl]]; // log in & get cookies
[request addRequestHeader: #"User-Agent" value: #"NetNewsWire/3.2b25 (Mac OS X; http://www.newsgator.com/Individuals/NetNewsWire/)"];
[request setPostValue: username forKey: #"Email"];
[request setPostValue: password forKey: #"Passwd"];
[request setPostValue: #"reader" forKey: #"service"];
[request setPostValue: source forKey: #"source"];
[request setPostValue: continueUrl forKey: #"continue"];
[request setDelegate: self];
[request setDidFailSelector: #selector(loginRequestFailed:)];
[request setDidFinishSelector: #selector(loginRequestFinished:)];
[request start];
}
-(void)loginRequestFinished:(ASIHTTPRequest *)request
{
NSString *responseString = [request responseString];
//login failed
if ([responseString containsString: #"Error=BadAuthentication" ignoringCase: YES])
{
[self setLastError: [self errorWithDescription: #"Bad Username/Passsword" code: 0x001 andErrorLevel: 0x00]];
if ([delegate respondsToSelector: #selector(gReaderLoginDidFail:)])
{
[delegate gReaderLoginDidFail: self];
}
return NO;
}
//captcha required
if ([responseString containsString: #"CaptchaRequired" ignoringCase: YES])
{
[self setLastError: [self errorWithDescription: #"Captcha Required" code: 0x001 andErrorLevel: 0x00]];
if ([delegate respondsToSelector: #selector(gReaderLoginDidFail:)])
{
[delegate gReaderLoginDidFail: self];
}
return NO;
}
//extract SID + auth
NSArray *respArray = [responseString componentsSeparatedByCharactersInSet: [NSCharacterSet newlineCharacterSet]];
NSString *sidString = [respArray objectAtIndex: 0];
sidString = [sidString stringByReplacingOccurrencesOfString: #"SID=" withString: #""];
[self setSid: sidString];
NSString *authString = [respArray objectAtIndex: 2];
authString = [authString stringByReplacingOccurrencesOfString: #"Auth=" withString: #""];
[self setAuth: authString];
//mesage delegate of success
if ([delegate respondsToSelector: #selector(gReaderLoginDidSucceed:)])
{
[delegate gReaderLoginDidSucceed: self];
}
return YES;
}
- (void)loginRequestFailed:(ASIHTTPRequest *)request
{
NSError *error = [request error];
//NSLog(#"login request failed with error: %#", [error localizedDescription]);
[self setLastError: error];
if ([delegate respondsToSelector: #selector(gReaderLoginDidFail:)])
{
[delegate gReaderLoginDidFail: self];
}
}
After login you can use sid and auth to forge requests to the Reader's API endpoints.
Example:
- (ASIHTTPRequest *) requestForAPIEndpoint: (NSString *) apiEndpoint
{
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:[NSURL URLWithString: apiEndpoint]];
[request addRequestHeader: #"User-Agent" value: #"NetNewsWire/3.2b25 (Mac OS X; http://www.newsgator.com/Individuals/NetNewsWire/)"];
[request addRequestHeader: #"Cookie" value: [self sidHeader]];
[request addRequestHeader: #"Authorization" value: [self authHeader]];
return request;
}
An interesting read about Google Reader and its private API is http://timbroder.com/2007/08/google-reader-api-functions.html
Please make sure to read the latest comments :)
/edit: I updated the code to use the auth header (which google introduced in june this year). I guess this would be the place to put your OAuth token in if you would use OAuth. guess
Ive since found this: "The Google Data APIs Objective-C Client Library provides an iPhone static library, a Mac OS X framework, and source code that make it easy to access data through Google Data APIs. " code.google.com/p/gdata-objectivec-client - which is great!
It doesn't include the Reader API however (because it's not been released).
I have been able to access the API by changing (in the OAuthSampleTouch example)
NSString *scope = #"http://www.google.com/m8/feeds/";
in OAuthSampleRootViewControllerTouch.m to
NSString *scope = #"http://www.google.com/reader/api/*";
and
urlStr = #"http://www.google.com/m8/feeds/contacts/default/thin";
to
urlStr = #"http://www.google.com/reader/atom/user/-/label/Design";
where Design is a folder name - check this http://code.google.com/p/pyrfeed/wiki/GoogleReaderAPI its a great help.
Update
I have since found that this technique to be the best / lightest / less-complicated :
Native Google Reader iPhone Application