Angelo Stavrow [dot] Blog

Missives and musings on a variety of topics.

Widgets in macOS are cool, but they’d be even cooler if I didn’t have to set them up all over again after every update. 🙃

Discuss...

“Good” is doing a lot of heavy lifting in this phrase.

“Screenshot of an iPhone lock screen reading ‘Good Morning’ and indicating a temperature of -18 Celsius, feels like -25.”

Discuss...

(You know, like finding your sea legs, but for photography.)

Yesterday, I promised myself I’d not only take my camera out with me, but that I’d commit to shooting at least three photos. And, so, I did. I’m not especially thrilled with how it went, but the results are here.

First thoughts: using a camera with thick gloves on is not much fun.

Also, I’d forgotten how incredibly critical I am of my photos. And wow, it’s so different to be taking photos from a device that writes them to a card, that I then have to plug into a computer of some sort to process (I always preferred shooting RAW) and share (how is it that Lightroom doesn’t have a connection to Flickr?). It’s a longer, slower process, but I’ve always enjoyed the almost ritualistic nature of producing a final image from the raw output of the camera’s sensor.

I remembered how aperture and shutter speed work against each other, but neglected to factor in sensitivity. There’s no reason for shooting these photos in broad (overcast) daylight at anything over base ISO. Which, on this camera is… I don’t even know. But I’m not loving the noise I see in the images.

I remembered how a RAW image needs way more massaging than the JPEG output from a digital camera. Levels and curves, sharpening. But mostly, I just did some cropping, and let Lightroom auto-process these, then tweaked the output a touch. They’re test images, and I don’t want to obsess over processing a bad capture because that’s just going to make me feel bad.

But these are technical issues that a little research and practice will always fix. In the end, the biggest challenge I’ve always faced with photography remains, be it while using a fancy dSLR with expensive glass, or the phone in my pocket: finding interesting subjects, and then not being shy to photograph them.

Discuss...

Testing to see how title-less posts propagate from Write.as through the Micro.blog cross-posting bot. Ignore me!

Discuss...

Hello, dot-blogosphere.

Discuss...

I'm thrilled to announce the release of [WriteFreely for iOS] on the App Store. 🚀

Read more...

On the weekend, while working on NetNewsWire, I ran into a source-control situation that made me spend a lot of time learning about how to move Git commits from one branch to another.

For whatever reason, I made my changes on the main branch and, once the work was done, I opened a first pull request against the NetNewsWire/main branch. Maurice Parker kindly reminded me that the PR should be opened against the mac-candidate branch, so I closed that PR and took a look at the situation.

Here's what my fork of the NetNewsWire repository looked like:

"Branch diagram of origin vs. upstream commits for original pull request"

The branch named origin is my fork of the original, upstream, NetNewsWire repo. Here's what the branch diagram needed to look like:

"Branch diagram of origin vs. upstream commits for required pull request"

Right.

So, here's something you should know about my experience with Git: so long as I stick to a very simple, branch-commit-merge strategy, everything's fine. I've even figured out how to keep my forked origin updated and in sync with upstream repos, like a good contributor.

But anything more complicated than that? Ugh. 😬

I knew what I needed to do — I had to move my commits from my main branch, in order, onto my candidate branch, and then open a new PR. After spending about a half hour making a good, solid, mess of my fork, I finally stumbled upon the answer: Git cherry-pick.

Like almost anything on the official Git documentation site, I personally find the docs on cherry-picking unhelpful at best, inscrutable at worst — I'm more of a visual person, I guess, so I found this StackOverflow answer to be much more useful in figuring out what it means to cherry-pick a commit in Git.

The process is actually pretty straightforward:

# Switch to the branch you want to move the commits to:
% git checkout mac-candidate

# Cherry-pick each commit, in order, using their commit hash,
# until you've moved them all to the intended branch:
% git cherry-pick 12ab34c

