Realm Swift

Realm Swift is "an object database for iOS and macOS applications" designed as a Swift-native database solution. Developed as an alternative to SQLite, it enables high-performance data operations through an intuitive object-oriented API without complex SQL queries. With built-in reactive programming, automatic UI updates, thread safety, and encryption capabilities, and optimizations specifically for mobile application development, it supports high-quality iOS/macOS application development.

SwiftDatabaseObject DatabaseiOSmacOSMobile

Library

Realm Swift

Overview

Realm Swift is "an object database for iOS and macOS applications" designed as a Swift-native database solution. Developed as an alternative to SQLite, it enables high-performance data operations through an intuitive object-oriented API without complex SQL queries. With built-in reactive programming, automatic UI updates, thread safety, and encryption capabilities, and optimizations specifically for mobile application development, it supports high-quality iOS/macOS application development.

Details

Realm Swift 2025 edition is optimized for modern iOS/macOS application development through complete integration with Swift 6 and SwiftUI. Automatic schema migration, real-time data synchronization, and offline-first design provide a robust data layer that prioritizes user experience. Compared to Core Data and SQLite, it achieves significantly simpler APIs and higher development efficiency while balancing enterprise-level security (AES-256 encryption) and performance. Natural integration with @Observable, @State, and async/await makes reactive data binding in SwiftUI easy to implement.

Key Features

  • Object-Oriented API: Database access as Swift objects
  • Reactive UI: Automatic UI updates and data binding
  • High Performance: Faster data access than SQLite
  • Thread Safety: Safe data operations in multi-threaded environments
  • Encryption: Comprehensive data protection with AES-256
  • SwiftUI Integration: Native SwiftUI support

Pros and Cons

Pros

  • Intuitive object-oriented data operations without SQL queries
  • Significant improvement in development efficiency through automatic UI updates
  • High performance surpassing SQLite and Core Data
  • Thread-safe design for secure multi-threaded programming
  • Enterprise-grade encryption and security features
  • Natural integration with SwiftUI and reactive programming support

Cons

  • Platform-specific limitation to iOS/macOS/watchOS
  • Potential memory usage increase with large datasets
  • Limited query functionality compared to rich SQL features
  • Difficulty porting to other platforms
  • Less widespread adoption than SQLite, requiring specialized knowledge
  • Limited backup and replication features in production environments

Reference Pages

Code Examples

Setup

// Package.swift
// dependencies: [
//     .package(url: "https://github.com/realm/realm-swift.git", from: "10.45.0")
// ]

// CocoaPods
// pod 'RealmSwift', '~> 10.45.0'

import RealmSwift
import SwiftUI
// Info.plist or configuration for encryption key management
// This example is for development. Use proper keystore management for production.

import Foundation
import Security

class RealmEncryptionKeyManager {
    private static let keyIdentifier = "RealmEncryptionKey"
    
    static func getOrCreateEncryptionKey() -> Data {
        if let existingKey = getEncryptionKeyFromKeychain() {
            return existingKey
        }
        
        let newKey = generateRandomKey()
        saveEncryptionKeyToKeychain(newKey)
        return newKey
    }
    
    private static func generateRandomKey() -> Data {
        var keyData = Data(count: 64) // 512-bit key for AES-256
        let result = keyData.withUnsafeMutableBytes { mutableBytes in
            SecRandomCopyBytes(kSecRandomDefault, 64, mutableBytes.bindMemory(to: UInt8.self).baseAddress!)
        }
        guard result == errSecSuccess else {
            fatalError("Failed to generate random key")
        }
        return keyData
    }
    
    private static func saveEncryptionKeyToKeychain(_ key: Data) {
        let query: [String: Any] = [
            kSecClass as String: kSecClassGenericPassword,
            kSecAttrService as String: keyIdentifier,
            kSecValueData as String: key
        ]
        SecItemAdd(query as CFDictionary, nil)
    }
    
    private static func getEncryptionKeyFromKeychain() -> Data? {
        let query: [String: Any] = [
            kSecClass as String: kSecClassGenericPassword,
            kSecAttrService as String: keyIdentifier,
            kSecReturnData as String: kCFBooleanTrue!,
            kSecMatchLimit as String: kSecMatchLimitOne
        ]
        
        var dataTypeRef: AnyObject?
        let status = SecItemCopyMatching(query as CFDictionary, &dataTypeRef)
        
        if status == errSecSuccess {
            return dataTypeRef as? Data
        }
        return nil
    }
}

Basic Model Definition

import RealmSwift
import Foundation

// Basic user model
class User: Object, ObjectKeyIdentifiable {
    @Persisted var id: ObjectId = ObjectId.generate()
    @Persisted var name: String = ""
    @Persisted var email: String = ""
    @Persisted var age: Int = 0
    @Persisted var isActive: Bool = true
    @Persisted var createdAt: Date = Date()
    @Persisted var updatedAt: Date = Date()
    @Persisted var tags: List<String> = List<String>()
    @Persisted var metadata: Map<String, AnyRealmValue> = Map<String, AnyRealmValue>()
    
