application:openURL not triggered - objective-c

I have a problem implementing - (BOOL)application:openURL and using UIDocumentInteractionController for exporting PDF file from an application to another.
(1) Target application does nothing but just display URL of the imported PDF file (in a label).
here is the code in AppDelegate.m:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions: (NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.viewController = [[ViewController alloc] initWithText:#"No file is imported."];
self.window.rootViewController = self.viewController;
[self.window makeKeyAndVisible];
return YES;
}
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication: (NSString *)sourceApplication annotation:(id)annotation
{
if (url != nil)
{
[self.viewController handleOpenURL:url];
return YES;
}
else
{
[self.viewController handleOpenURL:[NSURL fileURLWithPath:#"AppDelegate.h"]];
return NO;
}
}
Method "handleOpenURL" just take the url and put in a label in the view controller and show an alert:
- (void)handleOpenURL:(NSURL *)fileURL
{
_text = [fileURL absoluteString];
self.lblText.text = _text;
UIAlertView * alert = [[UIAlertView alloc] initWithTitle:#"Alert" message:_text delegate:self cancelButtonTitle:nil otherButtonTitles:nil, nil];
[alert show];
}
(2) In source application, I simply use UIDocumentInteractionController to list "Open In" options (my target application appears well in the list)
Here is the code:
_docInteractionController = [UIDocumentInteractionController interactionControllerWithURL:[NSURL fileURLWithPath:attachmentFile]];
_docInteractionController.delegate = self;
_docInteractionController.UTI = [_extensionUTIs objectForKey:[[attachmentFile pathExtension] lowercaseString]];
BOOL opened = [_docInteractionController presentOpenInMenuFromRect:CGRectZero inView:self.view animated:NO];
(3) Problem:
- When I select the target application (from "Open In" list), simulator switches from source application to target application okay, but looks like application:openURL method is not invoked because the label keeps as initial (No file is imported.) and no alert view shows up.
Please advise me what could be wrong here ?
Thanks in advance.

I used these two methods for facebook integration to handle openURL...its working fine.
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url {
return [ [[HIFacebookConnect sharedGameObject] facebook] handleOpenURL:url];
}
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
return [[[HIFacebookConnect sharedGameObject] facebook] handleOpenURL:url];
}

Just want to mark my question as answered because I have already found the glitch.
Update: It was my fault when not including full file path when initiating UIDocumentInteractionController object.

Related

iOS13 application openUrl? (Obj-C)

How do you import files to your app on ios13?
Previously I could download a txt file in Safari and chose Copy to (app) and I would catch this in the app delegate open Url delegate. Doesn't work anymore.
The Copy To is still there in Safari, but it just dismissed Safari and nothing happens.
-- Edit:
Sorry, I was a bit unclear.
Previously, when downloading a file through another app (like Safari), the user could select to open this file in my app by tapping "Copy To (app)".
I would then catch this copy request through the appdelegate:
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options
{
[...]
}
This delegate is not called in iOS13, only iOS12 and below.
I have tried finding a way to catch the "Copy to" request from other apps to no avail. There seems to be a new way of handling these things through a SceneDelegate?
In projects having SceneDelegate.swift file, should implement scene:openURLContext method.
func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) {
print(#function)
print(URLContexts)
}
Output:
scene(_:openURLContexts:)
[
<UIOpenURLContext: 0x282fbca20;
URL: file:///private/var/mobile/Containers/Data/Application/A644621B-BD6C-443B-A9D1-A212EA59EE2E/Documents/Inbox/file.pdf;
options: <UISceneOpenURLOptions: 0x2823112c0;
sourceApp: (null);
annotation: (null);
openInPlace: NO>>
]
Reference: Migration from AppDelegate to SceneDelegate
Version for Objective C.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
NSURL *url = [launchOptions objectForKey:UIApplicationLaunchOptionsURLKey];
[[CommonController sharedInstance] handleExternalUrl: url];
return YES;
}
- (BOOL)application:(UIApplication *)app
openURL:(NSURL *)url
options:(NSDictionary<UIApplicationOpenURLOptionsKey, id> *)options
{
NSLog(#"application openURL: %#", url);
return [[CommonController sharedInstance] handleExternalUrl: url];
}
- (void)scene:(UIScene *)scene willConnectToSession:(UISceneSession *)session options:(UISceneConnectionOptions *)connectionOptions API_AVAILABLE(ios(13.0)){
NSSet *c = connectionOptions.URLContexts;
if(c && [c count] > 0)
{
NSURL *url = ((UIOpenURLContext*)[[c allObjects] firstObject]).URL;
[[CommonController sharedInstance] handleExternalUrl: url];
}
}
- (void)scene:(UIScene *)scene openURLContexts:(nonnull NSSet<UIOpenURLContext *> *)URLContexts
API_AVAILABLE(ios(13.0)){
NSURL *url = [[URLContexts allObjects] firstObject].URL;
[[CommonController sharedInstance] handleExternalUrl: url];
}

I'm trying to open a specific view controller when a user goes to a specific URL scheme

I'm programming in Objective-C and I know that I need to implement this function in my AppDelegate
-(BOOL)application:(UIApplication *)application
openURL:(NSURL *)url
I can't find any good sources for doing something like this, does anyone know how I'd be able to?
I found this, but the question was unanswered.
URL Scheme to open specific View with data
Any help would be greatly appreciated!
You have to check for the scheme type and decide based on it.
-(BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
{
self.window.rootViewController = [[PaymentResultsViewController alloc] initWithNibName:nil bundle:nil];
UIViewController *viewController = nil;
if ([url.scheme isEqualToString:#"app1scheme"])
{
viewController = [[Scheme1ViewController alloc] init];
}
else if ([url.scheme isEqualToString:#"app2scheme"])
{
viewController = [[Scheme1ViewController alloc] init];
}
else if (etc..)
{
etc...
}
self.window.rootViewController = viewController;
return YES;
}

how to pass self to function in other class in objective c

Hi I am new in development of iOS. I make class named socialClass.h
#import <Social/Social.h>
#import <Accounts/Accounts.h>
- (void)facebookSharingStatusCheckCall:(NSString *)url image:(NSString *)img status:(NSString *)text viewCont:(UIViewController *)uiVew;
- (void)facebookForIosSix:(NSString *)url image:(NSString *)img status:(NSString *)text viewCont:(UIViewController *)uiVew;
and in socialClass.m
- (void)facebookSharingStatusCheckCall:(NSString *)url image:(NSString *)img status:(NSString *)text viewCont:(UIViewController *)uiVew
{
if ([SLComposeViewController isAvailableForServiceType:SLServiceTypeFacebook]) {
NSLog(#"service available");
[self facebookForIosSix:url image:img status:text viewCont:uiVew];
} else {
// facebook for iOS 5 function will be called here
}
}
-(void)facebookForIosSix:(NSString *)url image:(NSString *)img status:(NSString *)text viewCont:(UIViewController *)uiVew
{
if([SLComposeViewController isAvailableForServiceType:SLServiceTypeFacebook]) {
SLComposeViewController *fbcontroller = [SLComposeViewController composeViewControllerForServiceType:SLServiceTypeFacebook];
SLComposeViewControllerCompletionHandler myBlock = ^(SLComposeViewControllerResult result){
if (result == SLComposeViewControllerResultCancelled) {
NSLog(#"Post Cancelled");
} else
{
NSLog(#"Post Done");
}
[fbcontroller dismissViewControllerAnimated:YES completion:Nil];
};
fbcontroller.completionHandler =myBlock;
//Adding the Text to the facebook post value from iOS
[fbcontroller setInitialText:text];
//Adding the URL to the facebook post value from iOS
[fbcontroller addURL:[NSURL URLWithString:url]];
//Adding the Image to the facebook post value from iOS
[fbcontroller addImage:[UIImage imageNamed:img]];
[uiVew presentViewController:fbcontroller animated:YES completion:nil];
}
else{
UIAlertView *alertView = [[UIAlertView alloc]
initWithTitle:#"Sorry"
message:#"You can't Post a Status right now, make sure your device has an internet connection and you have at least one Twitter account setup"
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alertView show];
NSLog(#"UnAvailable");
}
}
Now I call in mainViewController.h
#import "socialClass.h"
and in mainViewController.m
- (IBAction)facebookShareBtn:(id)sender {
[[socialClass facebookSharingStatusCheckCall:[[DataPassing sharedManager] pageURL ]
image:[[DataPassing sharedManager]
pageIMGurl]
status:[[DataPassing sharedManager] pageTEXT]]
viewCont:(UIViewController*)self];
}
When I use this below code with self it gives error. Definitely because there is no self view
[self presentViewController:fbcontroller animated:YES completion:nil];
so i put uiView in function and try to pass self from mainViewController. again error in mainview
How can I use this facebook from other calls function in mainviewcontroller. thx
[EDIT]
i declare socialClass.h in mainViewController and call the function in button
[socialClass facebookForIosSix:...]
This error is comming... after updating to (UIViewController*)self
OK, a couple of things need to change in you function definition.
First you need a - at the front not a +. The plus denotes a class method whereas the - is for an instance method. You are using this like an instance method.
Second you need to include MainViewController.h in your SocialClass.h file. Then name the function like...
- (void)facebookForIosSix:(NSString *)url image:(NSString *)img status:(NSString *)text viewCont:(MainViewController *)mainViewController;
Then in mainViewController you can run...
[socialViewController facebookSharingStatusCheckCall:#"url" image:#"hello.png" status:#"Posting from App" viewCont:self];
this should work fine.
EDIT
If you want to run the function fro multiple places then don't import MainViewController.h and define the function like...
- (void)facebookForIosSix:(NSString *)url image:(NSString *)img status:(NSString *)text viewCont:(UIViewController *)viewController;
then run it like...
[socialViewController facebookSharingStatusCheckCall:#"url" image:#"hello.png" status:#"Posting from App" viewCont:(UIViewController*)self];
TBH, I don't think you'll need to cast it at all but just to be safe you can.
EDIT
You haven't balanced your brackets...
- (IBAction)facebookShareBtn:(id)sender {
[socialClass facebookSharingStatusCheckCall:[[DataPassing sharedManager] pageURL ]
image:[[DataPassing sharedManager] pageIMGurl]
status:[[DataPassing sharedManager] pageTEXT]
viewCont:(UIViewController*)self];
}
This will work.

iOS 6 Preservation and Restoration without Storyboards

I've been trying without any luck to implement state restoration and preservation.
I'm not using storyboards. I have to be doing something wrong.
I set up the restoration identifier for every Nib file.
I know the state is being stored, but never restored properly. The last state shows for half a second and then it goes back to the main view. I've tried many things with no luck. Please help!
-(BOOL)application:(UIApplication *)application willFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
NSLog(#"will finish");
return YES;
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
self.viewController = [[[ViewController alloc] initWithNibName:#"ViewController" bundle:nil] autorelease];
navigator = [[UINavigationController alloc] initWithRootViewController:self.viewController];
self.window.rootViewController = navigator;
[self.window makeKeyAndVisible];
[navigator release];
NSLog(#"did finish");
return YES;
}
// As you can see, I started the process of saving and restoring application state.
// Also, I added the restoration identifier for every class that should be restored.
-(BOOL)application:(UIApplication *)application shouldRestoreApplicationState:(NSCoder *)coder
{
NSLog(#"restoring");
return YES;
}
-(BOOL)application:(UIApplication *)application shouldSaveApplicationState:(NSCoder *)coder
{
return YES;
}
-(void)application:(UIApplication *)application didDecodeRestorableStateWithCoder:(NSCoder *)coder
{
NSLog(#"restored");
//navigator = [[UINavigationController alloc] initWithRootViewController:];
isRestored = YES;
}
You should do your controllers initialization in application:willFinishLaunchingWithOptions: because restoration is done before application:didFinishLaunchingWithOptions: is called.
Check this answer.
Also you should programmatically assign restorationIdentifier to all controllers.

Can't return firstResponder status

Have set up my appDelegate to return a firstResponder status, but when I compile (it compiles fine), the console returns "Could not become the first responder" but doesn't tell why.
I have attached the code. Can you tell me what's wrong? Thanks in advance.
HypnosisterAppDelegate.m
#import "HypnosisterAppDelegate.h"
#import "HypnosisView.h"
#implementation HypnosisterAppDelegate
#synthesize window = _window;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
HypnosisView *view = [[HypnosisView alloc] initWithFrame:[[self window]bounds]];
[[self window]addSubview:view];
BOOL success = [view becomeFirstResponder];
if (success) {
NSLog(#"HypnosisView became the first responder");
} else {
NSLog(#"Could not become the first responder");
}
self.window.backgroundColor = [UIColor whiteColor];
[self.window makeKeyAndVisible];
return YES;
}
-(BOOL)canBecomeFirstResponder
{
return YES;
}
You've implemented canBecomeFirstResponder on HypnosisterAppDelegate, which is not a UIResponder sub-class. You then send becomeFirstResponder to your custom view (HypnosisView).
HypnosisView (not the HypnosisterAppDelegate) needs to do this:
-(BOOL)canBecomeFirstResponder
{
return YES;
}