iOS 에이전트 문제 해결
NetFUNNEL 4 iOS 에이전트의 일반적인 문제를 해결하기 위한 포괄적인 가이드입니다.
빠른 진단
일반적인 문제 체크리스트
특정 해결 방법을 살펴보기 전에 다음 일반적인 문제를 확인하세요:
- 프레임워크가 프로젝트에 올바르게 추가됨
- AppDelegate에서 초기화가 호출됨
- 델리게이트 메서드가 올바르게 구현됨
- 프로젝트/세그먼트 키가 콘솔과 정확히 일치함
- 테스트를 위해 진입 허용 수가 0으로 설정됨
- 콘솔에서 세그먼트가 활성화됨
- 네트워크 연결이 사용 가능함
설치 문제
프레임워크를 찾을 수 없음
오류: No such module 'Netfunnel_iOS'
증상:
- import 오류로 빌드 실패
- Xcode에 빨간색 오류 표시기 표시
- 모듈이 인식되지 않음
해결 방법:
-
프레임워크 등록 확인:
- 프로젝트 → General → Frameworks, Libraries, and Embedded Content로 이동
- 목록에
netfunnel_ios.xcframework가 나타나는지 확인 - 프레임워크 옆에 물음표(?)가 있는지 확인
-
프레임워크 경로 수정:
프레임워크를 우클릭 → Source Control → netfunnel_ios.xcframework 추가 -
정리 및 재빌드:
- Product → Clean Build Folder (⌘+Shift+K)
- Product → Build (⌘+B)
-
프레임워크 위치 확인:
- 프레임워크가
Frameworks폴더에 있는지 확인 - 파일 경로가 올바른지 확인
- 프레임워크가
빌드 오류
오류: 프레임워크 관련 오류로 빌드 실패
증상:
- 컴파일 오류
- 링커 오류
- 아키텍처 불일치 오류
해결 방법:
-
iOS 배포 대상 확인:
- 대상이 iOS 12.0 이상인지 확인
- 프로젝트 → Build Settings → iOS Deployment Target
-
아키텍처 호환성 확인:
- 프레임워크는 arm64, armv7을 지원함
- Build Settings → Architectures 확인
-
빌드 폴더 정리:
Product → Clean Build Folder -
프레임워크 무결성 확인:
- 콘솔에서 프레임워크를 다시 다운로드
- 파일 크기 및 체크섬 확인
개인정보 보호 매니페스트 문제
오류: Invalid privacy manifest
증상:
- 개인정보 보호 매니페스트 오류로 빌드 실패
- App Store 거부
해결 방법:
-
최신 버전으로 업데이트:
- 콘솔에서 최신 프레임워크 다운로드
- 버전 4.3.2-onprem에는 업데이트된 개인정보 보호 매니페스트가 포함됨
-
프레임워크 버전 확인:
let version = Netfunnel.shared.getVersion()
print("NetFUNNEL Version: \(version)")
초기화 문제
에이전트가 초기화되지 않음
오류: 에이전트가 트래픽 제어를 우회함
증상:
- 대기실이 나타나지 않음
- 사용자가 큐를 우회함
- NetFUNNEL 로그 없음
해결 방법:
-
초기화 순서 확인:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// 메서드의 시작 부분에서 초기화
Netfunnel.initialize(...)
return true
} -
필수 매개변수 확인:
clientId가 비어있지 않아야 함delegate가 프로토콜을 구현해야 함
-
디버그 로깅 활성화:
Netfunnel.initialize(
clientId: "{{CLIENT_ID}}",
delegate: self,
printLog: true // 로깅 활성화
) -
네트워크 연결 확인:
- 네트워크 연결이 사용 가능한지 확인
- 브라우저 또는 curl로 테스트
잘못된 클라이언트 ID
오류: 초기화 실패
증상:
nfNetworkError콜백- 초기화 실패
- 에이전트가 우회 모드로 실행됨
해결 방법:
-
클라이언트 ID 형식 확인:
// ✅ 올바른 형식
clientId: "{{CLIENT_ID}}"
// ❌ 잘못된 형식
clientId: "" // 빈 클라이언트 ID
clientId: nil // 클라이언트 ID 누락 -
콘솔에서 클라이언트 ID 확인:
- NetFUNNEL 콘솔의 클라이언트 ID와 일치하는지 확인
- 클라이언트 ID가 올바르게 복사되었는지 확인
-
네트워크 권한 확인:
NSAppTransportSecurity가 HTTPS를 허용하는지 확인- Info.plist에서 인터넷 권한 확인
런타임 문제
델리게이트 콜백에서 앱 충돌
오류: 델리게이트 메서드가 호출될 때 앱 충돌
증상:
- 대기실 중 앱 충돌
nfSuccess,nfError등에서 충돌- 스레드 관련 충돌
해결 방법:
-
UI 업데이트에 메인 큐 사용:
func nfSuccess(projectKey: String, segmentKey: String, statusCode: Int, message: String) {
DispatchQueue.main.async {
// 여기서 UI 업데이트
self.updateUI()
}
} -
모든 필수 메서드 구현:
class ViewController: UIViewController, NetfunnelDelegate {
// 필수 메서드
func nfSuccess(...) { }
func nfError(...) { }
func nfNetworkError(...) { }
} -
약한 참조 사용:
func nfSuccess(projectKey: String, segmentKey: String, statusCode: Int, message: String) {
DispatchQueue.main.async { [weak self] in
self?.handleSuccess()
}
}
대기실이 나타나지 않음
오류: 트래픽 제어에도 불구하고 대기실이 표시되지 않음
증상:
- 사용자가 즉시 진입함
- 큐 경험 없음
- 트래픽 제어가 작동하지 않음
해결 방법:
-
진입 허용 수 설정 확인:
- 테스트를 위해
0으로 설정 - 콘솔 → 세그먼트 → 진입 허용 수
- 테스트를 위해
-
세그먼트 활성화 확인:
- 콘솔 → 세그먼트 → 세그먼트 활성화: ✅ 활성화됨
- 진입 상태:
대기
-
프로젝트/세그먼트 키 확인:
// 키가 콘솔과 정확히 일치하는지 확인
Netfunnel.shared.nfStart(projectKey: "exact_project_key", segmentKey: "exact_segment_key") -
디버그 로깅 활성화:
Netfunnel.initialize(
clientId: "{{CLIENT_ID}}",
delegate: self,
printLog: true
)
키가 반환되지 않음
오류: 서버로 키가 반환되지 않음
증상:
- 사용자가 큐에 갇힘
nfComplete콜백 없음- 서버에 키가 반환되지 않음으로 표시됨
해결 방법:
-
중지 함수가 호출되는지 확인:
// 기본 제어
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
Netfunnel.shared.nfStop(projectKey: "project", segmentKey: "segment")
}
// 구간 제어
func completeSection() {
Netfunnel.shared.nfStopSection(projectKey: "project", segmentKey: "segment")
} -
네트워크 연결 확인:
- 서버에 도달할 수 있는지 확인
- 네트워크 타임아웃 확인
-
네트워크 요청 모니터링:
- Xcode Network Inspector 사용
nfStop/nfStopSection요청 찾기
구성 문제
잘못된 제어 유형
오류: 제어 유형에 대한 예상치 못한 동작
증상:
- 기본 제어가 구간 제어처럼 동작함
- 구간 제어가 기본 제어처럼 동작함
- 잘못된 대기실 동작
해결 방법:
-
세그먼트 구성 확인:
- 콘솔 → 세그먼트 → 제어 유형
- 구현과 일치하는지 확인
-
함수 호출 확인:
// 기본 제어
Netfunnel.shared.nfStart(projectKey: "project", segmentKey: "segment")
Netfunnel.shared.nfStop(projectKey: "project", segmentKey: "segment")
// 구간 제어
Netfunnel.shared.nfStartSection(projectKey: "project", segmentKey: "segment")
Netfunnel.shared.nfStopSection(projectKey: "project", segmentKey: "segment")
네트워크 타임아웃 문제
오류: 빈번한 네트워크 타임아웃
증상:
nfNetworkError콜백- 사용자가 지연을 경험함
- 서버 타임아웃
해결 방법:
-
네트워크 타임아웃 증가:
Netfunnel.initialize(
clientId: "{{CLIENT_ID}}",
delegate: self,
networkTimeout: 5000 // 기본값 3000에서 증가
) -
네트워크 복구 활성화:
Netfunnel.initialize(
clientId: "{{CLIENT_ID}}",
delegate: self,
useNetworkRecoveryMode: true
) -
서버 성능 확인:
- 서버 응답 시간 모니터링
- 서버 로그에서 오류 확인
성능 문제
느린 앱 성능
오류: NetFUNNEL로 인해 앱이 느려짐
증상:
- UI 지연
- 느린 응답 시간
- 메모리 문제
해결 방법:
-
디버그 로깅 비활성화:
Netfunnel.initialize(
clientId: "{{CLIENT_ID}}",
delegate: self,
printLog: false // 프로덕션용으로 비활성화
) -
델리게이트 메서드 최적화:
func nfSuccess(projectKey: String, segmentKey: String, statusCode: Int, message: String) {
DispatchQueue.main.async { [weak self] in
// 경량 작업만
self?.handleSuccess()
}
} -
재시도 횟수 감소:
Netfunnel.initialize(
clientId: "{{CLIENT_ID}}",
delegate: self,
retryCount: 1 // 기본값에서 감소
)
메모리 문제
오류: 메모리 누수 또는 높은 메모리 사용량
증상:
- 메모리 경고
- 앱 충돌
- 높은 메모리 사용량
해결 방법:
-
약한 참조 사용:
func nfSuccess(projectKey: String, segmentKey: String, statusCode: Int, message: String) {
DispatchQueue.main.async { [weak self] in
self?.handleSuccess()
}
} -
적절한 정리:
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
// 리소스 정리
Netfunnel.shared.nfStop(projectKey: "project", segmentKey: "segment")
}
디버깅 기법
디버그 로깅 활성화
Netfunnel.initialize(
clientId: "{{CLIENT_ID}}",
delegate: self,
printLog: true // 디버그 로깅 활성화
)
로그 출력 포함:
- 네트워크 요청 및 응답
- 델리게이트 메서드 호출
- 오류 조건
- 키 관리 이벤트
네트워크 요청 모니터링
-
Xcode Network Inspector:
- Debug → Attach to Process
- Network 탭에 모든 요청 표시
-
Charles Proxy:
- HTTPS 요청 모니터링
- 요청/응답 세부 정보 보기
-
콘솔 로그:
// NetFUNNEL 메시지 찾기
NSLog(@"NetFUNNEL: %@", message);
다양한 시나리오 테스트
-
대기실 테스트:
- 진입 허용 수를 0으로 설정
- 대기실이 나타나는지 확인
-
진입 테스트:
- 진입 허용 수를 1로 설정
- 즉시 진입 확인
-
키 반환 테스트:
- 네트워크 요청 모니터링
nfComplete콜백 확인
일반적인 오류 코드
성공 코드
| 코드 | 의미 | 액션 |
|---|---|---|
| 200 | 큐를 성공적으로 통과함 | 정상 흐름 진행 |
| 300 | 오류/만료로 인한 우회 | 정상 흐름 진행 |
| 303 | 화이트리스트 우회 | 정상 흐름 진행 |
오류 코드
| 코드 | 의미 | 액션 |
|---|---|---|
| 500 | 시스템 오류 | 정상 흐름 진행 |
| 1001 | 네트워크 연결 끊김 | 네트워크 복구 활성화 |
| 1002 | 네트워크 타임아웃/서버 다운 | 서버 상태 확인 |
차단 코드
| 코드 | 의미 | 액션 |
|---|---|---|
| 301 | 세그먼트 차단됨 | 세그먼트 활성화 확인 |
| 302 | 사용자가 블랙리스트에 있음 | 사용자 상태 확인 |
닫기 코드
| 코드 | 의미 | 액션 |
|---|---|---|
| 495-499 | 사용자가 대기실을 닫음 | 사용자 취소 처리 |
FAQ
Q: 에이전트가 빌드되지 않음 (잘못된 개인정보 보호 매니페스트)
A: 버전 4.3.2-onprem부터 Apple 정책 변경으로 인해 에이전트의 privacyInfo가 업데이트되었습니다. 최신 에이전트 버전을 사용하고 있는지 확인하세요.
Q: 델리게이트 콜백에서 앱이 충돌함
A: 델리게이트 콜백 내부에서 UI를 조작하는 경우, DispatchQueue.main.async를 사용하여 코드가 메인 스레드에서 실행되도록 하세요.
Q: 디버그 로그를 보고 싶습니다
A: initialize 함수에서 printLog: true를 설정하여 로그를 활성화하세요. 디버깅 중에만 사용하고 프로덕션 빌드에서는 false로 설정하세요.
Q: 대기실이 나타나지 않습니다
A: 진입 허용 수가 0이면 대기실이 나타나야 하며 사용자가 진입할 수 없습니다. 콘솔 → 세그먼트 설정 → 기본 설정 → 진입 허용 수를 0으로 설정하여 대기실이 표시되도록 강제하세요.
Q: 델리게이트 콜백에서 UI를 업데이트하고 싶습니다
A: NetFUNNEL 콜백은 비동기입니다. 이러한 콜백 내부에서 UI 요소를 직접 호출하면 앱이 예상치 못하게 동작하거나 충돌할 수 있습니다. UI 업데이트를 위해 항상 메인 큐로 디스패치하세요.
Q: 에이전트 버전을 확인하는 방법
A: getVersion()을 사용하여 NetFUNNEL iOS 에이전트 버전을 가져옵니다.
도움 받기
지원팀에 문의하기 전에
- 이 문제 해결 가이드 확인
- 디버그 로깅 활성화 (
printLog: true) - 구성이 콘솔과 일치하는지 확인
- 최소 구성으로 테스트
- 네트워크 연결 확인
제공할 정보
지원팀에 문의할 때 다음을 포함하세요:
- 에이전트 버전 (
getVersion()) - iOS 버전 및 기기 유형
- Xcode 버전
- 오류 메시지 및 로그
- 사용된 구성
- 문제를 재현하는 단계
지원 리소스
- 문서: 이 문제 해결 가이드
- 콘솔 로그:
printLog: true활성화 - 네트워크 모니터링: Xcode Network Inspector 사용
- 커뮤니티: NetFUNNEL 개발자 커뮤니티