    // Relationships (inverse)
    @Persisted(originProperty: "author") var posts: LinkingObjects<Post>
    @Persisted var profile: Profile?
    
    // Primary Key
    override static func primaryKey() -> String? {
        return "id"
    }
    
    // Index settings
    override static func indexedProperties() -> [String] {
        return ["email", "isActive", "createdAt"]
    }
    
    // Computed properties
    var fullDisplayName: String {
        return name.isEmpty ? "Anonymous User" : name
    }
    
    var isAdult: Bool {
        return age >= 18
    }
    
    var postCount: Int {
        return posts.count
    }
    
    // Object lifecycle
    override func willSave() {
        super.willSave()
        updatedAt = Date()
    }
}

// Profile information (embedded type)
class Profile: EmbeddedObject {
    @Persisted var bio: String = ""
    @Persisted var website: String = ""
    @Persisted var location: String = ""
    @Persisted var avatarURL: String = ""
    @Persisted var socialLinks: Map<String, String> = Map<String, String>()
    @Persisted var skills: List<String> = List<String>()
    @Persisted var experienceYears: Int = 0
    @Persisted var isPublic: Bool = true
    
    var hasCompleteProfile: Bool {
        return !bio.isEmpty && !location.isEmpty && skills.count > 0
    }
}

// Post model
class Post: Object, ObjectKeyIdentifiable {
    @Persisted var id: ObjectId = ObjectId.generate()
    @Persisted var title: String = ""
    @Persisted var content: String = ""
    @Persisted var excerpt: String = ""
    @Persisted var isPublished: Bool = false
    @Persisted var publishedAt: Date?
    @Persisted var createdAt: Date = Date()
    @Persisted var updatedAt: Date = Date()
    @Persisted var viewCount: Int = 0
    @Persisted var tags: List<String> = List<String>()
    @Persisted var featuredImageURL: String = ""
    
    // Relationships
    @Persisted var author: User?
    @Persisted var category: Category?
    @Persisted var comments: List<Comment> = List<Comment>()
    
    override static func primaryKey() -> String? {
        return "id"
    }
    
    override static func indexedProperties() -> [String] {
        return ["isPublished", "publishedAt", "createdAt", "author"]
    }
    
    var isPublic: Bool {
        return isPublished && publishedAt != nil
    }
    
    var readingTimeMinutes: Int {
        let wordsPerMinute = 200
        let wordCount = content.split(separator: " ").count
        return max(1, wordCount / wordsPerMinute)
    }
    
    override func willSave() {
        super.willSave()
        updatedAt = Date()
        
        // Auto-generate excerpt
        if excerpt.isEmpty && !content.isEmpty {
            excerpt = String(content.prefix(200))
        }
        
        // Set published date
        if isPublished && publishedAt == nil {
            publishedAt = Date()
        }
    }
}

// Category model
class Category: Object, ObjectKeyIdentifiable {
    @Persisted var id: ObjectId = ObjectId.generate()
    @Persisted var name: String = ""
    @Persisted var description: String = ""
    @Persisted var color: String = "#007AFF"
    @Persisted var isActive: Bool = true
    @Persisted var sortOrder: Int = 0
    @Persisted var createdAt: Date = Date()
    
    @Persisted(originProperty: "category") var posts: LinkingObjects<Post>
    
    override static func primaryKey() -> String? {
        return "id"
    }
    
    override static func indexedProperties() -> [String] {
        return ["name", "isActive", "sortOrder"]
    }
    
    var postCount: Int {
        return posts.filter("isPublished == true").count
    }
}

// Comment model
class Comment: EmbeddedObject {
    @Persisted var id: ObjectId = ObjectId.generate()
    @Persisted var content: String = ""
    @Persisted var authorName: String = ""
    @Persisted var authorEmail: String = ""
    @Persisted var isApproved: Bool = false
    @Persisted var isSpam: Bool = false
    @Persisted var createdAt: Date = Date()
    @Persisted var ipAddress: String = ""
    @Persisted var userAgent: String = ""
    
    var isValid: Bool {
        return !content.isEmpty && !authorName.isEmpty && content.count >= 5
    }
}

Basic CRUD Operations

import RealmSwift

class UserRepository: ObservableObject {
    private let realm: Realm
    
    init() throws {
        // Encryption setup
        let encryptionKey = RealmEncryptionKeyManager.getOrCreateEncryptionKey()
        let config = Realm.Configuration(
            encryptionKey: encryptionKey,
            schemaVersion: 1,
            migrationBlock: { migration, oldSchemaVersion in
                // Migration processing
                if oldSchemaVersion < 1 {
                    // Implement migration processing as needed
                }
            }
        )
        
        self.realm = try Realm(configuration: config)
    }
    
