Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feat/#71] Add push notification when the message arrived #112

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 47 additions & 23 deletions DDooing/DDooing.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

4 changes: 3 additions & 1 deletion DDooing/DDooing/DDooing.entitlements
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,15 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>aps-environment</key>
<string>development</string>
<key>com.apple.developer.applesignin</key>
<array>
<string>Default</string>
</array>
<key>com.apple.security.application-groups</key>
<array>
<string>group.com.Seodongwon.DDooing</string>
<string>group.com.iOSDevJoy.DDooing</string>
</array>
</dict>
</plist>
16 changes: 16 additions & 0 deletions DDooing/DDooing/DDooingRelease.entitlements
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?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>aps-environment</key>
<string>development</string>
<key>com.apple.developer.applesignin</key>
<array>
<string>Default</string>
</array>
<key>com.apple.security.application-groups</key>
<array>
<string>group.com.iOSDevJoy.DDooing</string>
</array>
</dict>
</plist>
21 changes: 21 additions & 0 deletions DDooing/DDooing/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,21 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>FirebaseAppDelegateProxyEnabled</key>
<false/>
<key>NSAppTransportSecurity</key>
<dict>
<key>NSExceptionDomains</key>
<dict>
<key>114.70.193.152</key>
<dict>
<key>NSExceptionAllowsInsecureHTTPLoads</key>
<true/>
<key>NSIncludesSubdomains</key>
<true/>
</dict>
</dict>
</dict>
<key>UIAppFonts</key>
<array>
<string>Pretendard-Black.otf</string>
Expand All @@ -14,5 +29,11 @@
<string>Pretendard-SemiBold.otf</string>
<string>Pretendard-Thin.otf</string>
</array>
<key>UIBackgroundModes</key>
<array>
<string>fetch</string>
<string>processing</string>
<string>remote-notification</string>
</array>
</dict>
</plist>
22 changes: 22 additions & 0 deletions DDooing/DDooing/Models/NotificationDataModel.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
//
// NotificationData.swift
// DDooing
//
// Created by kimjihee on 5/25/24.
//

import SwiftData
import SwiftUI

@Model
final class NotificationDataModel {
@Attribute(.unique) var id: UUID
var body: String
var title: String

init(body: String, title: String) {
self.id = UUID()
self.body = body
self.title = title
}
}
34 changes: 19 additions & 15 deletions DDooing/DDooing/Views/Auth/RandomCodeView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ struct RandomCodeView: View {
@State private var isConnectionMode = true
@State private var code = ""
@State private var randomCode = ""
@AppStorage("userDeviceToken") private var userDeviceToken: String = ""


var body: some View {
NavigationStack{
Expand Down Expand Up @@ -88,32 +90,34 @@ struct RandomCodeView: View {
sendRandomCodeToFirebase(for: user, with: randomCode)
viewModel.observeUserConnectionStatus(userId: user.uid)
}
print("Device Token in HomeView: \(userDeviceToken)")
}
.navigationBarBackButtonHidden(true)
}
private func generateRandomCode(length: Int) -> String {
let lettersAndDigits = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
return String((0..<length).compactMap { _ in lettersAndDigits.randomElement() })
}
}


func sendRandomCodeToFirebase(for user: User, with code: String) {
let db = Firestore.firestore()
let docRef = db.collection("Users").document(user.uid)
docRef.setData([
"uid": user.uid,
"code": code,
"isConnected" : false,
], merge: true) { error in
if let error = error {
print("Error writing document: \(error)")
} else {
print("Document successfully written!")
func sendRandomCodeToFirebase(for user: User, with code: String) {
let db = Firestore.firestore()
let docRef = db.collection("Users").document(user.uid)
docRef.setData([
"uid": user.uid,
"code": code,
"isConnected" : false,
"deviceToken" : userDeviceToken,
], merge: true) { error in
if let error = error {
print("Error writing document: \(error)")
} else {
print("Document successfully written!")
}
}
}
}


func connectUsers(with code: String, userAUID: String) {
let db = Firestore.firestore()
db.collection("Users").whereField("code", isEqualTo: code)
Expand Down
124 changes: 124 additions & 0 deletions DDooing/DDooing/Views/DDooingApp.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,133 @@ struct DDooingApp: App {
}
}

// Initializing firebase and cloud messaging
class AppDelegate: NSObject, UIApplicationDelegate {
let gcmMessageIDKey = "gcm.message_id"

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {

FirebaseApp.configure()

// Setting cloud messaging
Messaging.messaging().delegate = self

// Setting notifications
UNUserNotificationCenter.current().delegate = self

let authOptions: UNAuthorizationOptions = [.alert, .badge, .sound]
UNUserNotificationCenter.current().requestAuthorization(
options: authOptions,
completionHandler: { _, _ in }
)

application.registerForRemoteNotifications()

return true
}

func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any],
fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {

// Do something with message data here.

UIImpactFeedbackGenerator(style: .medium).impactOccurred()

if let messageID = userInfo[gcmMessageIDKey] {
print("Message ID: \(messageID)")
}

// Print full message.
print(userInfo)

completionHandler(UIBackgroundFetchResult.newData)
}

// In order to receive notifications you need implement these methods.
func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: any Error) {
print(error.localizedDescription)
}

func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
Messaging.messaging().apnsToken = deviceToken
print("----- \(deviceToken)")
}


}

// Cloud messaging
extension AppDelegate: MessagingDelegate {
func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String?) {
print("Firebase register action token:")

// Store this token to firebase and retrieve when to send message to someone.
let dataDict: [String: String] = ["token": fcmToken ?? ""]

if let user = Auth.auth().currentUser {
setUsersFCMToken(token: fcmToken!, userAUID: user.uid)
UserDefaults.standard.set(fcmToken, forKey: "userDeviceToken")
}

// Store token in firestore for sending notifications from server in future
print(dataDict)
}

private func setUsersFCMToken(token : String, userAUID: String) {
let db = Firestore.firestore()

db.collection("Users").document(userAUID).updateData([
"deviceToken": token
]) { err in
if let err = err {
print("Error updating document: \(err)")
} else {
print("토큰 저장 성공 : \(token)")
}
}
}

}

// User notifications (InApp Notifications)
extension AppDelegate: UNUserNotificationCenterDelegate {
func userNotificationCenter(_ center: UNUserNotificationCenter,
willPresent notification: UNNotification,
withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
let userInfo = notification.request.content.userInfo

// Haptics
// UIImpactFeedbackGenerator(style: .medium).impactOccurred()

// Do something with message data.
print("User Info: \(userInfo)")
if let aps = userInfo["aps"] as? [String: Any],
let alert = aps["alert"] as? [String: String],
let body = alert["body"],
let title = alert["title"] {
// body와 title 값을 추출했습니다.
// 여기서 SwiftData를 사용하여 값을 저장합니다.
// saveNotificationData(body: body, title: title)
print("User alert: \(alert)")
print("User body: \(body)")
print("User title: \(title)")
}

completionHandler([[.banner, .badge, .sound]])
}


func userNotificationCenter(_ center: UNUserNotificationCenter,
didReceive response: UNNotificationResponse,
withCompletionHandler completionHandler: @escaping () -> Void) {
let userInfo = response.notification.request.content.userInfo

if let messageID = userInfo[gcmMessageIDKey] {
print("Message ID: \(messageID)")
}

print("User Info: \(userInfo)")

completionHandler()
}
}
Loading