[закрыто] coreData, cloudKit, резервное копирование


#12

#13

да даже не знаю - везде есть, стоит только набрать cloudKit swift в поиске в ютубе. У тех же Брайана Адвента, Кило Локо


#14

для кордаты для начала наверное проще cloudKit - там очень похоже на кордату. Для файербейза надо будет отдельный логин делать, что неудобно для пользователя, а с cloudKit всё автоматом будет, если пользователь вошёл в эппл айди. Но, simonova, помните, что при использовании cloudKit все данные пользователей будут сохраняться в ВАШ дашбоард на аккаунт разработчика…а там бесплатный трафик и объем ограничен (10гБ - хранение ассетов (250мб на одного юзера), 100мб - под базу данных (2,5мб на одного ;)), 2гБ - трафика (50мб на юзера)) тарифы. Хотя там от вида базы зависит - публичная или нет. Надо разбираться )) Я думаю вам бесплатного тарифа хватит вполне для вашей БД ключ-значение.


#15

как бекэнд БД - firebase в целом и firestore в частности мне показалось намного проще, чем cloudKit. Ну и возможностей больше намного у комплекса сервисов firebase.


#16

А зачем мне хранить у себя данные, у каждого же пользователя есть облако свое собственное по эпплАйди … вот пусть там и хранит каждый своё добро. Вот если зайти в Настройки - apple ID - iCloud -> почти в самом низу есть iCloud Drive. Если его включить, то можно разрешить программам хранить данные, я так понимаю это облако пользователя. Потому что когда в какой-то программе я его выключила (но из самой программы, а через настройки, как описано выше), то зайдя в программу она сразу мне выдала сообщение, что iCloud выключен и нужно включить.


#17

это уже icloud documents и туда записывать можно только файлы. В cloudKit вы можете сразу писать из кор-даты ключ-значение. Это разные вещи (насколько я понял :smiley:). Ну и cloudKit полезен если, например, надо чем-то делиться или сообщения можно там организовать…


[решено, но это не точно] Приложение для ограниченного круга пользователей
#18

В общем похоже никто ничего толком и не понимает по этой теме (( каким способом это лучше организовать


#19

На удивление на русском Стэковерфлоув тоже почти нет инфы. Есть на английском меленько - сегодня покапаюсь


#20

Получилось что-нибудь найти?


#21

Да.
Вот есть очень хороший пример того, что нужно. Там самое главное читайте первый ответ про один из ключей в info.plist - от этого, похоже, может зависить вся роботоспособность кода )).

И вот ещё тоже похожий пример того что нужно в дополнение и сравнение.

И вот ещё материал, на которые ссылается один из авторов (я его и так находил, но он мне показался какой-то небольшой, но сейчас смотрю - там всё локанично и понятно :slight_smile: ).

З.Ы. Сам ещё не проверял на практике - не было времени. Вечером попробую сделать под себя и протестить.


#22

Что-то я так и не поняла, как это работает. А у вас получилось?


#23

В процессе. Пока нет, но должно ))


#24

Вот рабочий код:

func saveToIcloud (localPath: String) throws {
    //is iCloud working?
    guard let iCloudDocumentsURL = FileManager.default.url(forUbiquityContainerIdentifier: "YourIdentifire")?.appendingPathComponent("yourFileName") else {print("iCloud is NOT working!"); return}
    print("create container successfully")
    //Create the Directory if it doesn't exist
    if !FileManager.default.fileExists(atPath: iCloudDocumentsURL.path, isDirectory: nil) {
        //This gets skipped after initial run saying directory exists, but still don't see it on iCloud
        do {
            try FileManager.default.createDirectory(at: iCloudDocumentsURL, withIntermediateDirectories: true, attributes: nil)
        } catch {
            print("error create dir to icloud - \(error.localizedDescription)")
            return
        }
    }
    //If file exists on iCloud remove it
    var isDir:ObjCBool = false
    if FileManager.default.fileExists(atPath: iCloudDocumentsURL.path, isDirectory: &isDir) {
        do {
            try FileManager.default.removeItem(at: iCloudDocumentsURL)
        } catch {
            print("error remove old file")
            return
        }
    }
    //copy from my local to iCloud
    do {
        try FileManager.default.copyItem(atPath: localPath, toPath: iCloudDocumentsURL.path)
    } catch {
        print("error copy local file to icloud")
        return
    }
    print("saving to icloud has been successfully")
}