    // Create user
    func createUser(name: String, email: String, age: Int) async throws -> User {
        let user = User()
        user.name = name
        user.email = email
        user.age = age
        user.createdAt = Date()
        
        return try await MainActor.run {
            try realm.write {
                realm.add(user)
                return user
            }
        }
    }
    
    // Get user
    func getUser(by id: ObjectId) -> User? {
        return realm.object(ofType: User.self, forPrimaryKey: id)
    }
    
    // Get all users
    func getAllUsers() -> Results<User> {
        return realm.objects(User.self).sorted(byKeyPath: "createdAt", ascending: false)
    }
    
    // Get active users
    func getActiveUsers() -> Results<User> {
        return realm.objects(User.self).filter("isActive == true").sorted(byKeyPath: "name")
    }
    
    // Search by name
    func searchUsers(by namePattern: String) -> Results<User> {
        return realm.objects(User.self)
            .filter("name CONTAINS[c] %@ OR email CONTAINS[c] %@", namePattern, namePattern)
            .sorted(byKeyPath: "name")
    }
    
    // Filter by age range
    func getUsersByAgeRange(min: Int, max: Int) -> Results<User> {
        return realm.objects(User.self)
            .filter("age >= %@ AND age <= %@", min, max)
            .sorted(byKeyPath: "age")
    }
    
    // Update user
    func updateUser(_ user: User, name: String, email: String, age: Int) async throws {
        try await MainActor.run {
            try realm.write {
                user.name = name
                user.email = email
                user.age = age
                user.updatedAt = Date()
            }
        }
    }
    
    // Update profile
    func updateUserProfile(_ user: User, profile: Profile) async throws {
        try await MainActor.run {
            try realm.write {
                user.profile = profile
                user.updatedAt = Date()
            }
        }
    }
    
    // Delete user
    func deleteUser(_ user: User) async throws {
        try await MainActor.run {
            try realm.write {
                // Also delete related posts (cascade delete)
                realm.delete(user.posts)
                realm.delete(user)
            }
        }
    }
    
    // Add tag
    func addTagToUser(_ user: User, tag: String) async throws {
        try await MainActor.run {
            try realm.write {
                if !user.tags.contains(tag) {
                    user.tags.append(tag)
                }
            }
        }
    }
    
    // Set metadata
    func setUserMetadata(_ user: User, key: String, value: AnyRealmValue) async throws {
        try await MainActor.run {
            try realm.write {
                user.metadata[key] = value
            }
        }
    }
    
    // User statistics
    func getUserStatistics() -> (total: Int, active: Int, averageAge: Double) {
        let allUsers = realm.objects(User.self)
        let activeUsers = allUsers.filter("isActive == true")
        let averageAge = allUsers.average(ofProperty: "age") ?? 0.0
        
        return (
            total: allUsers.count,
            active: activeUsers.count,
            averageAge: averageAge
        )
    }
}

// Usage example
class ContentView: View {
    @StateObject private var userRepository = try! UserRepository()
    @State private var users: Results<User>?
    @State private var newUserName = ""
    @State private var newUserEmail = ""
    @State private var newUserAge = 25
    @State private var searchText = ""
    
    var body: some View {
        NavigationView {
            VStack {
                // User creation form
                VStack(spacing: 10) {
                    TextField("Name", text: $newUserName)
                        .textFieldStyle(RoundedBorderTextFieldStyle())
                    
                    TextField("Email", text: $newUserEmail)
                        .textFieldStyle(RoundedBorderTextFieldStyle())
                        .keyboardType(.emailAddress)
                    
                    HStack {
                        Text("Age: \(newUserAge)")
                        Slider(value: Binding(
                            get: { Double(newUserAge) },
                            set: { newUserAge = Int($0) }
                        ), in: 0...100, step: 1)
                    }
                    
                    Button("Create User") {
                        Task {
                            try await createUser()
                        }
                    }
                    .disabled(newUserName.isEmpty || newUserEmail.isEmpty)
                }
                .padding()
                
                // Search bar
                TextField("Search users...", text: $searchText)
                    .textFieldStyle(RoundedBorderTextFieldStyle())
                    .padding(.horizontal)
                
                // User list
                if let users = users {
                    List(users, id: \.id) { user in
                        UserRowView(user: user, repository: userRepository)
                    }
                }
                
                Spacer()
            }
            .navigationTitle("Realm Swift Demo")
            .onAppear {
                loadUsers()
            }
            .onChange(of: searchText) { _, newValue in
                searchUsers()
            }
        }
    }
    
    private func createUser() async throws {
        let _ = try await userRepository.createUser(
            name: newUserName,
            email: newUserEmail,
            age: newUserAge
        )
        
        // Reset form
        newUserName = ""
        newUserEmail = ""
        newUserAge = 25
        
        // Update list
        loadUsers()
    }
    
    private func loadUsers() {
        users = userRepository.getAllUsers()
    }
    
