How to use system functionality programmatically via swift? - swift

If we look on hotkeys/shortcuts of the macOS, we can find there a lot of functionality. Some functionality is assigned to hotkeys, some is not.
As example:
make screenshot(cmd+shif+F5)
or to show desktop (hide all apps) (F11)
and lot of other built-in into the OS functions:
Question is the following: how to use this functionality from my code without using of hotkeys pressing imitation?
The Goal is do not write custom code in case of such functionality already excist in OS.
I have found only how to open some sort of system preferences, maybe this is direction that I need to go, but I didn't found any details via google.
import Cocoa
// Open Siri prefs
NSWorkspace.shared.open(URL(fileURLWithPath: "/System/Library/PreferencePanes/Speech.prefPane"))
// Open Siri prefs with another way
NSWorkspace.shared.open(URL(fileURLWithPath: "x-apple.systempreferences:com.apple.preference.speech"))
// Open System Preferences window
NSWorkspace.shared.open(URL(fileURLWithPath: "x-apple.systempreferences:com.apple.preference"))

The area you are looking at is System Services, and actually there is no one answer on your question, because some of those items available via own API, some of them are private macOS features, some of them available via actually services.
You can start your findings with:
BOOL NSPerformService(NSString *serviceItem, NSPasteboard *pboard)
and with Services Implementation Guide, which depicts details of that.
The other mechanism to use those things was AppleScript... very wide area.

Related

Cannot find UIDocumentPickerViewController in scope

I am completely new to iOS or Mac development, and I am trying to implement opening and reading files in an app for MacOS. By default I had my app use SwiftUI. Looking up how to implement such a functionality using SwiftUI I saw suggestions to use UIDocumentPickerViewController. However I cannot find a proper documentation as to how to use it in practice. Apple's documentation page is not informative at all -- it doesn't provide any information as of how to actually use this class.
Trying to follow some examples I found elsewhere on the Internet, I am now stuck with getting Cannot find UIDocumentPickerViewController in scope compilation error. I have tried importing UIKit, AppKit, CoreServices, MobileCoreServices, Cocoa but nothing seems to help -- extending the class as described in another StackOverflow answer just fails with the same compilation error.
How do I properly use UIDocumentPickerViewController, or how do I implement the same functionality using some other method if this one is wrong?
Apparently UIDocumentPickerViewController is not available when building for Mac OS X, and NSOpenPanel seems to be a way to get the necessary functionality.

Observing System Volume Changes OSX - Swift

I'm trying to execute a method when the system volume changes.
I've tried using
DistributedNotificationCenter.default().addObserver(self,selector: #selector(volumeChanged(_:)),name: NSNotification.Name(rawValue: "com.apple.sound.settingsChangedNotification"),object: nil) but it didn't work.
Well, it does work. But only if the System Preferences app is open.
What's the right way to accomplish this task?
Ps: note that it's on MacOS, not iOS
After trying countless ways I found a nice workaround: instead of searching for a probably non-existent notification, I try to get the physical key-press event.
As the media keys are not sending a normal CGEvent I came up with this solution: Capture OSX media control buttons in Swift
Note that the TouchBar simulates such a key event, so any app that you'll write using this method will also work for those MacBook models which have the TouchBar.
It's probably not the ideal solution, but it works. If anyone knows a better way please let me know.

How to detect keystrokes globally in Swift on macOS?

Here is what I tried:
NSEvent.addGlobalMonitorForEvents(matching: [.keyDown]) { (event) in
print(event.keyCode)
}
Unfortunately, it does not print anything.
And no, it's not a duplicate of this, that question is about modifier keys, my question is about keystrokes.
Looks like the "duplicate" mark got removed, but so has the answer that I kludged into the comments section. So, for posterity:
The reason this doesn't work is because global monitors for .keyDown events require more permissions than some of the other event handlers, including the one that somebody thought this was a duplicate of. This is mainly because global .keyDown monitors can be used for nefarious purposes, such as keyloggers. So there are additional security measures in place to make sure we're legit:
1) Your app needs to be code-signed.
2) Your app needs to not have the App Sandbox enabled, and:
3) Your app needs to be registered in the Security and Privacy preference pane, under Accessibility.
The third one of these things has to be enabled by the user, but you can nudge them in that direction with this code:
let options: NSDictionary = [kAXTrustedCheckOptionPrompt.takeUnretainedValue() as String : true]
let accessEnabled = AXIsProcessTrustedWithOptions(options)
if !accessEnabled {
print("Access Not Enabled")
}
This will prompt the user, giving him/her the option to automatically open the appropriate preference pane where the user can allow your app to control the computer via the Accessibility API, which, assuming your app is signed and not sandboxed, will allow your global .keyDown monitor to work.
if you only want global hotkey support all this is unnecessary (and not all random key or mouse events) you can do that easily with the hotkey API. look at e.g. PTHotkey :)
or a newer api .. seee also: How to implement shortcut key input in Mac Cocoa App?

