@cocoaphony@mastodon.social
@cocoaphony@mastodon.social avatar

cocoaphony

@cocoaphony@mastodon.social

Swift and Go. Love 'em both. They make me mad in completely different ways. Infosec as required. robnapier.net

This profile is from a federated server and may be incomplete. Browse more on the original instance.

mattiem, to random
@mattiem@mastodon.social avatar

A Swift concurrency pattern I’m seeing more and more is the “stateless actor”. This is fascinating, because it seems so counterintuitive. But I think people are reaching for this to get convenient access to background processing.

I don’t think this is “wrong”. But I think it is probably building bad habits. Local, private nonisolated methods are usually simpler and better long-term.

cocoaphony,
@cocoaphony@mastodon.social avatar

@mattiem For a while, I had assumed that I would only have actors, MainActor classes (which are almost actors), and values. But I am finding myself more and more reaching for Sendable classes.

When I need a small amount of isolation with a mostly synchronous interface, a Mutex (OSAULock) in a Sendable class has been much more practical than an actor.

Actors shine when many of their methods are naturally async.

The merging of "async because slow" and "async for isolation" is a bit awkward.

cocoaphony,
@cocoaphony@mastodon.social avatar

@mattiem I'm finding this even in "greenfield" situations. Making everything async creates a lot of special cases you have to consider during startup. You must always handle the "I may never have a value for this" case. You have to design UI that deals with that gracefully. It's a lot of work, when the only reason you needed it was for thread-safety.

Consider a simple case of a SwiftUI View that has a configurable background color stored in an Actor. How do I display the View?

cocoaphony,
@cocoaphony@mastodon.social avatar

@mattiem If I want that value to be accessed from non-UI contexts (to bidirectionally sync with the server, for example), then I'm going to need isolation.

So the question is which side is "default?" Do I need to justify the actor because of its impact on the UI, or do I need to justify the Mutex because actors are the "right" tool for isolation?

"Mutex unless it's a fundamentally async service" or "Actor unless it breaks the UI?"

If SwiftUI were itself async, this might be different.

cocoaphony,
@cocoaphony@mastodon.social avatar

@helge @mattiem I think that's a different thing. Making Views not be MainActor IMO leaves open CALayer-style rendering loops, where multiple versions of the same layer are computed in parallel. The deep idea IMO of View is that it be purely a transform of fixed State to a renderable tree.

In practice, I don't know if this will be realizable. But I'm kind of hopeful that it could be.

By "SwiftUI is not async" I mean there's no AsyncView like AsyncImage that makes "loading" a first class state.

cocoaphony,
@cocoaphony@mastodon.social avatar

@helge @mattiem Here's a terrible implementation I use in a personal program that needs async-loading of views because computing them is slow. Yes, I use Text("loading") as the placeholder View. Developing something better is hard, and the kind of thing that async-first makes you grapple with in ways that are time consuming.

cocoaphony,
@cocoaphony@mastodon.social avatar

@helge @mattiem The trouble is there's no distinction between what we often think of as "fast async" (isolation) and "slow async" (I/O). Swift treats all async as "potentially slow," and forces us to grapple with the case that it never returns. "Loading" would have to exist because there might be network. But adjusting things to assume async is fast (i.e. allowing us to block synchronously on await) opens the door to hung programs.

That said, Swift does nothing to stop sync from being slow....

cocoaphony,
@cocoaphony@mastodon.social avatar

@helge @mattiem Ultimately, this is not unlike the idea I posted from Joe Armstrong. In truth, any lock (especially an unfair lock) can block forever, so in principle every access should deal with that.

This pedantry is a powerful tool for making our programs correct. It really has driven out many bugs from my code where the compiler caught things I thought were impossible, but are actually only rare.

This pedantry is also a powerful tool for driving programmers to throw things.

jsq, to random
@jsq@mastodon.social avatar

Definitely not switching to passkeys any time soon

https://mjtsai.com/blog/2024/05/23/the-dark-age-of-authentication/

cocoaphony,
@cocoaphony@mastodon.social avatar

@jsq I’d been moving to “sign-in with Apple” on any site I could and the passkeys. And now I find myself looking for the link that lets me use email+password because it’s the only thing I trust to work 5 years from now with my 1Password7 vault that I will never, ever upgrade.