That's... about it. Like I said, though, I'm a visual person, so I found it helpful to do this in GitKraken (you can use this referral link if you're interested in trying it out), where I can just right-click on the commit I want to move, choose cherry-pick from the context menu, and watch as it gets applied to my mac-candidate branch. It definitely made it easier to make sure I didn't miss any commits or screw up the order.

Once that was done, all I had to do was open a new pull request (against the correct branch, this time) and the work was done!

#git

Discuss...

UPDATED: I opened my original PR against the wrong branch, so I've fixed the links here to point to the new PR.

I've been wanting to learn more about building macOS apps. SwiftUI multiplatform apps are a great way forward in building something quickly, but you'll often still need to drop into AppKit and UIKit to solve things that SwiftUI just doesn't address (yet). So, for someone that's got some experience building iOS apps, what's a good way to learn?

I could just build a bunch of toy projects on my own. I read through Hacking with macOS which taught me a tonne. But for myself, the best learning is social learning — by observing and interacting with others.

I've been lurking on the Slack group for NetNewsWire for months, and once I felt comfortable with the way the community worked together, I asked to tackle a first issue. Nothing especially complex for my level of experience, but that would have me digging through the codebase to figure out how things work, and learn how to make the changes for a framework (AppKit) that I'm less familiar with.

I like digging through a codebase and teasing apart the way it works. The advantage of poking at NetNewsWire is that it's a nicely-organized project, clearly structured for long-term maintainability by anyone willing to contribute.

(If we're ever able to sit and enjoy an afternoon restorative together, ask me about having to port a 20 kLOC, uncommented, single-file code project to another language.)

(On second thought — don't.)

It's one thing to learn how the Notifications API works by changing the way a feature works. But there's a lot to learn by looking at how others structure and organize their codebase, set up their build steps, share code between iOS and macOS targets, &cet. You just don't get that depth from simple how-to tutorials. Those tutorials have their place in the learning process, and they're a wonderful community resource! But you have to go deeper to go from “my first massive view controller app” to building a complex software project.

Another nice thing about contributing to NetNewsWire is that the community is wonderful. One thing I appreciated was that I was trusted to tackle the problem myself, rather than be told (more or less) what to do as a first-time contributor. Of course, any questions I had were answered, and whenever I asked for feedback it was honest and helpful. That's a testament to the community Brent Simmons has built around the project.

And so, I opened my first pull request this morning. In service of showing messy work (and because it's good Git hygiene, IMO), the work's broken up into a dozen fairly small commits. You can see some of the comments I removed after figuring out what exactly happens when you fetch the user's notification settings, for example.

I'm looking forward to the team's feedback on my proposed changes, and I'm looking forward to contributing more to the project!

#projects #swift #netnewswire

Discuss...

Using @EnvironmentObject is a great way to share data between your views. Previously, I'd been using @ObservedObjects all over my views, and it felt clumsy.

Hot tip: by setting an environmentObject for a NavigationView, any children of this NavigationView can then add a property like @EnvironmentObject var someType: SomeType. SwiftUI then gives them access to the observed object, without you having to pass the object down the navigation tree and through views that don't need access to it:

/* ContentView.swift */

import SwiftUI

struct ContentView: View {
    @ObservedObject var someType: SomeType

    var body: some View {
        NavigationView {
            MyView()
        }
        .environmentObject(someType)
    }
}

/* MyView.swift */

import SwiftUI

struct MyView: View {
    var body: some View {
        SomeTypeList()
    }
}


/* SomeTypeList.swift */

import SwiftUI

struct SomeTypeList: View {
    @EnvironmentObject var someType: SomeType
    
    var body: some View {
        // Do something with someType
    }
}

But! If you were passing it in to a child view as an ObservedObject and had set up some test object for use in your SwiftUI preview? If you try to pass in your test object, you'll get an error:

Cannot convert value of type 'SomeType' to expected argument type 'EnvironmentObject<SomeType>'

To fix this, use the environmentObject modifier on your child view's preview provider:

struct SomeTypeList_Previews: PreviewProvider {
    static var previews: some View {
        SomeTypeList()
            .environmentObject(testSomeType)
    }
}

Yay, your preview works again!

#swift #swiftui

Discuss...

Hot on the heels of the WriteFreely Swift Package, I'm kicking off another fun open-source project: building a WriteFreely client for all Apple platforms as a SwiftUI multiplatform app.

I've written about the project a bit more here, where I'm sharing updates on the WriteFreely/Write.as work I do. If WWDC got you interested in learning more about multiplatform apps and SwiftUI, join me in building this! The goal is to go from what you see in the GitHub project today to a functional app by the end of August. Developers of any level of experience are welcome!

This work will have two tracks — building the client app, which will be the bulk of the work, and improving the Swift package. Personally, I'm more excited about SwiftUI and multiplatform apps than I've been about other tech stacks in a long time.

That said, one of the reasons Per has been stagnating for as long as it did was because I got bitten by the Swift 2 → 3 transition, which kinda broke everything. I'm hoping that it'll be smoother for SwiftUI as it's improved and extended over the next few years.

More TK!

#writeas #projects #swift #swiftui

Discuss...

Enter your email to subscribe to updates.