Leaving Substack

After reading the note, I decided to leave Substack. This is an easy decision.

However, I'm also pausing Mango Newsletter for now. Even though I could move it somewhere else, I couldn't make it a priority. I need to spend more time on the actual development of Mango Baby and my next app.

If you are still interested in a relatively low volume of the updates on my indie dev work, you can find Mango Umbrella at @MangoUmbrella@indieapps.space or @mango.umbrella@threads.net.

Default Apps 2023

I saw this from Jay Wilson and took it as a template.

This is what I’m using at the point and time of publishing.

📨 Mail Client: Gmail app on iOS and gmail.com on macOS

📮 Mail Server: Google

📝 Notes: Apple Notes

✅ To-Do: Apple Notes

📷 Photo Shooting: iPhone 14 Pro, Sony A7R III, Sony FE 70-200 F4 G

🎨 Photo Editing: Lightroom on macOS, Photomator on iOS

📆 Calendar: Google Calendar

📁 Cloud File Storage: Google Drive, iCloud Drive

🙍🏻‍♂️ Contacts: Apple Contacts

🌐 Browser: Safari on iOS, Chrome on macOS

💬 Chat: WeChat, iMessages, Discord, Google Talk or whatever it is called today

🔖 Bookmarks: Chrome

📑 Read It Later: Apple Notes

📜 Word Processing: Google Docs

📈 Spreadsheets: Google Sheets

📊 Presentations: Google Slides

🛒 Shopping Lists: Apple Notes

🍴 Meal Planning: Google Docs, physical paper on the fridge

💰 Budgeting and Personal Finance: Google Sheets

📰 News: Mastodon

🎵 Music: YouTube Music

🎤 Podcasts: Overcast

🔐 Password Management: Chrome, Apple Keychain, KeePassXC

🧑‍💻 Code Editor: VS Code, Xcode

🌲 Git Client: git, GitHub Desktop

🖥️ Terminal: iTerm2

📐 Design: Figma

📝 Blog: In-house Engine and Client

✈️ VPN: Google Fi

∞ BREAKING NEWS: Myke Hurley Posted a Thread Again

Myke Hurley, the British professional podcaster, co-founder of the podcast network Relay FM, Chief Product Designer and co-founder at Cortex Brand, logged in to Threads today and is asking how to get his threads on news:

Post by @imyke
View on Threads

Does this count?

∞ How To Make a 800 Square-feet Sidewalk Garden in San Francisco's Mission District

Zach Klein wrote a great article on how they made a 800 square feet garden in San Francisco's Mission District:

This garden was conceived to help expand San Francisco's urban forest and it was designed to be an example of xeriscaping. It is drought-tolerant and requires no additional water other than seasonal rain. It is also a permeable landscape that improves the city's sewage treatment capacity by reducing storm water runoff through absorption.

Look at how beautiful it is:

A Sidewalk Garden in San Francisco's Mission District

I would have never guessed it's in the SF Mission district:

A Sidewalk Garden in San Francisco's Mission District

∞ Ask vs Guess Culture

Jean Hsu's article on Ask vs Guess Culture is a great read:

If you’re more a guess-culture person, asking people for help without knowing their circumstances can feel rude or intrusive. Broadcasting publicly your need for help can feel awkward and vulnerable.

If you’re more of an ask-culture person, the guess-culture example of juggling everyone’s specific scenarios and the historical context of favors probably seems exhausting. Dropping hints in the hopes that you won’t even have to make your request can feel extra passive and manipulative.

And because I'm an Asian living in the U.S., I experience so much clash between the cultures:

I was raised deeply in guess culture, as many Asians and Asian-Americans are. The Japanese proverb that “the nail that sticks up gets nailed down” reinforces the idea of social collectivism and keeping your individual needs and wants to yourself — values that are shared by many Asian culture.

Western society is very much ask culture. A classic example can be found in proverbs. “A squeaky wheel gets the grease” is an American proverb, enforcing the ideas of individualism and that asking for what you want will benefit you.

SwiftUI: How to Show Subscript and Superscript Texts

SwiftUI gives us a .baselineOffset(_:) modifier to set the vertical offset for the text relative to its baseline. You can combine this with smaller fonts to show subscript and superscript texts. For example:

var body: some View {
    Text("Mango")
    + Text("sub").font(.caption).baselineOffset(-3)
    + Text(" Umbrella")
    + Text("sup").font(.caption).baselineOffset(6)
}

`xcrun simctl status_bar` Is Not Working Since Xcode 14.1

xcrun simctl status_bar is a great tool to control what you want to display on the status bar in simulators. It's often used to set the time to 9:41 AM for screenshots.

Since Xcode 14.1 in Oct 2022 though, it's no longer working if the simulator runs iOS 16.1+. Neither Xcode 14.2 and 14.3 fixed this, and it has been a mysterious since.

However, today @saagar just posted the reason and a workaround:

If you’ve been trying to use xcrun simctl status_bar recently to take pretty screenshots and found that it doesn’t work past simulators running iOS 16.1, you can use SIMCTL_CHILD_SIMULATOR_RUNTIME_VERSION=16.0 xcrun simctl boot as a temporary workaround to get this back.