This is a very strange place to be as an early-adopter type. I made GPG keys! I helped build corporate PKI systems. I studied FIDO2 specs. But good grief. Why’d it have to go this way?

cocoaphony,
@cocoaphony@mastodon.social avatar

@dxzdb @jsq The move to 1Password 8 burned a lot of trust that AgileBits built up from the 1passwd days. I've finally been dragged to cloud storage, even on 7, so it's probably at this point as much personal history as specific technical issues. l always trusted AgileBits a great deal. I don't know if I have full trust in this company.

That said, I've been using 1Password7 for a long time and I know how it behaves. I need a pretty strong reason to risk breaking my autofills.

davidbures, to swift
@davidbures@mstdn.social avatar

Swift experts, I'm in need of assistance again

I have this code: https://gist.github.com/buresdv/aa1fa04f8d0c6bcd42cef1a361d7e0a1

It checks if a specified URL is a symlink, which works fine. But I'm having problems actually resolving the symlink using resolvingSymlinksInPath()

In the testing part at the bottom, I'm getting this:
Resolved symlink result: file:///Users/david/Developer/Testing/folderThatIsSymlink | expected /Users/david/Developer/Testing/folderThatIsSymlinkTarget

Why is the resolved symlink wrong?

cocoaphony,
@cocoaphony@mastodon.social avatar

@davidbures I can't reproduce this. Posted some comments. How did you setup the directories and links?

tonyarnold, to random
@tonyarnold@mastodon.social avatar

Is there a way to declare via a Swift Protocol that a property must be isolated to AnyActor in Swift 5.10?

cocoaphony,
@cocoaphony@mastodon.social avatar

@tonyarnold @rjmccall is there a reason for attaching this to a property rather than adding an Actor requirement to the protocol? (The alternate is generally to make things the conformance requires async, which might be the thing you’re running into rather than isolation.)

cocoaphony, to random
@cocoaphony@mastodon.social avatar

New Blog: ASCII

https://robnapier.net/ascii

cocoaphony, to random
@cocoaphony@mastodon.social avatar

