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 automatically enables and disables its menu items. This property contains a Boolean value, indicating whether the menu automatically enables and disables its menu items. If set to true, menu items of the menu are automatically enabled and disabled according to rules computed by the NSMenuValidation informal protocol....

September 25, 2019 · 1 min · 84 words · Khoa

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: NSCollectionViewItem> : NSObject, NSCollectionViewDataSource, NSCollectionViewDelegateFlowLayout { public let layout = NSCollectionViewFlowLayout() public let scrollView = NSScrollView() public let collectionView = ClickedCollectionView() public var items = [Item]() public var itemSize: () -> CGSize = { .zero } public var configure: (Item, Cell) -> Void = { _, _ in } override init() { super....

September 24, 2019 · 2 min · 261 words · Khoa

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 https://github.com/onmyway133/Omnia/blob/master/Sources/Shared/JSON.swift public func resolve<T>(_ jsonDictionary: [String: Any], keyPath: String) -> T? { var current: Any? = jsonDictionary keyPath.split(separator: ".").forEach { component in if let maybeInt = Int(component), let array = current as?...

September 12, 2019 · 1 min · 177 words · Khoa

How to work with Hardened runtime and sandbox in macOS

Issue #413 Hardened Runtime and Sandboxing Resolving Common Notarization Issues macOS Code Signing In Depth

September 11, 2019 · 1 min · 15 words · Khoa

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) registerForDraggedTypes([ .fileURL ]) highlightView.isHidden = true addSubview(highlightView) activate(highlightView.anchor.edges) highlightView.wantsLayer = true highlightView.layer?.borderColor = NSColor(hex: "#FF6CA8").cgColor highlightView.layer?.borderWidth = 6 } required init?(coder decoder: NSCoder) { fatalError() } override func draggingEntered(_ sender: NSDraggingInfo) -> NSDragOperation { highlightView.isHidden = false return NSDragOperation() } override func draggingEnded(_ sender: NSDraggingInfo) { guard let pathAlias = sender....

September 10, 2019 · 1 min · 163 words · Khoa

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 stepper.action = #selector(onStepperChange(_:)) @objc func onStepperChange(_ sender: NSStepper) { myLocalCount = sender.integerValue textField.stringValue = "\(sender.integerValue)" }

September 8, 2019 · 1 min · 42 words · Khoa

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

September 8, 2019 · 1 min · 19 words · Khoa

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 the symlink instead of the file it targets. If you want to select the target file, use the resolvingSymlinksInPath method to resolve any symlinks before calling this method. It is safe to call this method from any thread of your app. NSWorkspace.shared.selectFile( url....

September 7, 2019 · 1 min · 73 words · Khoa

How to use NSProgressIndicator in AppKit

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

September 7, 2019 · 1 min · 13 words · Khoa

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.homeDirectoryForCurrentUser panel.nameFieldStringValue = name let response = await panel.beginSheetModal(for: window) if response == .OK { return panel.url } else { return nil } } To save multiple files, use NSOpenPanel let panel = NSOpenPanel() panel.canChooseFiles = false panel.allowsMultipleSelection = false panel....

September 7, 2019 · 1 min · 83 words · Khoa

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 = true myView.wantsLayer = true myView.layer?.add(animation, forKey: "bounce")

September 6, 2019 · 1 min · 32 words · Khoa

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 message regardless of whether there are still panels open. (A panel in this case is defined as being an instance of NSPanel or one of its subclasses.) If your implementation returns NO, control returns to the main event loop and the application is not terminated. If you return YES, your delegate’s applicationShouldTerminate: method is subsequently invoked to confirm that the application should be terminated....

September 6, 2019 · 1 min · 95 words · Khoa

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 "MyApp.entitlements" "tool/mytool" To enable harden runtime codesign --verbose --force --deep -o runtime --sign

September 5, 2019 · 1 min · 44 words · Khoa

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, improving performance and reducing network traffic. The URLCache class is used for caching responses from network resources. Your app can directly access the shared cache instance by using the shared property of URLCache....

July 3, 2019 · 1 min · 92 words · Khoa

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 pullsDown if we want to set title automatically and not scale button for title Read more Managing Pop-Up Buttons and Pull-Down Lists

June 29, 2019 · 1 min · 60 words · Khoa

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. https://developer.apple.com/documentation/foundation/nscoder/2292924-decodeobject If the coder responds true to requiresSecureCoding, then the coder calls failWithError(_:) in either of the following cases: The class indicated by cls doesn’t implement NSSecureCoding. The unarchived class doesn’t match cls, nor do any of its superclasses....

June 29, 2019 · 2 min · 312 words · Khoa

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 the collection view know that it must update its internal data structures and possibly update its visual appearance. You can move the item to a different section or to a new location in the same section....

June 27, 2019 · 1 min · 154 words · Khoa

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(title: "") let languages = ["Swift", "Javascript"] languages.forEach { let item = NSMenuItem(title: $0, action: #selector(handleSelectLanguage(_:)), keyEquivalent: "") item.target = self item.isEnabled = true languageMenu.addItem(item) } let themeMenu = NSMenu(title: "") let themes = ["one dark", "one light"] themes....

June 27, 2019 · 1 min · 118 words · Khoa

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 and How to make scrollable vertical NSStackView to make our ScrollableInput For easy Auto Layout, we use Anchors for UIScrollView. Things worth mentioned for vertical scrolling...

June 26, 2019 · 1 min · 202 words · Khoa

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: String, with rules: [Rule]) -> String? { return rules.compactMap({ $0.check(text) }).first } func validate(input: InputView, with rules: [Rule]) { guard let message = validate(text: input.textField.text ?? "", with: rules) else { input....

June 25, 2019 · 2 min · 305 words · Khoa