Modify accessibility settings on macOS with Swift - swift

I'm writing a macOS app in swift and want to be able to enable text to speech for a user on their computer programmatically once they download my app. I'm not sure what commands to use to reconfigure a user's settings and ask for permission to change their accessibility settings. Does anyone know how to do this or where to find documentation that explains how to do this?

Apple requires that you ask explicity for the accessibillity settings. From sierra it is not possible to set this over the Database anymore. So the User has to click and enable your app for accessibility.
public func checkAccess() -> Bool{
//get the value for accesibility
let checkOptPrompt = kAXTrustedCheckOptionPrompt.takeUnretainedValue() as NSString
//set the options: false means it wont ask
//true means it will popup and ask
let options = [checkOptPrompt: true]
//translate into boolean value
let accessEnabled = AXIsProcessTrustedWithOptions(options as CFDictionary?)
return accessEnabled
}

Related

MacOS Cocoa: Is it possible to modify/add my own button or modify alpha of third party app's window?

I am trying to add my own button on top of the window of third party app's windows OR modify the alpha (kCGWindowAlpha I think) of third party app windows in MacOS. I don't need this app to be sandboxed.
I have been able to get details of third party windows using:
#IBAction func printWindows(_ sender: NSButton?) {
let runningApps = NSWorkspace.shared.runningApplications
print("runningApps: \(runningApps)")
if let info = CGWindowListCopyWindowInfo(.optionAll, kCGNullWindowID) as? [[ String : Any]] {
for dict in info {
print("dict: \(dict)")
print("type: \(type(of:dict))")
print("kCGWindowOwnerName: \(dict[kCGWindowOwnerName as String])")
}
}
}
This gives me a lot of details of all the app windows opened. However, I am unable to figure out how I can use that info to modify the third party window. Can you direct me in the right direction on how I can achieve something like this?
So far, I have seen this code which lets me get screenshots of windows:
https://github.com/sassman/son-of-grab/blob/main/Controller.m
Is this something which Services are for? My reading of Services indicates that it's inly meant for clipboard/pasteboard stuff:
https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/SysServices/Articles/providing.html
Is this something which can be achieved via Accessibility APIs?

Disable copy-past premission in iOS 16.1

as you may know, iOS 16 introduced a bug that when your app use UIPasteboardit keeps asking for permission every time. This annoying alert is gone after 16.1 as I heard, but still see it. User must go to the app setting in the iOS setting and change Paste from other apps to allow.
Is there anyway to do it on app that user doesn't need to do those crazy steps? Otherwise we should inform every user to do that to get rid of that alert.
Would be so grateful if you can give me a good hint to fix it. Maybe some privacy key on info.plist?
here is my simple code to read from clipboard
private func getURLFromClipboard() {
let pasteboardString: String? = UIPasteboard.general.string
if let string = pasteboardString {
if validateUrl(urlString: string as NSString) {
presentShareURL(url: string)
}
}
}

typeText() is typing inconsistent characters

I'm beginning to dip my toes into Swift alongside writing UI tests and am having a problem with typing text into a textField. Below is the code:
func testLoginUsernameField() {
let app = XCUIApplication()
app.launch()
let username = "testusername2"
let usernameField = app.textFields["username_field"]
XCTAssertTrue(usernameField.exists)
usernameField.tap()
usernameField.typeText(username)
XCTAssertEqual(usernameField.value as! String, username)
}
The problem occurs when I do usernameField.typeText(username). My text continues to write tstusername2 rather than the testusername2.
This issue happens on the simulator when the Hardware Keyboard is enabled.
Disable the hardware keyboard via the menu
Go to I/O -> Keyboard -> Uncheck "Connect Hardware Keyboard" or use the shortcut ⇧⌘K.
Disable the hardware programmatically
If you'd like to disable the hardware keyboard for your Scheme, no matter what simulator you run, refer to this StackOverflow post. I attempted to use other methods to disable the hardware keyboard via the App Delegate but had no luck.

Programmatically minimize all windows or besides my Cocoa application?

I haven't been able to find anything about this in Swift. Is there a way to programmatically make my application minimize all other windows open in the background, or even just minimize Safari? I basically want my application to run against the desktop, without any clutter in the background. Is there a way to programmatically do this for a Cocoa app? I'm pretty new to swift, so any help would be appreciated.
You can use api on NSWorkspace which allows you to hide all visible app in the background.
You can find more about NSWorkspace here: link
Hides all applications other than the sender. This method must be called from your app’s main thread.
NSWorkspace.shared().hideOtherApplications()
If you only want to hide Safari,
let appPath = NSWorkspace.shared().fullPath(forApplication: "Safari")
let identifier = Bundle.init(path: appPath!)?.bundleIdentifier
if let bundleID = identifier {
let runningApps = NSRunningApplication.runningApplications(withBundleIdentifier:bundleID )
if !runningApps.isEmpty {
runningApps.first?.hide()
}
}

NSUserDefaults and App Groups in WatchOS 2

I am trying to use NSUserDefaults to access an object I save in my NSUserDefaults.
I have looked everywhere but I must be missing something. Hoping anyone can help me out.
Heres what I have done.
I use Xcode 7.1
My bundle identifier is "com.mycompany.myapp"
I added a watchkit app (new target)
Bundle identifier for watch target is "com.mycompany.myapp.watchkitapp"
Bundle identifier for extension target is "com.mycompany.myapp.watchkitapp.watchkitextension"
I enabled App groups in all 3 targets.
App Group ID for all 3 targets is: "group.com.mycompany.myapp"
All 3 steps are checkmarked in the App Groups section
I use NSUserDefaults.standardUserDefaults() in all cases but the one where I need the object to be accessible from the watch.
In this case I use:
if let userDefaults = NSUserDefaults.init(suiteName: "group.com.mycompany.myapp")
{
userDefaults.setObject(myDate, forKey: UserDefaults.DateKey.rawValue)
userDefaults.synchronize()
}
I can reload this data using this code:
let mydefaults = NSUserDefaults(suiteName: "group.com.mycompany.myapp")
mydefaults!.synchronize()
let myDict = mydefaults!.dictionaryRepresentation()
for entry in myDict
{
print("ENTRY: \(entry)")
}
Works just fine, but executing the same code in awakeWithContext in my watch extensions InterfaceController just prints a few of the default keys. Not the one I set myself.
I basically just need to access a date stored in the iphone app.
Any idea what I am doing wrong?
You can no longer use app groups sharing with watchOS 2. At least I haven't found any solution yet. It is my understanding that you now have to use WatchConnectivity.
https://forums.developer.apple.com/thread/3927