iOS Push Notifications Integration

Implementation Overview

Implementing push notifications in your iOS app requires just 3 simple steps:

  1. Enable push notification capability in your Xcode project
  2. Request permission and get the device token from Apple
  3. Send this device token to our backend

That's it! Our backend handles all the complex APNs configuration and sending push notifications to your users.

Step 1: Enable Push Notification Capability

  1. In Xcode, select your project
  2. Select your app target
  3. Go to "Signing & Capabilities"
  4. Click "+ Capability" and add "Push Notifications"

Note: Make sure your bundle ID matches what you've provided to our team for APNs configuration.

Step 2: Request Permission and Get Device Token

Add this code to your AppDelegate:

import UIKit
import UserNotifications

class AppDelegate: UIResponder, UIApplicationDelegate {
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        // Request notification permissions
        UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound, .badge]) { granted, error in
            guard granted else { 
                print("Notification permission denied")
                return 
            }
            
            DispatchQueue.main.async {
                // This will trigger didRegisterForRemoteNotificationsWithDeviceToken
                UIApplication.shared.registerForRemoteNotifications()
            }
        }
        return true
    }
    
    // This method will be called with your device token
    func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
        // Convert binary token to string format
        let tokenParts = deviceToken.map { data in String(format: "%02.2hhx", data) }
        let token = tokenParts.joined()
        
        print("Device Token: \(token)")
        
        // Send the token to our backend
        sendDeviceTokenToBackend(token)
    }
    
    func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
        print("Failed to register for remote notifications: \(error.localizedDescription)")
    }
}

Step 3: Send Device Token to Our Backend

Add this method to your AppDelegate to send the token:

func sendDeviceTokenToBackend(_ token: String) {
    // Get the user ID from your authentication system
    guard let userId = UserDefaults.standard.string(forKey: "userId") else { 
        print("No userId found, can't register device token")
        return 
    }
    
    // Prepare API request to our backend
    let url = URL(string: "https://api.wecompleteapp.com/api/users/user/\(userId)/device-token")!
    var request = URLRequest(url: url)
    request.httpMethod = "POST"
    request.setValue("application/json", forHTTPHeaderField: "Content-Type")
    
    // Create request body with the token
    let body: [String: Any] = ["deviceToken": token]
    request.httpBody = try? JSONSerialization.data(withJSONObject: body)
    
    // Send the request
    URLSession.shared.dataTask(with: request) { data, response, error in
        if let error = error {
            print("Error registering device token: \(error.localizedDescription)")
            return
        }
        
        guard let httpResponse = response as? HTTPURLResponse else {
            print("Invalid response")
            return
        }
        
        if httpResponse.statusCode == 200 {
            print("✅ Device token registered successfully with backend")
        } else {
            print("❌ Failed to register device token: HTTP \(httpResponse.statusCode)")
        }
    }.resume()
}

API Endpoint Details

URL: https://api.wecompleteapp.com/api/users/user/{userId}/device-token

Method: POST

Headers: Content-Type: application/json

Body: { "deviceToken": "your-device-token-string" }

Response: { "success": true, "message": "Device token registered successfully" }

Step 4: Handle Incoming Notifications

Add this method to handle notifications when your app is in the background:

func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any], 
                             fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
    print("Received notification: \(userInfo)")
    
    // Process notification data
    if let aps = userInfo["aps"] as? [String: Any] {
        // Process standard Apple notification fields
    }
    
    if let data = userInfo["data"] as? [String: Any] {
        // Process our custom data fields
        if let notificationId = data["notificationId"] as? String {
            // You can use the notificationId to fetch more details
            print("Notification ID: \(notificationId)")
        }
        
        if let type = data["type"] as? String {
            // Handle different notification types
            switch type {
            case "message":
                // Navigate to message screen
                break
            case "reminder":
                // Navigate to reminder screen
                break
            default:
                break
            }
        }
    }
    
    completionHandler(.newData)
}

For a better user experience, implement the UNUserNotificationCenterDelegate:

// In your AppDelegate.swift
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    // ... existing code ...
    
    UNUserNotificationCenter.current().delegate = self
    
    return true
}

