I am opening the device settings page from my app.When I open through iPhone X(iOS11) and iPhone 8 it goes to app settings . But when I open through iPhone 8 Plus and iPhone SE it goes to home settings page.
I need to open home settings page of iPhone like iPhone 8 Plus(open home settings page) . I am running the below code.
UIApplication *application = [UIApplication sharedApplication];
NSURL *settingsURL = [NSURL URLWithString:UIApplicationOpenSettingsURLString];
[application openURL:settingsURL options:#{} completionHandler:^(BOOL success) {
if (success) {
NSLog(#"Opened url");
}
}];
My problem is, I created a new project and I ran this above code . Its working fine.And I can able to navigate to device home settings page in same iPhone X.
But when I run this code in my project in iPhone X it goes to app settings screen.I don't know where I missed.
Please help me if possible.
Thanks in advance.
Global Variable
UIApplicationOpenSettingsURLString
Used to create a URL that you can pass to the openURL: method. When you open the URL built from this string, the system launches the Settings app and displays the app’s custom settings, if it has any.
https://developer.apple.com/documentation/uikit/uiapplicationopensettingsurlstring?language=objc
This is from Apple official document. My guess is your app have its own setting page, that's why openURL function takes you to app's setting page instead of Setting home.
Related
I am experimenting with macOS xcode objective-C file handling - or having my app open files of a specific extension.
So far, I have used this doc to register file types (even though iOS and I'm using Mac, same process it seems) and that worked perfectly. That associates file extensions with my app and allows double-clicking of the files to launch my app.
Now I want to add handling of the file once it opens. I created a new Cocoa NSObject Subclass called FileOpen.
In my MainMenu.xib I created an Object (Blue Cube) and changed the class to FileOpen. I set it as delegate to File Owner. This was described in the selected answer to this stack question
Now, in FileOpen.m I have this - just to basically show a NSAlert when the file is opened:
- (void)applicationWillFinishLaunching:(NSNotification *)aNotification
{
NSLog(#"Application Finished Launching");
}
-(BOOL)application:(NSApplication*)sharedApplication openFile:(NSString*) fileName
{
[[NSAlert alertWithMessageText:#"Opening File"
defaultButton:#"OK"
alternateButton:nil
otherButton:nil
informativeTextWithFormat:#"Testing file opening handle code."] runModal];
return;
}
This all seems to work fine. If I run my app, I get the NSLog that the application finished launching. If I double-click a file, it runs the app and gives the NSAlert.
The problem I am running into is that my app has a splash screen. This shows until the user closes it and then the main app starts. If I disable my splash screen, the above all works fine as described. If I enable my splash screen, the NSLog saying application finished launching does run, after the splash screen, but then the application:openfile never runs (and no NSAlert).
I assume I need to add some code that waits for applicationWillFinishLaunching before running the
application:open file? Is there a way to wait until the application is fully initialized to be able to open/handle the file correctly? It seems that by having a splash screen is interrupting the application:openfile
Thanks to red_menace I was able to get this working. The key was moving the handling of my splash screen to the NSObject Subclass FileOpen. I did this by just adding a notification to open the splash screen in the FileOpen class instead of where it was originally invoked (the main view).
- (void)applicationWillFinishLaunching:(NSNotification *)aNotification
{
NSLog(#"applicationWillFinishLaunching");
[[NSNotificationCenter defaultCenter] postNotificationName:#"WhatsNewOpen" object:self];
}
-(BOOL)application:(NSApplication*)sharedApplication openFile:(NSString*) fileName
{
[[NSAlert alertWithMessageText:#"Opening Files"
defaultButton:#"OK"
alternateButton:nil
otherButton:nil
informativeTextWithFormat:#"Testing File Open"] runModal];
return;
}
Does UIApplication:openURL work?
NSString *iTunesLink = #"http://www.youtube.com/watch?v=TFFkK2SmPg4";
BOOL did = [[UIApplication sharedApplication] openURL:[NSURL URLWithString:iTunesLink]];
This does nothing.
I assume you're wanting to test a Custom URL Scheme. You will want to use canOpenURL to see if the URL can be opened first. canOpenURL returns a BOOL value indicating whether or not the URL’s scheme can be handled by some app installed on the device. If canOpenURL returns YES then you would continue to open the URL with openURL.
YouTube links open the YouTube app by default on iOS devices. This behavior is not yet testable on the new Apple TV as YouTube's app is not accessible in the tvOS beta.
Here's an example of how to use canOpenURL to see if Facebook is installed on an iOS device using its Custom URL Scheme:
Obj-C:
// Check if FB app installed on device
if ([[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:#"fb://"]]) {
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:#"fb://profile/355356557838717"]];
}
else {
// FB not installed
// Do something else
}
Swift:
// Check if FB app installed on device
if UIApplication.sharedApplication().canOpenURL(NSURL(string:"fb://")!) {
UIApplication.sharedApplication().openURL(NSURL(string:"fb://profile/355356557838717")!)
}
else {
// FB not installed
// Do something else
}
I'd anticipate that applications such as Facebook, and others, will implement their Custom URL Schemes in the same manner as their iOS counterparts.
I'm using the ServiceManagement framework to add a login item that will launch a Helper App, which will launch the main app whenever the user logs back in. The addLoginItem and disableLoginItem methods are called if the user selects or deselects "Launch at Login" with an NSButton of a switch-type:
//Add the Helper app as a login item
- (void)addLoginItem
{
NSLog(#"Enable login item");
if (!SMLoginItemSetEnabled((__bridge CFStringRef)kLoginHelperBundleIdentifier, true)) {
}
}
//Disable the Helper app as a login item
- (void)disableLoginItem
{
NSLog(#"Disable login item");
if (!SMLoginItemSetEnabled((__bridge CFStringRef)kLoginHelperBundleIdentifier, false)) {
}
}
The code for the helper app is rather simple...
- (void)applicationDidFinishLaunching:(NSNotification *)notification
{
[[NSWorkspace sharedWorkspace] launchApplication: #"My App"];
[[NSApplication sharedApplication] terminate:self];
}
The problem is that when the Main App is running, if a user repeatedly selects and deflects the 'Launch At Login' button, a second instance of the Main App will be launched. Whereas, what I want to happen is that the Main App will only be launched upon the user logging back in.
Upon looking at SMLoginItem.h, I saw that the documentation stated the following:
* #param enabled
* The Boolean enabled state of the helper application. This value is effective
* only for the currently logged in user. If true, the helper application will
* be started immediately (and upon subsequent logins) and kept running. If
* false, the helper application will no longer be kept running.
So, it seems as if the Helper App is being launched every time addLoginItem is called. Knowing that, I modified my Helper App to check if my main app is already running. If it is, then we will terminate the Helper App. Otherwise, we'll launch an instance of the Main App, and then terminate the Helper App.
- (void)applicationDidFinishLaunching:(NSNotification *)notification
{
if ([NSRunningApplication runningApplicationsWithBundleIdentifier:#"com.myCompany.MyApp"]){
[[NSApplication sharedApplication] terminate:self];
}
else {
[[NSWorkspace sharedWorkspace] launchApplication: #"My App"];
[[NSApplication sharedApplication] terminate:self];
}
}
However, if the user selects and deselects the "Launch At Login" button repeatedly, then a second instance of the Main App will be created. Does anyone have any idea on how to make sure a second instance of the Main App is not created by the Helper App if the user toggles "Launch At Login" multiple times?
EDIT The app is not being distributed through the Mac App Store, which is why I do not have code-signing or sandboxing enabled per the instruction in this tutorial.
The problem being that I had a few different copies of the application on my system (specifically, one on the desktop and on in the applications folder). Removing one of these application instances resolved my issue.
I have a Mac app with a preferences window. The preferences window is opened modally
-(IBAction)displayPreferencesWindow:(id)sender{
if (!pc) {
pc = [[PreferencesController alloc] initWithWindowNibName:#"PreferencesController"];
pc.delegate = self;
}
NSWindow *pcWindow = [pc window];
[NSApp runModalForWindow: pcWindow];
[NSApp endSheet: pcWindow];
[pcWindow orderOut: self];
}
In the preferences Window I have a button that opens the account preferences panel
- (IBAction)openSystemPrefs:(id)sender {
[[NSWorkspace sharedWorkspace] openFile:#"/System/Library/PreferencePanes/Accounts.prefPane"];
}
The problem is that the account preferences panel does not open in front of the actual Window. How can I achieve this?
This is kind of weird, and goes against the comments in the header, but try using this instead:
- (BOOL)openFile:(NSString *)fullPath withApplication:(NSString *)appName andDeactivate:(BOOL)flag;
From the comments there:
Open a file at some path. If you use the variant without the
withApplication: parameter, or if you pass nil for this parameter, the
default application is used. The appName parameter may be a full path
to an application, or just the application's name, with or without the
.app extension. If you pass YES for andDeactivate:, or call a variant
without this parameter, the calling app is deactivated before the new
app is launched, so that the new app may come to the foreground unless
the user switches to another application in the interim. Passing YES
for andDeactivate: is generally recommended.
So it sounds like your app should be deactivating (since you're calling a variant without the andDeactivate: parameter) but I would try explicitly using the variant with that parameter, just to be sure.
Empirically, it appears that the launched application will not activate if the launching application is presenting modal UI, at least not when using the NSWorkspace API. I was able to hack something up using AppleScript that appears to achieve the desired results:
- (IBAction)doStuff:(id)sender
{
[[NSWorkspace sharedWorkspace] openFile:#"/System/Library/PreferencePanes/Accounts.prefPane"];
dispatch_async(dispatch_get_global_queue(0, 0), ^{
NSString* s = #"tell application \"System Preferences\" to activate";
NSAppleScript* as = [[[NSAppleScript alloc] initWithSource: s] autorelease];
NSDictionary* error = nil;
if ([as compileAndReturnError: &error])
{
(void)[as executeAndReturnError: &error];
}
});
}
I dispatched it to the background queue because it takes a few hundred milliseconds to compile and run the AppleScript and it's a little conspicuous if done synchronously (the button stays highlighted longer than you expect).
If you were feeling really masochistic, you could probably get the script compiling phase out of it (i.e. quicker) by conjuring up the equivalent AppleEvents and sending them directly, but this appeared to achieve the desired effect, even while presenting modal UI in the launching application.
Im Linking to appstore from my app using
`NSString *iTunesLink = #"itms-apps://itunes.com/apps/companyname/";
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:iTunesLink]];
This works, but when returning to my app it's just a blank screen and I have to restart the app.
Am I missing some fundemanatal piece of code here
Try using a link with this format itms-apps://ax.itunes.apple.com/app/id123456789