    private func searchUsers() {
        if searchText.isEmpty {
            users = userRepository.getAllUsers()
        } else {
            users = userRepository.searchUsers(by: searchText)
        }
    }
}

Complex Queries and Relationships

class PostRepository: ObservableObject {
    private let realm: Realm
    
    init() throws {
        let encryptionKey = RealmEncryptionKeyManager.getOrCreateEncryptionKey()
        let config = Realm.Configuration(encryptionKey: encryptionKey)
        self.realm = try Realm(configuration: config)
    }
    
    // Create post
    func createPost(title: String, content: String, author: User, category: Category?) async throws -> Post {
        let post = Post()
        post.title = title
        post.content = content
        post.author = author
        post.category = category
        
        return try await MainActor.run {
            try realm.write {
                realm.add(post)
                return post
            }
        }
    }
    
    // Get published posts
    func getPublishedPosts() -> Results<Post> {
        return realm.objects(Post.self)
            .filter("isPublished == true")
            .sorted(byKeyPath: "publishedAt", ascending: false)
    }
    
    // Posts by user
    func getPostsByUser(_ user: User) -> Results<Post> {
        return realm.objects(Post.self)
            .filter("author == %@", user)
            .sorted(byKeyPath: "createdAt", ascending: false)
    }
    
    // Posts by category
    func getPostsByCategory(_ category: Category) -> Results<Post> {
        return realm.objects(Post.self)
            .filter("category == %@ AND isPublished == true", category)
            .sorted(byKeyPath: "publishedAt", ascending: false)
    }
    
    // Complex search query
    func searchPosts(
        titlePattern: String? = nil,
        author: User? = nil,
        category: Category? = nil,
        publishedOnly: Bool = false,
        tags: [String] = [],
        dateRange: ClosedRange<Date>? = nil
    ) -> Results<Post> {
        var predicates: [NSPredicate] = []
        
        // Title search
        if let titlePattern = titlePattern, !titlePattern.isEmpty {
            predicates.append(NSPredicate(format: "title CONTAINS[c] %@ OR content CONTAINS[c] %@", titlePattern, titlePattern))
        }
        
        // Author filter
        if let author = author {
            predicates.append(NSPredicate(format: "author == %@", author))
        }
        
        // Category filter
        if let category = category {
            predicates.append(NSPredicate(format: "category == %@", category))
        }
        
        // Published status filter
        if publishedOnly {
            predicates.append(NSPredicate(format: "isPublished == true"))
        }
        
        // Tag filter
        if !tags.isEmpty {
            let tagPredicates = tags.map { NSPredicate(format: "ANY tags == %@", $0) }
            predicates.append(NSCompoundPredicate(orPredicateWithSubpredicates: tagPredicates))
        }
        
        // Date range filter
        if let dateRange = dateRange {
            predicates.append(NSPredicate(format: "createdAt >= %@ AND createdAt <= %@", dateRange.lowerBound as NSDate, dateRange.upperBound as NSDate))
        }
        
        let compoundPredicate = NSCompoundPredicate(andPredicateWithSubpredicates: predicates)
        
        return realm.objects(Post.self)
            .filter(compoundPredicate)
            .sorted(byKeyPath: "createdAt", ascending: false)
    }
    
    // Popular posts (by view count)
    func getPopularPosts(limit: Int = 10) -> Results<Post> {
        return realm.objects(Post.self)
            .filter("isPublished == true")
            .sorted(byKeyPath: "viewCount", ascending: false)
            .prefix(limit)
    }
    
    // Recent post statistics
    func getRecentPostStats(days: Int) -> (total: Int, published: Int, drafts: Int) {
        let cutoffDate = Calendar.current.date(byAdding: .day, value: -days, to: Date()) ?? Date()
        let recentPosts = realm.objects(Post.self).filter("createdAt >= %@", cutoffDate)
        let publishedPosts = recentPosts.filter("isPublished == true")
        let draftPosts = recentPosts.filter("isPublished == false")
        
        return (
            total: recentPosts.count,
            published: publishedPosts.count,
            drafts: draftPosts.count
        )
    }
    
    // Increment view count
    func incrementViewCount(_ post: Post) async throws {
        try await MainActor.run {
            try realm.write {
                post.viewCount += 1
            }
        }
    }
    
    // Publish post
    func publishPost(_ post: Post) async throws {
        try await MainActor.run {
            try realm.write {
                post.isPublished = true
                post.publishedAt = Date()
            }
        }
    }
    
    // Add comment
    func addComment(to post: Post, content: String, authorName: String, authorEmail: String) async throws {
        let comment = Comment()
        comment.content = content
        comment.authorName = authorName
        comment.authorEmail = authorEmail
        comment.createdAt = Date()
        
        try await MainActor.run {
            try realm.write {
                post.comments.append(comment)
            }
        }
    }
    
