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

How to group array by property in Swift

Issue #510

Use Dictionary(grouping:by:)

func groups(countries: [Country]) -> [Group] {
    let dictionary = Dictionary(grouping: countries, by: { String($0.name.prefix(1)) })
    let groups = dictionary
        .map({ (key: String, value: [Country …

How to make full width list row in SwiftUI

Issue #508

We need to use frame(minWidth: 0, maxWidth: .infinity, alignment: .leading). Note that order is important, and padding should be first, and background after frame to apply color to the entire frame

struct BooksScreen: View {
    @ …

How to make full screen TabView in SwiftUI

Issue #507

View extends to the bottom, but not to the notch. We need to add .edgesIgnoringSafeArea(.top) to our TabView to tell TabView to extend all the way to the top.

Note that if we use edgesIgnoringSafeArea(.all) then TabView ’s bar will …

How to map error in Combine

Issue #506

When a function expects AnyPublisher<[Book], Error> but in mock, we have Just

func getBooks() -> AnyPublisher<[Book], Error> {
    return Just([
        Book(id: "1", name: "Book 1"),
        Book(id: …

How to fix unable to infer complex closure return type in SwiftUI

Issue #505

Make sure all String are passed into Text, not Optional<String>

VStack {
    Text(data.title)
    Text(data.description!)
    Text(data.text!)
}

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 make simple Redux for SwiftUI

Issue #502

Mutation is used to mutate state synchronously. Action is like intent, either from app or from user action. Action maps to Mutation in form of Publisher to work with async action, similar to redux-observable

AnyReducer is a type erasure …

How to use Firebase in macOS

Issue #501

  • Use Catalyst
  • Add to CocoaPods
platform :ios, '13.0'

target 'MyApp' do
  use_frameworks!

  pod 'FirebaseCore'
  pod 'Firebase/Firestore'

end

Troubleshooting

Select a team for …

How to use Xcode

Issue #499

Build setting

Build Library For Distribution

It turns on all the features that are necessary to build your library in such a way that it can be distributed

What does this error actually mean? Well, when the …

Links for Xcode

Issue #499

Build setting

Build Library For Distribution

It turns on all the features that are necessary to build your library in such a way that it can be distributed

What does this error actually mean? Well, when the …

How to access view in fragment in Kotlin

Issue #497

Synthetic properties generated by Kotlin Android Extensions plugin needs a view for Fragment/Activity to be set before hand.

In your case, for Fragment, you need to use view.btn_K in onViewCreated

override fun onCreateView(inflater: …

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 edit hexo theme hiero

Issue #494

Code

Remove max-width from source/css/style.styl

.outer
  clearfix()
  // max-width: (column-width + gutter-width) * columns + gutter-width
  margin: 40px auto
  padding: 0 gutter-width …

How to use Firebase RemoteConfig

Issue #493

Declare in Podfile

pod 'Firebase/Core'
pod 'Firebase/RemoteConfig'

Use RemoteConfigHandler to encapsulate logic. We introduce Key with CaseIterable and defaultValue of type NSNumber to manage default values.

import Firebase …

How to apply translations to Localizable.strings

Issue #492

Suppose we have a base Localizable.strings

"open" = "Open";
"closed" = "Closed";

After sending that file for translations, we get translated versions.

"open" = "Åpen";
"closed" = …

How to use CreateML to classify images

Issue #491

createml createml data createml train

CreateMLUI Playground

create ml ui

Read more

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