Last active
August 21, 2021 21:39
-
-
Save OctoberHammer/b6581ceb74e5366a6ed46cdb7cae0fa9 to your computer and use it in GitHub Desktop.
Запрос на консультацию. Последовательное получение картинок из PFFile для массива объектов PFObject
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// Model.swift | |
// KidSpace | |
// | |
// Created by October Hammer on 4/19/17. | |
// Copyright © 2017 Ocotober Hammer. All rights reserved. | |
// | |
import Foundation | |
import Parse | |
import ParseUI | |
import Bolts | |
//Это нужно чтобы зарегистрировать унаследованный от PFOject класс | |
extension Category: PFSubclassing { | |
static func parseClassName() -> String { | |
return "Category" | |
} | |
} | |
//Создаю класс, унаследованный от PFObject | |
class Category: PFObject { | |
//class Category { | |
// @NSManaged public private(set) var objectId: String? | |
@NSManaged public private(set) var name: String? | |
@NSManaged public private(set) var picture: PFFile? | |
@NSManaged public private(set) var pictureData: Data?//хочу хранить данные для картинки в этом свойстве | |
@NSManaged public private(set) var url: String? | |
@NSManaged public private(set) var parent: Category? | |
init(_ id: String, name: String) { | |
super.init() | |
self.objectId = id | |
self.name = name | |
} | |
//метод, которым получаю данные из PFFile | |
func retrieveImage(from: PFFile, result: @escaping (_ imageData: Data?) -> Void ) { | |
from.getDataInBackground(block: {(imageData: Data?, error: Error?) -> Void in | |
if error == nil { | |
if let imageData = imageData { | |
if let imageFile = UIImage(data: imageData) { | |
print("I've got a picture for \(self.objectId), size: \(imageData.count)") | |
imageFile.write(to: self.objectId!)// Записываю полученное изображение в файл | |
} | |
result(imageData)//И вызываю замыкание с результатом, чтобы присвоить полученные данные уже вне этого метода | |
} | |
} else { | |
print("☠️ \(error?.localizedDescription ?? "there is some error")") | |
result(nil) | |
} | |
}) | |
} | |
//вызов этого метода из ВьюКонтролера происходит вот так: | |
// Category.selectRootElements() { (result) -> Void in | |
// if let categorySelection = result { | |
// self.rootCategories = categorySelection | |
// self.collectionView?.reloadData() | |
// } | |
// } | |
static func selectRootElements(_ compleationHandler: @escaping ((_ categorySelection: [Category]?) -> Void)) { | |
var catSelection: [Category]? = []//Это у меня локальная переменная, в которую я буду скалдывать свою выборку | |
let query = PFQuery(className: "category") | |
query.whereKeyDoesNotExist("parentID")// Получаю только корневые элементы, то есть те, у которых ссылка на родителя - пустая, их у меня в приложении - 8 записей | |
query.findObjectsInBackground {(pfCategories: [PFObject]?, error: Error?) in | |
if error == nil { | |
if let pfCategories = pfCategories { | |
print("Successfully retrieved \(pfCategories.count) categories.") | |
//for (index, everyCategory) in pfCategories.enumerated() { | |
if pfCategories.count > 0 { | |
//Получаю 1-ю запись, с самой большой картинкой. Хочу сначала вытащить ее, и только потом обрабатывать последовательно остальные записи | |
let category = Category(pfCategories[0].objectId!, name: pfCategories[0]["name"] as! String)//по сути я создаю новый инстанс | |
category.url = pfCategories[0]["URL"] as? String | |
if let picture = pfCategories[0].value(forKey: "picture") as? PFFile { | |
category.retrieveImage(from: picture) {(_ imageData: Data?) -> Void in | |
category.pictureData = imageData//вот они, данные картинки | |
catSelection?.append(category)//добавил | |
} | |
}//Все, у меня иссякли идеи. Если просто перебирать полученные pfCategories в Цикле, | |
//то картинки вытаскиваются асинхронно, и первая самая большая приходит последней. | |
//Как Комплишен изменить таким образом, чтобы он после получения данных картинки запускал получение картинки в следующем элементе - я уже и не знаю. | |
//Раньше в класса PFFile были метод getData, сейчас все - inBackground | |
//Я думаю, может задействовать NSNotificationCenter - добавить подписку и обозревателя. Когда метод выполнится, чтобы он | |
//слал нотификацию о том, что мол картинка получена, можно запускать получение следующей | |
} | |
//После того, как я получил все нужные элементы, уже с картинками, я хочу их вернуть во ВьюКонтроллер: | |
DispatchQueue.main.async { | |
compleationHandler(catSelection) | |
} | |
} | |
} | |
} | |
} | |
func getImage() -> UIImage? { | |
let documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first! | |
let filePath = documentsURL.appendingPathComponent("\(self.objectId).png").path | |
if FileManager.default.fileExists(atPath: filePath) { | |
return UIImage(contentsOfFile: filePath) | |
} | |
return nil | |
} | |
} | |
extension UIImage { | |
func write(to: String){ | |
do { | |
let documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first! | |
let fileURL = documentsURL.appendingPathComponent("\(to).png") | |
if let pngImageData = UIImagePNGRepresentation(self) { | |
try pngImageData.write(to: fileURL, options: .atomic) | |
} | |
} catch { } | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment