iOS/APIExample-OC/.agent/skills/review-case/SKILL.md
Structured code review for a case in the APIExample-OC (Objective-C + UIKit) project. Checks engine lifecycle, thread safety, memory management, permissions, and OC conventions.
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 sharedEngineWithConfig:delegate:] called in viewDidLoad (not in Entry VC)[self.agoraKit leaveChannel:] + [AgoraRtcEngineKit destroy] called when leavingisMovingFromParentViewController in viewDidDisappear:, or in deallocCorrect:
- (void)viewDidDisappear:(BOOL)animated {
[super viewDidDisappear:animated];
if (self.isMovingFromParentViewController) {
[self.agoraKit leaveChannel:nil];
[AgoraRtcEngineKit destroy];
}
}
Wrong:
// Missing destroy — engine leaks
- (void)viewDidDisappear:(BOOL)animated {
[self.agoraKit leaveChannel:nil];
}
All AgoraRtcEngineDelegate callbacks may arrive on a background thread.
Check:
dispatch_async(dispatch_get_main_queue(), ^{ })UIView or other UIKit objects mutated directly in callbacksCorrect:
- (void)rtcEngine:(AgoraRtcEngineKit *)engine didJoinedOfUid:(NSUInteger)uid elapsed:(NSInteger)elapsed {
dispatch_async(dispatch_get_main_queue(), ^{
[self setupRemoteVideoWithUid:uid];
});
}
Wrong:
- (void)rtcEngine:(AgoraRtcEngineKit *)engine didJoinedOfUid:(NSUInteger)uid elapsed:(NSInteger)elapsed {
[self setupRemoteVideoWithUid:uid]; // UI update on background thread
}
Check:
__weak typeof(self) weakSelf = self used in all blocks that capture selfAgoraRtcEngineKit is weak (it is by SDK design, but verify no strong cycle)__unsafe_unretained used for delegate or view referencesCorrect:
__weak typeof(self) weakSelf = self;
[[NetworkManager shared] generateTokenWithChannelName:channelName success:^(NSString *token) {
[weakSelf.agoraKit joinChannelByToken:token ...];
}];
Check:
joinChannelByToken: for video casesjoinChannelByToken: for all casesjoinChannelByToken: called only inside the permission grant callbackCheck:
joinChannelByToken: checked (non-zero = error)rtcEngine:didOccurError: delegate method implemented and loggedrtcEngine:tokenPrivilegeWillExpire: if token is usedCheck:
UIViewController, Main class inherits BaseViewController<ExampleName>Entry / <ExampleName>Main patternconfigs dictionary (NSDictionary) used to pass data from Entry to MainExamples/Basic/ or Examples/Advanced/ matching the MenuItem section.h and .m files present; public interface minimal in .hCheck:
setVideoEncoderConfiguration: called before joinChannelByToken:setupLocalVideo: called before startPreview and joinChannelByToken:enableVideo called before setupLocalVideo: for video casessetClientRole: called before joinChannelByToken: for live streaming casesCheck:
[self.agoraKit destroyMediaPlayer:player])[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 improvementNS_ASSUME_NONNULL_BEGIN/END wraps the header to reduce nullability warningsIBOutlet properties are weak (Xcode default, but worth confirming)isMovingFromParentViewController is the correct guard in viewDidDisappear: for navigation-based cleanup — do NOT use isBeingDismissed (that's for modal presentation)retain/release calls should appeardevelopment
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.