개요

iOS에서 에어브릿지 이벤트를 구성하는데 필요한 데이터를 수집하는 방법에 대해서 설명합니다.

Airbridge Device ID

  • 설명 : Airbridge 기기 식별자
  • 타입 : NSString*
  • 예시 : "82a16ec9-a273-48b6-9bb2-017eab641109"
#import <AirBridge/AirBridge.h> AirBridge.deviceUUID;
import AirBridge AirBridge.deviceUUID

IDFA

  • 설명 : 광고 식별자
  • 타입 : NSString*
  • 예시 : "82a16ec9-a273-48b6-9bb2-017eab641109"
#import <AdSupport/AdSupport.h> ASIdentifierManager.sharedManager.advertisingIdentifier.UUIDString;
import AdSupport ASIdentifierManager.shared().advertisingIdentifier.uuidString

IFV

  • 설명 : IFV
  • 타입 : NSString*
  • 예시 : "82a16ec9-a273-48b6-9bb2-017eab641109"
UIDevice.currentDevice.identifierForVendor.UUIDString;
UIDevice.current.identifierForVendor?.uuidString

Limit AD Tracking

  • 설명 : 광고 추적 제한 여부
  • 타입 : BOOL
  • 예시 : false
#import <AdSupport/AdSupport.h> ASIdentifierManager.sharedManager.advertisingTrackingEnabled;
import AdSupport ASIdentifierManager.shared().isAdvertisingTrackingEnabled

Device Model

  • 설명 : 기기 모델명
  • 타입 : NSString*
  • 예시 : "iPhone"
UIDevice.currentDevice.localizedModel;
UIDevice.current.localizedModel

Device Identifier

  • 설명 : 기기 식별명
  • 타입 : NSString*
  • 예시 : "iPhone9,3"
#import <sys/utsname.h> struct utsname systemInfo; uname(&systemInfo); return [NSString stringWithCString:systemInfo.machine encoding:NSUTF8StringEncoding];
var systemInfo = utsname() uname(&systemInfo) return String(cString: &systemInfo.machine.0, encoding: .utf8)

Device Manufacturer

  • 설명 : 기기 제조사
  • 타입 : NSString*
  • 예시 : "Apple"
@"Apple"
"Apple"

OS Name

  • 설명 : OS 이름
  • 타입 : NSString*
  • 예시 : "iOS"
UIDevice.currentDevice.systemName;
UIDevice.current.systemName

OS Version

  • 설명 : OS 버전
  • 타입 : NSString*
  • 예시 : "13.3"
UIDevice.currentDevice.systemVersion;
UIDevice.current.systemVersion

Locale

  • 설명 : 기기 Locale
  • 타입 : NSString*
  • 예시 : "ko-KR"
