Khoa Pham
Khoa Pham

Ohayo

Swift Discovery

Discover all the tech

Featured

My year in review 2020

Issue #715

I remember this time last year in December 2019, I spent almost every single bit of my free time on Puma because I want a Swift friendly version of fastlane that suits my need and leverages Swift 5 features.

Here’s my review of my …

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 do lense in Swift

Issue #528

What is lense

https://www.schoolofhaskell.com/school/to-infinity-and-beyond/pick-of-the-week/a-little-lens-starter-tutorial

A lens is a first-class reference to a subpart of some data type. For instance, we have _1 which is the lens that …

How to convert from callback to Future Publisher in Combine

Issue #527

import Foundation
import Combine

public typealias TaskCompletion = (Result<(), Error>) -> Void

public protocol Task: AnyObject {
    var name: String { get }
    func run(workflow: Workflow, completion: TaskCompletion)
}

public …

How to make init with closure in Swift

Issue #526

public class Build: UsesXcodeBuild {
    public var arguments = [String]()
    
    public init(_ closure: (Build) -> Void = { _ in }) {
        closure(self)
    }
}

Use function builder

public class Workflow {
    public var …

How to test a developing package with Swift Package Manager

Issue #525

Use macOS Command Line project

Example Puma

  • Create a new macOS project, select Command Line Tool Screenshot 2019-11-30 at 22 40 35
  • Drag Puma.xcodeproj as a sub project of our test project
  • Go to our TestPuma target, under Link Binary with Libraries, select Puma framework …

How to use method from protocol extension in Swift

Issue #524

/// Any task that uses command line
public protocol UsesCommandLine: AnyObject {
    var program: String { get }
    var arguments: Set<String> { get set }
}

public extension UsesCommandLine {
    func run() throws {
        let …

How to organize dependencies in Swift Package Manager

Issue #523

In Puma I want to make build tools for iOS and Android, which should share some common infrastructure. So we can organize dependencies like.

Puma -> PumaAndroid, PumaiOS -> PumaCore -> xcbeautify, Files, Colorizer

// …

How to provide configurations in Swift

Issue #522

Sometimes ago I created Puma, which is a thin wrapper around Xcode commandline tools, for example xcodebuild

There’s lots of arguments to pass in xcodebuild, and there are many tasks like build, test and archive that all uses this …

How to use SurveyMonkey in React Native

Issue #521

#import <React/RCTBridgeModule.h>

@interface RNSurveyManager : NSObject <RCTBridgeModule>

@end
#import "RNSurveyManager.h"
#import <React/RCTLog.h>
#import <SurveyMonkeyiOSSDK/SurveyMonkeyiOSSDK.h> …

How to allow unnotarized app to run on macOS Catalina

Issue #520

Remove quarantine

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

How to use flipper

Issue #519

Run the app

brew install watchman


git clone https://github.com/facebook/flipper.git
cd flipper
yarn
yarn start

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 use ForEach with ScrollView in SwiftUI

Issue #517

Use ScrollView -> VStack -> ForEach -> Content

struct SearchScreen: View {
    @State var searchObjects: [SearchObject] = [
        SearchObject(name: "By name", search: { CountryManager.shared.search(byName: $0) }), …

How to modify data inside array in SwiftUI

Issue #516

Suppose we have an array of SearchObject, and user can enter search query into text property.

class SearchObject: ObservableObject {
    let name: String
    let search: (String) -> [Country]
    var text: String = ""

    init( …

How to use index in SwiftUI list

Issue #515

Use enumerated and id: \.element.name

struct CountriesView: View {
    let countries: [Country]

    var body: some View {
        let withIndex = countries.enumerated().map({ $0 })

        return List(withIndex, id: \.element.name) { …

How to setup multiple git accounts for GitHub and Bitbucket

Issue #514

Generate SSH keys

ssh-keygen -t rsa -C "onmyway133@gmail.com" -f "id_rsa_github"
ssh-keygen -t rsa -C "onmyway133bitbucket@gmail.com" -f "id_rsa_bitbucket"

pbcopy < ~/.ssh/id_rsa_github.pub
pbcopy < …

How to use objectWillChange in Combine

Issue #513

A publisher that emits before the object has changed

Use workaround DispatchQueue to wait another run loop to access newValue

.onReceive(store.objectWillChange, perform: {
    DispatchQueue.main.async {
        self.reload()
    }
}) …

How to enable z and zsh-autosuggestions on zsh

Issue #512

git clone https://github.com/zsh-users/zsh-autosuggestions …

How to show list with section in SwiftUI

Issue #511

struct CountriesView: View {
    let groups: [Group]

    init(countries: [Country]) {
        self.groups = CountryManager.shared.groups(countries: countries)
    }

    var body: some View {
        List {
            ForEach(groups) { …

Khoa Pham

Hello, I’m Khoa

I’m a thinker and storyteller with a passion for exploring the intersection of creativity and technology

🧑‍💻 I love crafting high quality and useful apps
🔥 I love open source. My GitHub open source has 2.3k followers with packages that are integrated by 45k+ apps and over 3.4m+ downloads on CocoaPods.
✍️ I write here on my blog and on Medium, which has over 2.7k+ followers with tons of articles and 90k+ monthly views.
🖥 Follow me for sharings about Swift, SwiftUI, iOS and macOS development.
Hei