Created
May 3, 2017 09:16
-
-
Save OctoberHammer/48e7f0f2751cc8e5eb6e387a4aaefd4d to your computer and use it in GitHub Desktop.
В конечном счете я решил, что это простая рекурсия. На других языках рекурсию я реализовывал. Пробую на свифте
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) | |
} | |
}) | |
} | |
static func selectRootElements(_ compleationHandler: @escaping ((_ categorySelection: [Category]?) -> Void)) { | |
var catSelection: [Category]? = []//Это у меня локальная переменная, в которую я буду скалдывать свою выборку | |
func completionInMainQ() { | |
//После того, как я получил все нужные элементы, уже с картинками, я хочу их вернуть во ВьюКонтроллер: | |
DispatchQueue.main.async { | |
compleationHandler(catSelection) | |
} | |
} | |
//Конструкции ниже - для реализации рекурсивного замыкания | |
typealias CBType = (Int, [PFObject]) -> Void //функциональный тайпалиас, чтобы строчкой ниже объявить | |
var getDataForItem: CBType? //переменную Опшионал этого типа, которая в свою очередь нужна, чтобы не поймать ошибку 'Variable used within its own initial value' или еще одну | |
let placeHolder: CBType = { (_ currentIndex: Int, pfCategories: [PFObject]) -> Void in | |
if pfCategories.count > currentIndex { | |
let category = Category(pfCategories[currentIndex].objectId!, name: pfCategories[currentIndex]["name"] as! String)//по сути я создаю новый инстанс | |
category.url = pfCategories[currentIndex]["URL"] as? String | |
if let picture = pfCategories[currentIndex].value(forKey: "picture") as? PFFile { | |
category.retrieveImage(from: picture) {(_ imageData: Data?) -> Void in | |
category.pictureData = imageData//вот они, данные картинки | |
catSelection?.append(category)//добавил | |
let nextIndex = currentIndex + 1 | |
if let getDataForNextItem = getDataForItem { // так как переменная - опшионал типа, то анврапим ее | |
getDataForNextItem(nextIndex, pfCategories) //и вызываем для следующего элемента | |
} | |
} | |
} | |
} else { | |
completionInMainQ() | |
} | |
} | |
// переменной, которую мы сначала объявили как опшионал, назначаем наше замыкание, которое получает картинку для и-того элемента массива | |
getDataForItem = placeHolder | |
//А вот дальше код | |
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() { | |
var currentIndex = 0 | |
placeHolder(currentIndex, pfCategories) | |
} | |
} | |
} | |
} | |
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