在webrequest会话中完成处理

时间:2017-06-15 17:36:20

标签: swift function completionhandler completion

我有一个带有jsonserialization的webrequest,之后是for-in fetch进程。 总的来说,这需要大约5-7秒。 之后我想在Viewcontroller中引用我的tableview。 该函数的方案如下所示。

public struct Container {
    let name: String
    let symbol: String
    let rank: String
}

public var dataArray = [Container]()


func fetchNewData() {

    var view = ViewController()

    // WebbRquest...

    // Json serialization...

    // the following list is much longer, will take a while...
    for items in json {
        let name = items["name"] as? AnyObject;
        let symbol = items["symbol"] as? AnyObject;
        let rank = items["rank"] as? AnyObject;
        let result = Container(name: name! as! String, symbol: symbol! as! String,rank: rank! as! String)

        dataArray.append(result)
    }

    // Now, after alle the work is done, i want to reload the tableview in Viewcontrller:
    view.reload()

    // Here i´m getting error, because nothing will be executed after return.

}

在webrequest过程完成后,如何调用重载功能?因为在返回之后,该函数不再执行任何操作。 当fetchNewData()函数完成时,没有其他函数会“知道”。 谢谢你的帮助!

@IBAction func updateButton(_ sender: Any) {

     fetchNewData()

    }

根据Phillipps的建议,我不得不稍微修改@IBAction功能。 但现在它正在工作。真棒! 这是完整的工作版本:

public struct Container {
    let name: String
    let symbol: String
    let rank: String
}

public var dataArray = [Container]()


func fetchNewData(completion:@escaping ([Container])->()) {

    var view = ViewController()

    // WebbRquest...

    // Json serialization...

    // the following list is much longer, will take a while...
    for items in json {
        let name = items["name"] as? AnyObject;
        let symbol = items["symbol"] as? AnyObject;
        let rank = items["rank"] as? AnyObject;
        let result = Container(name: name! as! String, symbol: symbol! as! String,rank: rank! as! String)

        dataArray.append(result)
    }

    completion(dataArray)


}

这是actionFunc:

 @IBAction func upDateButton(_ sender: Any) {

            let data = dataArray

            fetchNewData() {_ in (data)

            DispatchQueue.main.async {
                self.tableView.reloadData()
            }

 }

1 个答案:

答案 0 :(得分:1)

这是一个开始。这将是模糊的,因为我正在猜测我看不到的代码,但你可以将它转换为你自己的需要。

更改fetch函数,以便将闭包作为参数:

using System;
using Emgu.CV;
using Emgu.CV.UI;
using Emgu.CV.Structure;
using Emgu.CV.Util;
using Emgu.CV.CvEnum;

namespace OpenCV1
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                using (var image = new Image<Bgr, byte>(@"C:\Users\Administrator\Downloads\receipt-1.jpg"))
                {
                    float scale = (float)500 / (float)image.Height;
                    var resized = image.Resize(scale, Emgu.CV.CvEnum.Inter.Nearest);
                    var grey = image.Convert<Gray, byte>();
                    grey = grey.SmoothGaussian(5, 5, 1, 1);
                    var edged = grey.Canny(25, 100);

                    //ImageViewer.Show(edged, "edged");

                    VectorOfVectorOfPointF contours = new VectorOfVectorOfPointF();
                    Mat hierarchy = null;
                    CvInvoke.FindContours(edged.Copy(), contours, hierarchy, RetrType.List, ChainApproxMethod.ChainApproxSimple);
                    Console.ReadLine();
                }
            }
            catch(Exception ex)
            {
                Console.WriteLine(ex.Message);
                Console.ReadLine();
            }
        }
    }
}

...请注意,闭包将在调用时接受数据数组。 在你的json都被解析之后,你会调用闭包:

func fetchNewData(completion:([Container])->()) {

“魔法”位于视图控制器中,您可以告诉 dataArray.append(result) } completion(dataArray) 完成后要执行的操作。类似的东西:

fetchNewData

请注意,闭包是在视图控制器中编写的,因此@IBAction func updateButton(_ sender: Any) { fetchNewData() {(data) // Save the data where the view controller can use it self.tableArray = data // Main queue for UI update DispatchQueue.main.async { self.tableView.reloadData() } } } 是视图控制器。这意味着无需在fetch中创建第二个(无用的)控制器。