iOS 기초 설정

푸시메세지 발송을 위한 iOS OS 에서 필수로 설정해 주셔야 하는 가이드입니다.

APNS 인증서 발급

Firebase 연동

다음 Firebase console에서 프로젝트 개요 오른쪽의 setting 아이콘을 클릭하여 프로젝트 설정으로 들어갑니다.

클라우드 메시징 메뉴를 클릭하여 다음과 같이 발급받은 APN 인증 (.p8) 키를 업로드 합니다.

Firebase console 클라우드메시징 설정 화면에서 APNS Authentication Key (APN 인증키), APNS Certificates(APN인증서) 업로드 2가지 설정을 확인할 수 있습니다.

여기에 Apple 에서 발급받은 Key 또는 Certificates를 넣어야만 원격 푸시가 정상적으로 작동하며, 둘 중 하나만 업로드 하여도 됩니다.

  • APNS Key : .p8 형태를 띄고 하나만 업로드.

  • APNS Certificates : .p12 형태를 띄고 개발용, 배포용 인증서가 따로 존재. 일년마다 갱신 필요.

*와이즈트래커 도큐먼트는 .p8 업로드를 기준으로 작성되었습니다.

그리고 Firebase 구성 파일도 Xcode 루트에 복사합니다.

대시보드 설정

와이즈트래커 대시보드에서 푸시 연동을 위한 설정을 진행합니다.

서비스설정 > 어플리케이션설정 > 푸시연동 메뉴를 클릭합니다.

아래 이미지에서 푸시 서비스 타입을 Firebase Cloud Messaging 으로 선택 후 Android 푸시 연동시 추가한 Firebase Admin SDK용 "private key" 파일을 추가 해 주세요.

SDK 설치

Cocoapod에서 SDK 다운로드

Swift로 FCM을 사용할때는, 'pod' 파일을 수정할 필요는 없습니다.

XCode 프로젝트 파일중 Podfile 파일에 다음과 같이 SDK와 FirebaseMessaging을 추가합니다.

pod 'RW'
pod 'Firebase/Messaging'    >>> Objective-C 의 경우 추가 해 주세요.

기존에 SDK를 한번 설치한 경우에는 설치할SDK 버전을 표시해야 하는 경우도 있습니다. 아래와 같이 설치할 SDK버전을 명시적으로 표시하면 됩니다.

pod 'RW', '~> 1.1.49'

Terminal

Podfile 에 해당라인을 추가한 후 Terminal 프로그램을 실행하여 다음의 명령을 수행합니다.

pod install

SDK 버전 업데이트의 경우 다음의 명령을 수행합니다.

pod update

Cocoapod 사용하지 않을 경우

SDK 파일을 URL에서 다운로드 합니다.

다운된 파일을 압축 해제하면 다음과 같은 파일이 확인 가능하고 이중 아래에 선택된 3개의 파일을 분석 대상 앱 프로젝트에 추가합니다.

프로젝트 선택후 마우스 우클릭, Add Files to 메뉴를 선택합니다.

앞에서 다운로드 받고, 압축 해제한 폴더에 들어가서 아래와 같이 추가 대상 파일을 선택하고, 화면 아래쪽 설정은 존재하는 모든 target에 포함되었는지 확인후 추가 하면 됩니다.

BuildSetting 에 아래와 같이 설정을 추가합니다.

xcode 가 12.3 이후 버전이고 빌드 과정에서 아래와 유사한 오류가 발생하는 경우가 있으며,

위의 경우에는 아래와 같이 설정을 하고, 빌드를 하면됩니다.

CocoaPod을 사용하지 않을경우, Firebase 수동 설정은 아래의 Firebase 공식 document를 참고하여 수동으로 프로젝트에 추가해 주세요.

dotAuthorizationKey 등록

info.plist 파일을 Open As Source Code 방식으로 오픈한 후, 아래 코드를 추가합니다.

<key>dotAuthorizationKey</key>
<dict>
    <key>serviceNumber</key>
    <string>xxxxx</string>          >>> 서비스 번호 확인 후 변경
    <key>expireDate</key>
    <string>14</string>
    <key>isDebug</key>
    <string>true</string>
    <key>isInstallRetention</key>
    <string>true</string>
    <key>isFingerPrint</key>
    <string>true</string>
    <key>accessToken</key>
    <string></string>
    <key>useMode</key>
    <string>2</string>
</dict>

추가한 코드 중 serviceNumber의 value를 올바른 값으로 변경해야 합니다.

와이즈트래커 대시보드에 로그인하여 설정 > 서비스설정 메뉴에서 '서비스번호' 항목에 기재된 숫자를 확인 후 복사하여 serviceNumber 값을 변경 해 주세요.

HTTP 통신 허용

이 내용은 Wisetracker 기본 SDK가 이미 적용된 경우에는 새로 적용할 필요가 없습니다. 메시징 서비스만 이용하는 경우 참조해주세요.

http통신을 허용하기 위해 NSAppTransportSecurity 를 아래와 같이 추가합니다.

