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: .macOS(.v14, .v15)) { $0.drawsBackground = true $0.backgroundColor = .clear }

November 5, 2024 · 1 min · 44 words · Khoa

How to conditionally render widgets in iOS

Issue #984 The WidgetBundle lets us expose multiple widgets from a single widget extension It uses WidgetBundleBuilder to constructs a widget bundle’s body. In iOS 18, if we include ControlWidget then we need to check iOSApplicationExtension iOS 18. For now in Xcode 16 there’s a bug that prevents existing widgets from appearing in iOS 17. We can leverage WidgetBundleBuilder to conditionally render widgets for each iOS version import SwiftUI import WidgetKit import Widgets @main struct OurAppWidgetBundle: WidgetBundle { var body: some Widget { if #available(iOSApplicationExtension 18....

September 25, 2024 · 1 min · 123 words · Khoa

How to open app with Control Widget on iOS 18

Issue #983 In iOS 18, we can make Control Widget in Widget extension import WidgetKit import SwiftUI @available(iOS 18.0, *) struct BookControlWidget: ControlWidget { var body: some ControlWidgetConfiguration { StaticControlConfiguration(kind: "Book") { ControlWidgetButton(action: BookIntent()) { Label("Book", systemImage: "airplane") } } .displayName("Book") } } import AppIntents @available(iOS 18.0, *) struct BookIntent: AppIntent { static let title: LocalizedStringResource = "Book" static var openAppWhenRun = true static var isDiscoverable = true func perform() async throws -> some IntentResult & OpensIntent { let url = URL(string: "myapp://book")!...

September 25, 2024 · 2 min · 389 words · Khoa

How to use NSFetchedResultsController memory wise in Core Data

Issue #982 If you’re using NSFetchedResultsController in Core Data, it might take up a lot of memory, especially when working with large datasets. To keep your app running smoothly, it’s important to manage memory efficiently Use Fetch Limits and Batch Fetching If your dataset is large, limit the number of objects fetched at a time. You can achieve this by setting a fetchBatchSize and a fetchLimit on your NSFetchRequest. fetchBatchSize: This controls how many objects Core Data will fetch in memory at a time....

September 24, 2024 · 3 min · 547 words · Khoa

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 you’re dragging will be copied. This means the original stays in place, and a duplicate is created in the new location. When to Use: Use this when you want to create a copy of a file or item, without removing it from the original spot....