    // User post statistics
    func getUserPostStatistics() -> [(user: User, postCount: Int, publishedCount: Int)] {
        let users = realm.objects(User.self)
        
        return users.compactMap { user in
            let totalPosts = user.posts.count
            let publishedPosts = user.posts.filter("isPublished == true").count
            
            guard totalPosts > 0 else { return nil }
            
            return (user: user, postCount: totalPosts, publishedCount: publishedPosts)
        }.sorted { $0.postCount > $1.postCount }
    }
}

// Reactive updates in SwiftUI example
struct PostListView: View {
    @ObservedResults(Post.self,
                     filter: NSPredicate(format: "isPublished == true"),
                     sortDescriptor: SortDescriptor(keyPath: "publishedAt", ascending: false)
    ) var posts
    
    @StateObject private var postRepository = try! PostRepository()
    @State private var selectedCategory: Category?
    @State private var searchText = ""
    
    var filteredPosts: Results<Post> {
        if searchText.isEmpty && selectedCategory == nil {
            return posts
        }
        
        return postRepository.searchPosts(
            titlePattern: searchText.isEmpty ? nil : searchText,
            category: selectedCategory,
            publishedOnly: true
        )
    }
    
    var body: some View {
        NavigationView {
            VStack {
                // Search and filter
                VStack {
                    TextField("Search posts...", text: $searchText)
                        .textFieldStyle(RoundedBorderTextFieldStyle())
                    
                    // Category selection (simplified)
                    Text("Category filter would go here")
                }
                .padding()
                
                // Post list
                List {
                    ForEach(filteredPosts, id: \.id) { post in
                        PostRowView(post: post)
                            .onTapGesture {
                                Task {
                                    try await postRepository.incrementViewCount(post)
                                }
                            }
                    }
                }
            }
            .navigationTitle("Posts")
        }
    }
}

struct PostRowView: View {
    let post: Post
    
    var body: some View {
        VStack(alignment: .leading, spacing: 8) {
            Text(post.title)
                .font(.headline)
                .lineLimit(2)
            
            Text(post.excerpt)
                .font(.subheadline)
                .foregroundColor(.secondary)
                .lineLimit(3)
            
            HStack {
                if let author = post.author {
                    Text("by \(author.name)")
                        .font(.caption)
                        .foregroundColor(.secondary)
                }
                
                Spacer()
                
                Text("\(post.viewCount) views")
                    .font(.caption)
                    .foregroundColor(.secondary)
                
                if let publishedAt = post.publishedAt {
                    Text(publishedAt, style: .date)
                        .font(.caption)
                        .foregroundColor(.secondary)
                }
            }
            
            // Tag display
            if !post.tags.isEmpty {
                ScrollView(.horizontal, showsIndicators: false) {
                    HStack {
                        ForEach(Array(post.tags), id: \.self) { tag in
                            Text(tag)
                                .font(.caption)
                                .padding(.horizontal, 8)
                                .padding(.vertical, 4)
                                .background(Color.blue.opacity(0.1))
                                .foregroundColor(.blue)
                                .cornerRadius(8)
                        }
                    }
                    .padding(.horizontal)
                }
            }
        }
        .padding(.vertical, 4)
    }
}

Async Processing and Reactive Programming

import RealmSwift
import Combine

// Reactive data service
class RealtimeDataService: ObservableObject {
    private let realm: Realm
    private var notificationTokens: [NotificationToken] = []
    
    @Published var users: Results<User>?
    @Published var posts: Results<Post>?
    @Published var userStats: (total: Int, active: Int, average: Double) = (0, 0, 0.0)
    @Published var postStats: (total: Int, published: Int, drafts: Int) = (0, 0, 0)
    
    init() throws {
        let encryptionKey = RealmEncryptionKeyManager.getOrCreateEncryptionKey()
        let config = Realm.Configuration(encryptionKey: encryptionKey)
        self.realm = try Realm(configuration: config)
        
        setupRealtimeObservers()
    }
    
    deinit {
        notificationTokens.forEach { $0.invalidate() }
    }
    
    private func setupRealtimeObservers() {
        // Real-time user updates
        let userResults = realm.objects(User.self).sorted(byKeyPath: "createdAt", ascending: false)
        let userToken = userResults.observe { [weak self] changes in
            switch changes {
            case .initial(let results):
                self?.users = results
                self?.updateUserStats()
            case .update(let results, _, _, _):
                self?.users = results
                self?.updateUserStats()
            case .error(let error):
                print("User observation error: \(error)")
            }
        }
        notificationTokens.append(userToken)
        
        // Real-time post updates
        let postResults = realm.objects(Post.self).sorted(byKeyPath: "createdAt", ascending: false)
        let postToken = postResults.observe { [weak self] changes in
            switch changes {
            case .initial(let results):
                self?.posts = results
                self?.updatePostStats()
            case .update(let results, _, _, _):
                self?.posts = results
                self?.updatePostStats()
            case .error(let error):
                print("Post observation error: \(error)")
            }
        }
        notificationTokens.append(postToken)
    }
    
