CloudKit и NSPersistentCloudKitContainer — получение CKRecord для createUserRecordID для каждой CKRecord в общедоступнойIOS

Программируем под IOS
Ответить Пред. темаСлед. тема
Anonymous
 CloudKit и NSPersistentCloudKitContainer — получение CKRecord для createUserRecordID для каждой CKRecord в общедоступной

Сообщение Anonymous »

Я не знал, как сформулировать вопрос. Я знаю, что это вводит в заблуждение.
Контекст:
Я использую NSPersistentCloudKitContainer для своих общедоступных и частных база данных. Модель CoreData имеет две конфигурации: локальную и облачную. Local соответствует частной базе данных CloudKit, а Cloud — общедоступной базе данных CloudKit. Обе конфигурации содержат все объекты: List, ListItem и Like.
List имеет отношение ко-многим к ListItem (с обратным).
ListItem имеет отношение ко-многим к Аналогично (с обратным).
Реализация частной базы данных работает должным образом.
Пользователь может создавать списки и элементы списков. Каждый из этих объектов может быть установлен как общедоступный или частный с помощью атрибута isPublic.
У меня есть одноэлементный объект, который отслеживает изменения в списках и ListItems с помощью уведомления NSManagedObjectContextDidChange. Если пользователь обновляет атрибут isPublic до значения true, копия List или ListItem создается в общедоступной базе данных. Если пользователь устанавливает для isPublic значение false, List или ListItem имеет атрибут isTrashed, которому в общедоступной базе данных присвоено значение true (не знаю, когда действительно удалять записи из общедоступной базы данных, но это уже другой вопрос).Пользователь также может просматривать все элементы ListItem в общедоступной базе данных с помощью NSFetchedResultsController для загрузки данных и отслеживания изменений.
Проблема
Я могу отображать все общедоступные элементы ListItem с помощью UITableView и NSFetchedResultsController. У меня есть собственный UITableViewCell, который отображает пользователя, создавшего имя пользователя ListItem, и выглядит следующим образом:
  • Получите CreatorUserRecordID для NSManagedObject с помощью NSPersistentCloudKitContainer.record(for: )
  • Получите пользовательскую CKRecord для CreatorUserRecordID, используя CKContainer.default().publicCloudDatabase.record(for:)
  • Доступ к имени пользователя CKRecord
Я делаю этот асинхронный вызов для каждого UITableViewCell. Правильно ли это? Если да, то мне нужно будет реализовать механизм кэширования.
И не только это: что, если асинхронный вызов завершится неудачно? Теперь у меня есть ячейка UITableView с пустым именем пользователя. Должен ли я заранее получить имя пользователя для всех элементов в NSFetchedResultsController? Это могут быть тысячи объектов, которые даже не отображались, что увеличивает время загрузки.
Правильно ли асинхронно получать пользовательскую CKRecord каждого ListItem или есть лучший способ получить доступ к пользователь, создавший CKRecord?
Должен ли я создать собственный NSManagedObject пользователя?
Я также хотел бы отобразить имена пользователей каждого пользователя, которому понравился элемент списка. Означает ли это, что для каждого лайка мне нужно будет проделать один и тот же процесс? Это означает, что у меня будет вызов API для каждого имени пользователя каждого элемента списка и каждого лайка каждого элемента списка ((1 + x) * y вызовы API; x = количество лайков, y = количество элементов списка).
Предположим, я показываю 100 элементов ListItem со средним показателем 20 лайков. Это означает, что я сделаю:
(1 + 20) * 100 = 2100 вызовов API (без кэширования)
Это соответствует 40 запросам/ второй предел с менее чем двумя элементами списка.
Если потребуется дополнительная информация или больше кода, дайте мне знать.
Похоже, это мой лучший вариант заключается в создании пользовательского объекта User в моей модели CoreData, поскольку Настройка NSPersistentCloudKitContainer помогает мне установить отношения.
Пример кода (UITableViewCell)
public func configure(listItem: ListItem, environment: Environment) {
self.listItem = listItem
self.environment = environment
self.userRecordId = self.environment?.coreDataStack.creatorUserRecordID(for: listItem)

self.fetchUserTask?.cancel()

self.fetchUserTask = Task {
guard let userRecordId = self.userRecordId,
let userRecord = try? await CKContainer.default().publicCloudDatabase.record(for: userRecordId) else {
self.userNameLabel.text = "I'm server poor. You can't view this information."
return
}

if !Task.isCancelled {
Task { @MainActor in
self.userRecord = userRecord
self.userNameLabel.text = self.userRecord?["username"]
}
}
}

self.contentTextView.text = listItem.title

self.dateCreatedLabel.text = DateFormatter.localizedString(
from: listItem.modifiedAt!,
dateStyle: .medium,
timeStyle: .short
)

let likes = self.listItem?.likes
self.likeButton.setTitle("\(likes?.count ?? 0)", for: .normal)

if let likes = likes?.allObjects as? [Like] {
for like in likes {
guard let userRecordId = self.environment?.coreDataStack.creatorUserRecordID(for: like) else {
self.likeButton.isEnabled = false
continue
}

if userRecordId.recordName == CKCurrentUserDefaultName {
self.likeButton.isEnabled = false
break
}
}
}
}


Подробнее здесь: https://stackoverflow.com/questions/793 ... oruserreco
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «IOS»