iOS ๊ธฐ์ดˆ ์„ค์ •

ํ‘ธ์‹œ๋ฉ”์„ธ์ง€ ๋ฐœ์†ก์„ ์œ„ํ•œ iOS OS ์—์„œ ํ•„์ˆ˜๋กœ ์„ค์ •ํ•ด ์ฃผ์…”์•ผ ํ•˜๋Š” ๊ฐ€์ด๋“œ์ž…๋‹ˆ๋‹ค.

APNS ์ธ์ฆ์„œ ๋ฐœ๊ธ‰

Firebase ์—ฐ๋™

๋‹ค์Œ Firebase console์—์„œ ํ”„๋กœ์ ํŠธ ๊ฐœ์š” ์˜ค๋ฅธ์ชฝ์˜ setting ์•„์ด์ฝ˜์„ ํด๋ฆญํ•˜์—ฌ ํ”„๋กœ์ ํŠธ ์„ค์ •์œผ๋กœ ๋“ค์–ด๊ฐ‘๋‹ˆ๋‹ค.

ํด๋ผ์šฐ๋“œ ๋ฉ”์‹œ์ง• ๋ฉ”๋‰ด๋ฅผ ํด๋ฆญํ•˜์—ฌ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋ฐœ๊ธ‰๋ฐ›์€ APN ์ธ์ฆ (.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.57'

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 ํ†ต์‹  ํ—ˆ์šฉ

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๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ๋ฅผ ์ฐธ์กฐํ•˜์„ธ์š”.

SceneDelegate์˜ sceneDidBecomeActiveํ•จ์ˆ˜์— 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 ํด๋”๊ฐ€ ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค.

Language์— ๋”ฐ๋ฅธ ํด๋” ํ˜•ํƒœ
  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"์ธ ๊ฒฝ์šฐ์ž…๋‹ˆ๋‹ค.

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 : ์†Œ์Šค์ฝ”๋“œ ๋ชจ๋‘ ๋ฐ”๊พธ๊ธฐ
// =======================================================

iOS ๊ธฐ์ดˆ์„ค์ •์€ ์™„๋ฃŒํ•˜์…จ์Šต๋‹ˆ๋‹ค ๐ŸŽ‰

๋‹ค์Œ์œผ๋กœ ํ‘ธ์‹œ๋ฉ”์„ธ์ง€ ์„ค์ •์„ ์œ„ํ•œ ๋‹จ๊ณ„๋ฅผ ์ง„ํ–‰ ํ•ด ์ฃผ์„ธ์š” ๐Ÿ‘‡๐Ÿป

Last updated

Was this helpful?