ios webcal request - completion callback? - ios

NSURL *url = [NSURL URLWithString:#"valid_webcal_url"];
if (![[UIApplication sharedApplication] openURL:url])
{
// failure callback
NSLog(#"%#%#",#"Failed to open url:",[url description]);
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:LCHLocalizedString(#"SUBSCRIBE_ERROR", nil) message:nil delegate:self cancelButtonTitle:#"Okay" otherButtonTitles: nil];
[alert show];
}
So I've figured out how to see if there was an error loading the webcal, but how can I know when the webcal was loaded successfully? I display a loader when the "subscribe" button is tapped and just need to know when to turn it off.

As already stated in the comments this will put your app in the background with no guaranteed means to automatic return.
Assuming you actually want to invoke a web page (as opposed to doing a web api call) you should probably create a custom subclass of UIViewController with an embedded UIWebView.
Setting your subclass as a delegate of the UIWebView will allow you to react to failure/success. You can even intercept and stop UIWebView calls with - (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType

Because this is using openURL to retrieve an item using the webcal protocol, there is no visual separation of app and webcal retrieval.
What I'm having to do is listen for the notification UIApplicationWillResignActiveNotification after calling openURL and when the notification is fired I assume it's the webcal taking over from my openURL call.
This is tricky business and a rudimentary fix but hey, it works! Thanks for all help/suggestions.

Related

Cannot Launch an app from within another (iPhone)

I have followed exactly the same tutorial Launch an app from within another (iPhone) but the code is only executing the else part and showing alert, So I am unable to open the second app. You can see the steps I have followed in the link above.
Let's assume that we have two apps called FirstApp and SecondApp. When we open the FirstApp, we want to be able to open the SecondApp by clicking a button. The solution to do this is:
In SecondApp
Go to the plist file of SecondApp and you need to add a URL Schemes with a string iOSDevTips(of course you can write another string.it's up to you).
2 . In FirstApp
Create a button with the below action:
- (void)buttonPressed:(UIButton *)button
{
NSString *customURL = #"iOSDevTips://";
if ([[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:customURL]])
{
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:customURL]];
}
else
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"URL error"
message:[NSString stringWithFormat:#"No custom URL defined for %#", customURL]
delegate:self cancelButtonTitle:#"Ok"
otherButtonTitles:nil];
[alert show];
}
}
Add the custom Url in info.plist
1st image - In Your App which you are opening
2nd Image - In Your App which from you are opening
For full explanation and code visit my blog here

Showing Waiting Alert View At Load

I would like when my app starts for it to show an Alert view for about 5 seconds, then depending on the outcome of a background process, it will show another Alert view.
The problem I am experiencing is that when I try to use Sleep to wait for a background process to occur. The first Alert does not show and wait the 5 seconds. The app shows the first view of the app, and then after 5 seconds the first Alert shows briefly.
What do I need to do to perform what I wish.
Here is my code.
- (void)viewDidAppear:(BOOL)animated
{
SSGlobalSettings *connSettings = [SSGlobalSettings sharedManager];
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"Connecting" message:#"Please wait, while your device connects" delegate:Nil cancelButtonTitle:nil otherButtonTitles: nil];
[alertView show];
[NSThread sleepForTimeInterval:5.0f];
[alertView dismissWithClickedButtonIndex: alertView.cancelButtonIndex animated: YES];
if ([connSettings.connectionStatus isEqual: #"Not Found"])
{
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"Connection Failed" message:#"Cannot find your device on the network" delegate:Nil cancelButtonTitle:#"OK" otherButtonTitles: nil];
[alertView show];
}
else
{
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"Connection Success" message:#"WYour device has been found on the network" delegate:#"OK" cancelButtonTitle:nil otherButtonTitles: nil];
[alertView show];
}
}
Don't use sleep on the main thread. Ever. Also don't update UI from a background thread.
What you want to do is to display your alert on the main thread and return.
Then, when your networking code completes, have it send a message to the main thread. In the main thread, when you receive a notice that it's done, remove the alert.
It's not working right because you are trying to tell the main thread of the app to sleep. If you are telling that thread to sleep, then you're most likely not going to allow any UI updating to occur during that time, because all UI updating happens on the main thread.
What you need to do is move the code for showing the second UIAlertView to a second method, and then call the method - (void)performSelector:(SEL)aSelector withObject:(id)anArgument afterDelay:(NSTimeInterval)delay, passing it that second method for the selector, and giving it a delay of 5 seconds. Make sure you remove the call to sleep the main thread.
However, this still seems like a bad practice, because this action should be occurring as a result of your background task completing. So if you can, you should be running the code to show the second alert view upon completion of that task, which most likely could finish in varying amounts of time.
you block the main thread in you way.
i think it seems that you just want the user not to do anything before the first 5 sec(to let you connection connect successfully?), if so, lots ways could do that, e.g. just show a view on the top of the window, until you want the user can do something, you can show the disappear button on that view or just disappear it immediately.
You can use performSelector:withObject:afterDelay: method instead.

UIDocumentInteractionController disable open in certain apps

I'm currently using a UIDocumentInteractionController for open in functionality. When it opens it shows a list of all apps on the device that can handle that file type.
Is there a way to disable my app sending a document to specific apps, even if they support that file type? For example - if I have a PDF file open in my app and iBooks is on the iPad, if I tap the iBooks icon in the UIDocumentInteractionController, I don't want it to send it to the app.
Ideally - I see this as building a blacklist (or whitelist). For example, it would be great to do this:
- (void) documentInteractionController: (UIDocumentInteractionController *) controller willBeginSendingToApplication: (NSString *) application {
// if app is blacklisted
if ([application isEqualToString:#"com.schimera.WebDAVNavigator"]) {
[self.interactionController dismissMenuAnimated:YES];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"FAIL" message:#"NO" delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert show];
return
}
}
With this however, the document is still sent to the application even if it is "black listed".
Is this approach at all possible?
Cheers!
Change the UIDocumentInteractionController's URL to an invalid value if the app is blacklisted. In the method -[UIDocumentInteractionControllerDelegate documentInteractionController: willBeginSendingToApplication:].
-(void)documentInteractionController:(UIDocumentInteractionController *)controller willBeginSendingToApplication:(NSString *)application
{
if([application isEqualToString:#"com.evilcorp.badapp"){
controller.URL = nil;
}
}
To offer open file in a specific app (as white list), just add (using swift 3.0):
docController.uti = #"com.yourapp.package";

Is it possible to let remote notifications show in the notification center even when an app is running?

Is it possible to let a remote iOS5 notification show in the notification center even if my app is running, something like "I don't care about the remote notification at the moment even though I am running, let it show in the notification bar just as if I wasn't running"?
You show the UIAlertView to the user, instead of that.
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
NSLog(#"userInfo :%#",userInfo);
NSString* msg = [userInfo valueForKey:#"aps"];
if (self._VCObj.isViewLoaded && self._VCObj.view.window) {
// viewController is visible don't show.
}
else { // viewController is not visible
[[[UIAlertView alloc]initWithTitle:#"Title" message:msg delegate:self cancelButtonTitle:#"ok" otherButtonTitles: nil] show];
}
}
}
Tutorial
This is not possible. The only workaround I can think of is store notification somehow in app, and then on applicationWillTerminate(or some other method) schedule same notification as a LocalNotification and made it appear after second or two. This however could annoy me as a user if I get a notification right after I close some app :)

detecting URL webview has left the your iPhone app

i open a url within a Webview and whilst loading i show a spinner in a alert view.
If the url tapped opens an internal app such as iTunes how can i detect the web view has left my app so that when the user returns the dialog has been dismissed.
i have used didFailLoadWithError and this didn't work?
Any ideas?
Thanks dan
FIXED- i forgot to set the delegate Doh!
UIWebViewDelegate method webView:shouldStartLoadWithRequest:navigationType: will ask your webview's delegate if it is allowed to open every single url before trying to open it. You could check for url type in that method and return NO if it's not http or https, then present an alert for the user and let them chose if they want to open it or stay within your app, or just log that app was left to open another one and return YES;
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
NSString *urlString = [NSString stringWithFormat:#"%#", request.URL];
NSArray *urlComponents = [urlString componentsSeparatedByString:#"://"];
NSString *urlType = [urlComponents objectAtIndex:0];
if ([urlType isEqualToString:#"http"] || [urlType isEqualToString:#"https"]) {
// present an alert or do whatever you want with this url...
return NO;
}
return YES;
}
First of all, using an alert view to display loading progress in a web view is probably a bad idea, because it blocks all user interaction until it finishes loading.
You already have code that allows the web view to handle certain URLs with the built-in apps, such as iTunes (it doesn't do that on its own), so I guess when you use [[UIApplication sharedApplication] openURL:...] to open the external URL, you could easily hide the spinner there as well.
You could use applicationWillResignActive to detect when the app goes into an inactive state. It goes in your app delegate:
- (void)applicationWillResignActive:(UIApplication *)application {
//close your UIWebView here
}
If you can't access your UIWebView from the delegate, you could register for the UIApplicationDidEnterBackgroundNotification notification from your UIViewController. Make sure you un-register at some point.
//register
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(closeWebView) name:UIApplicationDidEnterBackgroundNotification object:nil];
//un-register
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationDidEnterBackgroundNotification object:nil];

Resources