How to customize NSTextView in AppKit

Issue #320 Scrollable Putting an NSTextView Object in an NSScrollView Use xib then load Embed image or NSTextAttachmentCellProtocol Select TextView Select Rich Text and Graphics Select Size Inspector -> Resizable and tick both Horizontally and Vertically Customize scrollView.drawsBackground = false textView.drawsBackground = false textView.string = "What's on your mind?" textView.delegate = self textView.selectedTextAttributes = [ NSAttributedString.Key.backgroundColor: NSColor(hex: "414858"), NSAttributedString.Key.foregroundColor: NSColor(hex: "ACB2BE") ] extension MainView: NSTextViewDelegate { func textViewDidChangeSelection(_ notification: Notification) { // Change text color again after image dragging } }

June 22, 2019 · 1 min · Khoa Pham

How to use custom font in AppKit

Issue #319 Add fonts to targets Declare in Info.plist https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/GeneralPurposeKeys.html#//apple_ref/doc/uid/TP40009253-SW8 ATSApplicationFontsPath (String - macOS) identifies the location of a font file or directory of fonts in the bundle’s Resources directory. If present, macOS activates the fonts at the specified path for use by the bundled app. The fonts are activated only for the bundled app and not for the system as a whole. The path itself should be specified as a relative directory of the bundle’s Resources directory....

June 22, 2019 · 1 min · Khoa Pham

How to avoid crash when closing NSWindow for agent macOS app

Issue #312 class ClosableWindow: NSWindow { override func close() { self.orderOut(NSApp) } } let window = ClosableWindow( contentRect: rect, styleMask: [.titled, .closable], backing: .buffered, defer: false } window.makeKeyAndOrderFront(NSApp) The reason is that window is released upon closed if it is not owned by NSWindowController, or we can use releasedWhenClosed The value of this property is YES if the window is automatically released after being closed; NO if it’s simply removed from the screen....

June 16, 2019 · 1 min · Khoa Pham

How to style NSButton in AppKit

Issue #297 let button = NSButton() button.wantsLayer = true button.isBordered = false button.setButtonType(.momentaryChange) button.attributedTitle = NSAttributedString( string: "Click me", attributes: [ NSAttributedString.Key.foregroundColor: NSColor.white, NSAttributedString.Key.font: NSFont.labelFont(ofSize: 13) ] button.layer?.backgroundColor = NSColor.orange.cgColor button.layer?.cornerRadius = 12 activate( button.anchor.height.equal.to(32), button.anchor.width.equal.to(100) ) To make it have native rounded rect button.imageScaling = .scaleProportionallyDown button.setButtonType(.momentaryPushIn) button.bezelStyle = .rounded button.isBordered = true import AppKit import Omnia extension NSButton { func style(imageName: String) { image = NSImage(named: NSImage.Name(imageName)) isBordered = false imageScaling = ....

May 31, 2019 · 1 min · Khoa Pham

20 recommended utility apps for macOS

Issue #274 Original post https://hackernoon.com/20-recommended-utility-apps-for-macos-in-2018-ea494b4db72b Depending on the need, we have different apps on the mac. As someone who worked mostly with development, below are my indispensable apps. They are like suits to Tony Stark. Since I love open source apps, they have higher priority in the list. Open source apps iTerm 2 https://www.iterm2.com/ iTerm2 is a replacement for Terminal and the successor to iTerm. It works on Macs with macOS 10....

May 23, 2019 · 6 min · Khoa Pham

Favorite WWDC 2018 sessions

Issue #245 Original post https://medium.com/fantageek/my-favourite-wwdc-2018-sessions-363d3fc9c9d5 Favourite WWDC 2018 sessions This year I failed the lottery ticket to WWDC, and I also missed the keynote live stream because I was sailing on the Christian Radich outside Oslo fjord that day. Luckily all the videos are available on Apple Developer site very shortly, and we can watch them now on Chrome or the unofficial WWDC app on macOS. I recommend the WWDC macOS app as it allows to mark favourites and filter, also offers the ability to adjust play speed to 1....