    private func updateUserStats() {
        guard let users = users else { return }
        
        let activeUsers = users.filter("isActive == true")
        let averageAge = users.average(ofProperty: "age") ?? 0.0
        
        DispatchQueue.main.async {
            self.userStats = (
                total: users.count,
                active: activeUsers.count,
                average: averageAge
            )
        }
    }
    
    private func updatePostStats() {
        guard let posts = posts else { return }
        
        let publishedPosts = posts.filter("isPublished == true")
        let draftPosts = posts.filter("isPublished == false")
        
        DispatchQueue.main.async {
            self.postStats = (
                total: posts.count,
                published: publishedPosts.count,
                drafts: draftPosts.count
            )
        }
    }
    
    // Async data operations
    func performBatchUserUpdate(updates: [(User, String, String, Int)]) async throws {
        try await withThrowingTaskGroup(of: Void.self) { group in
            for (user, name, email, age) in updates {
                group.addTask {
                    try await self.updateUserAsync(user, name: name, email: email, age: age)
                }
            }
            
            try await group.waitForAll()
        }
    }
    
    private func updateUserAsync(_ user: User, name: String, email: String, age: Int) async throws {
        try await MainActor.run {
            try realm.write {
                user.name = name
                user.email = email
                user.age = age
                user.updatedAt = Date()
            }
        }
    }
    
    // Data cleanup
    func cleanupOldData(olderThanDays days: Int) async throws {
        let cutoffDate = Calendar.current.date(byAdding: .day, value: -days, to: Date()) ?? Date()
        
        try await MainActor.run {
            try realm.write {
                // Delete old unpublished posts
                let oldDrafts = realm.objects(Post.self)
                    .filter("isPublished == false AND createdAt < %@", cutoffDate)
                
                realm.delete(oldDrafts)
                
                // Delete inactive users
                let inactiveUsers = realm.objects(User.self)
                    .filter("isActive == false AND updatedAt < %@", cutoffDate)
                
                realm.delete(inactiveUsers)
            }
        }
    }
    
    // Export functionality
    func exportUserData() async throws -> [String: Any] {
        let users = realm.objects(User.self)
        let posts = realm.objects(Post.self)
        
        let userData = users.map { user in
            [
                "id": user.id.stringValue,
                "name": user.name,
                "email": user.email,
                "age": user.age,
                "isActive": user.isActive,
                "postCount": user.posts.count
            ]
        }
        
        let postData = posts.map { post in
            [
                "id": post.id.stringValue,
                "title": post.title,
                "isPublished": post.isPublished,
                "viewCount": post.viewCount,
                "authorName": post.author?.name ?? ""
            ]
        }
        
        return [
            "users": userData,
            "posts": postData,
            "exportDate": Date().ISO8601String(),
            "totalUsers": users.count,
            "totalPosts": posts.count
        ]
    }
}

// Real-time dashboard view
struct RealtimeDashboardView: View {
    @StateObject private var dataService = try! RealtimeDataService()
    @State private var isExporting = false
    @State private var exportData: [String: Any]?
    
    var body: some View {
        NavigationView {
            ScrollView {
                VStack(spacing: 20) {
                    // User statistics
                    VStack(alignment: .leading, spacing: 10) {
                        Text("User Statistics")
                            .font(.headline)
                        
                        HStack {
                            StatCard(title: "Total Users", value: "\(dataService.userStats.total)")
                            StatCard(title: "Active Users", value: "\(dataService.userStats.active)")
                            StatCard(title: "Avg Age", value: String(format: "%.1f", dataService.userStats.average))
                        }
                    }
                    
                    // Post statistics
                    VStack(alignment: .leading, spacing: 10) {
                        Text("Post Statistics")
                            .font(.headline)
                        
                        HStack {
                            StatCard(title: "Total Posts", value: "\(dataService.postStats.total)")
                            StatCard(title: "Published", value: "\(dataService.postStats.published)")
                            StatCard(title: "Drafts", value: "\(dataService.postStats.drafts)")
                        }
                    }
                    
                    // Export button
                    Button("Export Data") {
                        Task {
                            isExporting = true
                            do {
                                exportData = try await dataService.exportUserData()
                                print("Export completed: \(exportData?.keys.joined(separator: ", ") ?? "Unknown")")
                            } catch {
                                print("Export failed: \(error)")
                            }
                            isExporting = false
                        }
                    }
                    .disabled(isExporting)
                    
                    // Cleanup button
                    Button("Cleanup Old Data") {
                        Task {
                            try await dataService.cleanupOldData(olderThanDays: 30)
                        }
                    }
                    .foregroundColor(.red)
                    
                    Spacer()
                }
                .padding()
            }
            .navigationTitle("Dashboard")
            .refreshable {
                // Pull-to-refresh automatically updates, so no special processing needed
            }
        }
    }
}