Is there a way in Safari to see alt-text? I don't need this for tooltips (yes, I know that's title); I'm checking accessibility. I thought maybe if I turned off images in the developer inspector, it would show alt-text, but it doesn't then either. And the Audit tool only says "yes, there's an alt tag." It doesn't let me check what's in it (for example, maybe "fit" when I've copied over some markdown).

Is there another tool that makes it easier to quickly spot-check accessibility mistakes?

cocoaphony, to random
@cocoaphony@mastodon.social avatar

I have a local variable declared in my Package.swift for swiftSettings so I can use it in a couple of places. It seems that if I move the declaration to the bottom of the file, after let package =, it is simply ignored. It still compiles, but the options aren't passed to the compiler. If I move it to the top of the file, it works.

I'm currently moving to @mattiem's solution (https://github.com/mattmassicotte/PackageTemplate/blob/main/Package.swift#L35-L39). But is this a bug, or intentional behavior?

cocoaphony,
@cocoaphony@mastodon.social avatar

@mattiem @jsq Agreed. I'd rather just copy the couple of lines than turn it into a formal template.

cocoaphony,
@cocoaphony@mastodon.social avatar

@krzyzanowskim Not the linked one (that's what I'm moving to instead of moving the setting). This one: https://gist.github.com/rnapier/1bf7a85eea76dc76fc61ad6aa0808fd2

cocoaphony,
@cocoaphony@mastodon.social avatar
schwa, to random
@schwa@mastodon.social avatar

deleted_by_author

  • Loading...
  • cocoaphony,
    @cocoaphony@mastodon.social avatar

    @schwa It is the second-worst tool that I can't find anything better than and so use every day for just about everything.

    The first is VSCode.

    In both cases, they're really powerful and can kind of do everything, and any complaint can probably be fixed if I were willing to write code for a few hours (and then maintain that code....). But so many little annoying complaints....

    cocoaphony, to random
    @cocoaphony@mastodon.social avatar

    I’m wondering if in large programs, having lots of independent actors is too many islands in the sea of concurrency. In my experience, developers don’t intuit the impact of await invalidating prior preconditions, and are quick to attach async to things in cases that it changes the semantics.

    I’ve been wondering if a large @\ServiceActor for many objects, similar to @\MainActor, is a safer design and matches how developers think about “in the background” vs “main.”

    Has anyone explored this?

    schwa, to random
    @schwa@mastodon.social avatar

    deleted_by_author

  • Loading...
  • cocoaphony,
    @cocoaphony@mastodon.social avatar

    @alexr @schwa What strikes me is how the same behavior lands so differently when trust and morale is high. Some of the most impactful bonuses I've ever received were $10 "Splash" awards that you could exchange for stupid stuff from a catalog. The branded lunch cooler I got 25 years ago I still have.

    But they came with a hand-written note from a colleague. And morale was high. And the company was supportive. Splash awards were "and also your teammates can recognize you" rather than "instead of…"

    Jeehut, to swift
    @Jeehut@iosdev.space avatar

    First time I'm using #Swift’s async-let in my apps, can you help me understand what's going on? 👨‍💻

    I expect that (1) and (2) run in parallel. But (3+) probably is sequential, cause I'm calling "try await" inside the loop, right? 🤔

    How to fix that? Is there a simple way? 💪

    cocoaphony,
    @cocoaphony@mastodon.social avatar

    @Jeehut from what you seem to be doing, you likely want a TaskGroup for your loop. Your other async-let look ok. https://docs.swift.org/swift-book/documentation/the-swift-programming-language/concurrency/#Tasks-and-Task-Groups

    stroughtonsmith, to random
    @stroughtonsmith@mastodon.social avatar

    So what does rewriting a Swift app in Swift 6 actually get you, that staying on Swift 5.x won’t? Will new Swift language/compiler features come to both language modes for the foreseeable future?

    cocoaphony,
    @cocoaphony@mastodon.social avatar

    @aleck @stroughtonsmith similar for me. The process of converting, which is still in its mid phases, has uncovered quite a few existing race conditions and threading violations, several of which have turned out to be the answer to existing crash reports.

    Answer: it finds bugs.

    The downside is it finds bugs you think you don’t care about, often related to debug tools or unit tests.

    The upside is it’s uncovered bugs I didn’t think I cared about but were actually causing the unit tests to crash.

    cocoaphony,
    @cocoaphony@mastodon.social avatar

    @helge @aleck @stroughtonsmith we’ve done almost no rewriting. I turn on targeted or complete, see what happens, turn it back down to minimal, and try to fix things it found. But the fixes are most commonly “make MainActor.”

    The bugs are usually discovered because “make MainActor” creates errors in other places and when I try to fix them I discover that other place assumed it was not MainActor.

    Plus it points me to places we were modifying properties on random threads.

    cocoaphony,
    @cocoaphony@mastodon.social avatar

    @helge @aleck @stroughtonsmith it is fair to note that several of the bugs have been discovered just because it forced someone to go look at code that hadn’t been touched in a while, and then say “wait, that doesn’t look right.” And all kinds of things that forced us to just go read old code might have done that.

    But quite a few have been specifically “mark MainActor, compiler complains, find existing mistake.”

    cocoaphony,
    @cocoaphony@mastodon.social avatar

    @amonduin @helge @aleck @stroughtonsmith I think most of this can be summarized as "Swift Concurrency lacks a serial queue." Yeah. IMO, that's a glaring hole right now. There are pretty simple patterns that let you create one using a single Task var, and AsyncChannel allows very powerful Go-like constructions. But all the approaches are still kind of ad hoc and tricky to do perfectly. There is a "patterns cookbook" in the works, and I'm hopeful that means by WWDC.

  • All
  • Subscribed
  • Moderated
  • Favorites
  • megavids
  • InstantRegret
  • magazineikmin
  • thenastyranch
  • modclub
  • everett
  • rosin
  • Youngstown
  • slotface
  • ethstaker
  • mdbf
  • kavyap
  • osvaldo12
  • DreamBathrooms
  • anitta
  • Durango
  • ngwrru68w68
  • tester
  • khanakhh
  • love
  • tacticalgear
  • cubers
  • GTA5RPClips
  • Leos
  • normalnudes
  • provamag3
  • cisconetworking
  • JUstTest
  • All magazines