Am I holding it wrong? - AsyncSequence file reading experiments with iOS 15 beta 1

[Update: Compiler but in Xcode 13 beta 1 confirmed. See below update]

[Update2: New post up with some rough and ready benchmarking of AsyncSequence file reading using URLSession]

So what I wanted to know was how to efficiently and asynchronously read a file into a Data object using the new structured concurrency approach in Swift. The short version is that I didn't manage to get the async approaches to file reading working, not sure yet if I was doing it wrong or there are currently problems with the frameworks (I have filed a bug report with Apple - FB9177012). Either way the async approaches were crashing for me. And I do welcome responses letting me know what I'm doing wrong.


I couldn't see any exact APIs that looked right for asynchronously reading a file. The Meet AsyncSequence talk from WWDC gave one possibility although it didn't look very efficient of handling the URL as an AsyncSequence of bytes but I thought I would do some investigation to check. I later as you can see at the end of this post realised that URLSession provides the method I need for a one shot request (that also wasn't working). I still would like to test how the performance of all these approaches varies.

Update

Confirmation that it is a beta 1 from someone who worked on some of the AsyncSequence stuff at Apple.

End update

MicroInjection - Tiny Dependency Injection Package

This is a follow up to my previous post (How does the SwiftUI Environment work and can it be used outside SwiftUI for Dependency Injection?).

Since writing that post I've refined the MicroInjection Package I created a bit. The core library is still a single file but with a couple of new features and fairly decent documentation included the file is now about 100 lines long.

[Apologies for the lack of code snippets, they are a real fiddle on Posthaven. I might move blogging to my own server at some point but I need to find time to migrate things].

[Update 20th Feb 2021: Package 1.0.0 release.]

Additional Features since Previous Post

How does the SwiftUI Environment work and can it be used outside SwiftUI for Dependency Injection?

Apologies for the lack of code syntax highlighting. I have plans to migrate my whole blog at some point in the future but I needed to get this out of my head before that. 

I woke up this morning with several questions in my head and I couldn't find an existing blog post that answered one. If one does exist let me know I'd love to compare notes.

  1. How does the SwiftUI Environment work?
  2. Can it be used outside SwiftUI for more general dependency injection?
  3. If not how similar can I make something to do the job?
  4. Why do people keep telling me the Environment is unsafe and will crash if the object requested hasn't been added?

By early evening I think I had the answers. By night the blog was written and by the early hours the Swift Package was published.

[Update 17th Feb 2021 - Follow up post now available with information about the Swift Package status.]

[Update 20th Feb 2021 - Package 1.0.0 released.]

Spoiler 1 - I Know Property Wrappers

I now have enough understanding of property wrappers to understand much but not all of what the SwiftUI environment is doing.

I didn't know Property Wrappers before this morning, beyond the concept and use of existing ones. I'm now much more familiar with them including the future extension from the Evolution proposal that seems to be live in Swift and it seems is the basis for the @Environment and @Published property wrappers.

Spoiler 2 - No it can't be used for DI but...

SwiftUI, Core Data and Combine - Early Days

Update: This was all about Xcode 12 beta 1. There is probably nothing still relevant in beta 5 which includes better built in Core dat support including ways to directly bind on objects and even fetch requests so NSFetchedResultsControllers should become unnecessary. Will try to post again when I have explored further.

This might be a bit of a ramble, it certainly isn’t a carefully designed tutorial but will be a mixture of a few general early thoughts and a few minor gotchas I’ve already hit in my experimentation. I’m still in the stumbling and exploring phase and certainly haven’t mastered SwiftUI or Combine to any great degree yet. This may mean it will be helpful to few people, it is probably too heavy on the jargon if you haven’t already had a good look at SwiftUI and is too light on detail and probably inaccurate if you have gone deeply in. Certainly the shelf life of this post feels short. Feel free to let me know anywhere that I am wrong, or have missed the best documentation or give any feedback either by Twitter or in the comments.

I’m less comfortable with SwiftUI than I was with Swift itself at the similar stage 5 years ago. I believe this is going to be great but there is a mental shift required which I haven’t yet achieved.

I’m in the early stages of rewriting my first ever app (Fast Lists) to create a new version with all the toys from WWDC 2019. Including but not limited to Cloudkit Core Data syncing, SwiftUI interface, support for Mac and Watch (not just iOS as before). Multi window support. I’m also hoping to add some drag and drop support later but I haven’t even started looking at that yet. Because I’m trying everything at once my progress is a bit stop start and random at the moment but it does mean that there is normally another piece to work on if I get stuck.

This is all based on experience with Version 11.0 beta (11M336w) (the first beta) so many of these issues may be resolved very soon. In a few places I note the feedback numbers that I have raised around things that are either bugs or potential areas for improvement.

Core Data seems a conceptual match for SwiftUI

Generating Core Data Swift

The Xcode generated NSManagedObject subclasses are annoying me. While they generate as a pair of files where you can add things to the main class and the @NSManaged variables are generated in an extension in a separate file so that they can be be overwritten and replaced as the model is updated without affecting the file where you make your changes unfortunately there is a big deficiency from my point of view in that the model type information does not get fully carried through to the Swift objects.

Insufficiently Typed

There are two generation options, with "Use scalar properties for primitive data types" you get usefully typed integers, floats, doubles and bools but lose the expression to express optionals/nil values. This is presumably due to the limitations of the Objective-C based API. It also expresses date types as NSTimeIntervals (Doubles) rather than NSDates.  The other option will generate with objects so you will get NSDates but for number values and Booleans you will get NSNumbers which lose information about whether it is a floating point type, integer or boolean.

Other Issues