Completion Handler is not working in viewDidLoad?
Asked Answered
E

6

9

I'm using this library in my app for banners. I am trying to get the Link by parsing the JSON.

The Images are are not showing in the slideshow view. If I press the slideshow view, after that everything works fine. I thought that there was some issue with my completion handler. But I can't solve it yet :)

@IBOutlet weak var slideshow: ImageSlideshow!
var transitionDelegate: ZoomAnimatedTransitioningDelegate?
var Banner : [AlamofireSource] = []

override func viewDidLoad() {
        super.viewDidLoad()
        Banners { (imagesource) in
            if imagesource != nil {
                self.bannershow()
            }
        }
  }

    func Banners(completionHandler: ([AlamofireSource]?) -> ()) -> (){
        Alamofire.request(.GET, "http://46.420.116.11/mobileapp/gps/api.php?rquest=get_banners")
            .responseJSON{ response in
                if let data = response.result.value{
                    let json = JSON(data)
                    let count = json["image_path"].count
                    for index in 0...count-1 {
                        let image :String = json["image_path"][index].stringValue
                        let source : AlamofireSource = AlamofireSource(urlString: image)!
                        self.Banner.append(source)
                    }
                    completionHandler(self.Banner)
                }
        }
  }

    func bannershow(){
        self.slideshow.backgroundColor = UIColor.whiteColor()
        self.slideshow.slideshowInterval = 2.0
        self.slideshow.contentScaleMode = UIViewContentMode.ScaleToFill
        self.slideshow.setImageInputs(self.Banner)

        let recognizer = UITapGestureRecognizer(target: self, action: "click")
        self.slideshow.addGestureRecognizer(recognizer)
        }

 func click() {
        let ctr = FullScreenSlideshowViewController()
        ctr.pageSelected = {(page: Int) in
            self.slideshow.setScrollViewPage(page, animated: false)
        }

        ctr.initialPage = slideshow.scrollViewPage
        ctr.inputs = slideshow.images
        self.transitionDelegate = ZoomAnimatedTransitioningDelegate(slideshowView: slideshow);
        ctr.transitioningDelegate = self.transitionDelegate!
        self.presentViewController(ctr, animated: true, completion: nil)
    }
Effeminize answered 13/2, 2016 at 18:16 Comment(8)
can u share the code in the click methodSelfsealing
@uchiha I have added itEffeminize
What a code style!!!Cutlor
@user3467240 did you try my answer? I think its gonna work..Selfsealing
@uchiha Please show me some codeEffeminize
Can you put some print statements inside the responseJSON closure and see if it prints? I hope you are ascertaining that this closure gets called and your Banners closure is calledEpictetus
To improve readability you should not name functions like Classes. For example Banners.Rhetorician
What happens if the request fails? You do not have any kind of error handler. responseJSON probably does not get called because an error is returned from the server.Rhetorician
Q
4

You probably have a threading problem. There is no guarantee that the Banners completion handler is called on the main thread. You need to step out to the main thread explicitly before doing anything that touches your properties or (especially) the interface.

Quitt answered 13/2, 2016 at 18:21 Comment(5)
If I am not wrong Alamofire calls the response in the main thread, so the switch may not be the cause of the issue in this case.Selfsealing
@uchiha You could be right, but I have seen this kind of thing so often — the interface fails to update until touched — and the cause is invariably a threading issue, so it seems a reasonable guess here.Quitt
@Quitt i think its definitely worth trying this method out to check if it resolves the problem in question.Selfsealing
I have checked Alamofire source and the callback is always called on the main queue (didn't know that before!).Rinker
You can also give another queue to Alamofire if you don't want it to use the main queue.Rhetorician
P
0

I think your problem might be that you're expecting the images to be available immediately but they need to be downloaded before, so they won't be available immediately after your viewDidLoad method finished. That's why you should probably configure your slideshow in the viewDidLoad and not in your bannershow() method. Something like this might be an improvement:

@IBOutlet weak var slideshow: ImageSlideshow!
var bannerImages : [AlamofireSource] = []

override func viewDidLoad() {
    super.viewDidLoad()
    slideshow.backgroundColor = UIColor.whiteColor()
    slideshow.slideshowInterval = 2.0
    slideshow.contentScaleMode = UIViewContentMode.ScaleToFill
    let recognizer = UITapGestureRecognizer(target: self, action: "click")
    slideshow.addGestureRecognizer(recognizer)

    getBanners { imagesource in
        self.showBanner()
    }
}

func getBanners(completionHandler: ([AlamofireSource]?) -> ()) -> (){
    Alamofire.request(.GET, "http://46.420.116.11/mobileapp/gps/api.php?rquest=get_banners")
        .responseJSON{ response in
            if let data = response.result.value{
                let json = JSON(data)
                let count = json["image_path"].count
                for index in 0...count-1 {
                    let image :String = json["image_path"][index].stringValue
                    let source : AlamofireSource = AlamofireSource(urlString: image)!
                    self.bannerImages.append(source)
                }

            }
            completionHandler(self.bannerImages)
    }
}

func showBanner() {
    slideshow.setImageInputs(bannerImages)
}
Pastorate answered 21/2, 2016 at 5:31 Comment(0)
O
0

Move the code to viewWillAppear.

override func viewWillAppear(animated: Bool) {
    Banners { (imagesource) in
        if imagesource != nil {
            self.bannershow()
        }
    }
}
Orchestral answered 23/2, 2016 at 6:31 Comment(0)
A
0
func Banners(completionHandler: ([AlamofireSource]?) -> ()) -> (){
    Alamofire.request(.GET, "http://46.420.116.11/mobileapp/gps/api.php?rquest=get_banners")
        .responseJSON{ response in
            if let data = response.result.value{
                let json = JSON(data)
                let count = json["image_path"].count
                for index in 0...count-1 {
                    let image :String = json["image_path"][index].stringValue
                    let source : AlamofireSource = AlamofireSource(urlString: image)!
                    self.Banner.append(source)
                }
                completionHandler(self.Banner)
            }
    }

}

You are executing for loop in Banners fun
for index in 0...count-1 { let image :String = json["image_path"][index].stringValue let source : AlamofireSource = AlamofireSource(urlString: image)! self.Banner.append(source) } Replace this code in some other method and place an Optional
var image :String? = json["image_path"][index].stringValue

or place an thumb image, That will make you confirm that image is downloaded successfully or not .

Let me know if it works

Thanks, Happy Coding

Afterdeck answered 23/2, 2016 at 7:3 Comment(0)
S
0

Maybe you don't see images because you update them in a secondary thread, you have to perform image update in main thread; In swift ( performSelectorOnMainThread() is not available), you may use something like this :

 dispatch_async(dispatch_get_main_queue(), {

                    myslideshow.updateimage();

 })
Spindly answered 23/2, 2016 at 16:8 Comment(0)
S
-1

Not really sure, but I am guessing that since your images need to get downloaded, they are nil when you call self.slideshow.setImageInputs(self.Banner), which internally sets the image from the list to an imageview which is added inside the scrollView. So one way I can think of is use SDWebImage to set the image to the imageView so that it updates the respective imageViews once the image is ready(downloaded). I think you will need to use it in the InputSource.swift class in the setToImageView(_:) method. You will have to check this though, this is the only possible problem i could think of that might be causing your issue.

Selfsealing answered 17/2, 2016 at 13:51 Comment(1)
the library here(one used in the question) is for slideshow and not image download. The proposed library is for asynchronous image download which is the probable solution to the problem. Please go through the libraries before adding misleading comments and downvoting.Selfsealing

© 2022 - 2024 — McMap. All rights reserved.