Highlight
Xcode 12 passed
LibraryContentProviderAllow developers to register custom SwiftUI Views and modifiers as draggableLibraryItem, Xcode will display these entries in the Library after scanning the source code, and keep Preview to continue rendering when inserted.
Core Content
As SwiftUI projects become larger, reusable views are often hidden in different files and packages. Team members know the systemButton、TextYou can drag it out from the Xcode Library, but you may not know that there is already a written one in the project.SmoothieRowView. If you rely on searching for file names and handwritten initialization parameters every time, the visual editing advantages of Preview will be interrupted.
Xcode 12 puts this back into Swift code. The developer declares aLibraryContentProviderType, wrap the important View or modifier intoLibraryItem. These entries will appear in the Xcode Library, and users can drag them into code or Canvas. The inserted content will still be a compilable Swift example, and Preview will continue to refresh.
In the demo project Fruta,SmoothieRowViewOriginally it was just a common SwiftUI View reused in multiple interfaces. After registering it to Library, Xcode will automatically discover this entry and generate a project category and title for it. Used when inserting.lemonberryAs placeholder data, parameters will be tokenized and developers can directly replace them with those in the current list.smoothie。
View is not the only entry point. The second half of the speechImagecommon onresizable、aspectRatio、frameCommission for three consecutive callsresizedToFill(width:height:), and then put it into the modifiers library. For XcodebaseThe parameters distinguish the modified object from the actual modifier to be inserted, and finally only the modifier call is written back to the code.
This mechanism does not require running the project. Xcode will scan the source code in the workspace to findLibraryContentProviderDisclaimer; this code will not be executed in release builds and will be stripped when building distribution products. Because the scan scope includes dependencies, Swift packages can also expose their Views to the Library. The Nutrition Facts package in the Fruta example is provided in this way.CalorieCountView。
Detailed Content
LibraryContentProviderIt’s the entrance (01:57)
To extend the Xcode Library, first declare aLibraryContentProvidertype. The protocol has two entrances:viewsProvide View entries,modifiers(base:)Provide modifier entries. Both returnLibraryItemarray.
public protocol LibraryContentProvider {
@LibraryContentBuilder
var views: [LibraryItem] { get }
@LibraryContentBuilder
public func modifiers(base: ModifierBase) -> [LibraryItem]
}
Key points:
viewsUsed to extend Xcode’s views library. -modifiers(base:)Used to extend the modifiers library. -@LibraryContentBuilderAllow a provider to return multipleLibraryItem.- Provider is placed next to the Swift code, and the compiler can help discover whether the item still works when the API changes.
An entry is a piece of completed content that can be inserted (02:32)
LibraryItemAt least a completion is required that will be inserted. It can also take visibility, title, category. In the demonstration,SmoothieRowViewuse.lemonberryAs default data, category selects.control。
LibraryItem(
SmoothieRowView(smoothie: .lemonberry),
visible: true,
title: "Smoothie Row View",
category: .control
)
Key points:
- first line
SmoothieRowView(smoothie: .lemonberry)It is the content inserted into the code after the user selects the item. -visibleControls whether items are displayed in the Library. -titleAvoid Xcode inferring the title based solely on completion. -category: .controlLet the items enter a clearer functional classification, and the icons in the demonstration will also change to control style.
The same View can have multiple configurations (03:22)
The speech emphasized View andLibraryItemNo one-to-one correspondence is required.SmoothieRowViewThere can be a normal version or an open versionshowNearbyPopularityversion. The second entry explains the difference with a custom title.
struct LibraryContent: LibraryContentProvider {
@LibraryContentBuilder
var views: [LibraryItem] {
LibraryItem(
SmoothieRowView(smoothie: .lemonberry),
category: .control
)
LibraryItem(
SmoothieRowView(smoothie: .lemonberry, showNearbyPopularity: true),
title: "Smoothie Row View With Popularity",
category: .control
)
}
}
Key points:
LibraryContentThis type name has no special meaning, the demo just uses it to host the provider.- first
LibraryIteminsert normalSmoothieRowView. - the second
LibraryItemInsert strapshowNearbyPopularity: trueconfiguration. -titleAllows users to distinguish between two similar items in Library search results.
Modifier is first extracted from repeated calls (08:57)
In the Fruta project, we often useresizable、aspectRatio、frameUsed continuously on pictures. The speech first encapsulates these three steps intoImageextension, and then add this capability to the modifiers library.
extension Image {
func resizedToFill(width: CGFloat, height: CGFloat) -> some View {
return self
.resizable()
.aspectRatio(contentMode: .fill)
.frame(width: width, height: height)
}
}
Key points:
resizedToFill(width:height:)stated inImageon, so the subsequent provider must beImageas base. -resizable()Make the image resizeable. -aspectRatio(contentMode: .fill)Maintain the aspect ratio and fill the target area. -frame(width:height:)Set the width and height of the final view.
baseTell Xcode which parts will be preserved (09:17)
When registering a modifier,modifiers(base:)The parameter type of modifier must match the type of modifier. here it isImage. Xcode passedbaseDistinguish between the modified object and the modifier to be inserted. The user will only get.resizedToFill(width:height:)this call.
@LibraryContentBuilder
func modifiers(base: Image) -> [LibraryItem] {
LibraryItem(
base.resizedToFill(width: 100.0, height: 100.0)
)
}
Key points:
base: ImagecorrespondImageon extensionresizedToFill。LibraryItemThe completion must containbase, so Xcode knows where the modifier is attached. -100.0is an example parameter. After insertion, the parameters will be tokenized and developers can replace them according to context.- This entry appears in the modifiers tab, not the views tab.
Xcode scans the source code to generate Library content (10:41)
The talk concluded by stating that Xcode does not require a build or run project to populate the Library. It will scan the source code forLibraryContentProviderAnd parse the declaration, so when the UI is refactored in the middle and the project is temporarily unable to run, the Library content can still be contributed.
This set of scans also covers dependencies in the workspace. Nutrition Facts Swift package that Fruta depends on is exposedCalorieCountView, Xcode will create a category for the package. Developers can find and insert this View in the Library without opening the package source code.
Core Takeaways
-
Design System Components Panel What to do: Register the buttons, cards, list rows, and empty state Views in the project to the Xcode Library. Why it’s worth doing: The core pain point in the speech is API discoverability, and Library is the entry point for developers to find visual content. How to start: Add to the module where the component is located
LibraryContentProvider,existviewsUse real sample data to return multipleLibraryItem。 -
Provide common states for the same component What to do: Prepare a View with normal, loading, empty, error, or multiple Library entries with additional information. Why it’s worth doing:
SmoothieRowViewUse two in the demoLibraryItemRepresents the normal version and the popularity version. How to start: In the sameviewsCreated multiple times in builderLibraryItem,usetitleWrite down the purpose of each configuration. -
Make the high-frequency modifier chain into an insertable item What to do: Encapsulate repeated modifier chains such as image cropping, rounded corners, shadows, fixed sizes, etc. and put them into the modifiers library. Why it’s worth doing: Speaking
resizable、aspectRatio、framesynthesisresizedToFill(width:height:), reduce repetitive handwriting. How to start: first write extension on the target type, and then implement itmodifiers(base:),usebase.yourModifier(...)returnLibraryItem。 -
Swift package comes with visual examples What to do: Provide Library content for a public view in a shared package, allowing users to discover it directly from the Xcode Library. Why it’s worth doing: Xcode scans the workspace for dependencies, so the Nutrition Facts package in the demo appears in the Library. How to start: Put the provider in the package source code, and prepare compilable sample data and clear titles for each public view.
Related Sessions
- Structure your app for SwiftUI previews — Talk about how to use sample data, data flow, and input design to make SwiftUI views easier to preview and test.
- Visually edit SwiftUI views — Demonstrates using the Xcode Previews canvas to iterate the SwiftUI interface and inspect the UI in different environments.
- Introduction to SwiftUI — Start with declarative code, SwiftUI view composition, and Xcode collaboration to provide the foundation for custom View Library entries.
- What’s new in SwiftUI — Overview of SwiftUI’s app, scene, controls, styles, and widgets updates in 2020, suitable for extending reusable components.
Comments
GitHub Issues · utterances