Launch Main app from MenuBar app - swift

I've managed to create an Application and I don't want it to be on the Dock until a user clicks the MenuBar Item, then it launches the app and if a user quits the Main app, the menubar Item still remains.

Ok after days of research, I finally figured how to do it.
Swift 2.3
func toggleApp(sender: AnyObject) {
if self.window!.visible {
self.window.orderOut(window)
NSApplication.sharedApplication().setActivationPolicy(NSApplicationActivationPolicy.Accessory)
} else {
NSApplication.sharedApplication().setActivationPolicy(NSApplicationActivationPolicy.Regular)
self.window!.makeKeyAndOrderFront(nil)
NSApp.activateIgnoringOtherApps(true)
}
}
And this is for keeping the Menubar when the user quits(CMD Q) the app:
func applicationShouldTerminate(sender: NSApplication) -> NSApplicationTerminateReply {
// Cancel terminate if pref set
self.window.close()
NSApplication.sharedApplication().setActivationPolicy(NSApplicationActivationPolicy.Accessory)
return NSApplicationTerminateReply.TerminateCancel
}
Hope it helps someone.

in Swift 5:
func toggleApp(sender: AnyObject) {
if self.window.visible {
self.window.orderOut(window)
NSApplication.shared.setActivationPolicy(NSApplication.ActivationPolicy.accessory)
} else {
NSApplication.shared.setActivationPolicy(NSApplication.ActivationPolicy.regular)
self.window!.makeKeyAndOrderFront(nil)
NSApp.activate(ignoringOtherApps: true)
}
}

Related

Dismiss In-App AppStore rating in UITests in Swift

Hello dear developers,
I'm currently stuck due to a problem with In-App AppStore rating (SKStoreReviewController).
Here is the situation, I've a screen "FirstScreen" with a button. When I tap on it, I'm going to the next screen "SecondScreen" and an in app alert for AppStore rating pop over.
I'm trying to find a solution for my UITests in order to dismiss this Alert.
I tried many solutions but I'm looking for one which do not depends on string (I don't want to localize the content of this Alert):
override func setUp() {
app = XCUIApplication()
app.launch()
addUIInterruptionMonitor(withDescription: "System Dialog") { (alert) -> Bool in
let allowButton = alert.buttons.element(boundBy: 1)
if allowButton.exists {
allowButton.tap()
}
}
}
I also tried to add an interaction ("app.swipeUp()") when I'm coming to "SecondScreen" in order to trigger this handler.
I've also tried another solution, as I know when this alert will be triggered:
let dismissButton = XCUIApplication(bundleIdentifier: "com.apple.springboard").buttons.element(boundBy: 1)
if dismissButton.exists {
dismissButton.tap()
}
No one worked and I'm still stuck :(
Does anybody found a solution in order to dismiss this alert ?
Thanks
Swiping up doesn't work but ironically swiping down does. Here is a very simplistic example
import UIKit
import StoreKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(2)) {
SKStoreReviewController.requestReview()
}
}
}
import XCTest
class UITests: XCTestCase {
override func setUp() {
continueAfterFailure = false
}
func test() {
let app = XCUIApplication()
app.launch()
sleep(5)
app.swipeDown()
sleep(3)
}
}

Get Notified When User Starts to Drive (CoreMotion)

I would like to send a notification to the user whenever he/she starts driving using CoreMotion. I can use CoreMotion to see what the user is doing while my app is on like so...
let activityManager = CMMotionActivityManager()
override func viewDidLoad() {
super.viewDidLoad()
activityManager.startActivityUpdates(to: .main) { (activity) in
guard let activity = activity else {
return
}
if activity.automotive {
print("Driving")
}
if activity.stationary {
print("Not Moving")
}
}
}
}
But how would I be able to detect the change to activity.automotive in the background to send a notification to the user even if my app is not on?

Detect "screenshot" press while in background on Apple Watch

I have followed this answer to make my app detect when the crown and side button are pressed at the same time. This works for me, but only when the app is in the foreground. My app uses an HKWorkoutSession to stay running in the background, but it does not detect the press of the two buttons. I need the app to detect the pressing of both buttons in the background for my app to work properly.
My code for setting up the workout session is:
func configureWorkout() {
configuration.activityType = .walking
configuration.locationType = .unknown
do {
session = try HKWorkoutSession(healthStore: store, configuration: configuration)
session!.delegate = self
session!.startActivity(with: dateManager.getDate())
}
catch let error as NSError {
fatalError("*** Unable to create the workout session: \(error.localizedDescription) ***")
}
}
The code I have so far to detect the buttons being pressed is:
func workoutSession(_ workoutSession: HKWorkoutSession, didGenerate event: HKWorkoutEvent) {
if(event.type == HKWorkoutEventType.pauseOrResumeRequest) {
print("Detected Press")
}
}
Thanks!

How to check notification permissions on the main thread in swift?

I've got a function in my code to check if we can have permission to display a UILocalNotification.
open func hasPermission() -> Bool {
if let permissions = UIApplication.shared.currentUserNotificationSettings {
if permissions.types.contains(.alert) {
return true
}
}
return false
}
This code has triggered a warning in Xcode 9:
UI API called from background thread:
UIApplication.currentUserNotificationSettings must be used from main
thread only
How do I fix this? I know there is the DispatchQueue.main.async method, just not sure how to implemented that.
You can do it like this.
DispatchQueue.main.async {
if hasPermission() {
//
}
}

OS X app doesn't launch new window on dock icon press in Swift

I am making a Mac app in Swift, and running into a problem. When my app is first launched from the terminated state, it automatically launches a new window. But if the user Xs out of my app (with the red X icon) instead of quitting it, then hits the app icon of my app, a new window doesn't automatically open.
How can I make my Mac app launch a new window every time the dock icon is hit, as long as there isn't already a window of my app open?
Add this to your App Delegate:
func applicationShouldHandleReopen(theApplication: NSApplication, hasVisibleWindows flag: Bool) -> Bool {
if !flag {
for window: AnyObject in theApplication.windows {
window.makeKeyAndOrderFront(self)
}
}
return true
}
Don't forget to put
lazy var windows = NSWindow()
to somewhere at AppDelegate
and then implement
func applicationShouldHandleReopen(theApplication: NSApplication, hasVisibleWindows flag: Bool) -> Bool {
if !flag {
for window: AnyObject in theApplication.windows {
window.makeKeyAndOrderFront(self)
}
}
return true
}
Like #Owlswipe wrote