// MARK: - UNUserNotificationCenterDelegate
extension AppDelegate: UNUserNotificationCenterDelegate {
    // Called when a notification is received while app is in foreground
    func userNotificationCenter(_ center: UNUserNotificationCenter, 
                               willPresent notification: UNNotification, 
                               withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
        // You can choose how to display the notification
        completionHandler([.banner, .sound, .badge])
    }
    
    // Called when user taps on a notification
    func userNotificationCenter(_ center: UNUserNotificationCenter, 
                               didReceive response: UNNotificationResponse, 
                               withCompletionHandler completionHandler: @escaping () -> Void) {
        let userInfo = response.notification.request.content.userInfo
        print("User tapped on notification: \(userInfo)")
        
        // Process the notification and navigate to relevant screen
        if let data = userInfo["data"] as? [String: Any],
           let type = data["type"] as? String {
            // Handle navigation based on notification type
        }
        
        completionHandler()
    }
}

Testing Push Notifications

To test if your push notification setup works correctly:

  1. Run your app on a physical device (not the simulator)
  2. Make sure you grant notification permissions when prompted
  3. Verify the device token appears in your console logs
  4. Confirm the "Device token registered successfully" message appears
  5. Use our test endpoint to send a test notification

Test API Endpoint

You can trigger a test notification using this endpoint:

URL: https://api.wecompleteapp.com/api/users/user/{userId}/send-test-notification

Example: https://api.wecompleteapp.com/api/users/user/nh74hejga9ynysqbtkpsfn6nsn7exnbm/send-test-notification

Method: POST

Headers: Content-Type: application/json

Body:

{
  "title": "Your custom title",
  "message": "Your custom message",
  "category": "Your notification category",
  "url": "wecomplete://memories/mem_123456"
}

All parameters are optional. The url parameter can be used for deep linking to specific screens in your app.

Using Push Notifications Across Your App

To send push notifications to users from your app, use the device token registration endpoint. Our backend will handle sending notifications to your users at the appropriate times.

Device Token Registration

URL: https://api.wecompleteapp.com/api/users/user/{userId}/device-token

Method: POST

Headers: Content-Type: application/json

Body: { "deviceToken": "your-device-token-string" }

Response: { "success": true, "message": "Device token registered successfully" }

Troubleshooting

Not receiving the device token

  • Check that push capability is enabled in your app
  • Verify you're testing on a physical device, not the simulator
  • Make sure your provisioning profile includes push entitlements
  • User must grant notification permissions
  • Check for any errors in the console log

Token registration fails

  • Make sure your userId is correctly stored in UserDefaults
  • Check your network connection
  • Verify the API URL is correct
  • Check the HTTP response code and message
  • Try testing with our API endpoints using Postman to verify server-side functionality

Notifications not appearing

  • Verify the device token was successfully registered with our backend
  • Check that notification permissions are granted in iOS Settings
  • Make sure your app is built with the correct bundle ID
  • Try sending a test notification to confirm the setup

Real-World Example: Habit Reminder Notifications

Let's walk through a complete example of implementing habit reminder notifications in your app:

Scenario

Users can set reminders for daily habits they want to track. Your app will send push notifications at scheduled times, and when a user taps on the notification, they'll be taken directly to the habit completion screen.

1. Creating the Habit Reminder

// HabitReminderView.swift
import SwiftUI

struct HabitReminderView: View {
    @State private var habitTitle = ""
    @State private var reminderTime = Date()
    @State private var showSuccess = false
    
    var body: some View {
        Form {
            Section(header: Text("Habit Details")) {
                TextField("Habit title", text: $habitTitle)
                DatePicker("Reminder time", selection: $reminderTime, displayedComponents: .hourAndMinute)
            }
            
            Button("Save Reminder") {
                createHabitReminder()
            }
        }
        .navigationTitle("New Habit Reminder")
        .alert("Reminder Set", isPresented: $showSuccess) {
            Button("OK") {}
        } message: {
            Text("You'll receive a notification for '(habitTitle)' daily at (formatTime(reminderTime))")
        }
    }
    