struct StatCard: View {
    let title: String
    let value: String
    
    var body: some View {
        VStack {
            Text(value)
                .font(.title2)
                .fontWeight(.bold)
            Text(title)
                .font(.caption)
                .foregroundColor(.secondary)
        }
        .frame(maxWidth: .infinity)
        .padding()
        .background(Color(.systemGray6))
        .cornerRadius(8)
    }
}

Error Handling and Security

import RealmSwift

// Custom error definition
enum RealmError: Error, LocalizedError {
    case initializationFailed(String)
    case encryptionKeyError
    case writeTransactionFailed(String)
    case objectNotFound(String)
    case validationFailed(String)
    case permissionDenied
    case databaseCorrupted
    
    var errorDescription: String? {
        switch self {
        case .initializationFailed(let message):
            return "Database initialization failed: \(message)"
        case .encryptionKeyError:
            return "Encryption key generation or retrieval failed"
        case .writeTransactionFailed(let message):
            return "Write transaction failed: \(message)"
        case .objectNotFound(let message):
            return "Object not found: \(message)"
        case .validationFailed(let message):
            return "Validation failed: \(message)"
        case .permissionDenied:
            return "Permission denied for database operation"
        case .databaseCorrupted:
            return "Database file is corrupted"
        }
    }
}

// Secure Realm operations class
class SecureRealmManager: ObservableObject {
    private let realm: Realm
    private let encryptionKey: Data
    
    init() throws {
        do {
            self.encryptionKey = RealmEncryptionKeyManager.getOrCreateEncryptionKey()
            
            let config = Realm.Configuration(
                encryptionKey: encryptionKey,
                schemaVersion: 2,
                migrationBlock: { migration, oldSchemaVersion in
                    // Safe migration processing
                    Self.performSafeMigration(migration: migration, from: oldSchemaVersion)
                },
                shouldCompactOnLaunch: { totalBytes, usedBytes in
                    // Compact if over 10MB and usage rate below 50%
                    let tenMB = 10 * 1024 * 1024
                    return (totalBytes > tenMB) && (Double(usedBytes) / Double(totalBytes)) < 0.5
                }
            )
            
            self.realm = try Realm(configuration: config)
        } catch {
            throw RealmError.initializationFailed(error.localizedDescription)
        }
    }
    
    private static func performSafeMigration(migration: Migration, from oldSchemaVersion: UInt64) {
        if oldSchemaVersion < 1 {
            migration.enumerateObjects(ofType: User.className()) { oldObject, newObject in
                newObject?["updatedAt"] = Date()
            }
        }
        
        if oldSchemaVersion < 2 {
            migration.enumerateObjects(ofType: Post.className()) { oldObject, newObject in
                newObject?["excerpt"] = ""
                newObject?["viewCount"] = 0
            }
        }
    }
    
    // Safe object creation
    func createObjectSafely<T: Object>(_ type: T.Type, configuration: (T) throws -> Void) async throws -> T {
        let object = type.init()
        
        do {
            try configuration(object)
            try validateObject(object)
            
            return try await MainActor.run {
                try realm.write {
                    realm.add(object)
                    return object
                }
            }
        } catch {
            throw RealmError.writeTransactionFailed(error.localizedDescription)
        }
    }
    
    // Object validation
    private func validateObject<T: Object>(_ object: T) throws {
        if let user = object as? User {
            try validateUser(user)
        } else if let post = object as? Post {
            try validatePost(post)
        }
    }
    
    private func validateUser(_ user: User) throws {
        guard !user.name.isEmpty else {
            throw RealmError.validationFailed("User name cannot be empty")
        }
        
        guard user.email.contains("@") && user.email.contains(".") else {
            throw RealmError.validationFailed("Invalid email format")
        }
        
        guard user.age >= 0 && user.age <= 150 else {
            throw RealmError.validationFailed("Age must be between 0 and 150")
        }
        
        // Email duplicate check
        let existingUser = realm.objects(User.self).filter("email == %@", user.email).first
        if let existing = existingUser, existing.id != user.id {
            throw RealmError.validationFailed("Email already exists")
        }
    }
    
    private func validatePost(_ post: Post) throws {
        guard !post.title.isEmpty else {
            throw RealmError.validationFailed("Post title cannot be empty")
        }
        
        guard post.content.count >= 10 else {
            throw RealmError.validationFailed("Post content must be at least 10 characters")
        }
        
        guard post.author != nil else {
            throw RealmError.validationFailed("Post must have an author")
        }
    }
    
    // Safe update operation
    func updateObjectSafely<T: Object>(_ object: T, updates: @escaping (T) throws -> Void) async throws {
        do {
            try await MainActor.run {
                try realm.write {
                    try updates(object)
                    try validateObject(object)
                }
            }
        } catch {
            throw RealmError.writeTransactionFailed(error.localizedDescription)
        }
    }
    
