this is the location of matplotlib config file, you will get something like …/matplotlib/mpl-data/matplotlibrc
The font folder is …/matplotlib/mpl-data/fonts/ttf , put your ttf file there.
2. Get ttf from ttc file (skip if you have ttf file already)
For macOS, the system Chinese fonts is Heiti, which is embed in a ttc file (ttc is a collection of multiple ttf files). Get the system ttc file in /System/Library/Fonts/STHeiti Medium.ttc Copy this file out and convert it to ttf. Here is an online ttc converter:
Harnessing The Power of Both Languages in Your Apps
To create an app that can be auto launched after login (i.e. adding login item) is far more complicated then expected…
For sandboxed app, the recommended approach is using the Service Management Framework. (Adding login items using a Shared File List is another approach for non-sandboxed app, which will not be discussed here.)
The basic concept is to create an “Helper Application” that registered to the system, which responsible for launching your main app while user login.
The Helper App
In your project, create a new Cocoa Application target.
As the helper app should have no visual element, remove the view controller and window scene from the storyboard, as well as the related swift files.
Remove the ViewController.swift
Remove the View Controller Scene in the storyboard
Remove the Window Controller Scene (if you want visual on the helper app to see if its successfully launched by the main app or not, as well as launched by the system service or not after logging in, you may keep it for a while and delete it afterwards)
As the helper app will have the same default AppDelegate.swift which conflict with the main app. You need to rename it and adjust the class name of App Delegate in the Application Scene accordingly.
Then make the helper app as a background service. In Info.plist, set Application is background only to Yes.
In the app delegate, check if the main app is already running or not. If not, launch it.
The tricky part is to delete the last four path components of the helper app bundle path. It is because the helper app is actually embedded inside the main app bundle, under the subdirectory Contents/Library/LoginItems. So including the helper app name there will be a total of 4 path components to be deleted.
Another tricky part is to set skip install = YES in the build setting.
You then turn on App Sandbox in Capabilities of the helper target, and the helper app part is done.
You first import ServiceManagement, then check if the helper app is already running or not, launch and register it with SMLoginItemSetEnabled(_:_:) if necessary.
In my sample app I created an checkbox to toggle the helper app, as well as showing if its already launched or not.
We then copy the helper app into the main app bundle. In the Build Phases of the main app, create a new Copy Files phase.
with the following settings:
Add the helper app file
The last step is to enable App Sandbox and Development Signing of both main and helper app, then your are good to go.
You can test the auto launch feature as follow:
Build the main app — NOT RUN (if you build and run the main app in Xcode, the helper app may not function after quitting Xcode)
Right click the product of your main app → Show in Finder
Double click the main app in Finder to launch it, and check the auto launch button
Quit everything and log out
Log in again
The main app should be auto launched by the helper, with the auto launch button checked.
Menu bar apps refer to apps that sit on the menu bar (a.k.a. status bar) of macOS. It provide instant access of the key functionalities, as well as being accessible all time during a login session.
Creating the Status Bar Item
We use NSStatusBar.system().statusItem(withLength: -1) to request a status bar item from the system. Note that it may be failed (return nil) if the status bar is already full packed with many other status bar items.
Upon successfully got an status bar item, you got a NSButton as the UI element to put on the menu bar. You need to configure it by providing an image, as well as setting the target and action of the button.
All these should be done during the app launching period, so in the app delegate, we have:
Note that a strong reference must be used to retain the status bar item object returned by the system. Otherwise it will be released afterwards, and nothing will be shown on the menu bar.
Displaying the Menu
To display the menu, you need to provide a reference point for placing the menu object, in this case, the status bar button. We then create a mouse event, and use popUpContextMenu(_:with:for:) to bring up the menu.
If your app is menu bar ONLY, similar to the Dropbox macOS client, you need to set Application is agent = YES in your Info.plist in order to omit the Dock’s app icon and the app menu on the upper left corner.