    func createHabitReminder() {
        guard !habitTitle.isEmpty else { return }
        
        // 1. Save habit locally
        let habit = Habit(id: UUID().uuidString, title: habitTitle, reminderTime: reminderTime)
        saveHabit(habit)
        
        // 2. Register with our backend
        registerHabitWithBackend(habit)
        
        showSuccess = true
    }
    
    func registerHabitWithBackend(_ habit: Habit) {
        guard let userId = UserDefaults.standard.string(forKey: "userId") else { return }
        
        let url = URL(string: "https://api.wecompleteapp.com/api/habits/(userId)/create")!
        var request = URLRequest(url: url)
        request.httpMethod = "POST"
        request.setValue("application/json", forHTTPHeaderField: "Content-Type")
        
        let body: [String: Any] = [
            "habitId": habit.id,
            "title": habit.title,
            "reminderTime": ISO8601DateFormatter().string(from: habit.reminderTime)
        ]
        request.httpBody = try? JSONSerialization.data(withJSONObject: body)
        
        URLSession.shared.dataTask(with: request) { data, response, error in
            // Handle response
        }.resume()
    }
    
    func formatTime(_ date: Date) -> String {
        let formatter = DateFormatter()
        formatter.timeStyle = .short
        return formatter.string(from: date)
    }
}

struct Habit {
    let id: String
    let title: String
    let reminderTime: Date
}

2. Handling the Push Notification

When our backend sends a habit reminder, you'll receive a notification with custom data:

// Example payload received from server
{
    "aps": {
        "alert": {
            "title": "Habit Reminder",
            "body": "Time to complete your habit: Morning Meditation"
        },
        "sound": "default",
        "badge": 1
    },
    "data": {
        "type": "habit_reminder",
        "habitId": "a1b2c3d4-e5f6-7890-abcd-1234567890ab"
    }
}

3. Processing Notification Taps

Update your UNUserNotificationCenterDelegate implementation to handle habit reminders:

// In your AppDelegate.swift
func userNotificationCenter(
    _ center: UNUserNotificationCenter,
    didReceive response: UNNotificationResponse,
    withCompletionHandler completionHandler: @escaping () -> Void
) {
    let userInfo = response.notification.request.content.userInfo
    
    if let data = userInfo["data"] as? [String: Any],
       let type = data["type"] as? String {
        
        switch type {
        case "habit_reminder":
            if let habitId = data["habitId"] as? String {
                // Open habit completion screen
                navigateToHabitCompletion(habitId: habitId)
            }
            break
            
        // Handle other notification types
        default:
            break
        }
    }
    
    completionHandler()
}

func navigateToHabitCompletion(habitId: String) {
    // Get the root view controller
    guard let rootViewController = UIApplication.shared.windows.first?.rootViewController else { return }
    
    // Create and present the habit completion screen
    // This implementation will depend on your app's navigation structure
    
    // For UIKit apps:
    let habitVC = HabitCompletionViewController(habitId: habitId)
    let navController = UINavigationController(rootViewController: habitVC)
    rootViewController.present(navController, animated: true)
    
    // For SwiftUI apps, you would set an app state variable that changes the navigation
}

4. Testing the Complete Flow

To test your implementation:

  1. Create a habit reminder in your app
  2. Verify the habit is sent to your backend (check network logs)
  3. Use our API to trigger a test notification with the habit payload
// Example cURL request to test the notification
curl -X POST \
  https://api.wecompleteapp.com/api/users/user/{"{userId}"}/send-test-notification \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -d '{
    "userId": "user-123",
    "title": "Habit Reminder",
    "body": "Time to complete your habit: Morning Meditation",
    "data": {
        "type": "habit_reminder",
        "habitId": "a1b2c3d4-e5f6-7890-abcd-1234567890ab"
    }
}'

Pro Tips

  • Schedule notifications at user-friendly times (not too early, not too late)
  • Add deep-linking capabilities to take users directly to relevant screens
  • Implement notification categories and actions for quick responses without opening the app
  • Track notification engagement metrics to improve your reminder strategy

Implementing Deep Linking with Push Notifications

Deep linking allows your notifications to navigate users directly to specific screens in your app. Here's how to implement it:

