통합 가이드
1. 에이전트 소개
섹션 제목: “1. 에이전트 소개”NetFUNNEL 에이전트는 NetFUNNEL 서버와 통신하기 위한 일종의 NetFUNNEL 전용 클라이언트 입니다. 사용자는 적용하고자 하는 클라이언트 어플리케이션 코드에 에이전트에서 제공하는 다양한 함수들을 적용, 구현하여 가상 대기실을 적용할 수 있습니다.
2. 에이전트 설치
섹션 제목: “2. 에이전트 설치”2.1 최소 요구 사항
섹션 제목: “2.1 최소 요구 사항”- iOS 15.6 이상
- Storyboard(Swift, Objective-C) 또는 SwiftUI
2.2 에이전트 추가
섹션 제목: “2.2 에이전트 추가”NetFUNNEL iOS 에이전트는 .xcframework 파일로 제공됩니다.
- NetFUNNEL 콘솔의 에이전트 탭에서 iOS 에이전트를 다운로드합니다.
- 프로젝트 루트에
Frameworks폴더를 만들고, 다운로드한 에이전트를 옮깁니다. - Xcode에서 프로젝트 > General > Frameworks, Libraries, and Embedded Content의 + 버튼을 누르고, **Add Files…**에서 에이전트를 선택한 뒤 Open을 클릭합니다.
프로젝트 루트/├── Frameworks/│ └── netfunnel_ios.xcframework├── {PROJECT_NAME}/└── {PROJECT_NAME}.xcodeproj2.3 초기화
섹션 제목: “2.3 초기화”NetFUNNEL iOS 에이전트는 앱 실행과 동시에 초기화되어야 합니다.
import UIKitimport Netfunnel_iOS
@mainclass AppDelegate: UIResponder, UIApplicationDelegate { func application( _ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? ) -> Bool { Netfunnel.shared.initialize( clientId: "{CLIENT_ID}", delegate: NetfunnelHandler.shared, // NetfunnelDelegate를 구현한 객체 networkTimeout: 3000, retryCount: 0, printLog: false, useNetfunnelTemplate: true, errorBypass: false, useNetworkRecoveryMode: false ) return true }}#import <Foundation/Foundation.h>#import <Netfunnel_iOS/NetfunnelDelegate.h>
NS_ASSUME_NONNULL_BEGIN
@interface NetfunnelHandler : NSObject <NetfunnelDelegate>
+ (instancetype)sharedInstance;
// 필수 콜백@property (nonatomic, copy, nullable) void (^onSuccess)(NSString *projectKey, NSString *segmentKey, NSInteger statusCode, NSString *message);@property (nonatomic, copy, nullable) void (^onError)(NSString *projectKey, NSString *segmentKey, NSInteger statusCode, NSString *message);@property (nonatomic, copy, nullable) void (^onNetworkError)(NSString *projectKey, NSString *segmentKey, NSInteger statusCode, NSString *message);
// 선택 콜백@property (nonatomic, copy, nullable) void (^onContinue)(NSString *projectKey, NSString *segmentKey, NSInteger statusCode, NSString *message, NSInteger aheadWait, NSInteger behindWait, NSString *waitTime, NSInteger progressRate);@property (nonatomic, copy, nullable) void (^onBlock)(NSString *projectKey, NSString *segmentKey, NSInteger statusCode, NSString *message);@property (nonatomic, copy, nullable) void (^onClose)(NSString *projectKey, NSString *segmentKey, NSInteger statusCode, NSString *message);@property (nonatomic, copy, nullable) void (^onComplete)(NSString *projectKey, NSString *segmentKey, NSInteger statusCode, NSString *message);
@end
NS_ASSUME_NONNULL_END#import "NetfunnelHandler.h"
@implementation NetfunnelHandler
+ (instancetype)sharedInstance { static NetfunnelHandler *sharedInstance = nil; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ sharedInstance = [[NetfunnelHandler alloc] init]; }); return sharedInstance;}
#pragma mark - NetfunnelDelegate Methods
- (void)nfSuccessWithProjectKey:(NSString *)projectKey segmentKey:(NSString *)segmentKey statusCode:(NSInteger)statusCode message:(NSString *)message { NSLog(@"nfSuccess %ld %@", (long)statusCode, message); /** * 대기열 통과 시 처리할 로직 * ex - 서비스 화면 진입 처리 */ if (self.onSuccess) { self.onSuccess(projectKey, segmentKey, statusCode, message); }}
- (void)nfErrorWithProjectKey:(NSString *)projectKey segmentKey:(NSString *)segmentKey statusCode:(NSInteger)statusCode message:(NSString *)message { NSLog(@"nfError %ld %@", (long)statusCode, message); /** * 에러 발생 시 처리할 로직 * ex - 사용자에게 오류 메시지 표시 또는 바이패스 */ if (self.onError) { self.onError(projectKey, segmentKey, statusCode, message); }}
- (void)nfNetworkErrorWithProjectKey:(NSString *)projectKey segmentKey:(NSString *)segmentKey statusCode:(NSInteger)statusCode message:(NSString *)message { NSLog(@"nfNetworkError %ld %@", (long)statusCode, message); /** * 네트워크 에러 발생 시 처리할 로직 * ex - 네트워크 재연결 안내 또는 재시도 화면으로 이동 */ if (self.onNetworkError) { self.onNetworkError(projectKey, segmentKey, statusCode, message); }}
- (void)nfContinueWithProjectKey:(NSString *)projectKey segmentKey:(NSString *)segmentKey statusCode:(NSInteger)statusCode message:(NSString *)message aheadWait:(NSInteger)aheadWait behindWait:(NSInteger)behindWait waitTime:(NSString *)waitTime progressRate:(NSInteger)progressRate { NSLog(@"nfContinue %ld %@", (long)statusCode, message); /** * 대기 진행 중 UI 업데이트 로직 (넷퍼넬 대기실 미사용 시에만 해당) * ex - 실시간 대기 정보를 커스텀 대기 화면에 업데이트 */ if (self.onContinue) { self.onContinue(projectKey, segmentKey, statusCode, message, aheadWait, behindWait, waitTime, progressRate); }}
- (void)nfBlockWithProjectKey:(NSString *)projectKey segmentKey:(NSString *)segmentKey statusCode:(NSInteger)statusCode message:(NSString *)message { NSLog(@"nfBlock %ld %@", (long)statusCode, message); /** * 사용자 진입 차단 시 처리할 로직 * ex - 접근 제한 메시지 표시 */ if (self.onBlock) { self.onBlock(projectKey, segmentKey, statusCode, message); }}
- (void)nfCloseWithProjectKey:(NSString *)projectKey segmentKey:(NSString *)segmentKey statusCode:(NSInteger)statusCode message:(NSString *)message { NSLog(@"nfClose %ld %@", (long)statusCode, message); /** * 사용자가 대기를 취소한 경우 처리할 로직 * ex - 종료 안내 Toast 표시 (웹뷰 자동 복귀) */ if (self.onClose) { self.onClose(projectKey, segmentKey, statusCode, message); }}
- (void)nfCompleteWithProjectKey:(NSString *)projectKey segmentKey:(NSString *)segmentKey statusCode:(NSInteger)statusCode message:(NSString *)message { NSLog(@"nfComplete %ld %@", (long)statusCode, message); /** * 최종 완료 시 처리할 로직 * ex - 대기 완료 후 후속 처리 */ if (self.onComplete) { self.onComplete(projectKey, segmentKey, statusCode, message); }}
@endNetFUNNEL iOS 에이전트는 다양한 부가 기능을 제공합니다. 부가 기능을 활성화하려면 초기화 함수에 설정값을 추가합니다.
| 파라미터 | 타입 | 설명 | 조건 |
|---|---|---|---|
clientId |
String | 클라이언트 고유 식별자 | 필수 |
delegate |
NetfunnelDelegate | 서버 응답을 받을 델리게이트 객체 | 필수 |
serverUrl |
String | NetFUNNEL 서버 주소 | 빈 문자열 불가 |
errorUrl |
String | NetFUNNEL 에러 페이지 HTML 주소 | 빈 문자열 불가 |
networkTimeout |
Long | 네트워크 응답 최대 대기 시간 | 기본 3,000ms · 최대 10,000ms · 최소 100ms |
retryCount |
Int | 네트워크 재시도 횟수 | 기본 0 · 최대 10 · 최소 0 |
printLog |
Bool | 디버그 로그 출력 | 기본: false |
useNetfunnelTemplate |
Bool | NetFUNNEL 대기실 사용 (false면 커스텀 대기실) | 기본: true |
errorBypass |
Bool | nfError·nfNetworkError 대신 nfSuccess 호출 | 기본: false |
userId |
String | 반복 요청 차단의 ID 기준 차단·허용에 사용할 사용자 ID | 기본: 없음 |
useNetworkRecoveryMode |
Bool | 네트워크 에러 시 대기실 유지 및 회복 | 기본: false |
isTransparent |
Bool | 대기실(WebView) 배경 투명화 | 기본: false |
3. 에이전트 적용
섹션 제목: “3. 에이전트 적용”NetFUNNEL iOS 에이전트에서 제공하는 함수를 통해 특정 화면에 대기실을 적용할 수 있습니다.
3.1 기본 제어
섹션 제목: “3.1 기본 제어”시작 함수
섹션 제목: “시작 함수”대기를 적용하고 싶은 지점에서 함수를 호출하여 키를 발급하고 대기실을 노출시킵니다. 화면 진입이나 이벤트 시작 부분에 적용합니다.
| 파라미터 | 타입 | 설명 | 필수 |
|---|---|---|---|
projectKey |
String | NetFUNNEL 콘솔의 프로젝트 키 | O |
segmentKey |
String | NetFUNNEL 콘솔의 세그먼트 키 | O |
Netfunnel.shared.nfStart(projectKey: "{PROJECT_KEY}", segmentKey: "{SEGMENT_KEY}")[[Netfunnel shared] nfStartWithProjectKey:@"{PROJECT_KEY}" segmentKey:@"{SEGMENT_KEY}"];종료 함수
섹션 제목: “종료 함수”진입을 완료한 후 키 반납을 위해 사용합니다. 진입 성공 후 또는 진입한 유저의 활동이 완료되는 지점에 적용합니다. 파라미터는 시작 함수와 같습니다.
Netfunnel.shared.nfStop(projectKey: "{PROJECT_KEY}", segmentKey: "{SEGMENT_KEY}")[[Netfunnel shared] nfStopWithProjectKey:@"{PROJECT_KEY}" segmentKey:@"{SEGMENT_KEY}"];3.2 구간 제어
섹션 제목: “3.2 구간 제어”구간 제어란, 앱의 특정 구간에서 동시 접속자 수를 일정하게 유지하도록 제어하는 기능입니다. 시작 함수 호출 시 키를 발급하고, 종료 함수를 호출하기 전까지는 유저가 활동 구간에 있는 것으로 판단하여 다음 대기자를 진입시키지 않습니다. 종료 함수를 호출하면 키를 반납하고 다음 대기자가 진입합니다. (예: 결제 흐름, 로그인부터 로그아웃까지)
시작 함수
섹션 제목: “시작 함수”구간이 시작되는 지점에서 호출합니다. 파라미터는 기본 제어의 시작 함수와 같습니다.
Netfunnel.shared.nfStartSection(projectKey: "{PROJECT_KEY}", segmentKey: "{SEGMENT_KEY}")[[Netfunnel shared] nfStartSectionWithProjectKey:@"{PROJECT_KEY}" segmentKey:@"{SEGMENT_KEY}"];종료 함수
섹션 제목: “종료 함수”진입한 유저의 활동 구간이 종료되는 지점에서 호출합니다. 파라미터는 기본 제어의 종료 함수와 같습니다.
Netfunnel.shared.nfStopSection(projectKey: "{PROJECT_KEY}", segmentKey: "{SEGMENT_KEY}")[[Netfunnel shared] nfStopSectionWithProjectKey:@"{PROJECT_KEY}" segmentKey:@"{SEGMENT_KEY}"];3.3 델리게이트 처리
섹션 제목: “3.3 델리게이트 처리”NetFUNNEL iOS 에이전트를 사용하기 위해서는 시작 함수와 종료 함수에 델리게이트를 반드시 주입해야 합니다.
대기실은 다양한 상황(대기 성공, 취소, 차단, 에러, 네트워크 오류 등)에 따라 종료될 수 있으며, 각 상황에 대한 처리 시나리오는 델리게이트를 통해 구현할 수 있습니다.
시작 응답
섹션 제목: “시작 응답”| 메서드 | statusCode | 설명 |
|---|---|---|
| nfSuccess | 200 | 대기열을 정상적으로 통과하여 서비스에 진입 |
| nfSuccess | 300 | 구독·라이선스 만료 · 프로젝트·세그먼트 비활성화 · errorBypass=true 설정 |
| nfSuccess | 303 | 화이트리스트 IP·ID 요청 (우회) |
| nfError | 500 | 초기화 없이 시작 함수 호출 · 존재하지 않는 프로젝트·세그먼트 키 사용 · 대기 중 세그먼트 삭제 · 서버 응답 누락 |
| nfNetworkError | 1001 | 네트워크 연결 차단 (Wi-Fi·셀룰러 차단) |
| nfNetworkError | 1002 | 네트워크 타임아웃 · 유효하지 않은 대기실 HTML 주소 · 넷퍼넬 서버 다운 |
| nfBlock | 301 | 세그먼트 차단 |
| nfBlock | 302 | 블랙리스트 · BotManager Basic 활성화 |
| nfClose | 499 | 기본 대기실의 취소 버튼 |
| nfClose | 498 | 차단실의 닫기 버튼 |
| nfClose | 497 | 매크로 차단실의 닫기 버튼 |
| nfClose | 496 | 사전 대기실의 닫기 버튼 |
| nfClose | 495 | 사후 대기실의 닫기 버튼 |
| nfContinue | 201 | useNetfunnelTemplate=false로 대기 중 (커스텀 대기실) |
종료 응답
섹션 제목: “종료 응답”종료 함수 호출 후 키 반납 결과가 nfComplete로 전달됩니다. 구현하지 않아도 서비스에 영향이 없습니다.
| 메서드 | statusCode | 설명 |
|---|---|---|
| nfComplete | 200 | 진입 키 반납 성공 |
| nfComplete | 500 | 진입 키 반납 실패 |
import Netfunnel_iOS
final class NetfunnelHandler: NSObject, NetfunnelDelegate { static let shared = NetfunnelHandler()
func nfSuccess(projectKey: String, segmentKey: String, statusCode: Int, message: String) { // 진입 또는 우회 응답: 넷퍼넬 적용 이전의 원래 서비스 로직 실행 // 예) 화면 이동, 함수 실행, API 요청 }
func nfError(projectKey: String, segmentKey: String, statusCode: Int, message: String) { // 시스템 에러: 원활한 서비스 이용을 위해 원래 서비스 로직 실행 }
func nfNetworkError(projectKey: String, segmentKey: String, statusCode: Int, message: String) { // 네트워크 에러: 원래 로직 실행 또는 안내 후 대기열 재진입 }
func nfBlock(projectKey: String, segmentKey: String, statusCode: Int, message: String) { // 진입 차단: 차단 안내 또는 무동작 }
func nfClose(projectKey: String, segmentKey: String, statusCode: Int, message: String) { // 대기실 닫기·취소: 취소 안내 또는 무동작 }
func nfContinue(projectKey: String, segmentKey: String, statusCode: Int, message: String, aheadWait: Int, behindWait: Int, waitTime: String, progressRate: Int) { // 커스텀 대기실 사용 시: 대기 정보로 UI 갱신 }
func nfComplete(projectKey: String, segmentKey: String, statusCode: Int, message: String) { // 키 반납 후 실행할 로직 }}#import "NetfunnelHandler.h"
@implementation NetfunnelHandler
+ (instancetype)shared { static NetfunnelHandler *instance; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ instance = [[NetfunnelHandler alloc] init]; }); return instance;}
#pragma mark - NetfunnelDelegate
- (void)nfSuccessWithProjectKey:(NSString *)projectKey segmentKey:(NSString *)segmentKey statusCode:(NSInteger)statusCode message:(NSString *)message { // 진입 또는 우회 응답: 넷퍼넬 적용 이전의 원래 서비스 로직 실행}
- (void)nfErrorWithProjectKey:(NSString *)projectKey segmentKey:(NSString *)segmentKey statusCode:(NSInteger)statusCode message:(NSString *)message { // 시스템 에러: 원활한 서비스 이용을 위해 원래 서비스 로직 실행}
- (void)nfNetworkErrorWithProjectKey:(NSString *)projectKey segmentKey:(NSString *)segmentKey statusCode:(NSInteger)statusCode message:(NSString *)message { // 네트워크 에러: 원래 로직 실행 또는 안내 후 대기열 재진입}
- (void)nfBlockWithProjectKey:(NSString *)projectKey segmentKey:(NSString *)segmentKey statusCode:(NSInteger)statusCode message:(NSString *)message { // 진입 차단: 차단 안내 또는 무동작}
- (void)nfCloseWithProjectKey:(NSString *)projectKey segmentKey:(NSString *)segmentKey statusCode:(NSInteger)statusCode message:(NSString *)message { // 대기실 닫기·취소: 취소 안내 또는 무동작}
- (void)nfContinueWithProjectKey:(NSString *)projectKey segmentKey:(NSString *)segmentKey statusCode:(NSInteger)statusCode message:(NSString *)message aheadWait:(NSInteger)aheadWait behindWait:(NSInteger)behindWait waitTime:(NSString *)waitTime progressRate:(NSInteger)progressRate { // 커스텀 대기실 사용 시: 대기 정보로 UI 갱신}
- (void)nfCompleteWithProjectKey:(NSString *)projectKey segmentKey:(NSString *)segmentKey statusCode:(NSInteger)statusCode message:(NSString *)message { // 키 반납 후 실행할 로직}
@end