2015-09-19 4 views
0

У меня есть класс Parse, называемый Product с 238 строками. Обратите внимание, что этот класс не является реализацией продукта Parse.com, это собственный класс, реализованный мной, поскольку мне не нужны все столбцы, которые Parse добавляет к их классу Product.Parse.com - Загрузить объекты из базы данных - Показать прогресс с ProgressBlock

Класс продукта имеет столбец указателя (в основном внешний ключ в таблицах SQL), называемый ShopId, поскольку каждый продукт принадлежит определенному магазину (у меня есть класс Parse Shop с столбцом ObjectId, используемым в указателе продукта.

Мой класс Продукт также имеет столбец файла под названием ImageFile, который содержит образ продукта.

Я хочу, чтобы загрузить все продукты от конкретного магазина, распаковать их файл изображения и поместить его в моем Swift класс продукта, который состоит из PFObject Parse Product и UIImageView и UIImage. Вот мой класс продукта в Swift:

class Product { 
    private var object: PFObject 
    private var imageView: MMImageView! 
    private var image: UIImage 

    init(object: PFObject, image: UIImage) { 
     self.object = object 
     self.image = image 
    } 

    func getName() -> String { 
     if let name = object["name"] as? String { 
      return name 
     } else { 
      return "default" 
     } 
    } 

    func setImageView(size: CGFloat, target: DressingRoomViewController) { 
     self.imageView = MMImageView(frame:CGRectMake(0, 0, size, size)) 
     imageView.contentMode = UIViewContentMode.ScaleAspectFit 
     imageView.image = self.image 
     imageView.setName(object["category"] as! String) 
     imageView.backgroundColor = UIColor.clearColor() 
     imageView.userInteractionEnabled = true 
     let tapGestureRecognizer = 
     UITapGestureRecognizer(target: target, action: "imageTapped:") 
     tapGestureRecognizer.numberOfTapsRequired = 1 
     imageView.addGestureRecognizer(tapGestureRecognizer) 
    } 

    func getImageView() -> MMImageView { 
     return self.imageView 
    } 
} 

В настоящее время я загружаю все файлы в порядке и получаю их изображение и создаю свои файлы Swift со своими образами. Однако моя логика UIProgressView немного выключена. У меня есть UIProgressView, работающий для каждого продукта, каждый раз, когда я распаковываю изображение продукта. Мне нужно перенести Parse.com ProgressBlock из быстрой функции getProduct и в loadProducts @IBAction. Когда я пытаюсь, он вызывает много ошибок перед компиляцией. Как переместить ProgressBlock до loadProducts @IBAction? Вот мой текущий код:

// 
// ChooseShopViewController.swift 
// MirrorMirror 
// 
// Created by Ben on 12/09/15. 
// Copyright (c) 2015 Amber. All rights reserved. 
// 

import UIKit 
import Parse 

class ChooseShopViewController: UIViewController { 

    var progressView: UIProgressView? 
    private var allProducts: [Product] = [] 
    private var categories: [ProductCategory] = [] 

    @IBAction func loadProducts(sender: AnyObject) { 
     let shopQuery = PFQuery(className:"Shop") 
     shopQuery.getObjectInBackgroundWithId("QjSbyC6k5C") { 
      (glamour: PFObject?, error: NSError?) -> Void in 
      if error == nil && glamour != nil { 
       let query = PFQuery(className:"Product") 
       query.whereKey("shopId", equalTo: glamour!) 
       query.findObjectsInBackgroundWithBlock { 
        (objects: [AnyObject]?, error: NSError?) -> Void in 
        self.getAllProductsAndCategories(objects, error: error) 
       } 
      } else { 
       print(error) 
      } 
     } 

    } 
    override func viewDidLoad() { 
     super.viewDidLoad() 
     // Create Progress View Control 
     progressView = UIProgressView( progressViewStyle: 
             UIProgressViewStyle.Default) 
     progressView?.center = self.view.center 
     view.addSubview(progressView!) 
    } 

    override func prepareForSegue( segue: UIStoryboardSegue, 
     sender: AnyObject?) { 
     if (segue.identifier == "dressingRoom") { 
      ShopDisplay.sharedInstance.setAllProducts(self.allProducts) 
      ShopDisplay.sharedInstance.setAllProductCategories(self.categories) 
     } 
    } 

    override func didReceiveMemoryWarning() { 
     super.didReceiveMemoryWarning() 
    } 



    func getAllProductsAndCategories(objects: [AnyObject]?, error: NSError?) { 
     if error == nil { 
      if let objects = objects as? [PFObject] { 
       for product in objects { 
        self.getCategory(product) 
        self.getProduct(product) 
       } 
      } 
     } else { 
      print("Error: \(error!) \(error!.userInfo)") 
     } 
    } 

    func getCategory(product: PFObject) { 
     if let category = product["category"] as? String { 
      var alreadyThere: Bool = false 
      for item in self.categories { 
       if category == item.rawValue { 
        alreadyThere = true 
        break 
       } 
      } 
      if alreadyThere == false { 
       self.categories.append(ProductCategory(rawValue: category)!) 
      } 
     } 
    } 

    func getProduct(product: PFObject) { 
     if let productImage = product["imageFile"] as? PFFile { 
      productImage.getDataInBackgroundWithBlock ({ 
       (imageData: NSData?, error: NSError?) -> Void in 
       if let imageData = imageData { 
        let image = UIImage(data:imageData) 
        self.allProducts.append(
         Product(object: product, image: image!)) 
       } 
       if let downloadError = error { 
        print(downloadError.localizedDescription) 
       } 
      }, progressBlock: { 
       (percentDone: Int32) -> Void in 
        self.progressView?.progress = Float(percentDone) 
       if (percentDone == 100) { 
        //self.performSegueWithIdentifier("dressingRoom", sender: UIColor.greenColor()) 
       } 
      }) 
     } 
    } 
} 

ответ

1

я решил не использовать progressBlock, и вместо того, чтобы обновить UIProgressView вручную с расчетом. Итак, вот код. Это немного ржавый. Я мог бы реорганизовать сейчас и, возможно, реализовать рассчитанную переменную, чтобы сделать ее более чистым. Если мое решение является плохой практикой, я благодарен, если это будет указано, и предложит лучшее решение (для производительности не кажется хорошим для проверки значения UIProgressView.progress на каждой итерации для выполнения задачи завершения выполнения segue).

import UIKit 
import Parse 

class ChooseShopViewController: UIViewController { 

    var progressView: UIProgressView? 
    private var allProducts: [Product] = [] 
    private var categories: [ProductCategory] = [] 
    static var numberOfProducts: Float = 0 

    @IBAction func loadProducts(sender: AnyObject) { 
     let shopQuery = PFQuery(className:"Shop") 
     shopQuery.getObjectInBackgroundWithId("QjSbyC6k5C") { 
      (glamour: PFObject?, error: NSError?) -> Void in 
      if error == nil && glamour != nil { 
       let query = PFQuery(className:"Product") 
       query.whereKey("shopId", equalTo: glamour!) 
       query.findObjectsInBackgroundWithBlock { 
        (objects: [AnyObject]?, error: NSError?) -> Void in 
        ChooseShopViewController.numberOfProducts = 
         Float((objects?.count)!) 
        print(ChooseShopViewController.numberOfProducts) 
        self.getAllProductsAndCategories(objects, error: error) 
       } 
      } else { 
       print(error) 
      } 
     } 
    } 

    override func viewDidLoad() { 
     super.viewDidLoad() 
     // Create Progress View Control 
     progressView = UIProgressView( progressViewStyle: 
             UIProgressViewStyle.Default) 
     progressView?.center = self.view.center 
     progressView?.progress = 0.00 
     view.addSubview(progressView!) 
    } 

    override func prepareForSegue( segue: UIStoryboardSegue, 
     sender: AnyObject?) { 
     if (segue.identifier == "dressingRoom") { 
      ShopDisplay.sharedInstance.setAllProducts(self.allProducts) 
      ShopDisplay.sharedInstance.setAllProductCategories(self.categories) 
     } 
    } 

    override func didReceiveMemoryWarning() { 
     super.didReceiveMemoryWarning() 
    } 

    func getAllProductsAndCategories(objects: [AnyObject]?, error: NSError?) { 
     if error == nil { 
      if let objects = objects as? [PFObject] { 
       for product in objects { 
        self.getCategory(product) 
        self.getProduct(product) 
       } 
      } 
     } else { 
      print("Error: \(error!) \(error!.userInfo)") 
     } 
    } 

    func getCategory(product: PFObject) { 
     if let category = product["category"] as? String { 
      var alreadyThere: Bool = false 
      for item in self.categories { 
       if category == item.rawValue { 
        alreadyThere = true 
        break 
       } 
      } 
      if alreadyThere == false { 
       self.categories.append(ProductCategory(rawValue: category)!) 
      } 
     } 
    } 

    func getProduct(product: PFObject) { 
     if let productImage = product["imageFile"] as? PFFile { 
      productImage.getDataInBackgroundWithBlock ({ 
       (imageData: NSData?, error: NSError?) -> Void in 
       if let imageData = imageData { 
        let image = UIImage(data:imageData) 
        self.allProducts.append(
         Product(object: product, image: image!)) 
        self.progressView?.progress += (100.00/
         ChooseShopViewController.numberOfProducts)/100.00 
        print(self.progressView?.progress) 
        if self.progressView?.progress == 1 { 
         self.performSegueWithIdentifier("dressingRoom", 
          sender: UIColor.greenColor()) 
        } 
       } 
       if let downloadError = error { 
        print(downloadError.localizedDescription) 
       } 

      }) 
     } 
    } 
} 
0

Я нашел это на Parse website. Это может быть полезно, поскольку у него есть блок, который показывает процент, который регулярно обновляется во время загрузки!

let str = "Working at Parse is great!" 
    let data = str.dataUsingEncoding(NSUTF8StringEncoding) 
    let file = PFFile(name:"resume.txt", data:data) 
    file.saveInBackgroundWithBlock({ 
      (succeeded: Bool, error: NSError?) -> Void in 
      // Handle success or failure here ... 
     }, progressBlock: {(percentDone: Int32) -> Void in 

    // Update your progress spinner here. percentDone will be between 0 and 100. 

}) 

Вы нашли лучшее решение? Кроме этого? Я пытаюсь сделать что-то подобное.

+0

Это, похоже, работает только с PFFIle, а не с PFObject, который содержит PFFIle. Im stumped – Pippo