Custom URL Scheme for Settings on iOS 10? - settings

Any Idea what happened to the Setting's Custom URL Scheme on iOS 10?
Is Apple still giving acess to third-pary apps to launch iOS Settings from the app via URL Scheme on iOS10? The Old URL scheme are not working anymore!

None of the previous methods for launching the root "Settings" app on iOS 8+ were officially supported by Apple, so unfortunately we can't rely on them. It's also possible that apps that relied on the undocumented behaviors could be rejected during App Store review, even if others have been approved--even if the same app had been previously approved!
I've been unable to discover any workaround either, so it seems your choices are:
Open the app-specific URL (as detailed in many places, including #alvin-varghese 's answer above), and then ask the user to navigate backwards. (A terrible user experience, since it involves the user knowing to scroll up from the app list into the main settings sections.)
Use an instructional screen or alert in your app to educate users on how to find it themselves. (Not much better, but at least aren't dropped into an unfamiliar context with no waypoints.)
There doesn't seem to be an officially supported way of making this happen in iOS 10, and as you pointed out, it seems like the old ways (adding prefs scheme to your Info.plist file and using openURL(_:)) do not work any more.

From iOS 10 some of the things are changed,
So, for something like bluetooth you need to write below lines of code,
Swift 3.0 :
func openBluetoothSettings(){
let urlBTSet = URL(string: "App-Prefs:root=Bluetooth")
let objApp = UIApplication.shared
objApp.openURL(urlBTSet!)
}
Objective-c
-(void) openBluetoothSettings{
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:#"App-Prefs:root=Bluetooth"]];
}
So, In above code what they have changed is string need to add "App-Prefs:root=Bluetooth" (This the example of opening bluetooth settings)
Don't forgot : 'Goto taget -> info -> URL Types -> Add "prefs" in URL Schemes'

Use this one, it works.
if let url = URL(string: UIApplicationOpenSettingsURLString) {
UIApplication.shared().open(url, options: [:], completionHandler: nil)
}

Related

Programmatically change order of full screen apps on macOS with AppKit

I’m trying to build a macOS utility that will allow me to programmatically change the order of full screen apps on my machine.
For example, let’s say the full screen apps on my machine are currently ordered as follows from left to right:
Chrome
iTerm
Xcode
I want to be able to call a method in AppKit to say something like “Move Xcode from full screen index 2 to index 0”. However, I can't identify an AppKit API that will help me do this.
NSScreen only gives the physical displays, not the full screen apps / spaces
NSApplication only gives the list of my app's windows
CGWindowListCopyWindowInfo looked promising, but it doesn't have information about the order of full screen apps. It also doesn't allow me to get a NSWindow object to have any hope of changing the order
Is what I'm trying to do even possible with AppKit?
Thank you!
Spaces (desktops and fullscreen apps are both just spaces) are a feature of the system Window Manager and only manageable by the user through the app Mission Control.
Of course, the Window Manager needs to expose an API for management, otherwise how would Mission Control interact with it? But that API is not public.
Reverse engineered headers for those private APIs can be found online, e.g.
https://github.com/NUIKit/CGSInternal
With those headers in place, you can write code like this:
#import "CGSInternal/CGSSpace.h"
CGSSpaceID activeSpace =
CGSGetActiveSpace(_CGSDefaultConnection());
NSLog(#"activeSpace: %zu", activeSpace);
CFArrayRef spaceArray =
CGSCopySpaces(_CGSDefaultConnection(), kCGSAllSpacesMask);
NSLog(#"allSpaces: %#", (__bridge id)spaceArray);
But the usual warnings apply here:
You cannot commit code using private APIs to Apple's App Store. There is no official documentation, all that is known about that API has been reversed engineered and may not always be correct. As the API is not public, Apple can change it at any time without any previous warning and thus your working code could break with every system update.

Need to convert a legacy safari extension into Safari App Extension. Searching for documentation, starting steps and tutorials on Xcode

I have a legacy safari extension which I need to convert into Safari App Extension to submit into Extension Gallery. I am new to Xcode therefore, not familiar with it's build and run process. I tried looking into official documentation from developer.apple.com but it is so abstract.
Why do we need to create a parent app in Xcode before creating a
safari extension target?
If so what parent app template should I
choose? Cocoa App?
Where I can find starter tutorials on Xcode?
What is the submission process to Extension Gallery?
How can add the extension under development to my safari through xcode for testing?
I heard they need the URL for extension to approval, when we are submitting extension through developer account why to host it on URL?
Any documentation or answers to the above questions would be very helpful. Thank you.
On 2. and 3, I had the same struggles - I wrote up a tutorial on basic style sheet injection in Safari App Extensions here: https://ulyngs.github.io/blog/posts/2018-11-02-how-to-build-safari-app-extensions/
I'm converting the legacy safari extension to safari app extension too and have some answers for your questions:
Because app extension is more as functional extension then safari browser extension and could bring more features to you. And as per Apple says: safari app extension gives more communication and data exchange between Safari and your native app, docs.
But I have no more ideas if you only want an extension for safari why this is only way to do extensions.
Yes, you should use the Cocoa App template. If you don't need the window for your app, you can remove it simply in Main.storyboard or make app as a "service".
A lot of docs from Apple I've read but understood a bit then expected. So I found some youtube channels (they are 2 or more years old but some things seems don't changed) Some vieos here and the Osx Dev Daily playlist on this channel. And of course official swift docs if you select swift for your app as PL.
I haven't read about this, but think it must be submitted with your Cocoa App.
First of all you should to run your app target and only after this you should run your extension target and choose "Safari" in showed window to run in. If you have no the signing at the moment so ensure to enable "Allow unsigned extensions" in Development > Allow unsigned extensions in Safari app.
Don't meet this info, could you share it, pls? (sry, don't have enough knowledges)
Hope, it helps to you!
P.S. also recomend to see the converting docs, but it may be insufficient for converting :)
EDIT: it's seems to be incorrect to remove app window or change the default menus created by Cocoa App template for app submit for App Store. Some people got negative decision of app submit because of menus changes of redundant items or app have poor functionality or has not it at all. So consider to read the submit docs.
Please, share your experience when you'll have success app submit!
EDIT 2: Today I found template in Xcode 10.1 that can be used for Safari Extensions directly. It is as previous workflow (template Cocoa App + add extension target) but there is safari extension target already included
The app window and menu is simplified for developers:
So you don't need work with your app and you can concentrate on extension only.

AXUIElementCopyAttributeNames returns cannotComplete in Cocoa App but works well in playground

I'm trying to build an utility in navigating to any visible & enabled ui-element without mouse or trackpad, so I have to enumerate those elements first.
I did some research and found maybe Accessibility APIs would help me to reach my goal. Then I tried them in playground as below :
//...
let key: String = kAXTrustedCheckOptionPrompt.takeUnretainedValue() as String
let options = [key: true]
let enabled = AXIsProcessTrustedWithOptions(options as CFDictionary)
if !enabled {
print("Not permitted")
NSApp.terminate(nil)
}
//...
let element = AXUIElementCreateApplication(pid as! pid_t)
var ans : CFArray?
let e = AXUIElementCopyAttributeNames(element, &ans)
if e == .success, let names = ans as? [String] {
print(names)
}
//...
It works well in playground. Then I created a new Cocoa App, copied codes above into it, ran it in debug mode, and AXUIElementCopyAttributeNames return an AXError - cannotComplete.
It's very sure Xcode is enabled in System Preferences > Security and Privacy > Privacy > Accessibility. AXIsProcessTrustedWithOptions always returns true seems that it's not an issue of permission.
How can I make it works? Did I miss any necessary setting?
I'm not good in English, sorry about that.
I've solved this issue by turning off App Sandbox. I'm still curious why there is not accessibility entitlement in sandbox. Given that I have no plan to put my app in Mac App Store, to turn off App Sandbox is a solution for me.
Thanks everyone.
"With App Sandbox, you can and should enable your app for accessibility, as described in Accessibility Programming Guide for OS X. However, you cannot sandbox an assistive app such as a screen reader, and you cannot sandbox an app that controls another app."
Excerpt from https://developer.apple.com/library/archive/documentation/Security/Conceptual/AppSandboxDesignGuide/DesigningYourSandbox/DesigningYourSandbox.html
Playgrounds are not sandboxed and that is why it worked there.

Xamarin MediaMager notifications on Android

I use the following code to start playing a local audio file. To my disappointment, no notification is shown on my Android emulator. After some digging, I notice that the Android MediaNotificationManager has all the code commented out.
I can see from a few other on GitHub, that other people does seem to have notifications (ironically, a few people seem to have problems getting rid of them - Example), so what do I need in order to get it?
IMediaFile mediaFile = new MediaFile(playRequest.Path, MediaFileType.Audio, ResourceAvailability.Local);
mediaFile = await CrossMediaManager.Current.MediaExtractor.ExtractMediaInfo(mediaFile);
await CrossMediaManager.Current.Play(mediaFile);
CrossMediaManager.Current.MediaNotificationManager.StartNotification(mediaFile);
CrossMediaManager.Current.MediaNotificationManager.UpdateNotifications(mediaFile, MediaPlayerStatus.Playing);
I found a reason. Notifications on Android require an Icon. By inspecting the source code of MediaNotificationManager, I found that on Android it actually handles notifications in a completely other class: MediaNotificationManagerImplementation found in MediaSession.
There, I also learned that it will look for an icon of type Android.Graphics.Bitmap in the property Art on the metadata. Curiously, the property ArtUri is not used for anything.
If this property is null, it will look for a drawable in resources, with the name xam_mediamanager_notify_ic. If none is found, it will use the application icon.
Now, this solves all my needs for Android. However, it's handled quite differently on other platforms, and I've yet to find out how to set the art on UWP (and I've not tested iOS yet).

AXIsProcessTrustedWithOptions doesn't return true even when the app is ticked in accessibility

As this question answered, I use AXIsProcessTrustedWithOptions with no option to test if my app has been enabled in the accessibility panel. If not, prompt the window to let users to enable it. There is button bound to this test call as well, so users don't need to close the UI and reopen it.
But sometimes, even after a user enables the app, AXIsProcessTrustedWithOptions still returns false. When I check the sqlite database, it shows my app as "kTCCServiceAccessibility|com.abc.def|0|1|1||". The first 1 digit indicates it has been allowed apparently. But the api call still returns false. At this point, if I close the UI, the app is unticked in the accessibility panel which causes a loop so users can never pass this step.
Another thing is this app is actually a version 2 of the previous app. But the user did replace the bundle with the v2 one. Not sure if this is related.
Any idea why this would happen?
NSDictionary *options = #{(id)kAXTrustedCheckOptionPrompt: #NO};
BOOL accessibilityEnabled = AXIsProcessTrustedWithOptions((CFDictionaryRef)options);
if (!accessibilityEnabled) {
NSString *urlString = #"x-apple.systempreferences:com.apple.preference.security?Privacy_Accessibility";
[[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:urlString]];
}
Update: In Xcode, Signing & Capabilities, make sure you have selected a Team and Signing Certificate.
Original answer:
I experienced this when developing an app on macOS 10.14.5 in Xcode trying both AXIsProcessTrusted and AXIsProcessTrustedWithOptions .
After wasting a lot of time trying all sorts of things, including different options for AXIsProcessTrustedWithOptions, logging out/in, rebooting, praying, and crying, I eventually shut down my machine and powered it back on in frustration. Then it worked. Hopefully nobody else has this same experience.

Resources