Geon

NotificationService를 통한 다국어 처리 본문

SwiftUI/지식 창고

NotificationService를 통한 다국어 처리

jgkim1008 2024. 6. 25. 23:25

TODO

  • App Groups으로 Push 와 프로젝트를 묶어 데이터 전달 할수 있게 설정
  • Localizable 파일 공유
  • 앱에서 선택한 언어 값을 읽어와 번들에 해당 언어 적용

 

사전 필요 지식

App Groups

  • 동일한 개발자가 만든 설치된 여러 앱 간의 통신 및 데이터 공유를 활성화

UserDefaults(suiteName: "그룹 네이밍")

  • 앱 그룹간의 설정된 언어를 가져오기 위해 UserDefaults로 가져올수있게 한다
  • UserDefaults(suiteName: "그룹 네이밍")?.string(forKey: "app_lang") 로 현재 설정된 언어 가져오기


시스템의 언어 설정 기준

  • if let 으로 데이터를 바꿔치는 이유는 bestAttemptContent를 그대로 보여주면 번들 과 사용자 키보드 언어를 조합해서 시스템 언어로 설정 및 그대로 번역된 언어가 보여진다.
  • 그래서 안에 내용을 꺼내서 앱에 셋팅된 언어 적용하게 변경하였습니다. (해당 언어의 path를 가져와서 bundle 적용)

 

셋팅 방법

  • 프로젝트 선택 → Targets → Auction → Signing & Caoabilities → Capability + 선택

 


APP Groups 으로 묶기(Notificaion Service) 에도 동일하게 적용

 

 

APP(Auction 프로젝트) 에 구현되어 있는 다국어 파일을 NotificationService 와 공유하기

  • Target → Push → Build Phase → Copy Bundle Resources 에 추가

 

 

NotificationService 코드 구현부

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
        bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent)
        if let aps = request.content.userInfo["aps"] as? [AnyHashable: Any] {
            if let alert = aps["alert"] as? [AnyHashable: Any] {
                // 알림을 커스텀 처리
                let titleLocKey = alert["title-loc-key"] as? String
                let locKey = alert["loc-key"] as? String
                if let titleLoc = titleLocKey,
                   let loc = locKey {
                    let content = UNMutableNotificationContent()
                    let titleArgs = alert["title-loc-args"] as? [String]
                    let contentArgs = alert["loc-args"] as? [String]
                    if let tArgs = titleArgs, !tArgs.isEmpty {
                        bestAttemptContent?.title = titleLoc.localizabled(with: tArgs)
                    } else {
                        bestAttemptContent?.title = titleLoc.localizabled()
                    }
                    if let cArgs = contentArgs, !cArgs.isEmpty {
                        bestAttemptContent?.body = loc.localizabled(with: cArgs)
                    } else {
                        bestAttemptContent?.body = loc.localizabled()
                    }
                    bestAttemptContent?.userInfo = request.content.userInfo
                    bestAttemptContent?.userInfo["processed"] = true
                }
            }
        }
        if let bestAttemptContent = bestAttemptContent {
            Messaging.serviceExtension().exportDeliveryMetricsToBigQuery(withMessageInfo: request.content.userInfo)
            Messaging.serviceExtension().populateNotificationContent(bestAttemptContent, withContentHandler: contentHandler)
        }
    }
    override func serviceExtensionTimeWillExpire() {
        // Called just before the extension will be terminated by the system.
        // Use this as an opportunity to deliver your "best attempt" at modified content, otherwise the original push payload will be used.
        if let contentHandler = contentHandler, let bestAttemptContent =  bestAttemptContent {
            contentHandler(bestAttemptContent)
        }
    }
}
extension String
{
    // MARK: - String localizabled
    func localizabled() -> String {
              return NSLocalizedString(self, tableName: nil, bundle: Bundle.localizedBundle(), value: "", comment: "")
          }
        func attributedStringWithColor(_ strings: [String], color: UIColor, characterSpacing: UInt? = nil) -> NSAttributedString {
        let attributedString = NSMutableAttributedString(string: self)
        for string in strings {
            let range = (self as NSString).range(of: string)
            attributedString.addAttribute(NSAttributedString.Key.foregroundColor, value: color, range: range)
        }
        guard let characterSpacing = characterSpacing else {return attributedString}
        attributedString.addAttribute(NSAttributedString.Key.kern, value: characterSpacing, range: NSRange(location: 0, length: attributedString.length))
        return attributedString
    }
    func localizabled(with arguments: [CVarArg]) -> String {
        return String(format: self.localizabled(), locale: nil, arguments: arguments)
    }
    func urlDecode() -> String? {
        return self.removingPercentEncoding
    }
}
// MARK: - Bundle
extension Bundle {
    private static var bundle: Bundle!
    // MARK: - Bundle localizabled
    static func localizedBundle() -> Bundle! {
        var appLang: String = ""
        appLang = UserDefaults(suiteName: "group.autowini.push")?.string(forKey: "app_lang") ?? "en"
        let path = Bundle.main.path(forResource: appLang, ofType: "lproj")
        bundle = Bundle(path: path!)
        return bundle
    }
    static func setLanguage(lang: String) {
        let path = Bundle.main.path(forResource: lang, ofType: "lproj")
        bundle = Bundle(path: path!)
    }
}

'SwiftUI > 지식 창고' 카테고리의 다른 글

mitmproxy로 iOS 네트워크 감청해보기  (1) 2024.09.05
긴급 심사 올리기  (0) 2024.08.21
Json Parsing with optional key  (0) 2023.02.02
TextEditor에 PlaceHolder 적용  (0) 2022.12.30
SwiftUI 텍스트 크기 지정  (0) 2022.12.14