- Published on
CloudKit 5: Qayta foydalanish mumkin bo'lgan Utility klassini yaratish
- Authors
- Name
- ShoxruxC
- @iOSdasturchi
Nega bizga Utility klass kerak?
Oldingi darslarda ko'rdikki, CloudKit kodlari ancha uzun. Tasavvur qiling, sizda 5 xil ekran va 5 xil ViewModel bor. Har biriga fetch(), save(), accountStatus kodlarini qayta-qayta yozaversangiz, kodlaringiz juda tartibsiz va o'qish qiyin bo'lib ketadi.
Buning o'rniga biz CloudKitUtility degan alohida bitta klass ochamiz. Barcha CloudKit amallarini shu yerga yozib qo'yamiz va ilovaning istalgan joyidan bitta qator kod bilan chaqirib ishlataveramiz.
Ushbu Utility ni yanada mukammal qilish uchun Combine dagi Future publisherlaridan foydalanamiz.
1. CloudKitUtility klassini yaratish
Yangi Swift fayl ochib, uning nomini CloudKitUtility deb nomlaymiz.
import Foundation
import CloudKit
import Combine
class CloudKitUtility {
// Biz o'zimizning maxsus xatoliklarimizni (Enum) yaratamiz
enum CloudKitError: String, LocalizedError {
case iCloudNotFound = "iCloud akkaunt topilmadi."
case iCloudNotDetermined = "iCloud statusi noma'lum."
case iCloudRestricted = "iCloud cheklangan."
case iCloudUnknown = "Noma'lum iCloud xatoligi."
}
}
2. Combine Future bilan funksiya yozish
Keling, iCloud ulanishini tekshiradigan accountStatus kodimizni ko'raylik.
class CloudKitUtility {
// ...
// Static funksiya qilsak, CloudKitUtility() deb e'lon qilmasdan ishlatish mumkin.
static func getiCloudStatus() -> Future<Bool, Error> {
return Future { promise in
CKContainer.default().accountStatus { status, error in
DispatchQueue.main.async {
switch status {
case .available:
promise(.success(true))
case .noAccount:
promise(.failure(CloudKitError.iCloudNotFound))
case .couldNotDetermine:
promise(.failure(CloudKitError.iCloudNotDetermined))
case .restricted:
promise(.failure(CloudKitError.iCloudRestricted))
default:
promise(.failure(CloudKitError.iCloudUnknown))
}
}
}
}
}
}
3. ViewModel'da Utility'dan foydalanish
Endi qaysi ViewModel'da iCloud statusi kerak bo'lsa, kod judayam qisqa bo'ladi:
import Combine
class MyViewModel: ObservableObject {
@Published var isSignedIntoiCloud: Bool = false
@Published var error: String = ""
var cancellables = Set<AnyCancellable>()
init() {
checkStatus()
}
func checkStatus() {
CloudKitUtility.getiCloudStatus()
.sink { [weak self] completion in
switch completion {
case .finished:
break
case .failure(let error):
self?.error = error.localizedDescription
}
} receiveValue: { [weak self] value in
self?.isSignedIntoiCloud = value
}
.store(in: &cancellables)
}
}
Keyingi qadamlar
Siz xuddi shu tarzda requestApplicationPermission, fetchUserRecordID, save, fetch, delete kabi funksiyalarni ham CloudKitUtility ichiga static func qilib kiritishingiz mumkin. Hatto Generics (<T>) ishlatib, har xil Record type'lar uchun universal fetch() yozsa bo'ladi.
Bu usul nafaqat hozirgi loyihangizni toza qiladi, balki kelajakda boshqa loyihaga o'tsangiz ham, shu CloudKitUtility.swift faylini ko'chirib olib, tayyor cloud bazadan darhol foydalanish imkonini beradi!