MAC os 157

How to clear background for TextField inside list in macOS

Issue #986

When using TextField in SwiftUI List on Mac, it has unwanted background color when focused. We can turn it off using introspection or a custom TextField wrapper

TextField("Search", text: $searchText)
    .introspect(.textField, on: …

How to use NSDragOperation

Issue #981

NSDragOperation represent which operations the dragging source can perform on dragging items.

There are several types of drag operations, and each one has a different purpose and visual cue.

Copy Operation .copy

  • What It Does: The item …

How to make NSCollectionView with diffable data source and SwiftUI

Issue #980

NSCollectionView, available since macOS 10.5+, is a good choice to present a list of content. Let’s make a SwiftUI wrapper for NSCollectionView with diffable data source and compositional layout

Use NSViewControllerRepresentable …

How to check NSTextField is first responder

Issue #961

NSTextField uses NSFieldEditor under the hood, you can check currentEditor if it is the firstResponder

extension NSTextField {
    var isFirstResponder: Bool {
        currentEditor() == window?.firstResponder
    }
}

How to make attributed TextView for macOS and iOS with SwiftUI

Issue #956

macOS

import Foundation
import SwiftUI
import AppKit

struct AttributedTextView: NSViewRepresentable {
    @Binding var attributedText: NSAttributedString
    var isEditable: Bool = true
    
    final class Coordinator: NSObject { …

How to drag multiple files in SwiftUI on Mac

Issue #951

Create a custom NSView that handles mouseDragged to beginDraggingSession

struct DraggingSourceViewWrapper: NSViewRepresentable {
    let fileUrls: [URL]
    let onEnd: () -> Void
    
    func makeNSView(context: Context) -> …

How to clear TextEditor background in SwiftUI

Issue #920

For iOS 16 and macOS 13.0

TextEditor(text: $text)
    .scrollContentBackground(.hidden)

For below, use [SwiftUI-Introspect](https://github.com/siteline/SwiftUI-Introspect)

TextEditor(text: $text)
    .instrospectTextView {
        $0. …

How to create Quick look thumbnail for files

Issue #913

Use QuickLookThumbnailing framework

import AppKit
import QuickLookThumbnailing

actor QuicklookService {
    static let shared = QuicklookService()
    
    private let generator = QLThumbnailGenerator.shared
    
    func image( …

How to show animated gif NSImage on Mac

Issue #903

let image = NSImage(contentsOf: url)
let imageView = NSImageView(image: image)
image.animates = true

How to find previous frontmost application in macOS

Issue #900

Listen to didActivateApplicationNotification and check that it is not our app

NSWorkspace.shared.notificationCenter
    .publisher(for: NSWorkspace.didActivateApplicationNotification)
    .sink(receiveValue: { [weak self] note in …

How to convert NSImage to PNG Data

Issue #885

Create NSBitmapImageRep with preferred size and draw NSImage onto that. Need to construct NSBitmapImageRep specifically instead of using convenient initializers like NSBitmapImageRep(data:), NSBitmapImageRep(cgImage:) to avoid device …

How to select in List in SwiftUI

Issue #881

Specify optional value for List(selection:).

This keeps selection on macOS, but not on iPad. On iPad each row in the List needs to be NavigationLink, no need for .tag. The selection is not updated, need to manually update with onTapGesture …

How to create document based macOS app

Issue #875

Read newDocument

This method calls openUntitledDocumentAndDisplay(_:).

Read openUntitledDocumentAndDisplay

The default implementation of this method calls defaultType to determine the type of new document to create, calls …

How to deinit NSWindow

Issue #848

Hold a weak reference to NSWindow, and let system window server manages its lifetime

weak var window = NSWindow()
window.isReleasedWhenClosed = true

How to convert NSEvent locationInWindow to window coordinate

Issue #822

Get active screen with mouse

func activeScreen() -> NSScreen? {
    let mouseLocation = NSEvent.mouseLocation
    let screens = NSScreen.screens
    let screenWithMouse = (screens.first { NSMouseInRect(mouseLocation, $0.frame, false) }) …

How to show modal window in AppKit

Issue #806

Use runModal

https://developer.apple.com/documentation/appkit/nsapplication/1428590-runmodalsession

Blocks main queue

A loop that uses this method is similar in some ways to a modal event loop run with runModal(for:), except with this …

How to resize NSImage with padding

Issue #795

extension NSImage {
    func resize(width: CGFloat, height: CGFloat, padding: CGFloat) -> NSImage {
        let img = NSImage(size: CGSize(width: width, height: height))

        img.lockFocus()
        let ctx = NSGraphicsContext. …

How to convert from paid to freemium in SwiftUI with RevenueCat

Issue #794

I’ve been distributing my apps PastePal and Push Hero as a paid upfront apps on Appstore. I’ve quickly come to realize the importance of trials since many have requested a tryout before purchasing.

Manual sending out trials …

How to manage WindowGroup in SwiftUI for macOS

Issue #789

Using WindowGroup

New in SwiftUI 2.0 for iOS 14 and macOS 11.0 is WindwGroup which is used in App protocol. WindowGroup is ideal for document based applications where you can open multiple windows for different content or files. For …

How to use Core Data

Issue #785

Core Data

Calling mergeChanges on a managed object context will automatically refresh any managed objects that have changed. This ensures that your context always contains all the latest …

How to tune performance with ButtonBehavior in SwiftUI

Issue #779

With Xcode 12.4, macOS 11.0 app. Every time we switch the system dark and light mode, the CPU goes up to 100%. Instruments show that there’s an increasing number of ButtonBehavior

Screenshot 2021-02-24 at 10 12 05

Suspect State in a row in LazyVStack

Every cell has …

How to use GroupBox in SwiftUI

Issue #778

For now using GroupBox has these issues in macOS

  • Prevents dragging scroll indicator to scroll
  • Switch from light to dark mode may cause 100% CPU usage

How to show close button in NSTextField in AppKit

Issue #771

Use NSSearchField instead

How to show modal window in SwiftUI for macOS

Issue #768

Use custom NSWindow, set level in becomeKey and call NSApp.runModal to show modal

final class ModalWindow: NSWindow {
    override func becomeKey() {
        super.becomeKey()

        level = .statusBar
    }

    override func close() { …

How to handle keyDown in SwiftUI for macOS

Issue #764

Use a custom KeyAwareView that uses an NSView that checks for keyDown method. In case we can’t handle certain keys, call super.keyDown(with: event)

import SwiftUI
import KeyboardShortcuts

struct KeyAwareView: NSViewRepresentable { …

How to use Sparkle for macOS app

Issue #762

Install Sparkle

  • For now, the latest stable version is 1.24.0 which supports CocoaPods OK, but still, have issues with SPM. Support non sandboxed apps
  • Version 2.0.0 is in beta and supports sandboxed apps

To install, use CocoaPods

platform …

How to handle keyDown in NSResponder

Issue #760

import AppKit
import Omnia

class MyWindow: NSWindow {
    override func keyDown(with event: NSEvent) {
        super.keyDown(with: event)

        if isKey(NSDeleteCharacter, event: event) {
            NotificationCenter.default.post( …

How to handle NSSearchToolbarItem in macOS 11

Issue #758

extension NSToolbarItem.Identifier {
    static let searchItem: NSToolbarItem.Identifier = NSToolbarItem.Identifier("SearchItem")
}

let searchItem = NSSearchToolbarItem(itemIdentifier: .searchItem)

extension AppDelegate: …

How to do launch at login for macOS apps

Issue #757

  • Use SMLoginItemSetEnabled from Service Management framework
  • Use a helper background app that checks and invokes our main application
  • Copy our helper app into Library/LoginItems
helper_dir="$BUILT_PRODUCTS_DIR/$CONTENTS_FOLDER_PATH …

How to create and notarize dmg file

Issue #753

  • Archive and export app from Xcode
  • Create dmg
  • Use create-dmg It is said that we don’t need to notarize the app, we can just notarize the whole dmg
  • Send dmg to notarize

This takes a while

xcrun altool -t osx -f PastePal.dmg --primary …

How to open downloaded app from browser in Big Sur

Issue #750

Recently when distributing staging releases of my app PastePal via GitHub release or Google Drive, people had hard time opening it

Screenshot 2021-01-15 at 10 26 26

The displayed error is

You do not have permission to open the application

The more verbose error when …

How to make popup button in SwiftUI for macOS

Issue #748

There is said to be PopUpButtonPickerStyle and MenuPickerStyle but these don’t seem to work.

There’s Menu button it shows a dropdown style. We fake it by fading this and overlay with a button. allowsHitTesting does not work, …

How to use Apple keyboard key symbols

Issue #743

•  = Apple logo • ⌘ = Command • ⇧ = Shift • ⌫ = Backspace/Delete • ⇪ = Caps lock • ⌥ = Option/Alt • ⌃ = Control • ⎋ = Escape • ←↑→↓ = Arrow Keys • ↩ = Return

How to disable scrolling in NSTextView for macOS

Issue #733

NSTextView has this handy method to make scrollable NSTextView NSTextView.scrollableTextView(). The solution is to get to the responder outside enclosing NSScrollView, in my case it is the SwiftUI hosting view

class DisabledScrollTextView: …

How to make attributed string Text in SwiftUI for macOS

Issue #730

Use NSTextField with maximumNumberOfLines

import AppKit
import SwiftUI

struct AttributedText: NSViewRepresentable {

    let attributedString: NSAttributedString

    init(_ attributedString: NSAttributedString) {
        self. …

How to do copy paste delete in Swift for macOS

Issue #729

@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {
    @IBAction func copy(_ sender: Any) {
        print("copy", sender)
    }


    @IBAction func paste(_ sender: Any) {
        print("paste", sender) …

How to make visual effect blur in SwiftUI for macOS

Issue #724

We can use .blur modifier, but with VisualEffectView gives us more options for material and blending mode.

public struct VisualEffectView: NSViewRepresentable {
    let material: NSVisualEffectView.Material
    let blendingMode: …

How to force set frame explicitly for NSWindow

Issue #721

For setFrame to take effect

mainWindow.setFrame(rect, display: true)

we can remove auto save frame flag

mainWindow.setFrameAutosaveName("MyApp.MainWindow")

How to rotate NSStatusItem

Issue #720

NSStatusItem is backed by NSButton, we can animate this inner button. We need to specify position and anchorPoint for button’s layer so it rotates around its center point

guard
    let button = statusItem.button
else { return }

let …

How to show image and text in menu item in SwiftUI for macOS

Issue #719

From SwiftUI 2 for macOS 11.0, we have access to Menu for creating menu and submenu. Usually we use Button for interactive menu items and Text for disabled menu items.

The easy way to customize menu with image is to call Menu with content …

How to make stepper with plus and minus buttons in SwiftUI for macOS

Issue #717

Try to use predefined system colors in Human Interface Guidelines for macOS

Here we use this color unemphasizedSelectedTextBackgroundColor for button background

Screenshot 2020-12-21 at 06 24 16
HStack(spacing: 1) {
    makeUnderListButton(action: {}, icon: .plus) …

How to fix Picker not showing selection in SwiftUI

Issue #716

I have an enum that conforms to CaseIterable that I want to show in Picker

enum Position: String, Codable, CaseIterable, Identifiable {
    var id: String { rawValue }
    case left
    case right
    case bottom
    case top
}

Picker( …

How to add toolbar programatically in macOS

Issue #713

To setup toolbar, we need to implement NSToolbarDelegate that provides toolbar items. This delegate is responsible for many things

  • Set visible and allowed items with toolbarDefaultItemIdentifiers
  • Provide item with itemForItemIdentifier …

How to show sidebar in SwiftUI for macOS

Issue #710

Starting from macOS 11, we can use List with SidebarListStyle inside NavigationView to declare master detail view. The SidebarListStyle makes list translucent. It automatically handles selection and marks selected row in list with accent …

How to support right click menu to NSStatusItem

Issue #707

The trick is to set the button oinside of statusItem to send actions on both leftMouseUp and rightMouseUp.

Another thing to note is we use popUpMenu on NSStatusItem, although it is marked as deprecated on macOS 10.14. We can set menu but …

How to convert from paid to free with IAP

Issue #703

What is receipt

Read When to refresh a receipt vs restore purchases in iOS?

From iOS 7, every app downloaded from the store has a receipt (for downloading/buying the app) at appStoreReceiptURL. When users purchases something via In App …

How to disable NSTextView in SwiftUI

Issue #702

The trick is to use an overlay

MessageTextView(text: $input.message)
    .overlay(obscure)

var obscure: AnyView {
    if store.pricingPlan.isPro {
        return EmptyView().erase()
    } else {
        return Color.black.opacity(0.01). …

How to check dark mode in AppKit for macOS apps

Issue #693

AppKit app has its theme information stored in UserDefaults key AppleInterfaceStyle, if is dark, it contains String Dark.

Another way is to detect appearance via NSView

struct R {
    static let dark = DarkTheme()
    static let light = …

How to make full size content view in SwiftUI for macOS

Issue #689

func applicationDidFinishLaunching(_ aNotification: Notification) {
    // extend to title bar
    let contentView = ContentView()
        // .padding(.top, 24) // can padding to give some space
        .edgesIgnoringSafeArea(.top)

    // …

How to style multiline Text in SwiftUI for macOS

Issue #681

Only need to specify fixedSize on text to preserve ideal height.

The maximum number of lines is 1 if the value is less than 1. If the value is nil, the text uses as many lines as required. The default is nil.

Text(longText)
    .lineLimit …

How to clear List background color in SwiftUI for macOS

Issue #680

For List in SwiftUI for macOS, it has default background color because of the enclosing NSScrollView via NSTableView that List uses under the hood. Using listRowBackground also gives no effect

The solution is to use a library like …

How to avoid reduced opacity when hiding view with animation in SwiftUI

Issue #679

While redesigning UI for my app Push Hero, I ended up with an accordion style to toggle section.

Screenshot 2020-10-01 at 06 58 33

It worked great so far, but after 1 collapsing, all image and text views have reduced opacity. This does not happen for other elements like …

How to unwrap Binding with Optional in SwiftUI

Issue #677

The quick way to add new properties without breaking current saved Codable is to declare them as optional. For example if you use EasyStash library to save and load Codable models.

import SwiftUI

struct Input: Codable {
    var bundleId: …

How to make custom toggle in SwiftUI

Issue #676

I’ve used the default SwiftUI to achieve the 2 tab views in SwiftUI. It adds a default box around the content and also opinionated paddings. For now on light mode on macOS, the unselected tab has wrong colors.

The way to solve this …

How to use HSplitView to define 3 panes view in SwiftUI for macOS

Issue #674

Specify minWidth to ensure miminum width, and use .layoutPriority(1) for the most important pane.

import SwiftUI

struct MainView: View {
    @EnvironmentObject var store: Store

    var body: some View {
        HSplitView { …

How to disable ring type in TextField in SwiftUI

Issue #636

Normally we can just wrap NSTextField

struct SearchTextField: NSViewRepresentable {
    @Binding var text: String
    var hint: String
    var onCommit: (String) -> Void

    func makeNSView(context: NSViewRepresentableContext< …

How to handle enter key in NSTextField

Issue #635

textField.delegate = self
NSTextFieldDelegate

func control(_ control: NSControl, textView: NSTextView, doCommandBy commandSelector: Selector) -> Bool {
    if (commandSelector == #selector(NSResponder.insertNewline(_:))) {
        // …

How to toggle with animation in SwiftUI

Issue #632

Use Group

private func makeHeader() -> some View {
    Group {
        if showsSearch {
            SearchView(
                onSearch: onSearch
            )
            .transition(.move(edge: .leading))
        } else { …

How to show context popover from SwiftUI for macOS

Issue #630

For SwiftUI app using NSPopover, to show context popover menu, we can ask for windows array, get the _NSPopoverWindow and calculate the position. Note that origin of macOS screen is bottom left

(lldb) po NSApp.windows
▿ 2 elements
  - 0 : …

How to make segmented control in SwiftUI for macOS

Issue #629

Use Picker with SegmentedPickerStyle.

Picker(selection: $preferenceManager.preference.display, label: EmptyView()) {
    Image("grid")
        .resizable()
    .padding()
        .tag(0)
    Image("list")
        .resizable …

How to check if NSColor is light

Issue #627

Algorithm from https://www.w3.org/WAI/ER/WD-AERT/#color-contrast

extension NSColor {
    var isLight: Bool {
        guard
            let components = cgColor.components,
            components.count >= 3
        else { return false } …

How to trigger onAppear in SwiftUI for macOS

Issue #626

SwiftUI does not trigger onAppear and onDisappear like we expect. We can use NSView to trigger

import SwiftUI

struct AppearAware: NSViewRepresentable {
    var onAppear: () -> Void

    func makeNSView(context: …

How to force refresh in ForEach in SwiftUI for macOS

Issue #625

For some strange reasons, content inside ForEach does not update with changes in Core Data NSManagedObject. The workaround is to introduce salt, like UUID just to make state change

struct NoteRow: View {
    let note: Note
    let id: UUID …

How to access bookmark url in macOS

Issue #624

By default the approaches above grant you access while the app remains open. When you quit the app, any folder access you had is lost.

To gain persistent access to a folder even on subsequent launches, we’ll have to take advantage of a …

How to make TextField focus in SwiftUI for macOS

Issue #620

For NSWindow having levelother than .normal, need to override key and main property to allow TextField to be focusable

class FocusWindow: NSWindow {
    override var canBecomeKey: Bool  { true }
    override var canBecomeMain: Bool { …

How to make tooltip in SwiftUI for macOS

Issue #617

On macOS 11, we can use .help modifier to add tooltip

Button()
    .help("Click here to open settings")

If you support macOS 10.15, then create empty NSView and use as overlay. Need to updateNSView in case we toggle the state of …

How to make translucent SwiftUI List in macOS

Issue #615

List {
    ForEach(books) { (book: Book) in
        BookRow(book: book)
    }
}
.listStyle(SidebarListStyle())  

How to present NSWindow modally

Issue #612

Use runModal

This method runs a modal event loop for the specified window synchronously. It displays the specified window, makes it key, starts the run loop, and processes events for that window. (You do not need to show the window …

How to use visual effect view in NSWindow

Issue #610

Set NSVisualEffectView as contentView of NSWindow, and our main view as subview of it. Remember to set frame or autoresizing mask as non-direct content view does not get full size as the window

let mainView = MainView()
    .environment(\. …

How to animate NSWindow

Issue #609

Use animator proxy and animate parameter

var rect = window.frame
rect.frame.origin.x = 1000
NSAnimationContext.runAnimationGroup({ context in
    context.timingFunction = CAMediaTimingFunction(name: .easeIn)
    window.animator().setFrame( …

How to find active application in macOS

Issue #608

An NSRunningApplication instance for the current application.

NSRunningApplication.current

The running app instance for the app that receives key events.

NSWorkspace.shared.frontmostApplication

 

How to use application will terminate in macOS

Issue #601

On Xcode 11, applicationWillTerminate is not called because of default automatic termination on in Info.plist. Removing NSSupportsSuddenTermination to trigger will terminate notification

func applicationWillTerminate(_ notification: …

How to change background color in List in SwiftUI for macOS

Issue #595

SwiftUI uses ListCoreScrollView and ListCoreClipView under the hood. For now the workaround, is to avoid using List

List {
    ForEach
}

use

VStack {
    ForEach
}

How to weak link Combine in macOS 10.14 and iOS 12

Issue #593

#if canImport(Combine) is not enough, need to specify in Other Linker Flags

OTHER_LDFLAGS = -weak_framework Combine

Read more

How to set font to NSTextField in macOS

Issue #591

Use NSTextView instead

How to make borderless material NSTextField in SwiftUI for macOS

Issue #590

Use custom NSTextField as it is hard to customize TextFieldStyle

import SwiftUI

struct MaterialTextField: View {
    let placeholder: String
    @Binding var text: String
    @State var isFocus: Bool = false

    var body: some View { …

How to make focusable NSTextField in macOS

Issue #589

Use onTapGesture

import SwiftUI

struct MyTextField: View {
    @Binding
    var text: String
    let placeholder: String
    @State
    private var isFocus: Bool = false

    var body: some View {
        FocusTextField(text: $text, …

How to observe focus event of NSTextField in macOS

Issue #589

becomeFirstResponder

class FocusAwareTextField: NSTextField {
    var onFocusChange: (Bool) -> Void = { _ in }

    override func becomeFirstResponder() -> Bool {
        let textView = window?.fieldEditor(true, for: nil) as? …

How to change caret color of NSTextField in macOS

Issue #588

class FocusAwareTextField: NSTextField {
    var onFocus: () -> Void = {}
    var onUnfocus: () -> Void = {}

    override func becomeFirstResponder() -> Bool {
        onFocus()
        let textView = window?.fieldEditor(true, …

How to make TextView in SwiftUI for macOS

Issue #587

Use NSTextVIew

From https://github.com/twostraws/ControlRoom/blob/main/ControlRoom/NSViewWrappers/TextView.swift

import SwiftUI

/// A wrapper around NSTextView so we can get multiline text editing in SwiftUI.
struct TextView: …

How to use Firebase Crashlytics in macOS app

Issue #585

New Firebase Crashlytics

Follow the new Firebase Crashlytics guide Get started with Firebase Crashlytics using the Firebase Crashlytics SDK

CocoaPods

Specify FirebaseCore for community managed macOS version of Firebase

platform :osx, …

How to handle radio group for NSButton

Issue #579

Use same action, or we can roll our own implementation

An NSButton configured as a radio button (with the -buttonType set to NSRadioButton), will now operate in a radio button group for applications linked on 10.8 and later. To have the …

How to use Applications folder in macOS

Issue #573

There are 2 Applications folder

  • /System/Applications: contains Notes, Books, Calculator, …
  • /Applications: contains Safari, Xcode, Keynote, …

How to allow unnotarized app to run on macOS Catalina

Issue #520

Remove quarantine

xattr -d com.apple.quarantine /Applications/Flipper.app

How to make Swift Package Manager package for multiple platforms

Issue #504

https://twitter.com/NeoNacho/status/1181245484867801088?s=20

There’s no way to have platform specific sources or targets today, so you’ll have to take a different approach. I would recommend wrapping all OS specific files in #if os and …

How to use Firebase in macOS

Issue #501

  • Use Catalyst
  • Add to CocoaPods
platform :ios, '13.0'

target 'MyApp' do
  use_frameworks!

  pod 'FirebaseCore'
  pod 'Firebase/Firestore'

end

Troubleshooting

Select a team for …

How to use Apple certificate in Xcode 11

Issue #458

For push notification, we can now use just Production Certificate for 2 environments (production and sandbox) instead of Development and Production certificates.

Now for code signing, with Xcode 11 …

How to style NSTextView and NSTextField in macOS

Issue #443

let textField = NSTextField()
textField.focusRingType = .none
let textView = NSTextView()
textView.insertionPointColor = R.color.caret
textView.isRichText = false
textView.importsGraphics = false
textView.isEditable = true
textView. …

How to center NSWindow in screen

Issue #442

On macOS, coordinate origin is bottom left

let window = NSWindow(contentRect: rect, styleMask: .borderless, backing: .buffered, defer: false)

window.center()
let frame = window.frame
window.setFrameOrigin(CGPoint(x: frame.origin.x, y: 100 …

How to log Error in Swift

Issue #439

Use localizedDescription

We need to provide NSLocalizedDescriptionKey inside user info dictionary, otherwise the outputt string may not be what we want.

NSError …

How to handle NSTextField change in macOS

Issue #438

Storyboard

In Storyboard, NSTextField has an Action option that specify whether Send on Send on Enter only` should be the default behaviour.

textfield

Code

In code, NSTextFieldDelegate notifies whenever text field value changes, and target action …

How to add section header to NSCollectionView in macOS

Issue #437

Normal

Use Omnia for itemId extension

HeaderCell.swift

final class HeaderCell: NSView, NSCollectionViewSectionHeaderView {
    let label: NSTextField = withObject(NSTextField(labelWithString: "")) {
        $0.textColor = R.color. …

How to show log in Apple Script

Issue #436

Open Script Editor, use log command and look for 4 tabs in bottom panel Result, Messages, Events and Replies

log "hello world"

How to show context menu from NSButton in macOS

Issue #435

Use NSMenu and popUp

func showQuitMenu() {
    let menu = NSMenu()
    let aboutItem = NSMenuItem(
        title: "About",
        action: #selector(onAboutTouched(_:)),
        keyEquivalent: ""
    )

    let quitItem = …

How to make checked NSButton in AppKit

Issue #433

  • Use Omnia for convenient style and isOn property
let checkButton = NSButton(checkboxWithTitle: "", target: nil, action: nil)
checkButton.stylePlain(title: "Autosave", color: R.color.text, font: R.font.text)
checkButton. …

How to save files in sandboxed macOS app

Issue #432

Read Container Directories and File System Access

When you adopt App Sandbox, your application has access to the following locations:

The app container directory. Upon first launch, the operating system creates a special directory for …

How to use marked in WKWebView in AppKit

Issue #429

Use https://github.com/markedjs/marked

<!doctype html>
<html>
<head>
  <meta charset="utf-8"/>
  <title>Marked in the browser</title>
</head>
<body>
  <div id="content" …

How to enable NSMenuItem in AppKit

Issue #428

Need to set target

let item = NSMenuItem(
    title: title,
    action: #selector(onMenuItemClicked(_:)),
    keyEquivalent: ""
)

item.target = self

Sometimes, need to check autoenablesItems

Indicates whether the menu …

How to use generic NSCollectionView in macOS

Issue #427

See CollectionViewHandler

Use ClickedCollectionView to detect clicked index for context menu. Embed NSCollectionView inside NSScrollView to enable scrolling

import AppKit

public class CollectionViewHandler<Item: Equatable, Cell: …

How to easily parse deep json in Swift

Issue #414

Codable is awesome, but sometimes we just need to quickly get value in a deepy nested JSON. In the same way I did for Dart How to resolve deep json object in Dart, let’s make that in Swift.

See …

How to support drag and drop in NSView

Issue #410

import AppKit
import Anchors

class DraggingView: NSView {
    var didDrag: ((FileInfo) -> Void)?
    let highlightView = NSView()

    override init(frame frameRect: NSRect) {
        super.init(frame: frameRect) …

How to use NSStepper in Appkit

Issue #409

let stepper = NSStepper()
let textField = NSTextField(wrappingLabelWithString: "\(myLocalCount)")

stepper.integerValue = myLocalCount
stepper.minValue = 5
stepper.maxValue = 24
stepper.valueWraps = false

stepper.target = self …

How to handle shortcut in AppKit

Issue #408

Podfile

pod 'MASShortcut'
let shortcut = MASShortcut(keyCode: kVK_ANSI_K, modifierFlags: [.command, .shift])

MASShortcutMonitor.shared()?.register(shortcut, withAction: {
    self.showPopover(sender: self.statusItem.button)
})

How to select file in its directory in AppKit

Issue #407

https://developer.apple.com/documentation/appkit/nsworkspace/1524399-selectfile

In macOS 10.5 and later, this method does not follow symlinks when selecting the file. If the fullPath parameter contains any symlinks, this method selects …

How to use NSProgressIndicator in AppKit

Issue #406

let progressIndicator = NSProgressIndicator()
progressIndicator.isIndeterminate = true
progressIndicator.style = .spinning
progressIndicator.startAnimation(nil)

How to show save panel in AppKit

Issue #405

Enable Read/Write for User Selected File under Sandbox to avoid bridge absent error

func showSave(
    name: String,
    window: NSWindow
) async -> URL? {
    let panel = NSSavePanel()
    panel.directoryURL = FileManager.default. …

How to animate NSView using keyframe

Issue #404

let animation = CAKeyframeAnimation(keyPath: "position.y")
animation.values = [50, 20, 50]
animation.keyTimes = [0.0, 0.5, 1.0]
animation.duration = 2
animation.repeatCount = Float.greatestFiniteMagnitude
animation.autoreverses = …

How to quit macOS on last window closed

Issue #403

https://developer.apple.com/documentation/appkit/nsapplicationdelegate/1428381-applicationshouldterminateafterl?language=objc

The application sends this message to your delegate when the application’s last window is closed. It sends this …

How to sign executable for sandbox

Issue #401

Find identity

security find-identity 

Sign with entitlements and identity. For macOS, use 3rd Party Mac Developer Application

codesign -f -s "3rd Party Mac Developer Application: Khoa Pham (123DK123F2)" --entitlements …

How to cache URLSession response

Issue #339

For simple cases, we don’t need to. Let’s use urlCache

The URL cache for providing cached responses to requests within the session.

Accessing Cached Data

The URL Loading System caches responses both in memory and on disk, …

How to show dropdown in AppKit

Issue #336

Use NSPopUpButton

var pullsDown: Bool

A Boolean value indicating whether the button displays a pull-down or pop-up menu.

func addItem(withTitle: String) Adds an item with the specified title to the end of the menu.

Should disable …

How to use NSSecureCoding in Swift

Issue #334

NSSecureCoding has been around since iOS 6 and has had some API changes in iOS 12

A protocol that enables encoding and decoding in a manner that is robust against object substitution attacks. …

How to use moveItem in NSCollectionView in AppKit

Issue #332

From moveItem(at:to:)

Moves an item from one location to another in the collection view.

After rearranging items in your data source object, use this method to synchronize those changes with the collection view. Calling this method lets …

How to show dropdown from NSSegmentedControl in AppKit

Issue #331

From NSSegmentedControl

The features of a segmented control include the following: A segment can have an image, text (label), menu, tooltip, and tag. A segmented control can contain images or text, but not both.

let languageMenu = NSMenu( …

How to make scrollable NSTextView in AppKit

Issue #330

When adding NSTextView in xib, we see it is embedded under NSClipView. But if we try to use NSClipView to replicate what’s in the xib, it does not scroll.

To make it work, we can follow Putting an NSTextView Object in an NSScrollView …

How to make simple form validator in Swift

Issue #328

Sometimes we want to validate forms with many fields, for example name, phone, email, and with different rules. If validation fails, we show error message.

We can make simple Validator and Rule

class Validator {
    func validate(text: …

How to animate NSCollectionView changes

Issue #323

Use proxy animator()

let indexPath = IndexPath(item: index, section: 0)
collectionView.animator().deleteItems(at: Set(arrayLiteral: indexPath))

let indexPath = IndexPath(item: 0, section: 0)
collectionView.animator().insertItems(at: Set( …

How to handle right click in AppKit

Issue #322

lazy var gr = NSClickGestureRecognizer(target: self, action: #selector(onPress(_:)))

gr.buttonMask = 0x2
gr.numberOfClicksRequired = 1
view.addGestureRecognizer(gr)

How to show context menu in NSCollectionView

Issue #321

Detect locationInWindow in NSEvent

class ClickedCollectionView: NSCollectionView {
    var clickedIndex: Int?

    override func menu(for event: NSEvent) -> NSMenu? {
        clickedIndex = nil

        let point = convert(event. …

How to customize NSTextView in AppKit

Issue #320

Scrollable

textview

Embed image or NSTextAttachmentCellProtocol

  • Select TextView
  • Select Rich Text and Graphics
  • Select Size Inspector -> Resizable and tick both Horizontally …

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. …

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 …

How to highlight selection of NSCollectionViewItem

Issue #296

Original answer https://stackoverflow.com/a/54793979/1418457


In your NSCollectionViewItem subclass, override isSelected and change background color of the layer. Test in macOS 10.14 and Swift 4.2

class Cell: NSCollectionViewItem { …

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 …

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 …

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 …

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 …

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.

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 …

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 …

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 …

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)
}) …

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” …

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 …

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 …

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: …

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] …

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: "")!

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)
} …

How to print current directory using Process in macOS

Issue #175

let process = Process()
process.launchPath = "/bin/pwd"
process.arguments = []

Should be the same as FileManager.default.currentDirectoryPath

How to change NSTextField backgroundColor in NSPopover

Issue #174

Disable vibrancy mode of NSPopover

let popover = NSPopover()
popover.appearance = NSAppearance(named: NSAppearance.Name.aqua)

How to make scrollable vertical NSStackView

Issue #173

You might need to flip NSClipView

import AppKit
import Anchors
import Omnia

final class ScrollableStackView: NSView {
    final class FlippedClipView: NSClipView {
        override var isFlipped: Bool {
            return true
        } …

How to load top level view from xib in macOS

Issue #171

var views: NSArray?
NSNib(nibNamed: NSNib.Name("ProfileView"), bundle: nil)?.instantiate(withOwner: nil, topLevelObjects: &views)
let profileView = views!.compactMap({ $0 as? ProfileView }).first!

How to generate QR code in AppKit

Issue #140

I need to generate QR code in https://github.com/onmyway133/AddressGenerator. Fortunately with CoreImage filter, it is very easy. Code is in Swift 4

import AppKit

final class QRCodeGenerator {
  func generate(string: String, size: CGSize) …

How to make NSCollectionView programatically in Swift

Issue #131

Here’s how to create NSCollectionView programatically. We need to embed it inside NScrollView for scrolling to work. Code is in Swift 4

NSCollectionView

let layout = NSCollectionViewFlowLayout()
layout.minimumLineSpacing = 4 …

Learning from Open Source Using Playground

Issue #94

One thing I like about kickstarter-ios is how they use Playground to quickly protoyping views.

We use Swift Playgrounds for iterative development and styling. Most major screens in the app get a corresponding playground where we can see a …

Learning from Open Source Making macOS app in code

Issue #91

I’m familiar with the whole app structure that Xcode gives me when I’m creating new macOS project, together with Storyboard. The other day I was reading touch-bar-simulator and see how it declares app using only code. See this …

Fixing login hanging in macOS High Sierra

Issue #86

Today I met a strange problem. After I enter my password, the progress bar runs to the end, and it is stuck there forever. No matter how many times I try to restart.

I finally need to go to Recovery mode by pressing Cmd+R at start up. I …

NSApplicationDelegate and notification

Issue #34

In an iOS project, we often see this in AppDelegate

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?

    func application(application: UIApplication, didFinishLaunchingWithOptions …

How to debug Auto Layout

Issue #23

hasAmbiguousLayout

Returns whether the constraints impacting the layout of the view incompletely specify the location of the view.

exerciseAmbiguityInLayout

This method randomly changes the frame of a view with an ambiguous layout between …

Markdown editor

Issue #6

I like writing with markdown, it gives me comfortable experience with complete control over what I want to write.

I recommend vmd which renders exactly as GitHub. vmd is for rendering only, you need an editor to write, I use Sublime Text …