September 23, 2024 · 3 min · 609 words · Khoa

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 First, let’s create a SwiftUI view that will represent the macOS view controller. We’ll use the NSViewControllerRepresentable protocol to bridge SwiftUI and AppKit. import SwiftUI import AppKit struct CollectionView: NSViewControllerRepresentable { func makeNSViewController(context: Context) -> CollectionViewController { return CollectionViewController() } func updateNSViewController(_ nsViewController: CollectionViewController, context: Context) { nsViewController....

August 15, 2024 · 3 min · 627 words · Khoa

How to sign in with Apple and Firebase and Supabase

Issue #977 Show ASAuthorizationController with a simple nonce. Once we have the idToken, create an OAuthProvider.appleCredential and pass to Firebase Auth final class AppleLoginService: NSObject { static let shared = AppleLoginService() private var nonce: String? func show() { let nonce = generateNonce() self.nonce = nonce let provider = ASAuthorizationAppleIDProvider() let request = provider.createRequest() request.requestedScopes = [.fullName, .email] request.nonce = nonce?.sha256 let vc = ASAuthorizationController(authorizationRequests: [request]) vc.delegate = self vc.presentationContextProvider = self vc....

August 3, 2024 · 1 min · 207 words · Khoa

How to detect Barcode and QR code

Issue #973 Before iOS 11, we used to use CIDetector and CIDetectorTypeQRCode to detect QR code CIDetector An image processor that identifies notable features, such as faces and barcodes, in a still image or video. CIDetectorTypeQRCode A detector that searches for Quick Response codes (a type of 2D barcode) in a still image or video, returning CIQRCodeFeature objects that provide information about detected barcodes. func readQrOnly(image: CGImage) async -> String? { let ciImage = CIImage(cgImage: image) let detector = CIDetector( ofType: CIDetectorTypeQRCode, context: nil, options: [ CIDetectorAccuracy: CIDetectorAccuracyHigh ] ) guard let detector = detector else { return nil } let features = detector ....

June 6, 2024 · 2 min · 271 words · Khoa

How to make swifty UserDefaults

Issue #972 We want to have a swifty UserDefaults API that works with subscript and in a type safe manner. extension Defaults.Keys { static let string = Defaults.Key("string", default: "0") } XCTAssertEqual(defaults[.string], "0") defaults[.string] = "1" XCTAssertEqual(defaults[.string], "1") UserDefaults plist compatibility Define Compatible protocol that allows value to be plist compatible The value parameter can be only property list objects: NSData, NSString, NSNumber, NSDate, NSArray, or NSDictionary. For NSArray and NSDictionary objects, their contents must be property list objects....

May 28, 2024 · 3 min · 504 words · Khoa

How to use OSLog and OSLogStore in Swift

Issue #970 We can use Logger to log and OSLogStore to retrieve logs import OSLog import ReuseAcross final class LogService { static let shared = LogService() let logger = Logger( subsystem: "com.example.myapp", category: "Log" ) func export() -> [String] { do { let store = try OSLogStore(scope: .currentProcessIdentifier) let position = store.position(timeIntervalSinceLatestBoot: 1) let logs = try store .getEntries(at: position) .compactMap { $0 as? OSLogEntryLog } .filter { $0.subsystem == Bundle....

February 8, 2024 · 1 min · 104 words · Khoa

How to escape characters in json and regex with Swift string

Issue #963 In the world of Swift programming, we often come across situations where we need to work with string literals that contain special characters. These characters can include new lines, tabs, backslashes, and quotes — all of which need to be handled appropriately to ensure they don’t inadvertently affect the structure or behavior of our code. Traditionally, we negate their special meaning by escaping them with backslashes. However, Swift provides an even simpler method — raw strings....

January 12, 2024 · 4 min · 812 words · Khoa

How to use nextjs Image

Issue #962 Fill parent div A boolean that causes the image to fill the parent element, which is useful when the width and height are unknown. The parent element must assign position: “relative”, position: “fixed”, or position: “absolute” style. <div className="relative"> <Image src="" alt="" fill objectFit="cover" /> </div>

January 7, 2024 · 1 min · 48 words · Khoa

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

January 7, 2024 · 1 min · 29 words · Khoa

Building an iOS camera calculator with Core ML’s Vision and Tesseract OCR

Issue #960 Also written on Fritz Math might be scary, but it’s an essential part of everyday life. Wouldn’t it be cool if we could build an app, point our phone’s camera at an expression, and let the app compute the result? Whenever I’ve needed to use math, I’ve wished this was possible. Now, with advances in machine learning and vision recognition in iOS, this is doable. In this guide, I’ll provide some of the technical details for working with Vision in iOS, as well as my personal experiences using this technology....

December 31, 2023 · 12 min · 2460 words · Khoa

How to decode dynamic JSON key with JSONDecoder

Issue #959 Decoding JSON in Swift is most of the time very straightforward with help of Codable protocol and JSONDecoder. Sometimes the json contains dynamic key, like { "shipmunk": { "name": "Shipmunk", "link": "https://indiegoodies.com/shipmunk" }, "pastepal": { "name": "PastePal", "link": "https://indiegoodies.com/pastepal" }, "codelime": { "name": "Codelime", "link": "https://indiegoodies.com/codelime" } } Decoding JSON with dynamic keys in Swift can be tricky because the keys in your data can change, and Swift likes to know exactly what it’s working with ahead of time....

December 21, 2023 · 2 min · 378 words · Khoa

How to bundle js for use in JavaScriptCore in Swift

Issue #958 We can use any bundler, like Parcel, Webpack or Vite. Here I use Webpack 5 Install Webpack and Babel npm install @babel/polyfill webpack webpack-cli --save-dev @babel/polyfill is a package provided by Babel, a popular JavaScript compiler. The polyfill is a way to bring modern JavaScript features and APIs to older browsers that don’t support them natively. Before ES6 (ECMAScript 2015), JavaScript lacked many features that are now considered standard....

December 7, 2023 · 2 min · 251 words · Khoa

How to handle log in JSContext with JavascriptCore

Issue #957 Define console object and set log function to point to our Swift function import JavaScriptCore extension JSContext { func injectConsoleLog() { evaluateScript( """ var console = {}; """ ) let consoleLog: @convention(block) (Any) -> Void = { print($0) } objectForKeyedSubscript("console") .setObject(consoleLog, forKeyedSubscript: "log" as NSString) } } Then we can just call let context = JSContext()! context.injectConsoleLog() context.evaluateScript(jsContent)

December 7, 2023 · 1 min · 60 words · Khoa

Apple Developer Learning resources

Issue #955 Besides WWDC videos & documentation, Apple also has interactive tutorials and books. Below are some of my favorites learning resources Tutorials Introducing SwiftUI: SwiftUI is a modern way to declare user interfaces for any Apple platform. Create beautiful, dynamic apps faster than ever before. Develop apps for iOS: Learn the basics of Xcode, SwiftUI, and UIKit to create compelling iOS apps. Develop in Swift: Develop in Swift Tutorials are a great first step toward a career in app development using Xcode, Swift, and SwiftUI....

November 29, 2023 · 1 min · 106 words · Khoa

How to show anchor bottom view in SwiftUI

Issue #954 From iOS 15, there’s a handy safeAreaInset that allows us to place additional content extending the safe area. Shows the specified content beside the modified view. safeAreaInset allows us to customize which edge and alignment we can place our views. This works for both ScrollView, List and Form and you can apply it multiple times. The content view is anchored to the specified horizontal edge in the parent view, aligning its vertical axis to the specified alignment guide....

November 22, 2023 · 2 min · 218 words · Khoa

How to store Codable in AppStorage

Issue #949 AppStorage and SceneStorage accepts RawRepresentable where value is Int or String. Creates a property that can read and write to a string user default, transforming that to RawRepresentable data type. init(wrappedValue:_:store:) init( wrappedValue: Value, _ key: String, store: UserDefaults? = nil ) where Value : RawRepresentable, Value.RawValue == String One clever thing (that does not work) is to use a custom Codable type that conforms to RawRepresentable, like below...

October 3, 2023 · 2 min · 333 words · Khoa