이전과 마찬가지로 info.plist 파일을 Open As Source Code 방식으로 오픈한 후, 아래 코드를 추가합니다.

<key>NSAppTransportSecurity</key>
<dict>
    <key>NSAllowsArbitraryLoads</key>
    <true/>
</dict>

"Push Notification" Capability 추가

앱에 푸시기능을 추가합니다.

"Signing & Capabilities" 탭을 선택한 후 화면 왼쪽의 "+ Capability"를 눌러주세요.

"Capability"화면에서 "Push Notification"기능을 검색하여 선택합니다.

Background Modes도 위와 같은 방법으로 검색 후 추가 해 줍니다.

초기화

  • 초기화 방법은 SceneDelegate 가 설정된 경우와 설정되지 않은 경우에 따라 달라집니다.

  • SceneDelegate를 사용하지 않으면 AppDelegate에서 초기화작업을 하고, 그렇지 않고 SceneDelegate를 사용하면 SceneDelegate에서 이 작업을 해야 합니다.

1. iOS13 미만 (SceneDelegate 없음)

AppDelegate의 didFinishLaunchingWithOptions 함수에 SDK를 Initialization하기 위한 코드를 다음과 같이 적용합니다. SDK가 정상적으로 초기화 되었을 때 아래와 같은 기본 분석이 가능합니다.

  • 앱 실행 및 방문수, 일/주/월순수방문수 등 방문과 관련된 지표

  • 통신사, 단말기, 국가 등 방문자의 단말기 환경으로 부터 추출될 수 있는 지표

import DOT
import Firebase

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
...
...
  // 등록 토큰을 수신하기 위한 SDK구성
  FirebaseApp.configure()
  
  // S: Wisetracker SDK init
  DOT.initialization(launchOptions, application: application)
  #if DEBUG
    DOT.checkDebugMode(true)
  #else
    DOT.checkDebugMode(false)
  #endif
  // E: Wisetracker SDK init
}

DOT가 사용되는 곳에서는 import DOT을 통해 import가 필요합니다.

2. iOS13 이상 (SceneDelegate 사용)

👉 iOS13 이상이어도 SceneDelegate를 사용하지 않을 수도 있어요, 이 때에는 위의 SceneDelegate를 사용하지 않는 경우를 참조하세요.

SceneDelegatesceneDidBecomeActive함수에 SDK를 Initialization하기 위한 코드를 다음과 같이 적용합니다. SDK가 정상적으로 초기화 되었을 때 아래와 같은 기본 분석이 가능합니다.

  • 앱 실행 및 방문수, 일/주/월순수방문수 등 방문과 관련된 지표

  • 통신사, 단말기, 국가 등 방문자의 단말기 환경으로 부터 추출될 수 있는 지표

import DOT
import Firebase

class SceneDelegate: UIResponder, UIWindowSceneDelegate {
...
  func sceneDidBecomeActive(_ scene: UIScene) {
  
    // 등록 토큰을 수신하기 위한 SDK구성
    FirebaseApp.configure()
  
    // =======================================================
    // Wisetracker 기본 SDK가 이미 적용된 경우에는 새로 적용할 필요가 없습니다.
    // 메시징 서비스만 이용하는 경우 참조해주세요.
    // =======================================================
    // Start : Wisetracker SDK 호출
    DOT.initialization(nil, application: UIApplication.shared)
    #if DEBUG
      DOT.checkDebugMode(true)
    #else
      DOT.checkDebugMode(false)
    #endif
    // E: Wisetracker SDK init
  }
...
}

Bridge 파일 추가

마지막으로 bridge 함수들을 호출 할 수 있게 bridge 파일을 추가 합니다.

왼쪽은 처음 플러그인 다운로드시 생긴 node_modules/DotReactNativeBridge/ios 폴더 하위에 있는 bridge파일의 위치이며 파일을 복사한 뒤 , 오른쪽에 보이는 현 프로젝트 폴더의 /프로젝트명/ios/프로젝트명과 동일한 폴더 경로에 복사한 두 개의 bridge 파일을 붙여넣습니다.

Bridge 파일 추가 후 AppDelegate.mm 파일에 DotReactBridge *dotReactBridge를 추가 해 줍니다.

#import "DotReactBridge.h"

- (NSArray<id<RCTBridgeModule>> *)extraModulesForBridge:(RCTBridge *)bridge
{
  // If you'd like to export some custom RCTBridgeModules, add them here!
  DotReactBridge *dotReactBridge = [DotReactBridge alloc];
  return @[dotReactBridge]; 
}

이미지 푸시메시지 적용 (선택사항)

  1. Notification Service Extension Target 추가

이미지를 포함한 푸시메세를 수신받기 위해 필요합니다.

File - New - Target 메뉴에서 "Notification Service Extension"을 선택합니다.

Product Name에 타겟명을 입력합니다. (아래에서 Podfile에 target을 추가할때 사용할 타겟명입니다)