1. Configure URL Scheme in Xcode

  1. Open your Xcode project
  2. Select your app target
  3. Go to "Info" tab
  4. Expand "URL Types"
  5. Click "+" to add a new URL type
  6. Set "Identifier" to your bundle ID
  7. Set "URL Schemes" to your custom scheme (e.g., "wecomplete")

2. Include Deep Link in Notification Payload

When sending notifications, include the deep link URL in the payload:

// Example notification with deep link
let notificationData = [
    "userId": "user_to_notify",
    "title": "New Memory Added",
    "body": "Your partner added a memory from your vacation",
    "data": [
        "type": "NEW_MEMORY",
        "memoryId": "mem_123456",
        "deepLink": "wecomplete://memories/mem_123456"
    ]
]

// Send using our notification API
let url = URL(string: "https://api.wecompleteapp.com/api/users/user/\(userId)/send-test-notification")!
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.setValue("YOUR_API_KEY", forHTTPHeaderField: "Authorization")
request.httpBody = try? JSONSerialization.data(withJSONObject: notificationData)

URLSession.shared.dataTask(with: request) { data, response, error in
    // Handle response
}.resume()

3. Handle Deep Links When Notification is Tapped

Update your notification handling code to extract and process the deep link:

// In AppDelegate.swift
func userNotificationCenter(
    _ center: UNUserNotificationCenter,
    didReceive response: UNNotificationResponse,
    withCompletionHandler completionHandler: @escaping () -> Void
) {
    let userInfo = response.notification.request.content.userInfo
    
    // Extract deep link if present
    if let data = userInfo["data"] as? [String: Any],
       let deepLink = data["deepLink"] as? String,
       let url = URL(string: deepLink) {
        
        // Process the deep link URL
        handleDeepLink(url)
    }
    
    completionHandler()
}

func handleDeepLink(_ url: URL) {
    guard let components = URLComponents(url: url, resolvingAgainstBaseURL: true) else { return }
    
    // Example: wecomplete://memories/mem_123456
    if components.host == "memories" {
        let pathComponents = components.path.components(separatedBy: "/")
        if pathComponents.count > 1 {
            let memoryId = pathComponents[1]
            navigateToMemory(memoryId: memoryId)
        }
    }
    // Handle other deep link patterns
}

4. Common Deep Link URL Patterns

FeatureDeep Link URL PatternExample
Open Memorywecomplete://memories/:idwecomplete://memories/mem_123456
View Profilewecomplete://profile/:idwecomplete://profile/user_789
Open Chatwecomplete://chat/:idwecomplete://chat/chat_456
View Habitwecomplete://habits/:idwecomplete://habits/habit_567

Best Practices for Deep Linking

  • Follow a consistent URL pattern across your app
  • Handle cases where the target content doesn't exist
  • Consider the user's login state - redirect to login if needed
  • For more robust linking, consider implementing Universal Links (iOS) which use your domain
  • Test deep links thoroughly on different app states (freshly launched, in background, etc.)

Using Our Notification APIs

Our backend already handles all the complexity of sending push notifications. Here's how to use our existing APIs to send notifications after specific actions.

Example: Notify Partner About New Memory

When a user creates a new memory, you can easily send a notification to their partner:

  1. First, create the memory using our Memory API
  2. Then, call our notification API to alert the partner
// Step 1: Create a memory
let userId = "user_abc123" // The current user's ID
let memoryData = [
    "action": "create",
    "title": "Our First Date",
    "description": "Remember that amazing restaurant?",
    "date": "2023-11-15T18:30:00",
    "location": "Italian Restaurant",
    "memoryType": "date"
]

let url = URL(string: "https://api.wecompleteapp.com/api/users/user/\(userId)/memories")!
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.httpBody = try? JSONSerialization.data(withJSONObject: memoryData)

URLSession.shared.dataTask(with: request) { data, response, error in
    guard let data = data, error == nil else {
        print("Error creating memory: \(error?.localizedDescription ?? "Unknown error")")
        return
    }
    
    // Parse the response to get the new memory ID
    if let memory = try? JSONSerialization.jsonObject(with: data) as? [String: Any],
       let memoryId = memory["_id"] as? String {
        
        // Step 2: Send notification to partner
        notifyPartnerAboutMemory(memoryId: memoryId, memoryTitle: memoryData["title"] as! String)
    }
}.resume()

