D3 is a powerful library for visualizing information. A common use case is building very flexible charting solutions. I wanted to take Apple's Swift Charts for a spin, and see how much of the common D3 visualizations I could faithfully replicate. This macOS project is a sample of my efforts. I would say I got close to 99% there, and the rest 1% was me wanting to wrap up my timebox on this project,…
Another instance of reuse that recently came up in Muziqi was building the new flow to add songs to a playlist. The Add Songs flow presents pretty much the same UI as the main view, but every view that you drill down to will have different elements. For example, the Album Detail view will let you Add All songs, and the tap on a song row will add it to the playlist instead of playing it back. At…
Building components in SwiftUI feels productive; declarative, high-level, and concise code, with instant previews. As you keep building a large enough codebase you also realize the power of component reuse . The Now Playing Indicator 🔗 Muziqi has a now playing indicator that shows if a song or an album in a list is currently playing. It looks like this: At first, the indicator showed up in…
I have been working on a new music player for iOS, tentatively named Muziqi . It is getting closer to becoming a reality, and I wanted to start a devlog to track my progress. Motivation 🔗 This project falls in the "scratching my itch" category. As someone who listens to a fair bit of music and other forms of audio, I have wanted an app that lets me bring in my own music library. Having tried…
I recently wrappd up a new release for Memorize , my iOS app for spaced repetition practice. The two core features of a flash card app are getting information in quickly , and a reliable study system . I had spent a lot of time on the study system before the initial release, but ended up neglecting the input system. It was a kludgy, multi-step flow: Your browser does not support the video tag. For…
I have a clear memory of holding the iPad for the first time 10 years ago. It left like a magazine. I remember being surprised by the heft, wishing it were a bit lighter. I loved holding a display of that size in my hands. I loaded up a book in iBooks, and started reading on the couch. Later that night my wife and I took it to a cafe and played checkers on it. We probably looked like dorks. At…
I recently redesigned my BART app . Earlier it showed the departures in a single table, but I wanted something more dynamic and visual. Maybe even Tufte-esque. This is what I ended up with: ...
I have had strong reservations about Functional Reactive Programming on iOS since I first looked at it 4-5 years ago. But things have changed recently: I have been using RxSwift for a few months now. This post lays out the reasoning for my switch. ( Please excuse my use of the terms Functional Reactive Programming, Rx, RxSwift, and Reactive Extensions somewhat interchangeably. Rx is Reactive…
Update : I relaunched this with Zola . I am launching sakunlabs.com with a new Swift-based static site generator. Backstory 🔗 The earlier iteration behind this domain was a monster-ish production. It had: the top-level website for my apps that I made using Hype a defunct blog produced by Hugo my visualization projects, for git repository exploration and BART real time departures , both of which…
A quick example of The Binder Architecture with RxSwift . You would like to fetch a Feed of Podcast s from an API and display it in a view controller. The model: struct Podcast: Codable { let id: Int let title: String } struct Feed: Codable { let podcasts: [Podcast] } Here is the fetch part: enum APIError: Error { case serverError case parsingError } final class API { func fetchPodcasts() ->…