    // Safe delete operation
    func deleteObjectSafely<T: Object>(_ object: T) async throws {
        try await MainActor.run {
            do {
                try realm.write {
                    realm.delete(object)
                }
            } catch {
                throw RealmError.writeTransactionFailed(error.localizedDescription)
            }
        }
    }
    
    // Create backup
    func createBackup() async throws -> URL {
        let backupURL = getBackupURL()
        
        try await MainActor.run {
            try realm.writeCopy(toFile: backupURL, encryptionKey: encryptionKey)
        }
        
        return backupURL
    }
    
    // Restore from backup
    func restoreFromBackup(backupURL: URL) async throws {
        guard FileManager.default.fileExists(atPath: backupURL.path) else {
            throw RealmError.objectNotFound("Backup file not found")
        }
        
        // Restore from backup with new Realm configuration
        let restoreConfig = Realm.Configuration(
            fileURL: backupURL,
            encryptionKey: encryptionKey,
            readOnly: true
        )
        
        let backupRealm = try Realm(configuration: restoreConfig)
        
        try await MainActor.run {
            try realm.write {
                // Clear data
                realm.deleteAll()
                
                // Restore data from backup
                let users = backupRealm.objects(User.self)
                let posts = backupRealm.objects(Post.self)
                let categories = backupRealm.objects(Category.self)
                
                realm.add(users, update: .modified)
                realm.add(categories, update: .modified)
                realm.add(posts, update: .modified)
            }
        }
    }
    
    // Database integrity check
    func performIntegrityCheck() -> [String] {
        var issues: [String] = []
        
        // Orphaned posts check
        let postsWithoutAuthors = realm.objects(Post.self).filter("author == nil")
        if !postsWithoutAuthors.isEmpty {
            issues.append("\(postsWithoutAuthors.count) posts without authors found")
        }
        
        // Duplicate email check
        let users = realm.objects(User.self)
        let emails = users.map { $0.email }
        let uniqueEmails = Set(emails)
        if emails.count != uniqueEmails.count {
            issues.append("Duplicate email addresses found")
        }
        
        // Invalid data check
        let invalidUsers = users.filter("age < 0 OR age > 150")
        if !invalidUsers.isEmpty {
            issues.append("\(invalidUsers.count) users with invalid age found")
        }
        
        return issues
    }
    
    // Secure deletion (complete data deletion)
    func secureDelete() async throws {
        try await MainActor.run {
            try realm.write {
                realm.deleteAll()
            }
        }
        
        // Physical file deletion
        let realmURL = realm.configuration.fileURL!
        let realmURLs = [
            realmURL,
            realmURL.appendingPathExtension("lock"),
            realmURL.appendingPathExtension("note"),
            realmURL.appendingPathExtension("management")
        ]
        
        for url in realmURLs {
            try? FileManager.default.removeItem(at: url)
        }
    }
    
    private func getBackupURL() -> URL {
        let documentsPath = FileManager.default.urls(for: .documentDirectory, 
                                                   in: .userDomainMask)[0]
        let timestamp = ISO8601DateFormatter().string(from: Date())
        return documentsPath.appendingPathComponent("realm_backup_\(timestamp).realm")
    }
}

// Error handling usage example
struct SecureDataView: View {
    @StateObject private var realmManager = try! SecureRealmManager()
    @State private var errorMessage: String?
    @State private var showingError = false
    @State private var isBackingUp = false
    @State private var integrityIssues: [String] = []
    
    var body: some View {
        VStack {
            Button("Create Safe User") {
                Task {
                    await createUserSafely()
                }
            }
            
            Button("Run Integrity Check") {
                integrityIssues = realmManager.performIntegrityCheck()
            }
            
            Button("Create Backup") {
                Task {
                    await createBackup()
                }
            }
            .disabled(isBackingUp)
            
            if !integrityIssues.isEmpty {
                Text("Integrity Issues:")
                    .font(.headline)
                    .foregroundColor(.red)
                
                ForEach(integrityIssues, id: \.self) { issue in
                    Text("• \(issue)")
                        .foregroundColor(.red)
                }
            }
        }
        .alert("Error", isPresented: $showingError) {
            Button("OK") { }
        } message: {
            Text(errorMessage ?? "Unknown error")
        }
    }
    
    private func createUserSafely() async {
        do {
            let user = try await realmManager.createObjectSafely(User.self) { user in
                user.name = "John Doe"
                user.email = "[email protected]"
                user.age = 30
            }
            print("User created safely: \(user.name)")
        } catch {
            errorMessage = error.localizedDescription
            showingError = true
        }
    }
    
    private func createBackup() async {
        isBackingUp = true
        do {
            let backupURL = try await realmManager.createBackup()
            print("Backup created at: \(backupURL)")
        } catch {
            errorMessage = error.localizedDescription
            showingError = true
        }
        isBackingUp = false
    }
}