Мой вариант использования
Я создаю WidgetExtension для своего приложения, и мне нужно получать данные в режиме реального времени, без необходимости входа пользователя в приложение, где я мог бы вручную обновить временную шкалу виджета. Приложение использует MongoDB и синхронизацию областей для хранения своих данных, поэтому я решил, что могу инициализировать гибкую область в виджете, когда мне нужно получить данные, а затем сделать их недействительными. Однако Apple налагает ограничение на память виджетов в 30 МБ, поэтому, когда я закончу извлекать данные из области, мне нужно сделать их недействительными и освободить память, чтобы я мог продолжить визуализацию виджета.
Воспроизводимый тест
Вот короткая демонстрация, в которой освещается проблема, а также некоторые из моих попыток решения.
Код: Выделить всё
class RealmManager: ObservableObject {
static let shared: RealmManager = RealmManager()
@Published var app: RealmSwift.App? = nil
@Published var realm: Realm? = nil
@MainActor
func loadRealm() async {
self.app = RealmSwift.App(id: "APP-ID")
let credentials = Credentials.userAPIKey("API-KEY")
let user = try! await app!.login(credentials: credentials)
let configuration = user.flexibleSyncConfiguration()
let realm = try! await Realm(configuration: configuration,
downloadBeforeOpen: .never )
self.realm = realm
}
@MainActor
private func removeSubscriptions() async {
let subs = self.realm!.subscriptions
try! await subs.update { subs.removeAll() }
}
//MARK: Clean
@MainActor
func cleanRealm() async {
await removeSubscriptions()
_ = try! Realm.deleteFiles(for: Realm.Configuration.defaultConfiguration)
try! await self.app!.currentUser?.remove()
self.realm!.invalidate()
self.realm = nil
self.app = nil
/// this is a function defined on RLMApp that erases all references to it throughout the codebase
App.resetAppCache()
}
}
struct ContentView: View {
@ObservedObject var realmManager = RealmManager.shared
var body: some View {
Text("REALM: \(RealmManager.shared.realm != nil)" )
Text("APP: \(RealmManager.shared.app != nil)" )
/// when first clicked the memory spikes to around 45MB, but does not come down when 'clean' is run
Button {
Task { await RealmManager.shared.loadRealm() }
} label: {
Text("load")
}
Button {
Task { await RealmManager.shared.cleanRealm() }
} label: {
Text("clean")
}
}
}
Подробнее здесь: https://stackoverflow.com/questions/786 ... d-by-realm
Мобильная версия