How can I do Junit tests for Google Maps in Android?

I am using the Google Maps API in an Android project and now I need to test it using JUnit if possible. (I am somewhat new to both JUnit and Google Maps.) I have been scouring the internet but was unable to find anything.
The map view has dots/pins for stations and when I tap one I get a balloon popup with the name and other info. Then when I tap the balloon I get a new view with information about the location and actions to perform such as navigate.
What I want to know is, is it possible to write a JUnit test case that finds all these dots/pins, taps them, and verifies information on the new view that pops up? Additionally, I would like to change/mock the location that the GPS has and see what happens if I try to, say navigate overseas or something like that.
I do have a list view of the same locations which I will test as well, but I would like to know if there is a way to test the map view.
I would prefer an automated test script like what JUnit provides. If this is not possible with JUnit what is the best alternative?
I am working with Android 4.0 and using Eclipse.
Any help would be greatly appreciated.
In case anyone wants to know after much searching I finally found something that can test Google Maps. Things such as zoom level and I believe tap pin (method is called tapMapMarkerItem()) are supported. I have not tested the pin tap yet tho.
Apparently the awesome Robotium does not support map testing by itself. Nicholas Albion was nice enough to create an extension to provides testing support for maps on Android. Thank you so much Nicholas!
So here it is:
1. Download the Robotium jars from robotium.org (I found this helpful http://www.vogella.com/articles/AndroidTesting/article.html - by Lars Vogel)
2. Download the extension from https://github.com/nalbion/robotium-maps

adding python interpreters programmatically

Is there a simple way to add and change interpreters using the Pydev plugin interface? I'm running pydev 1.6.1 and I'd like to be able to add and use a given interpreter based on a list of available interpreters in my environment.
Right now I can see the PythonInterpreterManager has a createInterpreterInfo call, but that doesn't seem to do anything. Looking at the source for pydev, it seems like I have to actually work with the preference pages to keep track of all of them.
Is there a simpler set of functions I can call to add these?
PythonInterpreterManager manager = (PythonInterpreterManager)PydevPlugin.getPythonInterpreterManager(true);
IInterpreterInfo info = manager.createInterpreterInfo(execPath, new NullProgressMonitor());
manager.addInterpreterInfo(info);
I can already do the above, but that only caches it, but doesn't display it as a valid interpreter option in the preferences.
I've even tried doing reflection to add these without much luck. I can call addNewInput on the editor as the Add button does, but then it says it doesn't have any knowledge of that interpreter. I've tried creating a popup preferences page and adding the values to the various members via reflection as getNewInput() would, but still don't see any more options in the preference page. I'm not sure if this is because I'm missing something or the popup preference page I make is totally unrelated to the page that pops up using the Window->"Preferences" pulldown.
The API is something as:
IInterpreterManager iMan = PydevPlugin.getPythonInterpreterManager(true);
IInterpreterInfo interpreterInfo = iMan.createInterpreterInfo("c:/python/python.exe", monitor, false);
iMan.setInfos(new IInterpreterInfo[]{interpreterInfo}, null, null);
Note that if you have 'manager.addInterpreterInfo' in there, you probably have an old version of PyDev... (and at that call you set all the interpreters available, so, if you want to keep some configuration, you should query it and add them back).
You can use: org.python.pydev.editor.codecompletion.revisited.javaintegration.AbstractWorkbenchTestCase.createPythonInterpreterManager(NullProgressMonitor) as a reference.