Great, problem solvedmitigated!

In addition, if you use @twostraws's awesome ControlRoom app, I sent out a PR (to be reviewed and merged) to add this workaround.

App Engine: Fixing a Go Panic, Metadata Fetch Failed

The Umbrella engine that powers this website is built using App Engine's Go Standard Environment.

In September 2021, Google Cloud enabled most of the legacy App Engine API on the second-generation App Engine runtimes. This means you could now use newer Go versions even in the standard App Engine. I migrated to Go 1.15 then and it worked smoothly.

Today, I was trying to upgrade the runtime to Go 1.20 since it was made generally available on March 24, 2023. Here is what I did:

  1. Install Go 1.20 locally from https://go.dev/doc/install.
  2. Change runtime: go115 to runtime: go120 in the app.yaml file.
  3. Make sure the app-engine-python and app-engine-go components from the gcloud CLI are up to date: gcloud components install app-engine-go app-engine-python

But running dev_appserver.py results in the following panic (trace simplified) when serving a request:

CRITICAL: panic: Metadata fetch failed for
'instance/attributes/gae_backend_version': Get
"http://metadata/computeMetadata/v1/instance/attributes/gae_backend_version":
dial tcp: lookup metadata: no such host

goroutine 7 [running]:
google.golang.org/appengine/v2/panic(...)
	go/src/runtime/panic.go:884 +0x204
google.golang.org/appengine/v2/internal.mustGetMetadata(...)
	google.golang.org/appengine/v2/internal/metadata.go:34 +0xa8
google.golang.org/appengine/v2/internal.VersionID(...)
	google.golang.org/appengine/v2/internal/identity.go:124 +0xe8
google.golang.org/appengine/v2.VersionID(...)
	google.golang.org/appengine/v2/identity.go:60
mangosite/code/public/common.Handle.func1(...)
	mangoumbrella/public/common/common.go:67 +0x430
net/http.HandlerFunc.ServeHTTP(...)
	go/src/net/http/server.go:2122 +0x38
github.com/gorilla/mux.(*Router).ServeHTTP(...)
	github.com/gorilla/mux@v1.8.0/mux.go:210 +0x19c
net/http.(*ServeMux).ServeHTTP(...)
	go/src/net/http/server.go:2500 +0x140
google.golang.org/appengine/v2/internal.executeRequestSafely(...)
	google.golang.org/appengine/v2/internal/api.go:136 +0x68
google.golang.org/appengine/v2/internal.handleHTTP(...)
	google.golang.org/appengine/v2/internal/api.go:116 +0x374
net/http.HandlerFunc.ServeHTTP(...)
	go/src/net/http/server.go:2122 +0x38
net/http.serverHandler.ServeHTTP(...)
	go/src/net/http/server.go:2936 +0x2d8

Upon investigation, I have the following code in my http handler:

import "google.golang.org/appengine/v2"

func handler(w http.ResponseWriter, r *http.Request) {
    c := appengine.NewContext(r)
    _ = appengine.VersionID(c)
}

The panic happens at the appengine.VersionID(c) call as it doesn't work locally. Instead, you could check if it's running locally and use a different code path:

if appengine.IsDevAppServer() {
   // Do something else
} else {
   // This runs in production.
   _ = appengine.VersionID(c)
}

Hope this helps.

Remembering Alex Hay

I'm very sad to hear Alex Hay, the maker of Toolbox Pro and many other apps, has passed aways after years of battling with cancer.

MacStories is dedicating Automation April 2023 in memory of Alex Hay:

So, with his family’s blessing, we’re dedicating Automation April 2023 in memory of Alex Hay, a brilliant and beloved member of the automation community who was taken from us far too early at the age of 36. MacStories is also making donations to the American Cancer Society and Cancer Research UK in Alex’s name, and we’d love it if you would join us in making a donation using the links above too.

The Apple automation community is a close-knit group of talented, creative people, and no one exemplified that more than Alex Hay. We’re grateful for the chance we had to get to know Alex and the apps he built that opened up so many new possibilities for Shortcuts users around the world. Our hearts go out to his family and friends, and we hope you’ll join us in thinking of him and his loved ones throughout Automation April.

Alex's work has inspired so many people and has advanced automation tooling on Apple platforms. He was also such a friendly person, helping other developers in the community. I have closely followed his research on the new iOS 16 AppIntent framework. Without that and a few brief exchanges on Twitter, I couldn't have launched Mango Baby's iOS 16 update with great AppIntent support.

We'll miss you.

∞ From 20 Dollars in His Pocket to a Dumpling Empire: Din Tai Fung Founder Dies at Age 96

By Heather Chen, CNN:

The founder of one of the world’s biggest dumpling empires has died.

Yang Bing-yi, who set up the Taiwanese restaurant chain Din Tai Fung, “passed away peacefully” at the age of 96, the company said in a statement Saturday.

Rest in piece.

Din Tai Fung is a Taiwanese restaurant chain. The first branch in the US opened in Arcadia, California, in 2000. Though this branch was permanently closed in 2020 due to COVID-19 impact, there are 13 other locations in California, Washington, Oregon, and Nevada.