추가 완료 후 NotificationServiceExtension 폴더가 생성됩니다.

  1. Podfile 수정

Podfile에 아래와 같이 앱의 타겟 안에 이미지 푸시를 위한 타겟을 추가한 후 pod install 명령어를 실행시켜 줍니다.

Podfile

✔️프레임워크 추가시 앱의 프레임워크 방식과 동일하게 작성될 수 있도록 한번 더 체크 해 주세요. (동적 or 정적)

✔️Wisetracker SDK 버전이 명시되어 있다면, 동일하게 버전이 명시되어 있는 형태로 추가했는지 체크 해 주세요.

target 'wisetracker' do
  ...
  # S: Wisetracker SDK add
  pod 'RW', '~> 1.1.45'
  pod 'Firebase/Messaging'
  # E: Wisetracker SDK add
  ...

  # =======================================================
  #Start : 이미지 푸시 수신을 위한 추가
  #=======================================================
  target ‘NotificationServiceExtension’ do
  
    # 프레임워크를 동적으로 링크하는것이 권장되오나, 앱에 따라 정적으로 링크하는 경우,
    # 앱의 프레임워크 링크방식과 동일하게 사용 해 주세요. 아래의 방식은 정적으로 링크하는 경우입니다.
    # use_frameworks!  >>>>>>>>> 동적의 경우일때 사용
    use_frameworks! :linkage => :static
    
    # Wisetracker SDK 의 버전이 명시되어 있는 경우 동일하게 버전을 명시 해 주세요.
    pod 'RW', '~> 1.1.45'
    pod ‘FirebaseMessaging’, :modular_headers => true
   end
  #=======================================================
  #End : 이미지 푸시
  #=======================================================

...
...
end

위의 "NotificationServiceExtension"은 고객사에서 만든 타켓명으로 해주셔야 합니다.

예시는 타겟명이 "NotificationServiceExtension"인 경우입니다.

🔴 Podfile에 이미지 푸시를 추가하였으나 아래와 같은 에러가 발생된다면 아래의 앱 확장 코드를 추가 해 주세요.

'sharedApplication' is unavailable: not available on iOS (App Extension) - Use view controller based solutions where appropriate instead.

target 'wisetracker' do
...

  post_install do |installer|
    react_native_post_install(
      installer,
      ...
      ...
    )
    ...
    ###############  App Extension 에러 발생시 추가 ######################
    # 앱 확장이 iOS 기능과 라이브러리에 자유롭게 액세스할 수 있게 설정.
    installer.pods_project.targets.each do |target|
     target.build_configurations.each do |config|
      config.build_settings[‘APPLICATION_EXTENSION_API_ONLY’] = ‘NO’
     end
    end
    ###################################################################
  end
  
  # S: Wisetracker SDK add
  pod 'RW', '~> 1.1.45'
  pod 'Firebase/Messaging'
  # E: Wisetracker SDK add
  
...
...
end

  1. NotificationService 수정

  • NotificationService 파일을 열어 아래의 내용으로 대체해 주세요. * 기존 내용을 모두 삭제하고 아래 내용으로 대체하는것이며, 추가가 아님에 유의 해 주세요.

NotificationService

// =======================================================
// Start : 소스코드 모두 바꾸기
// =======================================================
import UserNotifications
import FirebaseMessaging

class NotificationService: UNNotificationServiceExtension {
    var contentHandler: ((UNNotificationContent) -> Void)?
    var bestAttemptContent: UNMutableNotificationContent?

    override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) {
        self.contentHandler = contentHandler
        self.bestAttemptContent = request.content.mutableCopy() as? UNMutableNotificationContent
        
        if let bestAttemptContent = self.bestAttemptContent {
            // DOT didReceiveNotificationExtensionRequest 메서드 호출
            self.bestAttemptContent = self.didReceiveNotificationExtensionRequest(request, withContent: bestAttemptContent)
            
            if let contentHandler = self.contentHandler {
                FIRMessagingExtensionHelper().populateNotificationContent(bestAttemptContent, withContentHandler: contentHandler)
            }
        }
    }
    
    override func serviceExtensionTimeWillExpire() {
        if let contentHandler = self.contentHandler, let bestAttemptContent = self.bestAttemptContent {
            contentHandler(bestAttemptContent)
        }
    }
    
    func didReceiveNotificationExtensionRequest(_ request: UNNotificationRequest, withContent content: UNMutableNotificationContent) -> UNMutableNotificationContent {
        return content
    }
}
// =======================================================
// End : 소스코드 모두 바꾸기
// =======================================================

🔴 NotificationService 파일에서FirebaseMessaging 모듈이 없다는 에러 발생시 Notification Service Extension 타겟의 빌드 설정에서 "Header Search Paths" 항목을 확인하고 Firebase Messaging 헤더 파일이 포함된 디렉토리가 있는지 확인하세요.

iOS 기초설정은 완료하셨습니다 🎉

다음으로 푸시메세지 설정을 위한 단계를 진행 해 주세요 👇🏻

Last updated