сюда в localPath я передаю путь к своему локальному файлу. Сохраняется этот локальный файл у менят так:

var pathForSaveLibrary : String {
    let path = NSSearchPathForDirectoriesInDomains(FileManager.SearchPathDirectory.libraryDirectory, FileManager.SearchPathDomainMask.userDomainMask, true)[0]
    return path
}
var pathForSaveData : String {
    let path = pathForSaveLibrary + "/data.plist"
    return path
}

Вот ещё код для проверки наличия файла в айклоуд:

guard let iCloudDocumentsURL2 = FileManager.default.url(forUbiquityContainerIdentifier: "YourIdentifire") else { print("the test is not work"); return}
if let fileList = try? FileManager().contentsOfDirectory(at: iCloudDocumentsURL2, includingPropertiesForKeys: nil, options: .skipsHiddenFiles) {
    print("fileList - \(fileList)")
    for s in fileList {
        print("file in icloud: \(s)")
    }
} else {
    print("no read backup in icloud")
}

Загрузка - это тот же самый FileManager.default.copyItem только пути наоборот:

func loadFromIcloud(localPath: String) throws {

guard let iCloudDocumentsURL = FileManager.default.url(forUbiquityContainerIdentifier: "YourIdentifire")?.appendingPathComponent("yourFileName") else { print("iCloud is NOT working!"); return }
print("create container successfully")

var isDir:ObjCBool = false

if FileManager.default.fileExists(atPath: iCloudDocumentsURL.path, isDirectory: nil) {
    
    if FileManager.default.fileExists(atPath: localPath, isDirectory: &isDir) {
        do {
            try FileManager.default.removeItem(atPath: localPath)
        } catch {
            print("error remove old local file: \(error.localizedDescription)")
            return
        }
    }
    
    do {
        try FileManager.default.copyItem(atPath: iCloudDocumentsURL.path, toPath: localPath)
    } catch {
        print("error copy files from icloud - \(error.localizedDescription)")
        return
    }
} else {
    print("No backup data")
}

}


#25

Админы, ау, помогите? как сохранить базу coredata в облако - делать резервные копии (мы не про cloudKit, синхронизация на разных устройсвах не нужна, хотя по cloudKit-у тоже нужен курс) … но бэкапить корДату нужно, если телефон сломался и …

и нужно при переустановке приложение - чтобы данные вернулись из нашей сохраненной в облако базы … !? ЧТобы она сама бэюкапилась (точнее синхронизировалась с облаком) по времени или по изменениям в базе + наличию инета …

ПОМОГИТЕ НАМ … а то мы скоро опять велосипед какой-нибудь изобретем и только время потратим …


#26

Так всё же понятно! Именно для кордаты был создан cloudkit - там это всё делается несложно и схоже с кор датой - материала много! Если не нужно делиться данными, то создаётся приватный контейнер и всё.

Если надо писать бэкап в клоуд пользователя, то сохраняйте локальные файлы как я написал выше. Материал тоже есть.
Другой вопрос, что если вы хотите бекапить кордату не в клоудкит, то вам надо сначала ваши данный сохранить в файл! Как это делать я описывал тут. Но тогда не очень понятно зачем вам вообще кордата, если вы данные будете хранить в локальном файле???

Универсального ответа нет! И ни кто не принесёт ни чего на блюдечке :slight_smile:

По вашей ситуации ответа 2:

  1. если вы используете кордату, то бэкапте в клоудкит.
  2. если хотите в айклоуд пользователя, то и корадата вам ни к чему на простых приложениях.

#27

Как выше и написали - хранилище легко отделяется и копируется в облако.

И в более-менее проектах не советовал бы использовать сам CloudKit - проблемы с тестированием, автоматизацией и другие плюшки этого решения обеспечены.


#28

Я бы посоветовал отказаться от CoreData и пересесть на Firebase. База всегда в онлайне, не нужно переживать из-за поломки телефона или смены оного.


#29

А почему не вместе? Кор для локального сохранения и Firebase для сохранения данных в резерв?:thinking:


#30

Какой смысл держать 2 одинаковых функционала? Firevase в этом случае удовлетворит все потребности.


#31

Ну к примеру у меня и то и другое. Но чтобы не требовалось постоянный интернет я сохраняю локально. Потому что данные грузятся в трёх случаях: 1. При регистрации, 2. При авторизации, 3. При редактировании профиля.