// Function to notify partner
func notifyPartnerAboutMemory(memoryId: String, memoryTitle: String) {
    // Simply call our notification API
    let notificationData = [
        "partnerId": "partner_xyz789", // Partner's user ID
        "notificationType": "NEW_MEMORY",
        "title": "New Memory Created",
        "body": "Your partner just created a new memory: \(memoryTitle)",
        "data": [
            "memoryId": memoryId,
            "type": "memory_notification"
        ]
    ]
    
    let url = URL(string: "https://api.wecompleteapp.com/api/users/user/\(userId)/send-test-notification")!
    var request = URLRequest(url: url)
    request.httpMethod = "POST"
    request.setValue("application/json", forHTTPHeaderField: "Content-Type")
    request.setValue("YOUR_API_KEY", forHTTPHeaderField: "Authorization")
    request.httpBody = try? JSONSerialization.data(withJSONObject: notificationData)
    
    URLSession.shared.dataTask(with: request) { data, response, error in
        if let error = error {
            print("Failed to send notification: \(error.localizedDescription)")
        } else {
            print("Notification sent successfully")
        }
    }.resume()
}

Key Notification Endpoints

Send Notification API

URL: https://api.wecompleteapp.com/api/users/user/{userId}/send-test-notification

Method: POST

Headers:

  • Content-Type: application/json

Body:

{
  "title": "Notification Title",
  "body": "Notification message body",
  "category": "notification_category"
}

Send Test Notification

To quickly test if notifications are working:

URL: https://api.wecompleteapp.com/api/users/user/{userId}/send-test-notification

Method: POST

Headers: Content-Type: application/json

Body:

{
  "title": "Your custom title",
  "message": "Your custom message",
  "category": "Your notification category",
  "url": "wecomplete://memories/mem_123456"
}

All parameters are optional. The url parameter can be used for deep linking to specific screens in your app.

Get User Notifications

To retrieve a user's notification history:

URL: https://api.wecompleteapp.com/api/users/user/{userId}/notifications

Method: GET

Query Parameters:

  • limit - Maximum number of notifications to return (default: 50)
  • offset - Number of notifications to skip (for pagination, default: 0)
  • category - Filter notifications by category (optional)

Example Request:

// Fetch the 20 most recent notifications
let url = URL(string: "https://api.wecompleteapp.com/api/users/user/(userId)/notifications?limit=20")!

// Fetch only "reminder" category notifications
let url = URL(string: "https://api.wecompleteapp.com/api/users/user/(userId)/notifications?category=reminder")!

// Pagination example (second page of results)
let url = URL(string: "https://api.wecompleteapp.com/api/users/user/(userId)/notifications?limit=20&offset=20")!

Response:

{
  "success": true,
  "notifications": [
    {
      "_id": "notification_id_1",
      "userId": "user_id",
      "title": "Habit Reminder",
      "message": "Time to complete your daily meditation",
      "category": "reminder",
      "sentAt": "2023-11-15T18:30:00Z",
      "isRead": false,
      "successCount": 1,
      "totalDevices": 2
    },
    {
      "_id": "notification_id_2",
      "userId": "user_id",
      "title": "New Memory",
      "message": "Your partner added a new memory",
      "category": "memory",
      "sentAt": "2023-11-14T12:45:00Z",
      "isRead": true,
      "successCount": 2,
      "totalDevices": 2
    }
    // ... more notifications
  ],
  "pagination": {
    "limit": 20,
    "offset": 0,
    "total": 2
  }
}

Use this endpoint to display a notification history in your app or to check if a user has unread notifications.

Example: Displaying Notification History

Here's how to fetch and display a user's notification history in your app:

// NotificationsViewController.swift
import UIKit

class NotificationsViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
    
    @IBOutlet weak var tableView: UITableView!
    
    var notifications: [[String: Any]] = []
    var isLoading = false
    
    override func viewDidLoad() {
        super.viewDidLoad()
        tableView.dataSource = self
        tableView.delegate = self
        
        // Load notifications when view appears
        fetchNotifications()
    }
    
    func fetchNotifications() {
        guard !isLoading else { return }
        isLoading = true
        
        guard let userId = UserDefaults.standard.string(forKey: "userId") else { 
            print("No userId found")
            isLoading = false
            return 
        }
        
        let url = URL(string: "https://api.wecompleteapp.com/api/users/user/(userId)/notifications?limit=50")!
        var request = URLRequest(url: url)
        request.httpMethod = "GET"
        
        URLSession.shared.dataTask(with: request) { [weak self] data, response, error in
            guard let self = self else { return }
            
            DispatchQueue.main.async {
                self.isLoading = false
                
                if let error = error {
                    print("Error fetching notifications: (error.localizedDescription)")
                    return
                }
                
                guard let data = data else {
                    print("No data received")
                    return
                }
                
                do {
                    if let json = try JSONSerialization.jsonObject(with: data) as? [String: Any],
                       let success = json["success"] as? Bool,
                       success,
                       let notificationsData = json["notifications"] as? [[String: Any]] {
                        
                        self.notifications = notificationsData
                        self.tableView.reloadData()
                        
                        print("Loaded (notificationsData.count) notifications")
                    } else {
                        print("Invalid response format")
                    }
                } catch {
                    print("Error parsing JSON: (error.localizedDescription)")
                }
            }
        }.resume()
    }
    
    // MARK: - UITableViewDataSource
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return notifications.count
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "NotificationCell", for: indexPath)
        
        let notification = notifications[indexPath.row]
        
        // Configure cell
        cell.textLabel?.text = notification["title"] as? String
        cell.detailTextLabel?.text = notification["message"] as? String
        
        // Show unread indicator if needed
        if let isRead = notification["isRead"] as? Bool, !isRead {
            cell.backgroundColor = UIColor(white: 0.95, alpha: 1.0)
        } else {
            cell.backgroundColor = .white
        }
        
        // Show category badge
        if let category = notification["category"] as? String {
            let badgeLabel = UILabel()
            badgeLabel.text = category
            badgeLabel.textColor = .white
            badgeLabel.backgroundColor = categoryColor(for: category)
            badgeLabel.font = UIFont.systemFont(ofSize: 12)
            badgeLabel.textAlignment = .center
            badgeLabel.layer.cornerRadius = 8
            badgeLabel.clipsToBounds = true
            badgeLabel.frame = CGRect(x: 0, y: 0, width: 80, height: 16)
            cell.accessoryView = badgeLabel
        }
        
        return cell
    }
    
    // Helper to get color for category
    func categoryColor(for category: String) -> UIColor {
        switch category.lowercased() {
        case "reminder": return .systemBlue
        case "memory": return .systemPurple
        case "message": return .systemGreen
        default: return .systemGray
        }
    }
    
    // MARK: - UITableViewDelegate
    
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        tableView.deselectRow(at: indexPath, animated: true)
        
        // Mark as read when tapped
        if let notificationId = notifications[indexPath.row]["_id"] as? String {
            markNotificationAsRead(notificationId)
        }
        
        // Handle notification tap (e.g., navigate to relevant screen)
        if let data = notifications[indexPath.row]["data"] as? [String: Any],
           let type = data["type"] as? String {
            handleNotificationTap(type: type, data: data)
        }
    }
    
    func markNotificationAsRead(_ notificationId: String) {
        // Implementation to mark notification as read
        // This would typically call your backend API
    }
    
    func handleNotificationTap(type: String, data: [String: Any]) {
        // Navigate based on notification type
        switch type {
        case "memory_notification":
            if let memoryId = data["memoryId"] as? String {
                // Navigate to memory details
                let memoryVC = MemoryDetailViewController(memoryId: memoryId)
                navigationController?.pushViewController(memoryVC, animated: true)
            }
        case "reminder":
            // Navigate to reminder screen
            break
        default:
            break
        }
    }
}

Common Notification Scenarios

ScenarioWhen to SendNotification Type
New MemoryAfter creating a memoryNEW_MEMORY
Comment on MemoryWhen a user commentsNEW_COMMENT
Mood UpdatedWhen user updates moodMOOD_UPDATE
Event Reminder24h before saved dateEVENT_REMINDER

Need Help?

If you're experiencing issues implementing push notifications, contact our developer support at support@wecompleteapp.com.