handleOpenURL not called using a custom url schema in iPhone OS - iphone

I have successfuly added my own url schemes to my App. The App correctly launches using the schemes.
Now I want to handle the incoming data but the delegate is not called. It is an universal app and I have added the following function to both AppDelegates:
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url {
if (!url) { return NO; }
NSString *URLString = [url absoluteString];
UIAlertView *alert = [[UIAlertView alloc]
initWithTitle:NSLocalizedString(#"test message", nil)
message:URLString
delegate:self
cancelButtonTitle:nil otherButtonTitles:#"OK", nil];
[alert show];
[alert release];
return YES;
}
I am testing with a schema like: myapp://appalarm.com
…and would expect to be appalarm.com in the URLString
What is wrong with it?
Thanks for your responses!

I tried to clarify in another post. The answer of Ashley Clark is only partly correct. Under OS 4.0 the handleOpenURL gets called (at least for file URLs) and you have to implement it to handle open url calls for when the app is in background. Thus, opening the file in both methods may open it twice (if applicationDidFinishLaunchingWithOptions returned YES, which it should). See another post.

If your application delegate has implemented 'applicationDidFinishLaunchingWithOptions:' then the 'handleOpenURL:' method will never be called. Look at the options passed in through the other method to determine how your app was launched and what behavior you should implement.

Try your code into below function
-(BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
if (!url) { return NO; }
NSString *URLString = [url absoluteString];
UIAlertView *alert = [[UIAlertView alloc]
initWithTitle:NSLocalizedString(#"test message", nil)
message:URLString
delegate:self
cancelButtonTitle:nil otherButtonTitles:#"OK", nil];
[alert show];
[alert release];
return YES;
}

Related

fire an alert when a UILocalNotification is called

I have a UILocalNotification and I want to fire an alert when the app recovers from background to foreground. I can create the alert in didReceiveLocalNotification, but this method can only be called when the app is active. Now I want to check if a notification was fired while the app is in background and then fire an alert when the app recovers.
this is my current method
- (void)applicationDidBecomeActive:(UIApplication *)application
{
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
application.applicationIconBadgeNumber = 0;
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
NSLog(#"prefs %#",[prefs stringForKey:#"kTimerNotificationUserDef"]);
if([prefs stringForKey:#"kTimerNotificationUserDef"] != nil)
{
[prefs setObject:nil forKey:#"kTimerNotificationUserDef"];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Timer Alert" message:[prefs stringForKey:#"kTimerNotificationUserDef"] delegate:self cancelButtonTitle:#"Ok" otherButtonTitles:nil, nil];
[alert show];
}
}
the NSUserDefaults is set when I initialize the notification, however, this alert is called even though the notification did not arrive yet. So, Im assuming maybe I can do something like:
if([prefs stringForKey:#"kTimerNotificationUserDef"] != nil && didFireNotifFromBackground)
any suggestions? thanks!
- (void)application:(UIApplication *)application
didReceiveLocalNotification:(UILocalNotification *)notification {
notification.applicationIconBadgeNumber = 0;
NSString *reminderText = [notification.userInfo objectForKey:kRemindMeNotificationDataKey];
[viewController showReminder:reminderText];
}
show the alertview where class u want to show
- (void)showReminder:(NSString *)text
{
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"Reminder" message:text delegate:nil cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alertView show];
[alertView release];
}
It is in your settings. Settings ->Notification->Your application in right side-> Choose your alert style.
Then you get alert directly while firing local notification

problem in Error handling method in iPhone sdk

I am using Error Handling Method globally in appDelegate method to caught exceptions.
Code:
//In appDelegate.m
static void uncaughtExceptionHandler(NSException *exception)
{
printf("\n ===== In uncaughtExceptionHandler Method =======");
NSArray *stack = [exception callStackReturnAddresses];
NSLog(#"======== Exception *************%#", stack);
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"" message:#"Exception Occured"
delegate:self cancelButtonTitle:#"OK" otherButtonTitles: nil];
[alert show];
[alert release];
}
-(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary
*)launchOptions
{
// Override point for customization after application launch.
NSSetUncaughtExceptionHandler(&uncaughtExceptionHandler);
}
I am implementing an Alert in the uncaughtExceptionHandler Method. But I am getting Error as
"self " undeclared.
Can Anyone Please Suggest how to implement Alert when the uncaughtExceptionHandler is
called.
thanks in Advance.
Try implementing this Handle Uncaught Exception
self is undefined within a C function. If you want to make the application delegate the delegate for your alert view then you should probably replace self with [[UIApplication sharedApplication] delegate].

iPhone: Using Alerts to Help Debugging

I've been building a rather complex system and there's come the time now where I want more concise debugging. I would like to display the contents of a variable (for this example an NSString called v_string) in a notification window (the kind of window that appear when you receive an SMS text).
Is there an easy way to just call an alert with a variable?
Thanks in Advance,
Dan
NSLog does not do? If not (like if you need to debug an application running on a disconnected device), you can extend the UIAlertView with a category:
#implementation UIAlertView (Logging)
+ (void) log: (id <NSObject>) anObject
{
NSString *message = [anObject description];
UIAlertView *alert = [[self alloc] initWith…];
[alert show];
[alert release];
}
And then in code:
NSString *anInterestingString = …;
[UIAlertView log:anInterestingString];
When you build the string to display in the alert window, simply append your variable's string represenation using stringByAppendingString.
Alert window is cumbersome. Use NSLog instead:
NSLog(#"Variable is: %#", v_string);
And in Xcode's console you will see that text.
UIAlertView *message = [[UIAlertView alloc] initWithTitle:#"My Debug String" message:v_string delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[message show];
[message release];
I think this way you can see what you want.
But, as zoul said, why not to use NSLog(#"my var: %#", v_string); ?
Hope that it helps.

Is it me or xcode... Somethings wrong with my braces and it just causes errors! Please help! iPhone SDK + Urban Push

Help!
I cant find whats wrong. My code is up and mostly running and i needed to incorporate Urban Air push notification and there is something wrong with my code. If there is a better or different way to incorporate this that works without my errors I would appreciate that.
I took this code from a tut of Urban Airmail. I wasnt sure what to inlude and what not to from the sample app.
Now for my code. Ill notate where I get errors They are stray / errors and expected ; b4 :
errors
If you could fix the code that would be awesome!
//
// SuperSlickAppDelegate.m
// SuperSlick
//
// Created by on 8/2/10.
// Copyright __MyCompanyName__ 2010. All rights reserved.
//
#import <SystemConfiguration/SCNetworkReachability.h>
#include <netinet/in.h>
#import "SuperSlickAppDelegate.h"
#import "SuperSlickViewController.h"
#import "Reachability.h"
#implementation SuperSlickAppDelegate
#synthesize window;
#synthesize viewController;
#pragma mark -
#pragma mark Application lifecycle
#define kApplicationKey #"rnftzaemRp2HJMsNjwZvGQ"
#define kApplicationSecret #"X1XdTjdWQIaL72e-gXew5A"
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Override point for customization after application launch.
Reachability *r = [Reachability reachabilityWithHostName:#"google.com"];
NetworkStatus internetStatus = [r currentReachabilityStatus];
if ((internetStatus != ReachableViaWiFi) && (internetStatus != ReachableViaWWAN))
{
UIAlertView *myAlert = [[UIAlertView alloc] initWithTitle:#"No Internet Connection" message:#"You require an internet connection via WiFi or cellular network to use this! Try the settings app for WiFi Connectivity." delegate:self cancelButtonTitle:#"Ok" otherButtonTitles:nil];
[myAlert show];
[myAlert release];
}
//Register for notifications
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:(UIRemoteNotificationTypeBadge |UIRemoteNotificationTypeSound |UIRemoteNotificationTypeAlert)];
//ERROR HERE in line above Stray 357
-(void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)_deviceToken {
//ERROR HERE Wrong type argument to unary minus + stray
// Get a hex string from the device token with no spaces or < >
self.deviceToken = [[[[_deviceToken description] stringByReplacingOccurrencesOfString:#"<"withString:#""]
stringByReplacingOccurrencesOfString:#">" withString:#""]
stringByReplacingOccurrencesOfString: #" " withString: #""];
NSLog(#"Device Token: %#", self.deviceToken);
if ([application enabledRemoteNotificationTypes] == 0) {
NSLog(#"Notifications are disabled for this application. Not registering with Urban Airship");
return;
}
// this is straight out of the UA sample code
NSOperationQueue *queue = [[[NSOperationQueue alloc] init] autorelease];
NSString *UAServer = #"https://go.urbanairship.com";
NSString *urlString = [NSString stringWithFormat:#"%#%#%#/", UAServer, #"/api/device_tokens/", self.deviceToken];
NSURL *url = [NSURL URLWithString: urlString];
ASIHTTPRequest *request = [[[ASIHTTPRequest alloc] initWithURL:url] autorelease];
request.requestMethod = #"PUT";
// Authenticate to the server
request.username = kApplicationKey;
request.password = kApplicationSecret;
[request setDelegate:self];
[request setDidFinishSelector: #selector(registrationSuccessMethod:)]; // if you want to do something with the token
[request setDidFailSelector: #selector(requestWentWrong:)];
[queue addOperation:request];
}
- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *) error {
NSLog(#"Failed to register with error: %#", error);
}
- (void)requestWentWrong: (ASIHTTPRequest *)request {
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
NSError *_error = [request error];
NSLog(#"ERROR: NSError query result: %#", _error);
UIAlertView *someError = [[UIAlertView alloc] initWithTitle:
#"Network error" message: NSLocalizedString( #"Error registering with notifiction server",
#"Error registering with notifiction server")
delegate: self
cancelButtonTitle: #"OK"
otherButtonTitles: nil];
[someError show];
[someError release];
}
// Add the view controller's view to the window and display.
[window addSubview:viewController.view];
[window makeKeyAndVisible];
return YES;
}
}
- (void)applicationWillResignActive:(UIApplication *)application {
/*
Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
*/
}
- (void)applicationDidEnterBackground:(UIApplication *)application {
/*
Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
If your application supports background execution, called instead of applicationWillTerminate: when the user quits.
*/
}
- (void)applicationWillEnterForeground:(UIApplication *)application {
/*
Called as part of transition from the background to the inactive state: here you can undo many of the changes made on entering the background.
*/
}
- (void)applicationDidBecomeActive:(UIApplication *)application {
/*
Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
*/
}
- (void)applicationWillTerminate:(UIApplication *)application {
/*
Called when the application is about to terminate.
See also applicationDidEnterBackground:.
*/
}
#pragma mark -
#pragma mark Memory management
- (void)applicationDidReceiveMemoryWarning:(UIApplication *)application {
/*
Free up as much memory as possible by purging cached data objects that can be recreated (or reloaded from disk) later.
*/
}
- (void)dealloc {
[viewController release];
[window release];
[super dealloc];
}
#end
New Code that has troubles:
//Register for notifications
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:(UIRemoteNotificationTypeBadge |UIRemoteNotificationTypeSound |UIRemoteNotificationTypeAlert)];
;}}
-(void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)_deviceToken {
//ERROR HERE Wrong type argument to unary minus and semi colon b4
Doesn't look like you ever ended your application:didFinishLaunchingWithOptions: method - you should have an end brace after this line:
[[UIApplication sharedApplication] registerForRemoteNotificationTypes...
So it should look like this:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
...
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:(UIRemoteNotificationTypeBadge |UIRemoteNotificationTypeSound |UIRemoteNotificationTypeAlert)];
//ERROR HERE in line above Stray 357
}
-(void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)_deviceToken {
...
}
That should do it.
For your second code block - without seeing the surrounding code it's difficult to see what you're trying to do...you likely shouldn't have:
;}}
It should probably just be:
}
If you are looking for unbalanced parentheses, then this is probably the part that is giving you troubles:
[window addSubview:viewController.view];
[window makeKeyAndVisible];
return YES;
}
}

UIAlertView Pops Up Three Times per Call Instead of Just Once

I am getting odd behavior from an NSAlert in two different parts of my program. The behavior is:
Alert appears and then spontaneously disappears.
Alert reappears and then remains until dismissed by user i.e. normal behavior.
Alert reappears again.
This behavior only occurs the first time the method that displays the alert is called. After that first time, it behaves normally.
Here is the code for the one of the parts in which the behavior occurs:
UIAlertView * locationAlert = [[UIAlertView alloc] initWithTitle:#"You are in the right place." message:nil delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[locationAlert show];
[locationAlert release];
Or if you prefer, with a bit more context:
- (IBAction)locateMe {
NSLog(#"About to check location");
locMan = [[CLLocationManager alloc] init];
locMan.delegate = self;
locMan.desiredAccuracy = kCLLocationAccuracyThreeKilometers;
locMan.distanceFilter = 1609; //1 mile
[locMan startUpdatingLocation];
}
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation * )oldLocation {
if (newLocation.horizontalAccuracy >= 0) {
CLLocation *airportLocation = [[[CLLocation alloc] initWithLatitude:51.500148 longitude:-0.204669] autorelease];
CLLocationDistance delta = [airportLocation getDistanceFrom: newLocation];
long miles = (delta * 0.000621371) + 0.5; //metres to rounded mile
if (miles < 3) {
UIAlertView * locationAlert = [[UIAlertView alloc] initWithTitle:#"You are in the right place." message:nil delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[locationAlert show];
[locationAlert release];
[locMan stopUpdatingLocation];
} else {
UIAlertView * locationAlert = [[UIAlertView alloc] initWithTitle:#"You are not in the right place." message:nil delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[locationAlert show];
[locationAlert release];
[locMan stopUpdatingLocation];
}
}
}
- (void) locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error {
UIAlertView * locationAlert = [[UIAlertView alloc] initWithTitle:#"Error." message:error.code delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[locationAlert show];
[locMan release];
locMan = nil;
}
Any ideas? Thanks.
Edit---------
The other place this happens is:
- (void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError {
NSString * errorString = [NSString stringWithFormat:#"Unable to download feed from web site (Error code %i )", [parseError code]];
NSLog(#"error parsing XML: %#", errorString);
UIAlertView * errorAlert = [[UIAlertView alloc] initWithTitle:#"Error loading content" message:errorString delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[errorAlert show];
}
For context the first case is in the AppDelegate and the second in the view controller for the 1st tab view. The second problem occurs every time the xml is reloaded when there is no internet connection. The first one only occurs the first time the function is called.
Edit-----
If I move the alert it works. Unfortunatly this is not where I want it!
- (IBAction)locateMe {
UIAlertView * locationAlert = [[UIAlertView alloc] initWithTitle:#"You are in the right place." message:nil delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[locationAlert show];
/*
NSLog(#"About to check location");
locMan = [[CLLocationManager alloc] init];
locMan.delegate = self;
locMan.desiredAccuracy = kCLLocationAccuracyThreeKilometers;
locMan.distanceFilter = 1609; //1 mile
[locMan startUpdatingLocation];*/
}
Update:
I set some NSLog entries and discovered that despite the addition of [locMan stopUpdatingLocation] the didUpdateToLocation function was running multiple times.
I guess the spontaneous disappearance happens because the alert view is called again and the programme clears the first instance to make way for the second automatically.
Any ideas as to why [locMan stopUpdatingLocation] doesn't work would be appreciated but in the mean time I just moved the declaration of the locationAlert out of the function (so it is global), set it in the initial locate me function and use the following the first time it is called:
[locationAlert show];
locationAlert = nil;
That way it works perfectly.
You're not turning off your location manager when you first show the alert. As the location is refined by the device (ie, the accuracy is increased), your callback will be (potentially) called multiple times. You should use [locMan stopUpdatingLocation] after your alert display.
I set some NSLog entries and discovered that despite the addition of [locMan stopUpdatingLocation] the didUpdateToLocation function was running multiple times.
I guess the spontaneous disappearance happens because the alert view is called again and the programme clears the first instance to make way for the second automatically.
Any ideas as to why [locMan stopUpdatingLocation] doesn't work would be appreciated but in the mean time I just moved the declaration of the locationAlert out of the function (so it is global), set it in the initial locate me function and use the following the first time it is called:
[locationAlert show];
locationAlert = nil;
That way it works perfectly.
I think the NSAlert disappearing on its own is the key to solving this.
It's simple to explain why an alert displays unexpectedly i.e. it's just been called unexpectedly. However, it's not so common to programmatically dismiss an alert. Whatever is causing it to disappear is most likely triggering the display again.
To debug I suggest:
(1) Looking in your code for the NSAlert – dismissWithClickedButtonIndex:animated: method and see if somehow you're actually dismissing the alert programmatically.
(2) I believe (someone double-check me on this) that an alert view is added as a subview to whichever base view is currently on screen. It might be that the base view is disappearing for some reason and taking the alert view with it. If the view disappears and then reappears rapidly enough, it might not be obvious when the alert is frontmost. (Edit: see Ed Marty's comment below.)
(3) Since this happens in two separate pieces of the app, compare both to find a common element or structure. That common element might be the cause.
An odd problem.
Edit01: Updated for additional info
If locMan isan instance variable, it should be defined as a property and you should access it every time withself.locMan By accessing it directly, you lose your automatic retention management.
I encountered the same exact issue with the alert dialog appearing momentarily, reappearing, and finally appearing again after being dismissed. I was making a string comparison before deciding to show the alert view:
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {
if([string isEqualToString:#"OK"]) {
NSLog(#"(Settings)Registration Successful");
statusField.text = #"Registration successful!";
[settingsActivity stopAnimating];
}
else {
NSLog(#"(Settings)Registration Failure");
[settingsActivity stopAnimating];
UIAlertView * regFail = [[[UIAlertView alloc] initWithTitle:#"Registration Error!" message:#"Please check your email address and try again." delegate:self cancelButtonTitle:#"OK" otherButtonTitles: nil] autorelease];
[regFail show];
}}
To correct this behavior I simply verified the returned string rather than just showing the alert:
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {
if([string isEqualToString:#"OK"]) {
NSLog(#"(Settings)Registration Successful");
statusField.text = #"Registration successful!";
[settingsActivity stopAnimating];
}
else if([string isEqualToString:#"Error"]) {
NSLog(#"(Settings)Registration Failure");
[settingsActivity stopAnimating];
UIAlertView * regFail = [[[UIAlertView alloc] initWithTitle:#"Registration Error!" message:#"Please check your email address and try again." delegate:self cancelButtonTitle:#"OK" otherButtonTitles: nil] autorelease];
[regFail show];
}
I also got the Same problem while working on Location Manager. Here i checked with Nslog but it is executing multiple times, finally i fount that i am creating multiple objects and using Sharedinstance for same ViewController that contains Location Manger but i am not releasing the object, so at perticular location how many objects if we create that many times the location detects.So while working on LocationManger check handling objects thoroughly to reduce these type of problems.