How to find subview recursively in Swift

Issue #460 extension UIView { func findRecursively<T: UIView>(type: T.Type, match: (T) -> Bool) -> T? { for view in subviews { if let subview = view as? T, match(subview) { return subview } else { return view.findRecursively(type: type, match: match) } } return nil } }

October 11, 2019 · 1 min · 46 words · Khoa

How to deal with multiple scenarios with Push Notification in iOS

Issue #459 Here are my notes when working with Push Notification How to register Register to receive push notification registerForRemoteNotificationTypes is deprecated in iOS 8+ UIApplication.sharedApplication().registerForRemoteNotifications() Register to alert user through UI If your app displays alerts, play sounds, or badges its icon, you must call this method during your launch cycle to request permission to alert the user in these ways let types: UIUserNotificationType = [.Badge, .Sound, .Alert] let categories = Set<UIUserNotificationCategory>() let settings = UIUserNotificationSettings(forTypes: types, categories: categories) UIApplication....

October 11, 2019 · 6 min · 1214 words · Khoa

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 https://developer.apple.com/documentation/xcode_release_notes/xcode_11_release_notes we can just use Apple Development and Apple Distribution certificate for multiple platforms Signing and capabilities settings are now combined within a new Signing & Capabilities tab in the Project Editor. The new tab enables using different app capabilities across multiple build configurations....

October 11, 2019 · 1 min · 142 words · Khoa

How to create watch only watchOS app

Issue #457 From Creating Independent watchOS Apps The root target is a stub, and acts as a wrapper for your project, so that you can submit it to the App Store. The other two are identical to the targets found in a traditional watchOS project. They represent your WatchKit app and WatchKit extension, respectively.

October 10, 2019 · 1 min · 54 words · Khoa

How to use provisional notification in iOS 12

Issue #456 From WWDC 2018 What’s New in User Notifications Instead, the notifications from your app will automatically start getting delivered. Notifications that are delivered with provisional authorization will have a prompt like this on the notification itself. And this will help the users decide after having received a few notifications whether they want to keep getting these notifications or whether they want to turn them off It’s an automatic trial of the notifications from your app to help your users make a more informed decision about whether they want these notifications....

October 10, 2019 · 2 min · 281 words · Khoa

How to check if push notification is actually enabled in iOS

Issue #455 There are times we want to log if user can receive push notification. We may be tempted to merely use isRegisteredForRemoteNotifications but that is not enough. From a user ’s point of view, they can either receive push notification or not. But behind the scene, many factors are in the game. It can be that user has disabled push notification in app settings or in iOS Settings. It can also be that user enables push notification but disables all sound or banner display mechanism....

October 10, 2019 · 2 min · 289 words · Khoa

How to use UserNotificationsUI in iOS

Issue #454 From documentation https://developer.apple.com/documentation/usernotificationsui Customize how local and remote notifications appear on the user’s device by adding a notification content app extension to the bundle of your iOS app. Your extension manages a custom view controller, which you use to present the content from incoming notifications. When a notification arrives, the system displays your view controller in addition to, or in place of, the default system interface. https://developer.apple.com/documentation/usernotificationsui/customizing_the_appearance_of_notifications When an iOS device receives a notification containing an alert, the system displays the contents of the alert in two stages....

October 10, 2019 · 1 min · 166 words · Khoa

How to use AnyHashable in Swift

Issue #453 From documentation A type-erased hashable value. DiscussionThe AnyHashable type forwards equality comparisons and hashing operations to an underlying hashable value, hiding its specific underlying type.You can store mixed-type keys in dictionaries and other collections that require Hashable conformance by wrapping mixed-type keys in AnyHashable instances let descriptions: [AnyHashable: Any] = [ AnyHashable("😄"): "emoji", AnyHashable(42): "an Int", AnyHashable(Int8(43)): "an Int8", AnyHashable(Set(["a", "b"])): "a set of strings" ] print(descriptions[AnyHashable(42)]!) // prints "an Int" print(descriptions[AnyHashable(43)]) // prints "nil" print(descriptions[AnyHashable(Int8(43))]!...

October 10, 2019 · 1 min · 110 words · Khoa

How to register for alert push notification in iOS

Issue #452 Use UserNotifications framework import FirebaseMessaging import UserNotifications final class PushHandler: NSObject { private let center = UNUserNotificationCenter.current() private let options: UNAuthorizationOptions = [.alert] func setup() { Messaging.messaging().delegate = self } func register() { center.requestAuthorization(options: options, completionHandler: { granted, error in print(granted, error) self.getSettings() }) } func getSettings() { center.getNotificationSettings(completionHandler: { settings in guard case let .authorized = settings.authorizationStatus, case let .enabled = settings.alertSetting, settings.alertStyle != .none else { return } // TODO }) } func handle(userInfo: [AnyHashable: Any]) { } } extension PushHandler: MessagingDelegate { func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String) { print(fcmToken) } func messaging(_ messaging: Messaging, didReceive remoteMessage: MessagingRemoteMessage) { print(remoteMessage) } } @UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate { func application( _ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) { completionHandler(....

October 10, 2019 · 1 min · 169 words · Khoa