+ (NSString *)getSystemLocale { NSString* language = [#ClassName# getSystemLanguage]; NSString* country = [#ClassName# getSystemCountry]; if(language == nil || country == nil) { return nil; } return [NSString stringWithFormat:@"%@-%@", language, country]; } + (NSString*) getSystemLanguage { NSArray* preferredLanguages = NSLocale.preferredLanguages; if (preferredLanguages.count < 1) { return nil; } NSString* languageSource = preferredLanguages[0]; if (languageSource == nil) { return nil; } NSRange barIndex = [languageSource rangeOfString:@"-"]; if (barIndex.location != NSNotFound) { languageSource = [languageSource substringToIndex:barIndex.location]; } return languageSource; } + (NSString*) getSystemCountry { NSLocale* locale = NSLocale.autoupdatingCurrentLocale; if (locale == nil) { return nil; } return [locale objectForKey:NSLocaleCountryCode]; }
func getSystemLocale() -> String? { guard let language = getSystemLanguage() else { return nil } guard let country = getSystemCountry() else { return nil } return "\(language)-\(country)" } func getSystemLanguage() -> String? { let languages = Locale.preferredLanguages if languages.count < 1 { return nil } let languageSource = languages[0] guard let barIndex = languageSource.range(of: "-") else { return languageSource } return String(languageSource[..<barIndex.lowerBound]) } func getSystemCountry() -> String? { return Locale.autoupdatingCurrent.regionCode }

Timezone

  • 설명 : 기기 Timezone
  • 타입 : NSString*
  • 예시 : "Asia/Seoul"
NSTimeZone.systemTimeZone.name;
TimeZone.current.description

Orientation

  • 설명 : 기기 방향
  • 타입 : NSString*
  • 예시 : "portrait"
UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation; if (UIInterfaceOrientationIsLandscape(orientation)) return @"landscape"; else return @"portrait";
if UIDevice.current.orientation.isLandscape { return @"landscape" } else { return @"portrait" }

Screen Density

  • 설명 : 기기 화면 Density
  • 타입 : NSString*
  • 예시 : "3.000"
[NSString stringWithFormat:@"%.3f", UIScreen.mainScreen.scale];
String(format: "%.3f", UIScreen.main.scale)

Screen Height

  • 설명 : 기기 화면 세로 길이
  • 타입 : NSString*
  • 예시 : "667.0"
[NSString stringWithFormat:@"%.f", UIScreen.mainScreen.bounds.size.height];
String(format: "%.f", UIScreen.main.bounds.size.height)

Screen Width

  • 설명 : 기기 화면 가로 길이
  • 타입 : NSString*
  • 예시 : "375.0"
[NSString stringWithFormat:@"%.f", UIScreen.mainScreen.bounds.size.width];
String(format: "%.f", UIScreen.main.bounds.size.width)

Network Carrier

  • 설명 : 네트워크 사업자 정보
  • 타입 : NSString*
#import <CoreTelephony/CTCarrier.h> #import <CoreTelephony/CTTelephonyNetworkInfo.h> CTTelephonyNetworkInfo* networkInfo = [[CTTelephonyNetworkInfo alloc] init]; if (@available(iOS 12.1, *)) { NSDictionary<NSString*, CTCarrier*>* providers = [networkInfo serviceSubscriberCellularProviders]; return providers.allValues.firstObject.carrierName; } else { CTCarrier* provider = [networkInfo subscriberCellularProvider]; return provider.carrierName; }
import CoreTelephony let info = CTTelephonyNetworkInfo() if #available(iOS 12.1, *) { let providers = info.serviceSubscriberCellularProviders return providers?.values.first?.carrierName } else { let provider = info.subscriberCellularProvider return provider?.carrierName }

Cellular Status

  • 설명 : 데이터 사용 여부
  • 타입 : boolean
  • 예시 : false
#import <SystemConfiguration/SystemConfiguration.h> #import <netinet/in.h> + (BOOL) isCellular { return [#ClassName# getNetworkInfo] == CELLULAR; } typedef enum : NSInteger { WIFI, CELLULAR, NONE } ABNetwork; + (ABNetwork) getNetworkInfo { struct sockaddr_in zeroAddress; bzero(&zeroAddress, sizeof(zeroAddress)); zeroAddress.sin_len = sizeof(zeroAddress); zeroAddress.sin_family = AF_INET; SCNetworkReachabilityRef reachability = SCNetworkReachabilityCreateWithAddress(kCFAllocatorDefault, (const struct sockaddr *) &zeroAddress); if (reachability == nil) { return NONE; } SCNetworkReachabilityFlags flags; if (!SCNetworkReachabilityGetFlags(reachability, &flags)) { return NONE; } if ((flags & kSCNetworkReachabilityFlagsReachable) == 0) { return NONE; } if (((flags & kSCNetworkReachabilityFlagsConnectionRequired) != 0) && !(((flags & kSCNetworkReachabilityFlagsConnectionOnDemand ) != 0 || (flags & kSCNetworkReachabilityFlagsConnectionOnTraffic) != 0) && (flags & kSCNetworkReachabilityFlagsInterventionRequired) == 0)) { return NONE; } if ((flags & kSCNetworkReachabilityFlagsIsWWAN) == kSCNetworkReachabilityFlagsIsWWAN) { return CELLULAR; } else { return WIFI; } }
import SystemConfiguration func isCellular() -> Bool { return network() == .cellular } enum Network { case wifi case cellular case none } func getNetworkInfo() -> Network { var zeroAddress = sockaddr() bzero(&zeroAddress, MemoryLayout.size(ofValue: zeroAddress)) zeroAddress.sa_len = __uint8_t(MemoryLayout.size(ofValue: zeroAddress)) zeroAddress.sa_family = sa_family_t(AF_INET) guard let reachability = SCNetworkReachabilityCreateWithAddress(kCFAllocatorDefault, &zeroAddress) else { return .none } var flags = SCNetworkReachabilityFlags() if !SCNetworkReachabilityGetFlags(reachability, &flags) { return .none } if !flags.contains(.reachable) { return .none } if flags.contains(.connectionRequired) && !((flags.contains(.connectionOnDemand) || flags.contains(.connectionOnTraffic)) && !flags.contains(.interventionRequired)) { return .none } if flags.contains(.isWWAN) { return .cellular } else { return .wifi } }

WiFi Status

  • 설명 : WiFi 사용 여부
  • 타입 : boolean
  • 예시 : false
#import <SystemConfiguration/SystemConfiguration.h> #import <netinet/in.h> + (BOOL) isWifi { return [#ClassName# getNetworkInfo] == WIFI; } typedef enum : NSInteger { WIFI, CELLULAR, NONE } ABNetwork; + (ABNetwork) getNetworkInfo { struct sockaddr_in zeroAddress; bzero(&zeroAddress, sizeof(zeroAddress)); zeroAddress.sin_len = sizeof(zeroAddress); zeroAddress.sin_family = AF_INET; SCNetworkReachabilityRef reachability = SCNetworkReachabilityCreateWithAddress(kCFAllocatorDefault, (const struct sockaddr *) &zeroAddress); if (reachability == nil) { return NONE; } SCNetworkReachabilityFlags flags; if (!SCNetworkReachabilityGetFlags(reachability, &flags)) { return NONE; } if ((flags & kSCNetworkReachabilityFlagsReachable) == 0) { return NONE; } if (((flags & kSCNetworkReachabilityFlagsConnectionRequired) != 0) && !(((flags & kSCNetworkReachabilityFlagsConnectionOnDemand ) != 0 || (flags & kSCNetworkReachabilityFlagsConnectionOnTraffic) != 0) && (flags & kSCNetworkReachabilityFlagsInterventionRequired) == 0)) { return NONE; } if ((flags & kSCNetworkReachabilityFlagsIsWWAN) == kSCNetworkReachabilityFlagsIsWWAN) { return CELLULAR; } else { return WIFI; } }
import SystemConfiguration func isWifi() -> Bool { return network() == .wifi } enum Network { case wifi case cellular case none } func getNetworkInfo() -> Network { var zeroAddress = sockaddr() bzero(&zeroAddress, MemoryLayout.size(ofValue: zeroAddress)) zeroAddress.sa_len = __uint8_t(MemoryLayout.size(ofValue: zeroAddress)) zeroAddress.sa_family = sa_family_t(AF_INET) guard let reachability = SCNetworkReachabilityCreateWithAddress(kCFAllocatorDefault, &zeroAddress) else { return .none } var flags = SCNetworkReachabilityFlags() if !SCNetworkReachabilityGetFlags(reachability, &flags) { return .none } if !flags.contains(.reachable) { return .none } if flags.contains(.connectionRequired) && !((flags.contains(.connectionOnDemand) || flags.contains(.connectionOnTraffic)) && !flags.contains(.interventionRequired)) { return .none } if flags.contains(.isWWAN) { return .cellular } else { return .wifi } }

Package Name

  • 설명 : 어플리케이션 패키지
  • 타입 : NSString*
  • 예시 : "co.ab180.ablog"
NSBundle.mainBundle.bundleIdentifier;
Bundle.main.bundleIdentifier

Version

  • 설명 : 어플리케이션 버전
  • 타입 : NSString*
  • 예시 : "1.1.15"
[NSBundle.mainBundle.infoDictionary objectForKey:@"CFBundleShortVersionString"];
Bundle.main.infoDictionary?["CFBundleShortVersionString"]

Event Timestamp

  • 설명 : 이벤트 생성시간
  • 타입 : NSNumber*
  • 예시 : 1581043739682
[NSNumber numberWithUnsignedLongLong:NSDate.date.timeIntervalSince1970 * 1000];
UInt64(Date().timeIntervalSince1970 * 1000)