WWDC26 wishes
WWDC26 is just around the corner, and as always, it is the most exciting time of the year for Apple developers. Next week, Apple will show the future of its platforms, frameworks, and developer tools. Some announcements will probably be completely new, while others may finally address the gaps we have been feeling in our daily work.
Foundation Models
I use Foundation Models almost in every personal project to build recommendation systems, coaching, awareness, and other features. One feature I really miss is the image input. It will allow us to build a new class of image classification apps with on-device image recognition and analysis. We can build with it everything from calorie tracking to bill parsing.
@Generable struct FoodInformation {
@Guide(description: "title") let title: String
@Guide(description: "Estimated calories") let calories: Double
@Guide(description: "Is provided food healthy?") let isHealthy: Bool
}
func calculateMacros(for food: CGImage) async throws -> FoodInformation {
let session = LanguageModelSession(instructions: "Estimate macros for the food image")
return try await session.respond(generating: FoodInformation.self, for: food)
}
We already have on-device image generation using the ImagePlayground framework. Why not have image analysis as part of Foundation Models? I think it is the most expected feature along with increased context size.
Custom lazy layouts
Layout protocol is great and allows us to build super custom layouts from flow layout to hexagonal layout. One thing it is really missing at the moment is the option to make it lazy, like LazyVStack or LazyHStack.
public struct FlowLayout: Layout {
private let spacing: CGFloat
private let rowSpacing: CGFloat
public init(spacing: CGFloat = 8, rowSpacing: CGFloat = 8) {
self.spacing = spacing
self.rowSpacing = rowSpacing
}
public func sizeThatFits(
proposal: ProposedViewSize,
subviews: Subviews,
cache: inout ()
) -> CGSize {
let rows = rows(for: subviews, maxWidth: proposal.width ?? .greatestFiniteMagnitude)
let totalSpacing = CGFloat(max(0, rows.count - 1)) * rowSpacing
let totalHeight = rows.reduce(totalSpacing) { $0 + $1.height }
let maxRowWidth = rows.map(\.width).max() ?? 0
return CGSize(width: maxRowWidth, height: totalHeight)
}
public func placeSubviews(
in bounds: CGRect,
proposal: ProposedViewSize,
subviews: Subviews,
cache: inout ()
) {
let rows = rows(for: subviews, maxWidth: bounds.width)
var y = bounds.minY
for row in rows {
var x = bounds.minX
for item in row.items {
subviews[item.index].place(
at: CGPoint(x: x, y: y + (row.height - item.size.height) / 2),
proposal: ProposedViewSize(item.size)
)
x += item.size.width + spacing
}
y += row.height + rowSpacing
}
}
}
It can be achieved by introducing the LazyLayout protocol, which extends the Layout protocol and provides us with some sort of control over laziness. Or maybe it can be implementation details that we don’t need to control but will give us laziness out of the box without any code changes.
SwiftUI Recycling View
Another important feature I expect almost for three years is the recycling view in SwiftUI. At the moment, all views are displayed eagerly or lazily, but there is no reusing mechanism like in UITableView or UICollectionView. We still need to dive into UIKit from time to time and explore that opportunity behind the scenes.
You might say that most of the new devices are powered by new chips that have great performance, but even they need some kind of view reusing mechanism to display large collections of photos or mailboxes.
This’s not always possible to solve using lazy layouts. That’s why I still expect something similar to RecyclerView or maybe Apple can implement it behind the scenes using structured identity to identify similar views and recycle them inside the ForEach container.
Conclusion
SwiftUI is already great for building interfaces quickly, and Foundation Models open a completely new direction for intelligent, private, on-device experiences. But there are still areas where we need to drop down to UIKit or build complicated workarounds. I hope you enjoy the post. Feel free to follow me on Twitter and ask your questions related to this post. Thanks for reading, and see you next week!