Open instance of another Mac app in a subview in Swift? - swift

I I'm trying to open the photos app inside a subview in a macOS app. I have the following code that lets me open the Photos app using NSWorkspace but I wish to know how I can open this app inside a subview in another Swift app rather than opening the app in its original form.
import Cocoa
func openPhotos() -> Bool {
if let photosApp = FileManager.default.urls(
for: .applicationDirectory,
in: .systemDomainMask
).first?.appendingPathComponent("Photos.app") {
return NSWorkspace.shared.open(photosApp)
}
return false
}

Related

Trying to delete Realm object in Swift UIKit app and getting an error "Object has been deleted or invalidated."

I'm sorry if it seems like a duplicate, but I've read other topics about that and haven't found a solution.
What I'm trying to achieve:
Save a photo to Realm and use the Results<PhotoModel.self> array to display those photos in a TableView.
The whole app idea:
Client for Unsplash API that shows photos in collectionView - MainVC - where you can open any photo in a separate ViewController - DetailedVC - and then you can mark it as Favorite and it could be found using tabBar in another ViewController - FavoriteVC in a TableView.
Problem:
When I'm on DetailVC pressing a button to save - it works. When I then press it to delete - it works. When I then press the button to save it again, or go to MainVC(which is a collectionView) and try to open the same photo it's crashing.
In my view, I'm not trying to achieve this Realm object after deleting it when pressing a button to save it again or opening it in DetailedVC from MainVC, because I'm working with "local" data which came to me from JSON and was saved to a "local" variable. Not in RealmDB objects.
Method that I use to save/delete.
#objc func addToFavorite() {
guard let photoObject = photoObject else { return }
if realm.objects(PhotoModel.self).contains(where: { $0.id == photoObject.id }) {
deleteFromDB(photoObject)
} else {
saveToDB(photoObject)
}
}
DetailedVC https://pastecode.io/s/gegu7tkr

macOS app StatusBar icon only appears when Xcode is focussed

I'm building a macOS app with a StatusBar icon in Xcode (13.2, Swift 5) for personal use.
When I build in the dev environment it works as expected and the StatusBar icon appears.
To create the production app I go to Product > Archive > Distribute App > Copy App, and it creates a .app file with no errors (this method works for other apps without signing).
When I run the .app file, I see the app running in my processes, but no StatusBar icon appears.
Then if I switch to Xcode while the app is running, the StatusBar icon for the production app shows up. I know it's the distribution app because if I run the development build again I see two icons.
And if I kill the process one goes away.
Relevant code -
#NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {
let statusItem = NSStatusBar.system.statusItem(withLength:NSStatusItem.squareLength)
let popover = NSPopover()
var eventMonitor: EventMonitor?
func applicationDidFinishLaunching(_ aNotification: Notification) {
if let button = self.statusItem.button {
button.image = NSImage(named: NSImage.Name("MenuBarIcons"))
button.action = #selector(AppDelegate.togglePopover(_:))
}
self.popover.contentViewController = ViewController.newInstance()
self.popover.animates = false
self.eventMonitor = EventMonitor(mask: [.leftMouseDown, .rightMouseDown]) { [weak self] event in
if let strongSelf = self, strongSelf.popover.isShown {
strongSelf.closePopover(sender: event)
}
}
}
Questions are:
Why does the distribution app StatusBar icon only appear when I'm focused on Xcode?
What can I do to get the icon to always show up?

(UIApplication.shared.keyWindow?.rootViewController as? BaseSlidingController)?.openMenu() return nil Swift 4.2

I have a problem with the above stated. I can not find the exact information on the forums. Most of them are outdated and I have written the code programmatically. I have a controller that contains a view to edit the profile. I can not access that after changing the function listed below. I have a rootviewcontroller set to something else, but I tried the UiApplication calls anyway and it return nil and I can not open the profile controller. This is the function listed below.
#objc func handleOpen2() {
(UIApplication.shared.keyWindow?.rootViewController as? BaseSlidingController)?.openMenu()
}
Xcode does not give me an error but I can not get my menu to open. My rootviewcontroller is set to something else in app delegate. I have a controller that is used to control the sliding menu when I press the edit profile button.
func openMenu() {
isMenuOpened = true
redViewLeadingConstraint.constant = menuWidth
redViewTrailingConstraint.constant = menuWidth
performAnimations()
setNeedsStatusBarAppearanceUpdate()
}
This code is used to open my side bar menu with the information I need and also to perform animations as well. I was wondering if someone had any idea what I can do different instead in my handleOpen2 function. If you need more code, please let me know. Thanks
On swift 5 version:
(UIApplication.shared.windows.first?.rootViewController as? BaseSlidingController)?.openMenu()

How to observe other application icon in OS X?

I need to know current shown icon of another running application, I have tried this code:
var icon = NSRunningApplication.runningApplicationsWithBundleIdentifier("some.app.dentifier").first?.icon
but this returns a fixed app icon and if the other app changed its icon this code still returns same icon before change.
Is there a way to return current shown icon of another app or icon identifier ?
First add this to applicationDidFinishLaunching
let appChanged = Notification.Name("NSWorkspaceDidActivateApplicationNotification")
NSWorkspace.shared.notificationCenter.addObserver(self, selector: #selector(self.appChanged), name: appChanged, object: nil)
Then this function will get you the image
#objc func appChanged(notification:NSNotification){
if let userInfo = notification.userInfo![NSWorkspace.applicationUserInfoKey] as? NSRunningApplication {
let icon = userInfo.icon
}
}

Calling a function of the current UIViewController when using SWRevealViewController

I have an app written in swift that displays location information on different views. I am receiving location updates in AppDelegate (I don't want to use a singleton class since I want the location updates even when the app is in the background).
Now, I am using SWRevealViewController to implement a sidebar menu to toggle between the different views. When a new location update is received, how do I call the function of the viewController that is currently active to update the UI?
I searched a lot and all the solutions that talk about how to find the current UIViewController actually return SWRevealViewController as the current UIViewController, which doesn't help.
I gave it another shot and was able to find my viewController in my app from another view controller. However, I couldn't get my child view controllers app delegate.
Looking forward to other answers...
here's what I did:
let app = UIApplication.sharedApplication().delegate! as! AppDelegate
if let nav = app.window?.rootViewController?.childViewControllers {
nav.forEach { vc in
if let viewControllers = vc as? UINavigationController {
viewControllers.childViewControllers.forEach { vc in
if let x = vc as? ViewController {
print("Got it \(x)")
}
}
}
}
}