Devlog: June 13, 2023

I’ve heard that friends don’t let friends ship an app without adding a request for reviews. So I added that.

I followed two apple guides—the Human Interface Guidelines and requesting review documentation. I kinda just copied what the docs show—request once per version after at least 4 completed actions, and after the user has paused for 2 seconds.

.onReceive(viewState.$comparison
    .debounce(for: 2.0, scheduler: RunLoop.main)
) { _ in
            let version = AppInfo.fullVersion
            guard viewState.activeSheet == nil
                    && viewState.comparison.first == nil
                    && viewState.comparison.second == nil
                    && version != lastVersionPromptedForReview
                    && searchesCompleted > 3 else { return }
            
            requestReview()
            lastVersionPromptedForReview = version
        }

Here you can see some of the ugly internals of my app. The View I want to request a view on is show based on the state of the current comparison/search. So I debounce that change. Once it has settled for 2 seconds, I check if any sheets are shown, if the search is empty, and if I’ve already request a review this version. Might be better ways, but I’ll give this a shot. I’m not sure if there is a great way to test it…

Next, in the spirit of learning new things, I think I’ll try adding some in app purchases. Just a couple small tips that will unlock alternate icons or something.

Projects ScreenCred devlog

I’m Not Ready for visionOS and Spatial Computing

visionOS and the idea of spatial computing are pretty exciting. But as a mostly hobbyist iOS developer, I’m already a bit exhausted thinking about a new platform.

To make great apps, indie and solo devs already have a long list of skills and APIs they need to excel at. For myself, I’m a little worried about what visionOS and spatial computing is going to add to that list. I’ve started working through the related WWDC videos, and sure, a lot of what you know already will apply to visionOS—especially with SwiftUI. But it seems like to make truly great experiences, you’re probably going to also need to know 3D modeling, how to write custom Metal shaders, really understand ARKit, and more.

I’m sure there are people who are going to be able to keep up and master all this and be incredibly successful. And maybe what Apple provides will make all this way easier than I’m expecting. The baseline of people’s expectations of what an app provides seems to go up and up each year. I’m a little worried if I can keep up. Maybe I don’t need to, but at this moment, it feels a bit daunting.

Of course, this is coming from someone who doesn’t have any apps on the App Store and spends only a couple hours a week on making apps.

Devlog: June 11, 2023

While at the beach yesterday, I had an idea for an interaction—a folded piece of paper.

It’s made with a ZStack, with duplicate rectangles of text. One layer is masked to the shape of the left side fold and the other masked to the right side. This way they fit together when open, and then looks right when folded. Maybe not the best way, but this works pretty well!

Since the fold is not perfectly vertical, I had to break out a bit of trig on this to get the rotation correct.

.rotation3DEffect(.degrees(isOpen ? 0 : 175), axis: (-atan(2 / height), 1.0, 0.0), perspective: 0.8)

When you rotate a view, it doesn’t have a backside. So I had to do some guess work on the animation timing to change the opacity of the text so it’s not 100% when folded. I need to look more into the new SwiftUI animation stuff to see if I can make it more exact. Basically, when the rotation is between 0° and 90° the text should be shown, otherwise, hidden. Well, mostly hidden. I want it show a little bit so it looks like it’s on the back of the paper.

“SwiftUI rotated using rotation3DEffect showing how the text is reversed when rotated around the y-axis”Not great

Going to keep playing with this, but I’m quite happy with it.

Projects Activity Jar devlog

Devlog: June 7, 2023

Taking a little break from ScreenCred to work on a new idea. It’s summer break now and my daughter is home from school. My wife made a few jars with some slips of paper that have some activities to do. We have a jar for when she’s bored, needs a chore to do, or when her sister is napping.

With WWDC23 and new features in Swift and SwiftUI—including SwiftData—I thought this would be a fun thing to turn into an app and try out all the new goodies.

Started with SwiftData this morning. I didn’t get very far because the preview kept crashing with an unhelpful error. I got it to the point that it would crash in the simulator with Fatal error: Unable to have an Attribute named description. This is a bummer because I often can’t think of a better attribute name than description”. I think this was an issue in CoreData as well. So should’ve been expected. Maybe I’ll submit some feedback. Just need to read through their new writing good bugs so we’ll actually look at it” document…

Projects Activity Jar devlog

I Tried Alpine

As part of my little Frosthaven calculator, I gave Alpine.js a try. I think I like it.

If you look at the PR for the switch, you can see that using Alpine really simplified the JS, and has the advantage of keeping my template in the HTML.

To keep my template a bit cleaner, I used Alpine.data() and Alpine.store() in a separate JS file. As you might expect, you don’t get all the niceties you’d expect when using Vue or Angular, like jumping to a definition. But you gain a very lightweight and flexible framework that’s pretty easy to use.

I also used the Persist plugin to remove my own local storage implementation. With a few characters, you get automatic persistence of a value. That’s really nice.

There’s a lot of directives and features I didn’t use, but Alpine really seems like it’s got a lot of what you’d need. It was very simple for me to loop through an array and display table rows. It worked well for this small project. I’d be interested to see how it scales though. It seems to be geared toward server-side projects where you can componentize things with partials or includes to reuse code. The JS and HTML could get a bit unwieldy if you’re not able to refactor things into smaller files.

I’m definitely going to look to use Alpine more in future projects. I’ve been trying to explore more what it’s like to not immediately bring in a build step when making a website. While Alpine is not right for every project, I think it could be a really good step for some projects before jumping to use another, heavier” JS framework. But, since I don’t do a lot of serverside stuff like Laravel or Rails, it may make more sense for me to reach for another framework in order to make components and whatnot.

PicoCSS

I’ve been using PicoCSS on a couple small projects. I (mostly) really like it!

What I Like:

  • Easy to add to a project.
  • Makes things look nice out of the box, without adding a bunch of classes.

What I Don’t Like:

  • Hard to customize colors.
    • Because of how it handles automatic dark mode, colors are defined in 2 places for light mode and dark mode. Overriding the colors is not trivial and not obvious. Maybe I’m missing something.
/* Pink Light scheme (Default) */
/* Can be forced with data-theme="light" */
[data-theme="light"],
:root:not([data-theme="dark"]) {
  --primary: #d81b60;
  --primary-hover: #c2185b;
  --primary-focus: rgba(216, 27, 96, 0.125);
  --primary-inverse: #FFF;
}

/* Pink Dark scheme (Auto) */
/* Automatically enabled if user has Dark mode enabled */
@media only screen and (prefers-color-scheme: dark) {
  :root:not([data-theme]) {
    --primary: #d81b60;
    --primary-hover: #e91e63;
    --primary-focus: rgba(216, 27, 96, 0.25);
    --primary-inverse: #FFF;
  }
}

Anyway, it’s a nice thing to add to get going on small, quick projects. I like having some nice-ish styles from the get-go so I get less distracted from trying to make things look passably nice before I work on actual functionality.

Picture of Sam Warnick

As my daughter says, I'm just a tired dad, with a tired name, Sam Warnick. I'm a software developer in Beaufort, SC.

Some things I do