#ios #swift #firebase #google-cloud-firestore
#iOS #swift #firebase #google-облако-firestore
Вопрос:
В настоящее время я пытаюсь реализовать функцию заметок в своем приложении, и способ, которым я реализовал сохранение PKDrawings
, приведен ниже:
func saveDrawingData() {
var drawingDataArray = [String : Any]()
let drawingData = convertImageToBase64String(img: canvasView.screenshot!)
drawingDataArray["drawing_data"] = drawingData
if let client = selectedClient, let fileNumber = selectedFileNumber {
dbm.addCaseDataToDatabase(client, fileNumber, drawingDataArray)
} else {
print("Data not sent to Firestore")
}
}
Я делаю это, преобразуя чертеж в изображение, используя метод «скриншот» ниже:
extension UIView {
var screenshot : UIImage? {
var screenshot :UIImage?
let scale = UIScreen.main.scale
UIGraphicsBeginImageContextWithOptions(layer.frame.size, false, scale);
guard let context = UIGraphicsGetCurrentContext() else {return nil}
layer.render(in:context)
screenshot = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return screenshot
}
}
Хотя данные успешно сохраняются в Firestore, сейчас я пытаюсь извлечь их PKDrawing
из базы данных и поместить обратно на холст, чтобы их можно было дополнительно отредактировать и сохранить.
Ниже приведен мой код для отображения данных, которые были загружены из базы данных:
func displayDrawingFromDatabase(from data: [String: Any]) -> UIView {
if let drawing = data["drawing_data"] {
//convert downloaded key-value pair to image
let downloadedImage = convertBase64StringToImage(imageBase64String: drawing as! String)
//convert image to string
let imageString = convertImageToBase64String(img: downloadedImage)
//convert string to data
let imageData = Data(base64Encoded: imageString, options: .ignoreUnknownCharacters)
//Apply to canvasView
canvasView.drawing = imageData
}
return canvasView
}
Когда я это делаю, я получаю сообщение об ошибке:
cannot assign value of type Data? to type PKDrawing
Я попытался извлечь данные из чертежа с помощью этого .dataRepresentation()
метода, но мне не удалось успешно извлечь данные из пары ключ-значение displayDrawingDataFromDatabase()
.
Что я должен сделать, чтобы исправить код?
Редактировать:
Я вызываю displayDrawingFromDatabase()
с помощью:
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
if let client = selectedClient, let fileNumber = selectedFileNumber {
dbm.readDrawingDataFromDatabase(client, fileNumber) { (caseData, success) in
self.displayDrawingFromDatabase(from: caseData)
}
}
и этот код основан на функции, приведенной ниже:
func readDrawingDataFromDatabase(_ client: Client, _ fileNumber: FileNumber, completion: @escaping ((_ documentData: [String: Any], _ success: Bool) -> Void)) {
guard let uid: String = Auth.auth().currentUser?.uid else { return print("Cannot retrieve uid")}
let clientDocumentID = client.documentID
let fileNumberDocumentID = fileNumber.documentID
let clientRef = db.collection("users").document(uid).collection("clients")
let fileNumberRef = clientRef.document(clientDocumentID).collection("file_numbers")
let query = fileNumberRef.whereField("document_id", isEqualTo: fileNumberDocumentID as Any)
query.getDocuments() { (querySnapshot, err) in
if let err = err {
print("Error getting documents: (err)")
} else {
for document in querySnapshot!.documents {
//print("(document.documentID) => (document.data())")
let documentData: [String: Any] = document.data()
completion(documentData, true)
}
}
}
}
Комментарии:
1. В вопросе много неизвестных, поэтому ответить как есть будет невозможно. Почему вы не сохраняете штрихи, составляющие рисунок, вместо снимка экрана? Что вы передаете
displayDrawingFromDatabase
? И почему вы возвращаетесьreturn canvasView
, когда он выглядит как класс var? Какая конкретная строка выдает ошибку? Добавили ли вы точку останова и пошагово просматривали код построчно, проверяя переменные, чтобы определить, какой из них идет не так? Пожалуйста, обновите и уточните вопрос и код, и мы посмотрим.2. Во-первых, спасибо, что посмотрели на него. Что касается ваших вопросов: 1. Почему вы
3. Чтобы ответить на ваши вопросы: 1. Почему вы не сохраняете штрихи? Я понятия не имею, как это сделать. Я просто случайно нашел метод скриншота, и он, похоже, сработал. 2. Я вызываю displayingDrawingFromDatabase, используя
if let client = selectedClient, let fileNumber = selectedFileNumber { dbm.readDrawingDataFromDatabase(client, fileNumber) { (caseData, success) in self.displayDrawingFromDatabase(from: caseData) }
3. Строка, которая выдает ошибку:canvasView.drawing = imageData
. Ошибкаcannot assign value of type Data to type PKDrawing
.4. Если вы хотите сохранить фактический чертеж (UIImage) или электронную таблицу .pdf или .numbers или действительно любой файл, перейдите по ссылке в моем комментарии, чтобы сохранить их в хранилище Firebase, поскольку для этого оно и предназначено. Поля Firestore не являются подходящим местом для хранения больших файлов (больших двоичных объектов). Имейте в виду, что PKDrawings состоят из массива отдельных PKStrokes — это то, что я бы сохранил в Firestore. Вам все равно нужно будет кодировать / декодировать их как NSData, но это гораздо более гибко, чем сохранение документа в виде файла, поскольку тогда у вас есть доступ к каждому штриху.
5. Я бы также предложил использовать NSKeyedArchiver и NSKeyedUnarchiver для хранения и извлечения данных из Firestore (например, Any, или String или PKStroke и т. Д.).