Skip to content

Instantly share code, notes, and snippets.

@OctoberHammer
Last active August 21, 2021 21:39
Show Gist options
  • Save OctoberHammer/b6581ceb74e5366a6ed46cdb7cae0fa9 to your computer and use it in GitHub Desktop.
Save OctoberHammer/b6581ceb74e5366a6ed46cdb7cae0fa9 to your computer and use it in GitHub Desktop.
Запрос на консультацию. Последовательное получение картинок из PFFile для массива объектов PFObject
//
// 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