250x250
Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
Tags
- front-end
- react
- html5
- 개발자
- effect
- jQuery
- 애니메이션
- iOS 개발자
- iPhone
- 비전공자
- javascript
- CSS
- xcode
- 자바스크립트
- ipad
- hover
- MAC
- 비전공 개발자
- keyframes
- 프론트엔드
- IOS
- 백엔드
- Animation
- 풀스택
- image
- HTML
- css3
- SWIFT
- button
- php
Archives
- Today
- Total
비전공자 개발일기
Real Time Notice' s modal (Firebase Remote Config & A/B Test) 본문
728x90
SMALL
Remote Config
- 배포 및 업데이트 다운로드 없이 앱 변경
- 기본값을 설정한 후 값을 재정의
- 클라우드 기반 Key - Value 저장소
- 앱 사용층에 변경사항을 빠르게 적용(업데이트 없이 앱의 UI/UX 변경을 지원)
- 사용자층의 특정 세그먼트에 앱 맞춤 설정(앱 버전, 언어 등으로 분류된 사용자 세그먼트별 환경 제공)
- A / B Test를 실행하여 앱 개선(사용자 세그먼트별로 개선사항을 검증 후 점진적 적용을 해볼 수 있음)
A / B Test
- Google Analytics, Firebase 예측을 통한 사용자 타겟팅
- 원격구성(Remote Config or Cloud Messaging)활용
- 재품, 마케팅 실험을 쉽게 실행, 분석, 확장이 가능
- 제품 환경 테스트 및 개선(앱 동작 및 모양을 변경하여 최적의 제품 환경을 확인할 수 있음)
- 사용자의 재참여를 유도할 방안 모색(앱 사용자를 늘리기에 가장 효과적인 문구와 메시징을 설정할 수 있음)
- 새로운 기능의 안전한 구현(작은 규모의 사용자 집합을 대상으로 원하는 목표를 달성할 수 있는지 확인)
- 예측된 사용자 그룹 타켓팅(특정 행동을 할 것으로 예측된 사용자에게 A / B Test를 실시해볼 수 있음)
import UIKit
import Firebase
@main
class AppDelegate: UIResponder, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
FirebaseApp.configure()
Installations.installations().authTokenForcingRefresh(true) { result, error in
if let error = error {
print("Error")
return
}
guard let result = result else { return }
print("Installation auth token: \(result.authToken)")
}
return true
}
// MARK: UISceneSession Lifecycle
func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
// Called when a new scene session is being created.
// Use this method to select a configuration to create the new scene with.
return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
}
func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set<UISceneSession>) {
// Called when the user discards a scene session.
// If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
// Use this method to release any resources that were specific to the discarded scenes, as they will not return.
}
}
import UIKit
class NoticeViewController: UIViewController {
var noticeContents: (title: String, detail: String, date: String)?
@IBOutlet weak var noticeView: UIView!
@IBOutlet weak var titleLabel: UILabel!
@IBOutlet weak var detailLabel: UILabel!
@IBOutlet weak var dateLabel: UILabel!
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
noticeView.layer.cornerRadius = 6
view.backgroundColor = UIColor(red: 0, green: 0, blue: 0, alpha: 0.5)
guard let noticeContents = noticeContents else { return }
titleLabel.text = noticeContents.title
detailLabel.text = noticeContents.detail
dateLabel.text = noticeContents.date
}
@IBAction func okayBTN(_ sender: UIButton) {
dismiss(animated: true)
}
}
import UIKit
import FirebaseRemoteConfig
import FirebaseAnalytics
class ViewController: UIViewController {
var remoteConfig: RemoteConfig?
override func viewDidLoad() {
super.viewDidLoad()
remoteConfig = RemoteConfig.remoteConfig()
let setting = RemoteConfigSettings()
setting.minimumFetchInterval = 0
remoteConfig?.configSettings = setting
remoteConfig?.setDefaults(fromPlist: "RemoteConfigDefaults")
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
getNotice()
}
}
extension ViewController {
func getNotice() {
guard let remoteConfig = remoteConfig else { return }
remoteConfig.fetch { [weak self] status, _ in
if status == .success {
remoteConfig.activate()
} else {
print("Error: Config not fetched")
}
guard let self = self else { return }
if !self.isNoticeHidden(remoteConfig) {
let noticeViewController = NoticeViewController(nibName: "NoticeViewController", bundle: nil)
noticeViewController.modalPresentationStyle = .custom
noticeViewController.modalTransitionStyle = .crossDissolve
let title = (remoteConfig["title"].stringValue ?? "").replacingOccurrences(of: "\\n", with: "\n")
let detail = (remoteConfig["detail"].stringValue ?? "").replacingOccurrences(of: "\\n", with: "\n")
let date = (remoteConfig["date"].stringValue ?? "").replacingOccurrences(of: "\\n", with: "\n")
noticeViewController.noticeContents = (title: title, detail: detail, date: date)
self.present(noticeViewController, animated: true)
} else {
self.showEventAlert()
}
}
}
func isNoticeHidden(_ remoteConfig: RemoteConfig) -> Bool {
return remoteConfig["isHidden"].boolValue
}
}
// A/B Testing
extension ViewController {
func showEventAlert() {
guard let remoteConfig = remoteConfig else {
return
}
remoteConfig.fetch { [weak self] status, _ in
if status == .success {
remoteConfig.activate()
} else {
print("Config not fetched")
}
}
let message = remoteConfig["message"].stringValue ?? ""
let confirmAction = UIAlertAction(title: "Check", style: .default) { _ in
Analytics.logEvent("promotion_alert", parameters: nil)
}
let cancelAction = UIAlertAction(title: "Cancel", style: .cancel)
let alertController = UIAlertController(title: "Surprise", message: message, preferredStyle: .alert)
alertController.addAction(confirmAction)
alertController.addAction(cancelAction)
self.present(alertController, animated: true)
}
}
//RemoteConfigDefaults.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>isHidden</key>
<true/>
<key>title</key>
<string>Here's UR guide</string>
<key>detail</key>
<string>Please refer to the service
Please refer to the service
</string>
<key>date</key>
<string>22.12.20(Tue) 00:00-03:00(3 hours)</string>
</dict>
</plist>
728x90
LIST
'SWIFT' 카테고리의 다른 글
Egg Timer (0) | 2022.12.24 |
---|---|
Xylophone (0) | 2022.12.23 |
Local Push Notification (0) | 2022.12.19 |
Remote Push Notification(APNs, FCM) (0) | 2022.12.19 |
Diary (0) | 2022.12.18 |