6.0 KiB
DroidStar iOS Live Activity / Dynamic Island Setup (qmake + Xcode)
This project uses Qt/qmake to generate an Xcode project. The Live Activity UI must live in an iOS Widget Extension target (WidgetKit), while the app starts/updates/ends the activity from the main app target (ActivityKit).
Critical: why your extension/target-membership “disappears”
When you re-run iOS qmake, it regenerates DroidStar.xcodeproj. That regeneration typically wipes:
- Swift Target Membership checkmarks
- the Widget Extension target
- embedding settings, linker flags changes, build settings edits, etc.
Rule: generate the Xcode project once, then do all Xcode setup below, and do not regenerate unless you’re ready to repeat the setup.
Prerequisites
- iOS 16.1+ required for Live Activities / Dynamic Island.
- A Dynamic Island device is required to see the island UI. (Live Activities can still show on Lock Screen on non-Island devices.)
- Ensure the app
Info.plistcontains:NSSupportsLiveActivities=YES(already present in this repo’sInfo.plist)
1) Generate the Xcode project (once)
- (Optional) delete any previously generated
DroidStar.xcodeprojif it’s in a broken state. - Run the iOS qmake you use to generate the Xcode project.
- Open the generated
DroidStar.xcodeprojin Xcode.
2) Create the Widget Extension target (with Live Activity)
In Xcode:
- File → New → Target…
- Choose Widget Extension
- Product Name:
DroidStarLiveActivityExtension - Ensure Include Live Activity is checked
- Finish
This creates:
- an extension target
- a Swift file for the Widget/Live Activity UI
- an extension
Info.plist
3) Set correct Target Membership for Swift files
Open each file → right sidebar → Target Membership.
A) LiveActivityManager.swift
- ✅ DroidStar (main app target)
- ⛔️ DroidStarLiveActivityExtension (extension target)
B) DroidStarActivityAttributes.swift
- ✅ DroidStar (main app target)
- ✅ DroidStarLiveActivityExtension (extension target)
C) ios/DroidStarLiveActivityExtension/DroidStarLiveActivityExtension.swift
- ✅ DroidStarLiveActivityExtension
- ⛔️ DroidStar
Why: the ActivityAttributes type must be shared between app + extension, but the Widget UI must only compile into the extension.
4) Main app target configuration (DroidStar)
Select Target → DroidStar (main app).
A) Embed the extension into the app (required)
- Go to Build Phases
- Ensure Embed App Extensions exists and contains:
DroidStarLiveActivityExtension.appex
- It should be Embed & Sign
(Depending on Xcode version you may also see this under General → Frameworks, Libraries, and Embedded Content.)
B) Signing
Configure Signing Team for the app target so the app can sign/launch.
5) Extension target configuration (DroidStarLiveActivityExtension)
Select Target → DroidStarLiveActivityExtension.
A) Signing
Set a valid Team so the extension can sign.
B) iOS Deployment Target
Set iOS Deployment Target = 16.1 (or higher).
C) Required extension build setting
Set:
- Build Settings → APPLICATION_EXTENSION_API_ONLY = YES
D) Remove Qt from the extension (must be clean)
The extension must not link to Qt or Qt permission plugins.
-
Build Phases → Link Binary With Libraries
- Remove any Qt libraries/frameworks (examples):
Qt6Core,Qt6Gui,Qt6Qml,Qt6Quick, etc.- any
libQt*.aorQt*.framework
- Remove any Qt libraries/frameworks (examples):
-
Build Settings → Other Linker Flags (OTHER_LDFLAGS)
- Remove Qt-specific forced-undefined symbols (examples):
-Wl,-u,_QDarwinCameraPermissionRequest-Wl,-u,_QDarwinMicrophonePermissionRequest- any other
-u _QDarwin…
- Good state is typically:
- empty, or
- only
$(inherited)if Xcode insists
- Remove Qt-specific forced-undefined symbols (examples):
6) Build + run (recommended order)
- Product → Clean Build Folder
- Build the extension:
- Select scheme
DroidStarLiveActivityExtension→ Build
- Select scheme
- Build/run the app:
- Select scheme
DroidStar→ Run
- Select scheme
7) Enable Live Activities in iOS settings
On the simulator/device:
- Settings → DroidStar → Live Activities → ON
- Also check Settings → Notifications → Live Activities (if present on your iOS version)
If Live Activities are disabled, iOS will refuse to show them.
8) How to actually see it
- Connect DroidStar so it starts updating the activity.
- Then go to Home or Lock Screen:
- Live Activity appears on Lock Screen.
- Dynamic Island appears on Dynamic Island devices.
Tip: the island can be easier to notice outside the foreground app.
9) Debugging: what to look for in the Xcode console
This repo includes logs that explain the most common failure modes.
A) Swift class not found (Target Membership not set)
If you see logs like:
[DroidStar][LiveActivity] LiveActivityManager class not found...
Then LiveActivityManager.swift is not compiled into the main app target.
Re-check Target Membership for:
LiveActivityManager.swift→ ✅ DroidStarDroidStarActivityAttributes.swift→ ✅ DroidStar
B) Live Activities disabled by system
If you see logs like:
areActivitiesEnabled == false
Then enable Live Activities in Settings as described above.
C) Activity.request failed
If you see:
[DroidStar][LiveActivity] Error starting Live Activity: ...
The error text usually indicates missing entitlements/settings, OS version issues, or an extension embed/signing problem.
10) Persistence warning (again)
If you re-run iOS qmake and regenerate DroidStar.xcodeproj, you will need to:
- recreate the extension target
- re-embed the
.appex - re-set Swift Target Membership
- re-remove Qt linkage from the extension
If you want regeneration-safe setup, use a separate extension Xcode project and an .xcworkspace (so qmake regen won’t delete the extension project).