May 19, 2019 · 9 min · Khoa Pham

How to get running window informations in macOS

Issue #243 From https://developer.apple.com/documentation/coregraphics/1455137-cgwindowlistcopywindowinfo Generates and returns information about the selected windows in the current user session. struct MyWindowInfo { let frame: CGRect let name: String let pid: Int let number: Int init?(json: [String: Any]) { guard let pid = json["kCGWindowOwnerPID"] as? Int else { return nil } guard let name = json["kCGWindowOwnerName"] as? String else { return nil } guard let rect = json["kCGWindowBounds"] as? [String: Any] else { return nil } guard let x = rect["X"] as?...

May 16, 2019 · 1 min · Khoa Pham

How to show full screen window programmatically in macOS

Issue #242 let window = NSWindow(contentRect: mainScreen.frame, styleMask: .borderless, backing: .buffered, defer: false) window.level = .floating window.contentView = NSView() window.makeKeyAndOrderFront(NSApp) NSApp.activate(ignoringOtherApps: true) and then later hide it window.orderOut(NSApp)

May 16, 2019 · 1 min · Khoa Pham

How to work around app damaged warning in macOS

Issue #238 “App” is damaged and can’t be opened. You should move it to the Trash. 👉 Disable gate keeper sudo spctl --master-disable spctl --status Current workaround is to remove Launch At Login handling code.

May 15, 2019 · 1 min · Khoa Pham

How to shake NSView in macOS

Issue #233 Animation on macOS using CAAnimation Shake let midX = box.layer?.position.x ?? 0 let midY = box.layer?.position.y ?? 0 let animation = CABasicAnimation(keyPath: "position") animation.duration = 0.06 animation.repeatCount = 4 animation.autoreverses = true animation.fromValue = CGPoint(x: midX - 10, y: midY) animation.toValue = CGPoint(x: midX + 10, y: midY) box.layer?.add(animation, forKey: "position") Animation on macOS using NSAnimationContext Wiggle NSAnimationContext.runAnimationGroup({ context in let animation = CAKeyframeAnimation(keyPath: "transform") animation.beginTime = CACurrentMediaTime() + 5....

May 15, 2019 · 1 min · Khoa Pham

How to run AppleScript in macOS

Issue #223 Surround script by single quotes let script = """ tell application "XcodeWay" activate end tell """ let command = "osascript -e '\(script)'" let process = Process() process.launchPath = "/bin/bash" process.arguments = ["-c", command] Run as administrator In terminal, we can cd ~/Library sudo mkdir MyNewFolder In code, we use with administrator privileges, this when run will ask for password or fingerprint do shell script "mkdir MyNewFolder" with administrator privileges

May 2, 2019 · 1 min · Khoa Pham

How to fix not found zlib problem in macOS Mojave

Issue #217 https://developer.apple.com/documentation/xcode_release_notes/xcode_10_release_notes The command line tools will search the SDK for system headers by default. However, some software may fail to build correctly against the SDK and require macOS headers to be installed in the base system under /usr/include. If you are the maintainer of such software, we encourage you to update your project to work with the SDK or file a bug report for issues that are preventing you from doing so....

April 29, 2019 · 1 min · Khoa Pham

How to update NSMenuItem while NSMenu is showing in macOS

Issue #213 Use Runloop timer = Timer.scheduledTimer(withTimeInterval: 1, repeats: true, block: { [weak self] _ in let date = Date() self?.updateStopItem(seconds: finishDate.timeIntervalSince1970 - date.timeIntervalSince1970) }) RunLoop.main.add(timer!, forMode: .common) Use Dispatch timer = Timer.scheduledTimer(withTimeInterval: 1, repeats: true, block: { [weak self] _ in let date = Date() DispatchQueue.main.async { self?.updateStopItem(seconds: finishDate.timeIntervalSince1970 - date.timeIntervalSince1970) } }) Updated at 2020-09-08 07:54:36

