Introduction
Fullstory for Mobile Apps now enables customers to automatically generate selectors for SwiftUI view hierarchies. The selector generator works by instrumenting views at runtime. Because SwiftUI relies on the compiled type of a view to support model data dependencies, the instrumentation mechanism can't function unless the compiled representation changes. Fullstory has provided a tool to automatically instrument the view hierarchy at build time which you will need to install in your Xcode project.
Getting started
You will need a copy of FullStory 1.51.1 or later as well as Xcode 15.1 or later and your application project open. Be aware that the feature is in preview and subject to change in future versions of the Fullstory SDK!
Installation
First, install the Fullstory SDK as described in our Getting Started with iOS Data Capture instructions.
Next, update your Info.plist to include the following keys and values in the FullStory dictionary: SwiftUIEnabled set to YES, SwiftUISelectorVersion set to 3, and SwiftUISelectorPreview set to 2. Future preview releases will increment the Preview value; when SwiftUISelectorVersion 3 is out of preview, the SwiftUISelectorPreview setting will be removed.
Finally, you will need to add FullStorySwiftUITransformer to your build rules. This step should be repeated for every Xcode target that contains custom SwiftUI views (structs that implement the View protocol). Currently, there is no support for the instrumentation of Swift packages - please contact customer support if you need this feature.
- In the project navigator, select your app’s project
- In the editor panel, select your app’s target
- Choose the Build Rules tab, click the + button (next to "All") to add a rule to the top
- Choose to process "Swift source files" using "Custom script". Paste the following code for the script, including the quotes, but substituting /path/to/FullStory with the path to your copy of the Fullstory SDK, as with the setup for FullStoryCommandLine:
"path/to/FullStory/tools/FullStorySwiftUITransformer" "$SCRIPT_INPUT_FILE" "$DERIVED_FILE_DIR/${INPUT_FILE_BASE}_transformed.swift" - Go to "Output Files" for the rule, click + and edit the rule to say $(DERIVED_FILE_DIR)/$(INPUT_FILE_BASE)_transformed.swift
- Click the + button again to add another rule above the one you just added. Choose to process "Source files with names matching:" and enter *_transformed.swift
The resulting build rules should look like this (the order and positioning at the top is important). In this case, "/path/to/Fullstory… was replaced with "${BUILD_DIR%Build/*}/SourcePackages/artifacts/fullstory-swift-package-ios/fullstory/… because the SDK was installed via Swift Package Manager:
Now, you should be able to run your app and make sure it works (on simulator and/or device). If you look through the Build output, you should see your source being transformed by the transformer tool and the transformed source built by the Swift compiler:
Fullstory should now capture sessions for your app with an automatically instrumented SwiftUI view hierarchy!
Additional notes
Note that the FullStorySwiftUITransformer tool outputs new source files when it transforms the existing ones, but the new files will be added to Xcode's build folders and not checked into the source repository.
Because of this, debugging breakpoints added to the original source will not be hit in the transformed source. One way to work around this is to remove the build step in a Git branch, and checkout this branch whenever debugging is needed. (Make sure to rebase the branch as needed to keep it up to date!)
The Build output pane in Xcode will allow you to view the transformed files (e.g. go to All Messages and double-click on a Compile MyView_transformed.swift message).
The instructions above add the _transformed suffix to each file's name before the file extension; for example, MyView.swift becomes MyView_transformed.swift. This will change the way the files are reported by any tools that use the compiled file names, for example, in crash reports. However, the FullStorySwiftUITransformer tool should preserve the existing line numbers of your files for crash reporting or other purposes. In addition, type names will remain the same, and the only change to a variable is made to the body property of each SwiftUI View struct.
You may use a different suffix than _transformed if you wish, as long as it will uniquely identify transformed SwiftUI files. For example, if none of your SwiftUI files end in an underscore _ , you could make the suffix just the underscore character.
Not every view type is supported for automatic instrumentation in this preview release. If an unknown view type is encountered, the class .fs-unknownview will be applied to the view and the sub-hierarchy beneath this view will not be instrumented. This can occur because support has not been added for a SwiftUI View type, because a SwiftUI View type behaves unexpectedly, or because you have not used the SwiftUIViewTransformer on a custom view type. You can still write selectors based on this unknown view; for example, you could write a privacy rule to mask all unknown views. The captured view hierarchy may change in future releases of Fullstory as support for SwiftUI is improved.
If you have any questions, run into any issues, or have requests to add support for a view, please contact support! We will be very happy to help.