Ios 226

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 …

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 …

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

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 …

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 …

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 = {}; …

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

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

How to update widget for iOS 17

Issue #948

iOS 17 has a new Stand by mode so SwiftUI introduces containerBackground for the system to decide when to draw background. It also automatically applies margin to widget so we may need to disable that

To update existing widgets, we can …

How to move Core Data database to AppGroup folder

Issue #938

To let app and extension to talk to the same database, we need to use AppGroup. Here is how to use replacePersistentStore

Replaces one persistent store with another

actor DatabaseMigrator {
    @AppStorage( …

How to read write files to iCloud Drive

Issue #937

First, you need to enable iCloud Documents capability. Go to target settings -> Signing & Capabilities -> iCloud ` Screenshot 2023-07-28 at 16 09 14

Then inside your Info.plist, add this with your iCloud identifier and app name …

How to use keychain in Swift

Issue #934

There are a few keychain wrappers around but for simple needs, you can write it yourself

Here is a basic implementation. I use actor to go with async/await, and a struct KeychainError to contain status code in case we want to deal with …

How to make share and action extension in iOS

Issue #932

Add Share extension and Action extension respectively in Xcode. We can use the same code to both extension

Screenshot 2023-07-12 at 21 11 41

SwiftUI

I usually make a ShareView in SwiftUI with ShareViewModel to control the logic

struct ShareView: View {
    @ …

AppStore screenshots size checklist

Issue #931

AppStore screenshots

Screenshot specifications

iPhone 6.7"

Portrait 1290 x 2796

iPhone 6.5"

Portrait 1242 x 2688

In-App Purchase screenshots

In-app purchase information

iOS 640 x 920 tvO 1920 x1080 pixels macOS 1280 x 800 pixels

How to use AppIntents in iOS 16

Issue #930

AppIntents

Declare AppShortcutsProvider, note that appShortcuts uses @AppShortcutsBuilder syntax

import AppIntents

struct OurShortcutsProvider: AppShortcutsProvider {
    static var shortcutTileColor: ShortcutTileColor = .lightBlue …

SwiftUI EnvironmentValues

Issue #922

EnvironmentValues Views in SwiftUI can react to configuration information that they read from the environment using an Environment property wrapper

Updated for iOS 17

SwiftUI Environment values

How to make TextField Stepper in SwiftUI

Issue #921

Use HStack with TextField and a little extension

extension Binding where Value == Int {
    var toString: Binding<String> {
        Binding<String>(
            get: {
                "\(wrappedValue)"
            }, …

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

Learning Metal for SwiftUI

Issue #919

WWDC23 introduces lots of new additions to SwiftUI, notably Metal shader support with these modifiers

  • colorEffect: Returns a new view that applies shader to self as a filter effect on the color of each pixel.
  • layerEffect: Returns a new …

WWDC23 SwiftUI Q&A

Issue #918

Interesting SwiftUI Q&A during WWDC23

Observable vs ObservableObject

Q: With the new SwiftUI @Observable macro, are there any cases where ObservableObject would still be a better alternative?

A: Use ObservableObject when you need to …

What's new in SwiftUI iOS 17 at WWDC23

Issue #916

WWDC23 brings new additions to SwiftUI

Screenshot 2023-06-07 at 22 02 36

Scrolling

The scroll transition modifier is very similar to the visual effect modifier Curt used earlier for the welcome screen. It lets you apply effects to items in your scroll view.

I’m …

How to run parallel Task with Swift concurrency

Issue #911

Make an parallelTask function that wraps TaskGroup

public func parallelTask(@ParallelTaskBuilder builder: () -> [ParallelTaskBuilder.Work]) async {
    await withTaskGroup(of: Void.self) { group in
        for work in builder() { …

How to use Range and NSRange in Swift

Issue #910

Use one-sided range operator

let string = "Hello world"
string[string.startIndex...] // Hello world
string[..<string.endIndex] // Hello world

Substring

let string = "Hello world"
let range = string.startIndex ..< …

How to handle status bar with custom overlay UIWindow

Issue #908

When we add another UIWindow, then its rootViewController will decide the style of the status bar, not the rootViewController of the keyWindow anymore

childForStatusBarStyle

The usual way to fix this is to defer the decision to the correct …

How to use actor in Swift concurrency

Issue #905

Protect mutable state with Swift actors

Actor reentrancy

abc

Imagine we have two different concurrent tasks trying to fetch the same image at the same time. The first sees that there is no cache entry, proceeds to start downloading the …

How Task use thread in Swift concurrency

Issue #904

Consider this code where we have an ObservableObject with fetch1 and async fetch2, and a fetch inside ContentView

Here the observation in Xcode 14

  • ViewModel.fetch1: run on main thread
  • ViewModel.fetch2: run on cooperative thread pool …

How to handle shortcut intents in iOS

Issue #902

iOS 13 Intents Extension & Intents UI Extension

Siri can predict shortcuts to actions that a user may want to perform using your app, and suggest those shortcuts to the user in places such as …

How to use Universal Links in iOS

Issue #901

Apple app site association

https://com.example/.well-known/apple-app-site-association

Supporting Associated Domains New format from iOS 13 Can also remove components section if we match all URLs

{
  "applinks": { …

How to set popoverPresentationController sourceView in SwiftUI

Issue #894

Use a UIView as source view and set it in background

class ViewModel {
    lazy var sourceView = UIView()
}

struct SourceView: UIViewRepresentable {
    let viewModel: ViewModel

    func makeUIView(context: Context) -> UIView { …

How to get notification userInfo at launch

Issue #884

When user taps on push notification, depending on app state

SceneDelegate

Checking UIScene.ConnectionOptions.notificationResponse?.notification.request.content.userInfo in scene(_:willConnectTo:options:)

  • app terminated: sometimes nil
  • app …

How to use native SSL Pinning

Issue #880

From iOS 14, we can do Identity Pinning: How to configure server certificates for your app right from Info.plist

<key>NSAppTransportSecurity</key>
    <dict>
        <key>NSPinnedDomains</key> …

How to use NSPersistentCloudKitContainer

Issue #879

Setting Up Core Data with CloudKit

  • Enable iCloud
  • Enable CloudKit and Push Notifications
  • Enable Remote Notifications in the Background

Creating a Core Data Model for CloudKit

Initialize Your CloudKit Schema During Development

let …

How to add dot indicator to tab bar item in iOS

Issue #874

From iOS 13, use UITabBarAppearance and UITabBarItemAppearance

let appearance = UITabBarAppearance()

let itemAppearance = UITabBarItemAppearance(style: .stacked)
itemAppearance.normal.badgeBackgroundColor = .clear
itemAppearance.normal. …

How to use Multipeer Connectivity

Issue #873

Use assistant

let assistant = MCAdvertiserAssistant(serviceType: "my-service, discoveryInfo: nil, session: mcSession)
assistant.start()

let browser = MCBrowserViewController(serviceType: "my-service", session: mcSession) …

How to use Apple Pay in iOS

Issue #856

Use PKPaymentRequest and PKPaymentAuthorizationViewController

@MainActor
final class WalletViewModel: NSObject, ObservableObject {
    var canMakePayments: Bool {
        PKPaymentAuthorizationViewController.canMakePayments()
    } …

How to scale system font size to support Dynamic Type

Issue #847

We should use Dynamic Font Type as much as possible, as per Typography guide and https://www.iosfontsizes.com/

But in case we have to use a specific font, we can scale it with UIFontMetrics

import SwiftUI
import UIKit

extension Font { …

How to make multiline message text view in SwiftUI

Issue #843

This can be used in message bar input or some popover form. We use sizeThatFits to calculate the height so that it grow under certain height limit

import SwiftUI
import UIKit

struct MessageTextField: View {
    let placeholder: String …

How to make equal width buttons in SwiftUI

Issue #835

I usually define ButtonStyle to encapsulate common styles related to buttons. Here we specify .frame(maxWidth: .infinity) to let this button take the whole width as possible

struct MyActionButtonStyle: ButtonStyle {
    func makeBody( …

How to do NavigationLink programatically in SwiftUI

Issue #824

Use a custom NavigationLink with EmptyView as the background, this failable initializer accepts Binding of optional value. This works well as the destination are made lazily.

extension NavigationLink where Label == EmptyView {
    init …

How to make custom navigation bar in SwiftUI

Issue #823

Make atomic components and compose them. Firstly with NavigationBar that has custom leading and trailing content, there we can customize padding.

import SwiftUI

struct NavigationBar<Leading: View, Trailing: View>: View {
    @ …

How to highlight link in Text in SwiftUI

Issue #820

Use NSDataDetector to detect links, and NSMutableAttributedString to mark link range. Then we enumerateAttributes and build our Text

Screenshot 2021-07-06 at 07 23 56
func attribute(string: String) -> Text {
    guard let detector = try? NSDataDetector(types: …

How to cancel vertical scrolling on paging TabView in SwiftUI

Issue #814

From iOS 14, TabView has the PageTabViewStyle that turns TabView into the equivalent UIPageViewController.

We can of course implement our own Pager but the simple DragGesture does not bring the true experience of a paging UIScrollView or …

How to use SwiftFormat

Issue #811

Don’t add SwiftFormat as SPM package, instead use command line directly

if which swiftformat >/dev/null; then
  swiftformat .
else
  echo "warning: SwiftFormaat not installed, download from …

How to show context menu with custom preview in SwiftUI

Issue #809

Add a hidden overlay UIContextMenuInteraction. Provide preview in previewProvider and actions in actionProvider. Use @ViewBuilder to make declaring preview easy.

extension View {
    func contextMenuWithPreview<Content: View>( …

How to use SwiftLint in SPM project

Issue #807

Don’t add SwiftLint via SPM, but just add a Run Script Build phrase

if which swiftlint >/dev/null; then
  swiftlint
else
  echo "warning: SwiftLint not installed, download from https://github.com/realm/SwiftLint"
fi …

How to make your apps stand out on the AppStore

Issue #799

Besides coming up with a good idea and building the app, there are many other things you can do to boost your apps’ visibility

Twitter thread https://twitter.com/onmyway133/status/1387851727714635776 Thread reader …

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 use dynamic color in iOS

Issue #792

iOS 13 introduced Dark Mode with User Interface Style that makes it easy to support dark and light theme in our apps. Before we dive in, here are some official resources

How too save image to Photo library in iOS

Issue #790

Use UIImageWriteToSavedPhotosAlbum

Adds the specified image to the user’s Camera Roll album.

Let’s make an NSObject delegate class so we can perform target action to notify about completion

import UIKit

struct ImageService { …

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 make simple search bar in SwiftUI

Issue #776

We need to use a custom Binding to trigger onChange as onEditingChanged is only called when the user selects the textField, and onCommit is only called when return or done button on keyboard is tapped.

import UIKit
import SwiftUI
import …

How to fix share and action extension not showing up in iOS 14

Issue #775

My share sheet and action extension not showing up in iOS 14, built-in Xcode 12.3. The solution is to restart test device, and it shows up again.

Also make sure your extension targets have the same version and build number, and same …

How to add alternative app icons for iOS

Issue #749

Some apps want to support alternative app icons in Settings where user can choose to update app icon. Here’s some must do to make it work, as of Xcode 12.2

  • In Info.plist, must declare CFBundleIcons with both CFBundlePrimaryIcon and …

How to use UITextView in SwiftUI

Issue #747

Need to use Coordinator conforming to UITextViewDelegate to apply changes back to Binding

import SwiftUI
import UIKit

struct MyTextView: UIViewRepresentable {
    @Binding
    var text: String

    final class Coordinator: NSObject, …

How to check app going to background in SwiftUI

Issue #746

From iOS 13, the default is to support multiple scene, so the the old UIApplicationDelegate lifecycle does not work. Double check your Info.plist for UIApplicationSceneManifest key

<key>UIApplicationSceneManifest</key> …

How to make Auto Layout more convenient in iOS

Issue #742

Auto Layout has been around since macOS 10.7 and iOS 6.0 as a nicer way to do layouts over the old resizing masks. Besides some rare cases when we need to manually specify origins and sizes, Auto Layout is the preferred way to do …

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 avoid multiple match elements in UITests from iOS 13

Issue #691

Supposed we want to present a ViewController, and there exist both UIToolbar in both the presenting and presented view controllers.

From iOS 13, the model style is not full screen and interactive. From UITests perspective there are 2 …

How to test push notifications in simulator and production iOS apps

Issue #682

After has recently reminded about his updating APNs provider API which makes me realised a lot has changed about push notifications, both in terms of client and provider approach.

The HTTP/2-based Apple Push Notification service (APNs) …

How to draw arc corner using Bezier Path

Issue #673

To draw rounded 2 corners at top left and top right, let’s start from bottom left

let path = UIBezierPath()
// bottom left
path.move(to: CGPoint(x: 0, y: bounds.height))
// top left corner
path.addArc(withCenter: CGPoint(x: radius, y …

How to make dynamic font size for UIButton

Issue #671

Use adjustsFontForContentSizeCategory

A Boolean that indicates whether the object automatically updates its font when the device’s content size category changes.

If you set this property to YES, the element adjusts for a new …

How to test for view disappear in navigation controller

Issue #670

To test for viewWillDisappear during UINavigationController popViewController in unit test, we need to simulate UIWindow so view appearance works.

final class PopTests: XCTestCase {
    func testPop() {
        let window = UIWindow(frame: …

How to set text color for UIDatePicker

Issue #660

Apply tintColor does not seem to have effect.

datePicker.setValue(UIColor.label, forKeyPath: "textColor")
datePicker.setValue(false, forKey: "highlightsToday")

How to mask with UILabel

Issue #603

Need to set correct frame for mask layer or UILabel, as it is relative to the coordinate of the view to be masked

let aView = UIView(frame: .init(x: 100, y: 110, width: 200, height: 100))

let textLayer = CATextLayer()
textLayer. …

How to sync multiple CAAnimation

Issue #600

Use same CACurrentMediaTime

final class AnimationSyncer {
    static let now = CACurrentMediaTime()

    func makeAnimation() -> CABasicAnimation {
        let animation = CABasicAnimation(keyPath: "opacity")
        animation. …

How to build SwiftUI style UICollectionView data source in Swift

Issue #598

It’s hard to see any iOS app which don’t use UITableView or UICollectionView, as they are the basic and important foundation to represent data. UICollectionView is very basic to use, yet a bit tedious for common use cases, but …

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 test drag and drop in UITests

Issue #583

In UITests, we can use press from XCUIElement to test drag and drop

let fromCat = app.buttons["cat1"].firstMatch
let toCat = app.buttons["cat2"]
let fromCoordinate = fromCat.coordinate(withNormalizedOffset: CGVector(dx: 0, …

How to set corner radius in iOS

Issue #582

Use View Debugging

Run on device, Xcode -> Debug -> View debugging -> Rendering -> Color blended layer On Simulator -> Debug -> Color Blended Layer

Corner radius

How to work with SceneDelegate in iOS 12

Issue #580

Events

open url

Implement scene(_:openURLContexts:) in your scene delegate.

If the URL launches your app, you will get …

How to make rotation in same direction in iOS

Issue #571

From CGFloat.pi / 2 to -CGFloat.pi / 2 + epsilon

How to get updated safeAreaInsets in iOS

Issue #570

Use viewSafeArea

@available(iOS 11.0, *)
override func viewSafeAreaInsetsDidChange() {
    super.viewSafeAreaInsetsDidChange()

    self.collectionView.reloadData()
}

Use …

How to disable implicit decoration view animation in UICollectionView

Issue #569

From documentation https://developer.apple.com/documentation/uikit/uicollectionviewlayout/1617726-initiallayoutattributesforappear

This method is called after the prepare(forCollectionViewUpdates:) method and before the …

How to make simple adapter for delegate and datasource for UICollectionView and UITableView

Issue #567

Code

Make open Adapter

import UIKit

public protocol AdapterDelegate: class {

  /// Apply model to view
  func configure(model: Any, view: UIView, indexPath: IndexPath)

  /// Handle …

Why is didSelectItem not called in UICollectionView

Issue #550

Check

  • shouldHighlightItem -> shouldSelectItem -> didSelectItem
  • Gesture recognizer
  • isUserInteractionEnabled

How to take screenshots for UITest in Xcodee

Issue #539

XCUIScreenshot

extension XCTestCase {
    func takeScreenshot(name: String) {
        let screenshot = XCUIScreen.main.screenshot()
        let attach = XCTAttachment(screenshot: screenshot)
        attach.lifetime = .keepAlways …

How to fix UIToolbar Auto Layout issues

Issue #538

Hierarchy

UIToolbar -> _UIToolbarContentView -> _UIButtonBarStackVie

UIToolbarContentView

_UIToolbarContentView's width should equal 0
_UIToolbarContentView's height should equal 0

Workaround that fixes 1 warning

toolbar. …

How to use passed launch arguments in UITests

Issue #537

Specify launch arguments

In xcodebuild, specify launch arguments.

You can specify this under Launch Arguments in Run action of the app scheme or UITest scheme

Screenshot 2019-12-10 at 23 27 02
-AppleLanguages (jp) -AppleLocale (jp_JP)
(lldb) po ProcessInfo().arguments
▿ …

How to add padding to left right view in UITextField

Issue #536

extension UITextField {
    func setLeftView(_ view: UIView, padding: CGFloat) {
        view.translatesAutoresizingMaskIntoConstraints = true

        let outerView = UIView()
        outerView.translatesAutoresizingMaskIntoConstraints = …

How to set date color in UIDatePicker in iOS 13

Issue #535

datePicker.setValue(UIColor.green, forKey: "textColor")
datePicker.setValue(false, forKey: "highlightsToday")

In iOS 14

if #available(iOS 14.0, *) {
    datePicker.preferredDatePickerStyle = .wheels
    datePicker.tintColor …

How to fix cropped image in UIImageView

Issue #530

Although UIImageView frame is correct, image is still cropped. Watch out for any layer.mask within view

How to use decoration view in UICollectionView

Issue #529

indexPath

https://developer.apple.com/documentation/uikit/uicollectionviewlayoutattributes/1617786-layoutattributesfordecorationvie

It is up to you to decide how to use the indexPath parameter to identify a given decoration view. …

How to test UserDefaults in iOS

Issue #518

let userDefaults = UserDefaults(suiteName: suiteName)
userDefaults.removePersistentDomain(forName: suiteName)

https://developer.apple.com/documentation/foundation/userdefaults/1417339-removepersistentdomain

Calling this method is …

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 refresh receipt and restore in app purchase in iOS

Issue #496

Read this Restoring Purchased Products to understand the purposes between the 2.

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 …

How to add monkey test to iOS apps

Issue #484

Use SwiftMonkey which adds random UITests gestures

Add to UITests target

target 'MyAppUITests' do
  pod 'R.swift', '~> 5.0'
  pod 'SwiftMonkey', '~> 2.1.0'
end

Troubleshooting

Failed to …

How to use CommonCrypto in iOS

Issue #480

Use modulemap

modulemap approach

I use modulemap in my wrapper around CommonCrypto https://github.com/onmyway133/arcane, https://github.com/onmyway133/Reindeer

For those getting header not found, please take a look …

How to configure test target in Xcode

Issue #478

This applies to

  • Main targets
    • App
    • Framework
  • Test targets
    • Unit tests
    • UI tests

Examples

Dependencies used

Examples

  • Cocoapods
  • Carthage

Notes

  • Make sure test target can link to all the …

How to use external display in iOS

Issue #473

Before iOS 13

Use UIScreen.didConnectNotification

NotificationCenter.default.addObserver(forName: UIScreen.didConnectNotification,
                         object: nil, queue: nil) { (notification) in
        // Get the new screen …

How to show error message like Snack Bar in iOS

Issue #472

Build error view

Use convenient code from Omnia

To make view height dynamic, pin UILabel to edges and center

import UIKit

final class ErrorMessageView: UIView {
    let box: UIView = {
        let view = UIView()
        view. …

How to hide tab bar when push in iOS

Issue #471

let navigationController = UINavigationController(rootViewController: viewControllerA)
navigationController.pushViewController(viewControllerB, animated: true)

In view controller B, need to set hidesBottomBarWhenPushed in init

final class …

How to add trailing image to UILabel in iOS

Issue #470

Use NSTextAttachment inside NSAttributedString

extension UILabel {
    func addTrailing(image: UIImage) {
        let attachment = NSTextAttachment()
        attachment.image = image

        let attachmentString = NSAttributedString( …

How to handle different states in a screen in iOS

Issue #469

If there are lots of logics and states inside a screen, it is best to introduce parent and child container, and switch child depends on state. Each child acts as a State handler.

In less logic case, we can introduce a Scenario class that …

How to structure classes

Issue #466

iOS

View Controller -> View Model | Logic Handler -> Data Handler -> Repo

Android

Activity -> Fragment -> View Model | Logic Handler -> Data Handler -> Repo

How to zoom to fit many coordinates in Google Maps in iOS

Issue #463

func zoom(location1: CLLocation, location2: CLLocation) {
    let bounds = GMSCoordinateBounds(coordinate: location1.coordinate, coordinate: location2.coordinate)
    let update = GMSCameraUpdate.fit(bounds, withPadding: 16)
    mapView. …

How to use Codable to store preferences in Swift

Issue #462

Using object, we don’t need to care about nil vs false like in UserDefaults, our object is the source of truth

class StoringHandler<T: Codable> {
    private let key: Storage.Keys
    private let storage = Deps.storage …

How to custom UIAlertController in iOS

Issue #461

With UIAlertController we can add buttons and textfields, and just that

func addAction(UIAlertAction)
func addTextField(configurationHandler: ((UITextField) -> Void)?)

To add custom content to UIAlertController, there are some …

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 …

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

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

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 …

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 …

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

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 …

How to get url of app on the iOS AppStore

Issue #440

http://itunes.apple.com/[country]/app/[App–Name]/id[App-ID]?mt=8

For example https://apps.apple.com/nl/app/cutters/id1466739130

How to handle UICollectionView reloadData with selected index path

Issue #434

When calling collectionView.reloadData(), selected indexpath stays the same, but be aware that order of data may have changed

let selectedData = ...
let indexPathForSelectedData = ...

collectionView.scrollToItem(
    at: …

How to use Firebase ID token

Issue #424

One confusing point here that people often do not realize is that even though the custom token itself expires after one hour, a modern client SDK authenticated …

How to constrain to views inside UICollectionViewCell in iOS

Issue #422

To constrain views outside to elements inside UICollectionViewCell, we can use UILayoutGuide.

Need to make layout guide the same constraints as the real elements

let imageViewGuide = UILayoutGuide()
collectionView.addLayoutGuide( …

How to secure CVC in STPPaymentCardTextField in Stripe for iOS

Issue #421

private func maskCvcIfAny() {
    guard
        let view = paymentTextField.subviews.first(where: { !($0 is UIImageView) }),
        let cvcField = view.subviews
			.compactMap({ $0 as? UITextField })
			.first(where: { $0.tag == 2 …

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 speed up GMSMarker in Google Maps for iOS

Issue #412

  • Google Maps with a lot of pin, and no clustering can have bad performance if there are complex view in the marker.
  • The workaround is to use manual layout and rasterization

shouldRasterize

When the value of this property is true, the …

How to support drag and drop in UICollectionView iOS

Issue #411

See DragAndDrop example

class ViewController: UIViewController, UICollectionViewDropDelegate, UICollectionViewDragDelegate {

    // MARK: - UICollectionViewDragDelegate

    func collectionView(_ collectionView: UICollectionView, …

How to test Date with timezone aware in Swift

Issue #402

I want to test if a date has passed another date

let base =  Date(timeIntervalSince1970: 1567756697)
XCTAssertEqual(validator.hasPassed(event: event, date: base), true)

My hasPassed is using Calendar.current

func minuteSinceMidnight(date: …

How to do simple analytics in iOS

Issue #395

Prefer static enum to avoid repetition and error. The Log should have methods with all required fields so the call site is as simple as possible. How to format and assign parameters is encapsulated in this Analytics.

import Foundation …

How to choose Firebase vs Google Analytics

Issue #387

Google Analytics is shutting down. From Firebase Analytics console, we can choose to upgrade to Google Analytics, no code change is needed.

https://support.google.com/firebase/answer/9167112?hl=en

In October 2019, we will start to sunset …

How to use lessThan and greaterThan in Auto Layout in iOS

Issue #386

When it comes to right and bottom side, we should use negative values, and use lessThan, as it means less than a negative value

How to manage OneSignal push notification in iOS

Issue #377

OneSignal is an alternative for Parse for push notifications but the sdk has many extra stuff and assumptions and lots of swizzling.

We can just use Rest to make API calls. From https://github.com/onmyway133/Dust

Every official push …

How to do throttle and debounce using DispatchWorkItem in Swift

Issue #376

https://github.com/onmyway133/Omnia/blob/master/Sources/Shared/Debouncer.swift

import Foundation

public class Debouncer {
    private let delay: TimeInterval
    private var workItem: DispatchWorkItem?

    public init(delay: TimeInterval …

How to simplify UIApplication life cycle observation in iOS

Issue #375

final class LifecyclerHandler {
    private var observer: AnyObject!
    var action: (() -> Void)?
    private let debouncer = Debouncer(delay: 1.0)

    func setup() {
        observer = NotificationCenter.default.addObserver( …

How to do UITests with Google Maps on iOS

Issue #374

Interact with GMSMapView

Add accessibilityIdentifier to the parent view of GMSMapView. Setting directly onto GMSMapView has no effect

accessibilityIdentifier = "MapView"
let map = app.otherElements.matching(identifier: …

Make to make rounded background UIButton in iOS

Issue #373

UIButton.contentEdgeInsets does not play well with Auto Layout, we need to use intrinsicContentSize

final class InsetButton: UIButton {
    required init(text: String) {
        super.init(frame: .zero)

        titleLabel?.textColor = . …

How to make scrolling UIScrollView with Auto Layout in iOS

Issue #371

Scrolling UIScrollView is used in common scenarios like steps, onboarding. From iOS 11, UIScrollView has contentLayoutGuide and frameLayoutGuide

Docs

https://developer.apple.com/documentation/uikit/uiscrollview/2865870-contentlayoutguide …

How to fix Auto Layout issues in iOS

Issue #369

UITemporaryLayoutHeight and UITemporaryLayoutWidth

  • Demystify warnings with https://www.wtfautolayout.com/
  • Reduce priority
  • Use Auto Layout directly instead of using manual frame layout, specially for scrolling pager …

How to simplify anchor with NSLayoutConstraint in iOS

Issue #368

See https://github.com/onmyway133/Omnia/blob/master/Sources/iOS/NSLayoutConstraint.swift

extension NSLayoutConstraint {

    /// Disable auto resizing mask and activate constraints
    ///
    /// - Parameter constraints: constraints to …

How to handle link clicked in WKWebView in iOS

Issue #365

import WebKit
import SafariServices

final class WebViewHandler: NSObject, WKNavigationDelegate {
    var show: ((UIViewController) -> Void)?
    let supportedSchemes = ["http", "https"]

    func webView(_ webView: …

How to use AppFlowController in iOS

Issue #364

AppFlowController.swift

import UIKit
import GoogleMaps
import Stripe

final class AppFlowController: UIViewController {
    private lazy var window = UIWindow(frame: UIScreen.main.bounds)

    func configure() {
        GMSServices. …

How to declare UIGestureRecognizer in iOS

Issue #362

let tapGR = UITapGestureRecognizer(target: self, action: #selector(handleTap(_:)))

@objc private func handleTap(_ gr: UITapGestureRecognizer) {
    didTouch?()
}

We need to use lazy instead of let for gesture to work

lazy var tapGR = …

How to use Payment Intent and Setup Intents with Stripe in iOS

Issue #356

StripeHandler.swift

From Stripe 16.0.0 https://github.com/stripe/stripe-ios/blob/master/CHANGELOG.md#1600-2019-07-18

Migrates STPPaymentCardTextField.cardParams property type from STPCardParams to STPPaymentMethodCardParams

final class …

How to not resign first responder for UITextField in iOS

Issue #353

When using STPPaymentCardTextField from stripe-ios, the default behavior is when we touch outside to dismiss keyboard, it checks and focus on number text field is it is invalid

STPPaymentCardTextField.m

- (STPFormTextField *) …

How to use Firebase PhoneAuth in iOS

Issue #350

Read Authenticate with Firebase on iOS using a Phone Number

Disable swizzling

Info.plist

<key>FirebaseAppDelegateProxyEnabled</key>
<string>NO</string>

Enable remote notification

Enable Capability -> Background …

How to make digit passcode input in Swift

Issue #347

Add a hidden UITextField to view hierarchy, and add UITapGestureRecognizer to activate that textField.

Use padding string with limit to the number of labels, and prefix to get exactly n characters.

code

DigitView.swift

import UIKit

final …

How to make credit card input UI in Swift

Issue #346

We have FrontCard that contains number and expiration date, BackCard that contains CVC. CardView is used to contain front and back sides for flipping transition.

We leverage STPPaymentCardTextField from Stripe for working input fields, …

How to stop implicit animation when title change on UIButton

Issue #345

UIButton with system type has implicit animation for setTitle(_:for:)

Use this method to set the title for the button. The title you specify derives its formatting from the button’s associated label object. If you set both a title and an …

How to use addSubview in iOS

Issue #344

addSubview can trigger viewDidLayoutSubviews, so be careful to just do layout stuff in viewDidLayoutSubviews

This method establishes a strong reference to view and sets its next responder to the receiver, which is its new superview. …

How to run app on beta iOS devices

Issue #343

Xcode 10.3 with iOS 13

sudo ln -s /Applications/Xcode-beta.app/Contents/Developer/Platforms/iPhoneOS.platform/DeviceSupport/13.0 /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/DeviceSupport

Xcode 10.3 with iOS 13.1 …

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 do custom presentation with UIViewPropertyAnimator in iOS

Issue #337

Normally we just present from any UIViewController in any UINavigationController in UITabBarController and it will present over tabbar

present(detailViewController, animated: true, completion: nil)

If we have animation with …

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 simplify pager interaction with Rx

Issue #333

In a traditional pager with many pages of content, and a bottom navigation with previous and next button. Each page may have different content, and depending on each state, may block the next button.

The state of next button should state …

How to handle keyboard for UITextField in scrolling UIStackView in iOS

Issue #329

Firstly, to make UIStackView scrollable, embed it inside UIScrollView. Read How to embed UIStackView inside UIScrollView in iOS

It’s best to listen to keyboardWillChangeFrameNotification as it contains frame changes for Keyboard in …

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 deal with weak in closure in Swift

Issue #326

Traditionally, from Swift 4.2 we need guard let self

addButton.didTouch = { [weak self] in
    guard
        let self = self,
        let product = self.purchasedProduct()
    else {
        return

    self.delegate?.productViewController …

How to make material UITextField with floating label in iOS

Issue #325

  • Use UILabel as placeholder and move it
  • When label is moved up, scale it down 80%. It means it has 10% padding on the left and right when shrinked, so offsetX for translation is 10%
  • Translation transform should happen before scale
  • Ideally …

How to embed UIStackView inside UIScrollView in iOS

Issue #324

view.addSubview(scrollView)
scrollView.addSubview(stackView)

NSLayoutConstraint.on([
    scrollView.pinEdges(view: view),
    stackView.pinEdges(view: scrollView)
])

NSLayoutConstraint.on([
    stackView.widthAnchor.constraint(equalTo: …

How to make custom controller for View in iOS

Issue #318

I do UI in code, and usually separate between View and ViewController.

class ProfileView: UIView {}

class ProfileViewController: UIViewController {
	override func loadView() {
        self.view = ProfileView()
    }
}

But in places where …

How to make UIPanGestureRecognizer work with horizontal swipe in UICollectionView

Issue #315

extension PanCollectionViewController: UIGestureRecognizerDelegate {
    func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
        let velocity = panGR.velocity(in: panGR.view)
        return abs( …

How to use new APIs in iOS

Issue #313

iOS 10

UserNotifications

Push user-facing notifications to the user’s device from a server, or generate them locally from your app.

UIViewPropertyAnimator

A class that animates changes to views and allows the dynamic modification …

Links for WWDC

Issue #313

iOS 10

UserNotifications

Push user-facing notifications to the user’s device from a server, or generate them locally from your app.

UIViewPropertyAnimator

A class that animates changes to views and allows the dynamic modification …

What is new in iOS

Issue #313

iOS 10

UserNotifications

Push user-facing notifications to the user’s device from a server, or generate them locally from your app.

UIViewPropertyAnimator

A class that animates changes to views and allows the dynamic modification …

What's new in iOS

Issue #313

iOS 10

UserNotifications

Push user-facing notifications to the user’s device from a server, or generate them locally from your app.

UIViewPropertyAnimator

A class that animates changes to views and allows the dynamic modification …

How to get cell at center during scroll in UICollectionView

Issue #311

See Omnia https://github.com/onmyway133/Omnia/blob/master/Sources/iOS/UICollectionView.swift#L30

extension HorizontalUsersViewController: UIScrollViewDelegate {
    func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) { …

How to show location in Apple Maps and Google Maps app in iOS

Issue #309

Apple Maps

let placemark = MKPlacemark(coordinate: coordinate, addressDictionary: nil)
let mapItem = MKMapItem(placemark: placemark)
mapItem.name = shop.name
mapItem.openInMaps(launchOptions: [:])

Google Maps …

How to format distance in iOS

Issue #307

import MapKit

let formatter = MKDistanceFormatter()
formatter.unitStyle = .abbreviated
formatter.units = .metric
distanceLabel.text = formatter.string(fromDistance: distance) // 700m, 1.7km

How to test drive view in iOS

Issue #303

Instead of setting up custom framework and Playground, we can just display that specific view as root view controller

window.rootViewController = makeTestPlayground()

func makeTestPlayground() -> UIViewController {
    let content = …

How to make carousel layout for UICollectionView in iOS

Issue #302

Based on AnimatedCollectionViewLayout

final class CarouselLayout: UICollectionViewFlowLayout {
    override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
        guard let attributes = super. …

How to make simple pan to dismiss view in iOS

Issue #301

Make it more composable using UIViewController subclass and ThroughView to pass hit events to underlying views.

class PanViewController: UIViewController {
    var animator = UIViewPropertyAnimator(duration: 0, curve: .easeOut)
    lazy …

How to add indicator under tab bar buttons in iOS

Issue #288

selectionIndicatorImage

Use this property to specify a …

How to fix wrong status bar orientation in iOS

Issue #280

Original post https://medium.com/fantageek/how-to-fix-wrong-status-bar-orientation-in-ios-f044f840b9ed


When I first started iOS, it was iOS 8 at that time, I had a bug that took my nearly a day to figure out. The issue was that the status …

Learn iOS best practices by building a simple recipes app

Issue #258

I started iOS development when iOS 7 had been announced. And I have learned a bit, through working, advice from colleagues and the iOS community.

In this article, I’d like to share a lot of good practices by taking the example of a simple …

How to move tab bar icons down in iOS

Issue #250

UITabBarItem subclasses from UIBarItem which has imageInsets. We need both top and bottom to avoid shrinking

viewController1.tabBarItem.imageInsets = UIEdgeInsets(top: 10, left: 0, bottom: -10, right: 0)

How to test LaunchScreen in iOS

Issue #249

Making splash screen with LaunchScreen.storyboard is now the default way to do in iOS. Testing it with UITests is a bit tricky as this screen is showed the system, and if we test that, we are just testing the system.

What we should test is …

How to enable black mode in Google Maps in iOS

Issue #246

Use GMSMapStyle https://developers.google.com/maps/documentation/android-sdk/styling Export styling json from https://mapstyle.withgoogle.com/

let mapStyleUrl = Bundle.main.url(forResource: "mapStyle", withExtension: "json" …

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 fit UIBezierPath in frame in iOS

Issue #232

From https://github.com/xhamr/paintcode-path-scale with some updates

extension CGRect {
    var center: CGPoint {
        return CGPoint( x: self.size.width/2.0,y: self.size.height/2.0)
    }
}

extension CGPoint {
    func vector(to p1: …

How to use CAReplicatorLayer to make activity indicator in iOS

Issue #230

CAReplicatorLayer is a layer that creates a specified number of sublayer copies with varying geometric, temporal, and color transformations

Here we use instanceTransform which applies transformation matrix around the center of the …

How to do rotation for CALayer in iOS

Issue #229

Use keypath

let animation = CASpringAnimation(keyPath: #keyPath(CALayer.transform))
animation.fromValue = 0
animation.valueFunction = CAValueFunction(name: CAValueFunctionName.rotateZ)
animation.timingFunction = CAMediaTimingFunction(name: …

How to not use isRemovedOnCompletion for CAAnimation in iOS

Issue #228

CAAnimation is about presentation layer, after animation completes, the view snaps back to its original state. If we want to keep the state after animation, then the wrong way is to use CAMediaTimingFillMode.forward and …

How to make simple search box in iOS

Issue #227

final class SearchBox: UIView {
    lazy var textField: UITextField = {
        let textField = UITextField()
        let imageView = UIImageView(image: R.image.search()!)
        imageView.frame.size = CGSize(width: 20 + 8, height: 20) …

How to capture video in iOS simulator

Issue #226

Take screenshot

xcrun simctl io booted screenshot image.png

Record video

xcrun simctl io booted recordVideo video.mp4

How to use custom fonts in iOS

Issue #225

<key>UIAppFonts</key>
<array>
    <string>OpenSans-Bold.ttf</string>
    <string>OpenSans-BoldItalic.ttf</string>
    <string>OpenSans-ExtraBold.ttf</string>
    <string> …

How to create UITabBarController programmatically in iOS

Issue #224

let tabBarController = UITabBarController()

let navigationController1 = UINavigationController(rootViewController: viewController1)
let navigationController2 = UINavigationController(rootViewController: viewController2)
let …

How to ignore App Transport Security in iOS

Issue #221

Ignore a host

<key>NSAppTransportSecurity</key>
<dict>
    <key>NSExceptionDomains</key>
    <dict>
        <key>example.com</key>
        <dict>
            <key> …

How to use Stripe and Apple Pay in iOS

Issue #219

Show basic add card in iOS

import UIKit
import Stripe

final class MainController: UIViewController {

    func showPayment() {
        let addCardViewController = …

Understanding AVFoundation and MediaPlayer frameworks in iOS

Issue #210

Depending on what features we want to achieve, we need to go with either AVFoundation or MediaPlayer framework. As someone who worked with many apps that involve media playback, here are some of my observations

MPMoviePlayerController vs …

How to handle reachability in iOS

Issue #209

Here are what I learn about reachability handling in iOS, aka checking for internet connection. Hope you will find it useful, too.

This post starts with techniques from Objective age, but many of the concepts still hold true

The naive way …

How to zoom in double in MapKit

Issue #183

func zoomInDouble(coordinate: CLLocationCoordinate2D) {
    let region = mapView.region
    let zoomInRegion = MKCoordinateRegion(
        center: coordinate,
        span: MKCoordinateSpan(
            latitudeDelta: region.span. …

How to select cluster annotation in MapKit

Issue #182

func mapView(_ mapView: MKMapView, didSelect view: MKAnnotationView) {
    guard let coordinate = view.annotation?.coordinate else {
        return
    }
    
    if (view.annotation is MKClusterAnnotation) {
        zoomInDouble( …

How to cluster annotations in MapKit in iOS 11

Issue #181

https://developer.apple.com/documentation/mapkit/mkannotationview/decluttering_a_map_with_mapkit_annotation_clustering

final class AnnotationView: MKMarkerAnnotationView {
    override init(annotation: MKAnnotation?, reuseIdentifier: …

How to get properties of JSValue in JavascriptCore

Issue #179

let rough = context.objectForKeyedSubscript("myObject")
myObject.toDictionary()

Using CircleCI 2.0

Issue #158

We ’ve been using CircleCI for many of our open source projects. Since the end of last year 2017, version 2.0 began to come out, and we think it’s good time to try it now together with Swift 4.1 and Xcode 9.3

The problem with …

UITableViewCell and Model

Issue #154

The most common UI element in iOS is UITableView, and the most common task is to display the UITableViewCell using the model.

Although the title specifies UITableViewCell, but the problem involves other views (UICollectionView, custom …

Learning from Open Source Generic Factory

Issue #148

From https://github.com/devxoul/Pure/blob/master/Sources/Pure/FactoryModule.swift

public protocol FactoryModule: Module {

  /// A factory for `Self`.
  associatedtype Factory = Pure.Factory<Self>

  /// Creates an instance of a …

How to use standalone UINavigationBar in iOS

Issue #144

There are times we want the same UIViewController to look good when it’s presented modally or pushed from UINavigationController stack. Take a look at BarcodeScanner and the PR https://github.com/hyperoslo/BarcodeScanner/pull/82

When …

How to deal with animation in UITests in iOS

Issue #143

Today I was writing tests and get this error related to app idle

    t =    23.06s         Assertion Failure: <unknown>:0: Failed to scroll to visible (by AX action) Button, 0x6000003827d0, traits: 8858370049, label: 'cart', …

How to use R.swift in UITest in iOS

Issue #138

Here is how to use R.swift in UITest target

  • Add Localizable.strings to UITest target
  • Declare pod
target 'MyAppUITests' do
  pod 'R.swift', '~> 4.0'
end
  • In UITest target settings, add $(FRAMEWORK_SEARCH_PATHS) …

Hiding back button in navigation bar in iOS

Issue #137

Use a custom NavigationController

import UIKit

class NavigationController: UINavigationController {
  override func viewDidLoad() {
    super.viewDidLoad()
    navigationBar.tintColor = .white
    navigationBar.barStyle = .black …

Using dlopen in iOS

Issue #133

With dlopen we can make uses of some private frameworks. It will be fun

From iPhone X home button

#import <dlfcn.h>

// somewhere in viewDidLoad
dlopen([binaryPath cStringUsingEncoding:NSUTF8StringEncoding], RTLD_NOW);
UIView *const …

How to prevent UIVisualEffectView crash

Issue #124

We all know that there’s a potential crash with UIVisualEffectView on iOS 11. The fix is to not add sub views directly to UIVisualEffectView, but to its contentView. So we should change

effectView.addSubview(button)

to

effectView. …

Collection Update

Issue #119

This is about collection update, how to provide correct IndexPath and a simple diffing algorithm

Using Playground with CocoaPods

Issue #113

This is a follow up from my post Learning from Open Source: Using Playground on how to actually add a playground to your production project.

The idea is simple: create a framework so that Playground can access the code. This demo an iOS …

URL Routing with Compass

Issue #110

Medium version https://medium.com/@onmyway133/url-routing-with-compass-d59c0061e7e2


Apps often have many screens, and UIViewController works well as the basis for a screen, together with presentation and navigation APIs. Things are fine …

Coordinator and FlowController

Issue #106

Every new architecture that comes out, either iOS or Android, makes me very excited. I’m always looking for ways to structure apps in a better way. But after some times, I see that we’re too creative in creating architecture, …

It's good to have a CI

Issue #101

I have Unit tests and UI tests pass on my simulator and device, locally. But when I make the build on Buddybuild, it fails with the reason Activity cannot be used after its scope has completed. People seem to have the same issue too. …

Diff algorithm

Issue #99

I’ve been searching for efficient ways to diff collections, here are some interesting papers that I find

Myers

How to use safeAreaLayoutGuide in iOS 10

Issue #98

The safeAreaLayoutGuide was introduced in iOS 11. And it is advised to stop using topLayoutGuide bottomLayoutGuide as these are deprecated.

To use safeAreaLayoutGuide, you need to do iOS version check

if #available(iOS 11.0, *) { …

Learning from Open Source Using Coordinator

Issue #97

The Coordinator pattern can be useful to manage dependencies and handle navigation for your view controllers. It can be seen from BackchannelSDK-iOS, take a look at BAKCreateProfileCoordinator for example

@implementation …

Learning from Open Source Managing dependencies

Issue #96

Another cool thing about ios-oss is how it manages dependencies. Usually you have a lot of dependencies, and it’s good to keep them in one place, and inject it to the objects that need.

The Environment is simply a struct that holds …

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 …

Testing keychain in iOS

Issue #92

Today I was upgrading Keychain to swift 4, and take this opportunity to fix the test. The tests pass on macOS, but on iOS, I get -25300 error for

var status = SecItemCopyMatching(query as CFDictionary, nil)

It is because there is no …

What about performance?

Issue #85

That’s the question I hear often when people are introduced to a new framework. It’s a valid concern. But it seems to me that they ask this just for fun. To my surprise, most people just don’t care, and the frameworks with …

How to do implement notification in iOS with Firebase

Issue #64

Note: This applies to Firebase 4.0.4

Preparing push notification certificate

Go to Member Center -> Certificates -> Production

Certificate

You can now use 1 certificate for both sandbox and production environment push

Auth Key

  • If you …

Pixel and point

Issue #59

TL;DR: Don’t use nativeScale and nativeBounds, unless you’re doing some very low level stuff

What is point and pixel

From …

Favorite WWDC 2017 sessions

Issue #56

  1. Introducing Core ML
  • Core ML
  1. Introducing ARKit: Augmented Reality for iOS
  • ARKit
  1. What’s New in Swift
  • String
  • Generic
  • Codable
  1. Advanced Animations with UIKit
  • Multiple animation
  • Interactive animation …

How to run UITests with map view in iOS

Issue #45

Mock a location

You should mock a location to ensure reliable test

Create the gpx file

Go to Xcode -> File -> New -> GPX File

gpx

It looks like

<?xml version="1.0"?>
<gpx version="1.1" creator="Xcode" …

How to use MainController in iOS

Issue #36

Usually in an app, we have these flows: onboarding, login, main. And we usually set OnboardingController, LoginController and MainController as the root view controller respectively depending on the state.

I find it useful to have the …

How to handle Auto Layout with different screen sizes

Issue #35

Auto Layout is awesome. Just declare the constraints and the views are resized accordingly to their parent ’s bounds changes. But sometimes it does not look good, because we have fixed values for padding, width, height, and even fixed …

How to define SDK and Deployment Target in iOS

Issue #33

I see that my answer to the question What’s the meaning of Base SDK, iOS deployment target, Target, and Project in xcode gets lots of views, so I think I need to elaborate more about it

Good read

App backed by website in iOS 9

Issue #32

iOS 9 introduces new ways for your app to work better, backed by your websites

Smart App Banners

If the app is already installed on a user’s device, the banner intelligently changes its action, …

How to make lighter AppDelegate in iOS

Issue #24

There is Lighter View Controllers, and there is Lighter AppDelegate, too

Since working with iOS, I really like the delegate pattern, in which it helps us defer the decision to another party.

The iOS application delegates its event to …

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 …

How to create a piano using iOS 9 Auto Layout

Issue #22

In the beginning, people use frame and Autoresizing Mask, then they use Auto Layout, then iOS 9 encourages them to use NSLayoutAnchor, UILayoutGuide and UIStackView

For more convenient Auto Layout, check How to make Auto Layout more …

How to handle RefreshControl in iOS

Issue #20

The other day I was doing refresh control, and I saw this Swift Protocols with Default Implementations as UI Mixins

extension Refreshable where Self: UIViewController
{
    /// Install the refresh control on the table view
    func …

How to hack iOS apps

Issue #19

We need to care about security nowadays, here are some links I find useful to read more about this matter

Hello world, again

Issue #1

I’ve used Wordpress, then moved to GitHub Pages with Jekyll, Octopress, Hexo, Hugo. You can view my page here http://fantageek.com/. It was good with all the custom themes and Disqus

But then I was a bit lazy with all the commands …