美文网首页js css html
基于Firebase平台开发(九) —— 使用Firebase

基于Firebase平台开发(九) —— 使用Firebase

作者: 刀客传奇 | 来源:发表于2021-04-10 20:11 被阅读0次

    版本记录

    版本号 时间
    V1.0 2021.04.10 星期六

    前言

    Firebase是一家实时后端数据库创业公司,它能帮助开发者很快的写出Web端和移动端的应用。自2014年10月Google收购Firebase以来,用户可以在更方便地使用Firebase的同时,结合Google的云服务。Firebase能让你的App从零到一。也就是说它可以帮助手机以及网页应用的开发者轻松构建App。通过Firebase背后负载的框架就可以简单地开发一个App,无需服务器以及基础设施。接下来几篇我们就一起看一下基于Firebase平台的开发。感兴趣的看下面几篇文章。
    1. 基于Firebase平台开发(一) —— 基于ML Kit的iOS图片中文字的识别(一)
    2. 基于Firebase平台开发(二) —— 基于ML Kit的iOS图片中文字的识别(二)
    3. 基于Firebase平台开发(三) —— Firebase基本使用简介(一)
    4. 基于Firebase平台开发(四) —— Firebase基本使用简介(二)
    5. 基于Firebase平台开发(五) —— Firebase基本使用简介(三)
    6. 基于Firebase平台开发(六) —— 基于Firebase Analytics的App使用率的跟踪(一)
    7. 基于Firebase平台开发(七) —— iOS的A/B Test(一)
    8. 基于Firebase平台开发(八) —— 使用Firebase Cloud Messaging进行Push Notification的发送和接收(一)

    源码

    1. Swift

    首先看下工程组织结构

    下面就是源码了

    1. AppMain.swift
    
    import SwiftUI
    
    @main
    struct AppMain: App {
      @UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
    
      var body: some Scene {
        WindowGroup {
          AppTabView()
            .accentColor(Color("rw-green"))
        }
      }
    }
    
    2. AppDelegate.swift
    
    import UIKit
    import Firebase
    import FirebaseMessaging
    import FirebaseAnalytics
    
    class AppDelegate: NSObject, UIApplicationDelegate {
      func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil) -> Bool {
        FirebaseApp.configure()
        FirebaseConfiguration.shared.setLoggerLevel(.min)
    
        UNUserNotificationCenter.current().delegate = self
        let authOptions: UNAuthorizationOptions = [.alert, .badge, .sound]
        UNUserNotificationCenter.current().requestAuthorization(
          options: authOptions) { _, _ in }
        application.registerForRemoteNotifications()
    
        Messaging.messaging().delegate = self
    
        return true
      }
    }
    
    extension AppDelegate: UNUserNotificationCenterDelegate {
      func userNotificationCenter(
        _ center: UNUserNotificationCenter,
        willPresent notification: UNNotification,
        withCompletionHandler completionHandler:
        @escaping (UNNotificationPresentationOptions) -> Void
      ) {
        process(notification)
        completionHandler([[.banner, .sound]])
      }
    
      func userNotificationCenter(
        _ center: UNUserNotificationCenter,
        didReceive response: UNNotificationResponse,
        withCompletionHandler completionHandler: @escaping () -> Void
      ) {
        process(response.notification)
        completionHandler()
      }
    
      func application(
        _ application: UIApplication,
        didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data
      ) {
        Messaging.messaging().apnsToken = deviceToken
      }
    
      private func process(_ notification: UNNotification) {
        let userInfo = notification.request.content.userInfo
        UIApplication.shared.applicationIconBadgeNumber = 0
        if let newsTitle = userInfo["newsTitle"] as? String,
          let newsBody = userInfo["newsBody"] as? String {
          let newsItem = NewsItem(title: newsTitle, body: newsBody, date: Date())
          NewsModel.shared.add([newsItem])
          Analytics.logEvent("NEWS_ITEM_PROCESSED", parameters: nil)
        }
        Messaging.messaging().appDidReceiveMessage(userInfo)
        Analytics.logEvent("NOTIFICATION_PROCESSED", parameters: nil)
      }
    }
    
    extension AppDelegate: MessagingDelegate {
      func messaging(
        _ messaging: Messaging,
        didReceiveRegistrationToken fcmToken: String?
      ) {
        let tokenDict = ["token": fcmToken ?? ""]
        NotificationCenter.default.post(
          name: Notification.Name("FCMToken"),
          object: nil,
          userInfo: tokenDict)
      }
    }
    
    3. NewsModel.swift
    
    import Foundation
    
    class NewsModel: ObservableObject {
      @Published private(set) var newsItems: [NewsItem] = []
    
      func add(_ items: [NewsItem]) {
        var tempItems = newsItems
        tempItems.append(contentsOf: items)
        newsItems = tempItems.sorted {
          $0.date > $1.date
        }
      }
    }
    
    extension NewsModel {
      static let shared = mockModel()
      private static func mockModel() -> NewsModel {
        let newsModel = NewsModel()
        let decoder = JSONDecoder()
        decoder.dateDecodingStrategy = .iso8601
        guard
          let url = Bundle.main.url(forResource: "MockNewsItems", withExtension: "json"),
          let data = try? Data(contentsOf: url),
          let newsItems = try? decoder.decode([NewsItem].self, from: data)
        else {
          return newsModel
        }
        newsModel.add(newsItems)
        return newsModel
      }
    }
    
    4. NewsItem.swift
    
    import Foundation
    
    struct NewsItem: Identifiable, Codable {
      var id = UUID()
      let title: String
      let body: String
      let date: Date
    
      private enum CodingKeys: String, CodingKey {
        case title
        case body
        case date
      }
    }
    
    5. TopicsModel.swift
    
    import SwiftUI
    import FirebaseMessaging
    
    class TopicsModel: ObservableObject {
      static let familyKey = "family"
      static let petsKey = "pets"
      @AppStorage(TopicsModel.familyKey) var family = false {
        didSet {
          updateSubscription(for: TopicsModel.familyKey, subscribed: family)
        }
      }
      @AppStorage(TopicsModel.petsKey) var pets = false {
        didSet {
          updateSubscription(for: TopicsModel.petsKey, subscribed: pets)
        }
      }
    
      private func updateSubscription(for topic: String, subscribed: Bool) {
        if subscribed {
          subscribe(to: topic)
        } else {
          unsubscribe(from: topic)
        }
      }
    
      private func subscribe(to topic: String) {
        Messaging.messaging().subscribe(toTopic: topic)
      }
    
      private func unsubscribe(from topic: String) {
        Messaging.messaging().unsubscribe(fromTopic: topic)
      }
    }
    
    6. AppTabView.swift
    
    import SwiftUI
    
    struct AppTabView: View {
      var body: some View {
        TabView {
          NavigationView {
            NewsListView(newsModel: NewsModel.shared)
          }
          .tabItem {
            Image(systemName: "newspaper")
            Text("News")
          }
          NavigationView {
            TopicsView()
          }
          .tabItem {
            Image(systemName: "rectangle.3.offgrid.bubble.left")
            Text("Topics")
          }
        }
      }
    }
    
    struct AppTabView_Previews: PreviewProvider {
      static var previews: some View {
        AppTabView()
      }
    }
    
    7. NewsListView.swift
    
    import SwiftUI
    
    struct NewsListView: View {
      @ObservedObject var newsModel: NewsModel
    
      var body: some View {
        List(newsModel.newsItems) { newsItem in
          NewsItemView(newsItem: newsItem)
        }
        .listStyle(InsetGroupedListStyle())
        .navigationTitle("Good News")
      }
    }
    
    struct NewsListView_Previews: PreviewProvider {
      static var previews: some View {
        NavigationView {
          NewsListView(newsModel: NewsModel.shared)
        }
      }
    }
    
    8. NewsItemView.swift
    
    import SwiftUI
    
    struct NewsItemView: View {
      let newsItem: NewsItem
      var body: some View {
        VStack(alignment: .leading) {
          Text(newsItem.title)
            .font(.title2)
            .bold()
          Text(newsItem.body)
            .font(.body)
          Text(newsItem.date, formatter: dateFormatter)
            .font(.caption2)
            .italic()
        }
      }
    
      private var dateFormatter: DateFormatter {
        let formatter = DateFormatter()
        formatter.dateStyle = .short
        formatter.timeStyle = .short
        return formatter
      }
    }
    
    struct NewsItemRowView_Previews: PreviewProvider {
      static var previews: some View {
        NewsItemView(newsItem: NewsItem(title: "News Title", body: "News body, with more information", date: Date()))
      }
    }
    
    9. TopicsView.swift
    
    import SwiftUI
    
    struct TopicsView: View {
      @ObservedObject var topicsModel = TopicsModel()
    
      var body: some View {
        Form {
          Section(header: Text("Select the topics you would like to receive notifications for")) {
            Toggle("Family", isOn: $topicsModel.family)
            Toggle("Pets", isOn: $topicsModel.pets)
          }
        }
        .navigationTitle("Topics")
      }
    }
    
    struct SubscriptionsView_Previews: PreviewProvider {
      static var previews: some View {
        NavigationView {
          TopicsView()
        }
      }
    }
    
    10. NotificationService.swift
    
    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
        guard let bestAttemptContent = bestAttemptContent else { return }
        FIRMessagingExtensionHelper().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)
        }
      }
    }
    

    后记

    本篇主要讲述了使用Firebase Cloud Messaging进行Push Notification的发送和接收,感兴趣的给个赞或者关注~~~

    相关文章

      网友评论

        本文标题:基于Firebase平台开发(九) —— 使用Firebase

        本文链接:https://www.haomeiwen.com/subject/algnkltx.html