iOS/APIExample-SwiftUI/.agent/skills/review-case/SKILL.md
Structured code review for a case in the APIExample-SwiftUI project. Checks engine lifecycle, SwiftUI state ownership, thread safety, permissions, and API correctness.
npx skillsauth add agoraio/api-examples review-caseInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Check:
AgoraRtcEngineKit created inside setupRTC() of the RTC class, not in the Entry viewleaveChannel() + AgoraRtcEngineKit.destroy() called inside onDestroy()setupRTC() called from .onAppear, onDestroy() called from .onDisappearCorrect:
.onAppear { rtc.setupRTC(configs: configs) }
.onDisappear { rtc.onDestroy() }
Wrong:
// Missing onDisappear — engine never destroyed
.onAppear { rtc.setupRTC(configs: configs) }
Check:
@ObservedObject, not @StateObject@Published properties used for state that drives UI updatesCorrect:
struct MyCase: View {
@ObservedObject private var rtc = MyCaseRTC() // correct
}
Wrong:
struct MyCase: View {
@StateObject private var rtc = MyCaseRTC() // wrong — SwiftUI owns lifetime, may outlive view
}
All AgoraRtcEngineDelegate callbacks may arrive on a background thread.
Check:
@Published property mutation inside a delegate callback is dispatched to DispatchQueue.mainCorrect:
func rtcEngine(_ engine: AgoraRtcEngineKit, didJoinedOfUid uid: UInt, elapsed: Int) {
DispatchQueue.main.async {
self.remoteUid = uid
}
}
Check:
joinChannel()joinChannel() called only inside the permission grant callbackCheck:
joinChannel() checkedrtcEngine(_:didOccurError:) implemented and loggedCheck:
NSObject, conforms to ObservableObject and AgoraRtcEngineDelegate<ExampleName>Entry, main view named <ExampleName><ExampleName>RTCconfigs dictionary used to pass data from Entry to Mainbody computed propertyCheck:
onDestroy()onDestroy()[SEVERITY] file/line — issue description
Suggestion: how to fix
Severity levels:
[CRITICAL] — crash, leak, or incorrect behavior[WARNING] — convention violation or subtle bug risk[INFO] — style or minor improvementonAppear can fire multiple times (e.g., sheet dismiss, navigation pop/push) — verify setupRTC is idempotent or guardedonDisappear fires when the view is covered by another view in a TabView — verify this does not prematurely destroy the engineVideoView / VideoUIView) must be created before setupRTC is called so the canvas can be set up correctly[weak self] required in all closures capturing self inside the RTC class to avoid retain cyclesdevelopment
Add a new API example or modify an existing one. Covers both creation and modification scenarios, including dialog class structure, message map registration, and ARCHITECTURE.md updates.
development
Code review for API examples. Ensures examples follow project conventions, handle lifecycle correctly, manage threads safely, and use APIs properly.
development
Add a new API example or modify an existing one. Covers both creation and modification scenarios, including file structure, registration, and ARCHITECTURE.md updates.
development
Code review for API examples. Ensures examples follow project conventions, handle lifecycle correctly, manage threads safely, and use APIs properly.