How to flat map publisher of publishers in Combine

Issue #451 For some services, we need to deal with separated APIs for getting ids and getting detail based on id. To chain requests, we can use flatMap and Sequence, then collect to wait and get all elements in a single publish FlatMap Transforms all elements from an upstream publisher into a new or existing publisher. struct FlatMap<NewPublisher, Upstream> where NewPublisher : Publisher, Upstream : Publisher, NewPublisher.Failure == Upstream.Failure Publishers.Sequence...

October 9, 2019 · 1 min · 191 words · Khoa

How to make container view in SwiftUI

Issue #450 Following the signatures of ScrollView and Group, we can create our own container public struct ScrollView<Content> : View where Content : View { /// The content of the scroll view. public var content: Content } extension Group : View where Content : View { /// The type of view representing the body of this view. /// /// When you create a custom view, Swift infers this type from your /// implementation of the required `body` property....

October 9, 2019 · 2 min · 225 words · Khoa

How to show web content as QR code in SwiftUI in watchOS

Issue #449 WatchKit does not have Web component, despite the fact that we can view web content https://www.imore.com/how-view-web-pages-apple-watch-watchos-5 A workaround is to show url as QR code import SwiftUI struct QRCodeView: View { let title: String let url: URL var body: some View { GeometryReader { geometry in VStack { self.makeImage(size: geometry.size) .padding(.top, 10) Text("Scan to open") .font(.system(.footnote)) }.navigationBarTitle(self.title) } } private func makeImage(size: CGSize) -> some View { let value = size....

October 8, 2019 · 1 min · 86 words · Khoa

How to load remote image in SwiftUI

Issue #448 Use ObservableObject and onReceive to receive event. URLSession.dataTask reports in background queue, so need to .receive(on: RunLoop.main) to receive events on main queue. For better dependency injection, need to use ImageLoader from Environment There should be a way to propagate event from Publisher to another Publisher, for now we use sink ImageLoader.swift import Combine import WatchKit class ImageLoader: ObservableObject { private var cancellable: AnyCancellable? let objectWillChange = PassthroughSubject<UIImage?, Never>() func load(url: URL) { self....

October 8, 2019 · 1 min · 184 words · Khoa

How to do navigation in SwiftUI in watchOS

Issue #447 NavigationView is not available on WatchKit, but we can just use NavigationLink List(services.map({ AnyService($0) })) { anyService in NavigationLink(destination: ItemsView(service: anyService.service) .navigationBarTitle(anyService.service.name) .onDisappear(perform: { anyService.service.requestCancellable?.cancel() }) ) { HStack { Image(anyService.service.name) .resizable() .frame(width: 30, height: 30, alignment: .leading) Text(anyService.service.name) } } } Adding NavigationLink to a View adds a round shadow cropping effect, which is usually not want we want. But we shouldn’t wrap Button as Button handles its own touch event, plus it has double shadow effect....

October 8, 2019 · 1 min · 110 words · Khoa

How to use protocol in List in SwiftUI

Issue #446 Suppose we have Service protocol, and want to use in List protocol Service { var name: String { get } } struct MainView: View { let services = [ Car() Plane() ] var body: some View { List(services) { service in HStack { Image(service.name) Text(service.name) } } } } This is not possible because item in List needs to conform to Identifiable Protocol type ‘Service’ cannot conform to ‘Identifiable’ because only concrete types can conform to protocols...

October 7, 2019 · 2 min · 231 words · Khoa

How to support Swift Package Manager for existing projects

Issue #445 How to add SPM Run swift package init Check enum for version for each platform https://developer.apple.com/documentation/swift_packages/supportedplatform/tvosversion Example https://github.com/onmyway133/Anchors/blob/master/Package.swift // swift-tools-version:5.1 import PackageDescription let package = Package( name: "Anchors", platforms: [ .macOS(.v10_11), .iOS(.v9), .tvOS(.v9) ], products: [ .library( name: "Anchors", targets: ["Anchors"]), ], targets: [ .target( name: "Anchors", dependencies: [], path: "Sources" ), .testTarget( name: "AnchorsTests", dependencies: ["Anchors"]), ], swiftLanguageVersions: [.v5] ) To test, swift test to test locally, this should validate Package....

October 7, 2019 · 1 min · 202 words · Khoa

How to fix unreadable ASCII characters in Swift

Issue #444 To avoid compiler error Unprintable ASCII character found in source file, from Swift 5, we can use isASCII. Run this from the generator app that generates Swift code. let normalized = weirdString.filter({ $0.isASCII }) For more check, see Character https://developer.apple.com/documentation/swift/character/3127011-isletter Watch out for Delete/House symbol ⌂ code 127 (0x7f) The above does not seem to work, use find to find  character (copy Sublime Text to see 0x7f character)...

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

Support

Thanks for downloading my app. For any inquiries, please contact me at onmyway133@gmail.com

October 6, 2019 · 1 min · 13 words · Khoa

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.isSelectable = true textView.drawsBackground = false textView.allowsUndo = true

October 5, 2019 · 1 min · 34 words · Khoa

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

October 4, 2019 · 1 min · 29 words · Khoa