【问题标题】:Parse.com - Download Objects From Database - Show Progress With ProgressBlockParse.com - 从数据库下载对象 - 使用 ProgressBlock 显示进度
【发布时间】:2016-05-11 23:39:31
【问题描述】:

我有一个名为 Product 的 Parse 类,它有 238 行。请注意,这个类不是 Parse.com 的 Product 实现,它是我自己实现的自定义类,因为我不需要 Parse 添加到他们的 Product 类中的所有列。

Product 类有一个 Pointer 列(基本上是 SQL 表中的外键),称为 ShopId,因为每个产品都属于一个特定的 Shop(我有一个名为 Shop 的 Parse 类,其中 Product Pointer 中使用了一个 ObjectId 列。

我的 Product 类还有一个名为 imageFile 的 File 列,其中包含产品的图像。

我想从特定商店下载所有产品,解压缩它们的图像文件并将其放入我的 Swift 产品类中,该类由 Parse 产品的 PFObjectUIImageViewUIImage 组成。这是我在 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 swift 函数中移出并移到 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())
                }
            })
        }
    }
}

【问题讨论】:

    标签: parse-platform uiprogressview


    【解决方案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)
                    }
    
                })
            }
        }
    }
    

    【讨论】:

      【解决方案2】:

      我在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.
      
       })
      

      您找到更好的解决方案了吗?除此以外?我正在尝试做类似的事情。

      【讨论】:

      • 这似乎只适用于 PFFIle 而不是包含 PFFIle 的 PFObject。我被难住了
      猜你喜欢
      • 1970-01-01
      • 2021-06-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-02-08
      • 1970-01-01
      • 2019-05-26
      • 1970-01-01
      相关资源
      最近更新 更多