0.08

It’s been a while

I got out of the habit on writing on Sunday’s. I reflected about this yesterday and realized I definitely want to continue writing. Writing for the project and outside of it as well. There is a great benefit to the project when writing.

Writing is a time consuming process, but it is well worth it. I realized yesterday night that writing not only helped to cement the ideas of what was done, but also develop what should be done next. Without the next steps being thought about and articulated it’s very easy to lose sight of the now. Very easy to get lost in the overwhelming nature of the future. At least it is for me.

I’ve been reading [[How to Take Smart Notes]] and I am starting to see how it is applicable to this project. In some sense it does a good job digesting what flow I want. Helps to guide the flow. Initially the Sunday Writing’s were quite easy. I had a bunch of quick notes that I filtered through, cut the unimportant ones out, and then wrote about the bigger ones. I think this is one of the core motivating factors behind the podcast. I keep finding amazing information in them, but I want to write on it after the fact. I want to come back and listen to that specific section to jog my memory of exactly the bigger idea that note was getting at.

Goal Review

Doing a quick review of the goals, basically the whole thing has changed from its initial state. The podcast totally took over and I’m okay with this.

I have been saying it for a couple weeks now, but I think the biggest thing will be to integrate the podcast’s into the stream. I am still debating exactly how this should be done, but I guess for now it doesn’t really matter. I will do what I have done and just dump the whole JSON object into the stream. This way I can parse after the fact. For now it just needs to be human readable enough for me to understand and write. I will probably quickly write a parser on top of it and rewrite the format as I realize it’s awful to parse. Should be fun!

What’s happened since 0.04?

A lot of refinement.

A lot of lessons about Swift and iOS development. I am still learning a lot and have a long ways to go. I am not very familiar with a lot of the patterns that appear in Swift. I definitely want to reduce the number of lines I have written. I think a lot of what I’ve done can be more generic.

In 0.04 the player was a relative nightmare compared to where it is now. Here’s a list of the bugs that were fixed

0.05

  • Load images from the Podcast and display them for Episodes

  • Don’t let multiple podcasts play at the same time.

    • This includes having only one tick active at any time

  • Add SegmentedPicker for searching for Podcasts v Episodes

  • Changed the CoreData model to support the correct relationship between Podcasts and Episodes (One to Many), previously the default was used

  • Add NowPlayingControlView which allows the user to control the podcast

    • Slider to control time

    • Back 30 and Forward 30

    • Basic information display

    • Is in a Sheet which is quite nice

  • Persist Episode State

0.06

  • Minor UI changes to reflect if podcast is new, in progress or completed

  • Add in support to search Episodes using ObservableObject as opposed to using our EnviornmentObject

  • Change some code around so that if episode is playing the search UI is not constantly bouncing.

    • This is a bug that I learned a lot from in 0.07

  • Refresh all episodes

  • Oh yeah I also rewrote the Go server

    • Has new endpoints

      • /new/thought

      • /new/entity

      • /action/player

      • /start/activity/

      • /stop/activity/

    • Note: a thought is really an entity too, but we are handling it as a special case for now

    • This should help to support adding Podcasts and Episodes to the feed as well as generating the most basic data surrounding them. Or rather surrounding what notes belong to what.

    • Is it independent of podcasts or was it in one, and if it was which one?

0.07

  • Don’t let Podcast immediately play when resuming the app. Quite frustrating at times.

    • Other times it’s nice but the app can’t read my mind 😢

  • Fixed all kinds of weird playback nonsense issues

    • Mostly stemming from hacked up state I have all over the place. This is starting to be a nightmare and needs refactor.

      • Can’t be mad at Netflix/YouTube or anyone using this if there is a problem. There is a lot of state management to do and it’s not always clear exactly what should be done. Still it is remarkably easy to play

  • Added nearly full support for MPNowPlayingInfoCenter and MPRemoteCommandCenter

    • Image loads

    • Can seek, play, pause, skip 30, back 30 mostly without issue

  • Dug deep in a huge UI performance issue

    • Every 1 second the whole UI would redraw if a podcast was playing

      • When scrolling it caused unacceptable lag.

      • This happened because I have a periodic tick firing and I update a variable to display the current time in the UI

    • So I did a dirty thing it seems like. I put a lot of state into my EnviornmentObject the problem with this is any time this is mutated the whole UI will refresh if it depends on this object. That is even if the value mutated does not affect the UI.

      • I think what happens is the object itself is actually immutable. So when a value inside of it changes, the whole thing is copied then redrawn on all views which are children of this.

      • Anyway I looked into the performance and I believe this object was causing a 30ms draw on the screen. This is horrible. Way over the 16.67ms I have to actually draw.

    • So now what to do? I did a few experiments seeing how I could still have the current time in the app without destroying the scrolling performance. The only thing that helped is if I made a separate class and mutated that outside of the environment

      • So that’s what I did. It is a big ugly of a solution, but basically I instantiate this class PodcastPlayer and it contains some information about the current time and the total run time. It registers for the Tick callback. When it gets the tick it posts a notification which the UI receives.

      • Now the UI only has to receive this value somewhere deeply nested, so it doesn’t have to redraw the whole thing, just the piece that changed. This brought the draw time down to about 8ms which is great. Still not as performant as I would like, but this is reasonable and should support 120Hz screens without major issue.

  • So this UI bug taught me another lesson.

    • Use Combine and Publish/Subscribe. This will be the way forward, especially to have a performant app.

    • I still have absolutely no idea what the fuck this is or how to use it. I need to explore some Apps which are really using it to see how I can too. I’ve started just a little bit but still not satisfied with where it’s at.

What about 0.08?

  • EPISODE QUEUE!!!!

    The queue is meant to be the primary UI location. I pretty much only care about the existing queue or adding to the queue

    • Yeah this was super necessary. Right now it doesn’t play episodes back to back, but at least I can keep myself sane.

    • This was one of the things about Apple Podcasts that drove me nuts.

      • I don’t want just and endless list of Podcasts.

      • Looking at the app maybe you can add your own custom lists but I’m a dumb user.

      • I just want new podcasts to go somewhere “new” and if I’ve listened to them then make them go away.

    • So what’s the behavior?

      Ways to add:

      • Search

        • Search for episode and add to queue (default add to top)

      • Subscription List (Inbox View)

        • Click ‘+’ to add this episode to the queue. This might get removed.

      • Automatically

        • If the last refresh was >6hours ago, refresh all podcasts and add the new ones to the queue.

      • Currently Playing

        • The currently playing podcast goes to the front of the queue.

  • Fix some more minor playback issues

  • Can search for episodes and add them to the queue

    • Full support for images

  • Refactored Podcast Search to be in line with Episode Search using ObservableObject now and DataTaskPublisher for getting the results

  • Experimented more with Combine, still a lot to learn with this.

Demo

What’s Next?

  • Put Podcasts on the Stream

  • Mark notable areas of a podcast

  • Favorite Podcasts

  • Continue writing more about [[The Philosophy of Tools]] when it feels right

project