Introduction
Fullstory for Mobile Apps SDK can now automatically generate selectors for SwiftUI Views. Selector generations happen at runtime, but because SwiftUI relies on the compiled type of a View to support model data dependencies, the mechanism can't function unless the compiled representation changes. Fullstory has provided a tool to automatically instrument the Views at build time which you can add to your project.
Getting Started by Updating the SDK
The first step in getting set up for SwiftUI automatic selector generation is to update the SDK.
This feature is in Preview and subject to change in future versions of the Fullstory SDK
- Follow the steps in Getting Started with iOS Data Capture to ensure you have installed the Fullstory SDK.
-
Note that the User Script Sandboxing build setting must be set to
NO.
Installation
Once the SDK is updated, manually update settings in Xcode — specifically adding keys to the Info.plist and configuring a build phase to run Fullstory’s SwiftUI transformer script. This enables automatic selectors for the build.
-
Next, update your
Info.plistto include the following in theFullStorydictionary:-
SwiftUIEnabledtypeBooleantoYES -
SwiftUISelectorVersiontypeNumberto3 -
SwiftUISelectorPreviewtypeNumberto2
-
-
Finally, run the included
FullStorySwiftUITransformerusing either:-
Build Rules,
which doesn't modify the source in your repository,
OR - Build Phase, which modifies the source in your repository, but supports the use of debug breakpoints.
Swift Packages, however, can only be transformed using Build Phase.
-
Build Rules,
which doesn't modify the source in your repository,
- Once you decide whether to use Build Rules or Build Phase, follow the corresponding steps below.
Transformation using Build Rules
Repeat this step for every Xcode Target that contains custom SwiftUI Views (structs that implement the View protocol). This step does not instrument Swift Packages - please use the steps for Build Phase, below, to instrument packages.
- In the project navigator, select your App’s Project, then select your Target in the editor panel
- Open 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 and paste the script below, including all quotes, as a single line, to run
FullStorySwiftUITransformerin Fullstory SDK'stoolsfolder (sample below shows when Fullstory is added via Swift Package Manager):"${BUILD_DIR%Build/*}SourcePackages/artifacts/fullstory-swift-package-ios/FullStory/tools/FullStorySwiftUITransformer" "$SCRIPT_INPUT_FILE" "$DERIVED_FILE_DIR/${INPUT_FILE_BASE}_transformed.swift" - Under "Output Files" section of 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 Process > Source files with names matching: enter *_transformed.swift.
- Choose Using > Swift Compiler.
-
Resulting Build Rules should look like below (note that the ordering is important).
-
Run the Build and in the Build output, you should see your source being transformed and the transformed source files generated by Swift compiler:
Note that
FullStorySwiftUITransformergenerates new source files that are not checked into the source repository. Because of this, debugging breakpoints added to the original source will not be hit. If this is not desired, 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
FullStorySwiftUITransformershould 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.
Pre-transformation using Build Phase
With this method, you can support Swift Packages and/or Debug Breakpoints by pre-transforming the source in your project, which means all transformations will remain in your source repository. All transformations live within /*Fullstory_XFORM_start*/ and /*Fullstory_XFORM_end*/ for easy identification and removal, if needed. The Build phase can transform the Swift Package source artifacts and/or pre-transform the source in your project.
- In the project navigator, select your App’s Project, then select your Target in the editor panel
- Open the Build Phases tab, click the + button to add a New Run Script Phase
- Drag the phase to the top of the list of phases, before Compile Sources
-
To transform Swift Packages, paste the script below, including all quotes, as a single line, to run
FullStorySwiftUITransformerin Fullstory SDK'stoolsfolder (sample below shows when Fullstory is added via Swift Package Manager):find "${BUILD_DIR%Build/*}SourcePackages/checkouts" -type f -name "*.swift" | tr \\n \\0 | xargs -S 1048576 -P $(sysctl -n hw.ncpu) -0 -n 1 -I % "${BUILD_DIR%Build/*}SourcePackages/artifacts/fullstory-swift-package-ios/FullStory/tools/FullStorySwiftUITransformer" "%" "%" -
To transform your project's source code, similarly paste the script below, including all quotes, as a single line:
find . -type f -name "*.swift" | tr \\n \\0 | xargs -S 1048576 -P $(sysctl -n hw.ncpu) -0 -n 1 -I % "${BUILD_DIR%Build/*}SourcePackages/artifacts/fullstory-swift-package-ios/FullStory/tools/FullStorySwiftUITransformer" "%" "%"
In addition, when transforming Swift Packages, it may help to reset package caches before building. Otherwise, your app may build with a cached copy of the package instead of the transformed package source.
Additional Notes
Not every View type is supported 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 will be skipped. This can occur because support has not been added for said View type, because it 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.
To skip transforming a file, add the string //Fullstory_XFORM_disable (no spaces) to the file.
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.