I am creating an image filtering app, basically you have the image displayed on the view controller and few different image filters in the bottom; clicking on one will effect the main image brightness (for example). I noticed that applying the filter takes longer time on higher resolution images so i thought of creating a completion handler (this is the first time i am doing this completion thing) and display the "activity indicator view" in the center of the viewcontroller to notify the user that its working... so below is the func (in a ImageProcessor.swift class) that changes the image brightness and send back the CIImage to the view Controller:
func setBrightness(ciImage: CIImage, intensity: Float = 0.5, completion: (CIImage) -> CIImage) -> CIImage? {
let filter = CIFilter(name: "CIColorControls");
filter?.setValue(ciImage, forKey: kCIInputImageKey);
filter?.setValue(intensity, forKey: "inputBrightness");
return completion((filter?.outputImage)!);
}
then this is how its being called from the viewcontroller:
case .Brightness:
self.loader.startAnimating();
imgViewFiltered.image = processor.getUIImage(processor.setBrightness(CIImage(image: imgViewFiltered.image!)!, completion: { (let ci) -> CIImage in
dispatch_async(dispatch_get_main_queue()) {
self.loader.stopAnimating();
}
return ci;
})!)
lastUsedFilter = FilterTypes.Brightness;
appliedFilters.updateValue(0.5, forKey: FilterTypes.Brightness)
Problem:
1st: I dont know if i am using the completion handler properly since its my first time so i will welcome some advice on it.
2nd: the indicator does not show or stop. the app just freeze for few seconds and back up again which made me think maybe the completion is not doing its job in the background.
thanks alot for your time.
Finally found the solution. It is by not making the function return anything and use the closure to assign to the object when its ready. i guess that was hooking up the main_que so this is the amendment:
func setBrightness(ciImage: CIImage, intensity: Float = 0.5, completion: (CIImage) -> Void) {
let filter = CIFilter(name: "CIColorControls");
filter?.setValue(ciImage, forKey: kCIInputImageKey);
filter?.setValue(intensity, forKey: "inputBrightness");
completion(filter?.outputImage)!;
}
and to call it and assign the image:
case .Brightness:
self.loader.startAnimating();
processor.setBrightness(CIImage(image: imgViewFiltered.image!)!, completion: { (let ci) in
dispatch_async(dispatch_get_main_queue()) {
imgViewFiltered.image = UIImage(CIImage: ci);
self.loader.stopAnimating();
}
})!
lastUsedFilter = FilterTypes.Brightness;
appliedFilters.updateValue(0.5, forKey: FilterTypes.Brightness)
hope this could help others facing same issue.