April 23, 2019 · 1 min · Khoa Pham

How to launch app at start up in macOS

Issue #205 ServiceManagement framework https://developer.apple.com/documentation/servicemanagement/1501557-smloginitemsetenabled SMLoginItemSetEnabled Enable a helper application located in the main application bundle’s “Contents/Library/LoginItems” directory. Login items macOS Sierra: Open items automatically when you log in You can have apps, documents, folders, or server connections open automatically whenever you log in to your Mac. Add or remove automatic items Choose Apple menu > System Preferences, then click Users & Groups.

April 14, 2019 · 1 min · Khoa Pham

How to notarize macOS app

Issue #203 New Notarization Requirements https://developer.apple.com/news/?id=04102019a With the public release of macOS 10.14.5, we require that all developers creating a Developer ID certificate for the first time notarize their apps, and that all new and updated kernel extensions be notarized as well Signing Your Apps for Gatekeeper https://developer.apple.com/developer-id/ Unpublished Software. It’s easy to get unpublished software notarized with the Export process or xcodebuild. Custom build workflows are supported by the xcrun altool command line tool for uploading, and you can use xcrun stapler to attach the ticket to the package....

April 11, 2019 · 2 min · Khoa Pham

How to use shared AppGroup UserDefaults in macOS and Xcode extension

Issue #201 Go to both app and extension target, under Capabilities, enable AppGroup Specify $(TeamIdentifierPrefix)group.com.onmyway133.MyApp $(TeamIdentifierPrefix) will expand to something like T78DK947F3., with . Then using is like a normal UserDefaults let defaults = UserDefaults(suiteName: "T78DK947F3 .group.com.onmyway133.MyApp") defaults?.set(true, forKey: "showOptions") defaults?.synchronize() Updated at 2020-11-12 19:57:33

April 10, 2019 · 1 min · Khoa Pham

How to check file under Library in macOS

Issue #200 let home = NSSearchPathForDirectoriesInDomains(.applicationScriptsDirectory, .userDomainMask, true).first! let path = home.appending(".XcodeWayExtensions/XcodeWayScript.scpt") let exists = FileManager.default.fileExists(atPath: path)

April 10, 2019 · 1 min · Khoa Pham

How to run ffmpeg in macOS app

Issue #178 Install ffmpeg, which installs ffprobe brew install ffmpeg Find location of installed ffmpeg which ffmpeg Add all executables to project Get error unable to obtain file audio codec with ffprobe Run in verbose mode ffmpeg -v Get [debug] Encodings: locale US-ASCII, fs utf-8, out None, pref US-ASCII [debug] Python version 2.7.10 (CPython) - Darwin-18.2.0-x86_64-i386-64bit [debug] exe versions: ffmpeg present, ffprobe present Run version of ffprobe...

March 19, 2019 · 1 min · Khoa Pham

How to get path to resource in running macOS app

Issue #177 This is useful to refer to another executable in a running executable in Process Bundle.main.path(forResource: "ffmpeg", ofType: "")!

March 19, 2019 · 1 min · Khoa Pham

How to run executable in macOS

Issue #176 Enable executable chmod +x executable Add executable file to target Use Process with correct launchPad import Foundation protocol TaskDelegate: class { func task(task: Task, didOutput string: String) func taskDidComplete(task: Task) } class Task { weak var delegate: TaskDelegate? let process = Process() func run(arguments: [String]) { DispatchQueue.background.async { let launchPath = Bundle.main.path(forResource: "executable", ofType: "")! self.run(launchPath: launchPath, arguments: arguments) } } func stop() { DispatchQueue.background.async { if self.process.isRunning { self....

March 19, 2019 · 1 min · Khoa Pham