iOS Swift fetching more data for collection view after having navigated to detail view not working -


i working on assignment job interview. have finished of assignment. there's bug can't figure out. have been trying 3 days now.

i had make client app flickr api allows users search photos using specific words. display results in collection view infinite scroll. , when photo selected should show details of photo in detail view.

the bug: working if stay in collection view. can search on , on again , infinite scroll working.as specific index in index path hit. new request sent same search term. if select photo , navigate collection view , try new search nothing comes , error handeling returns error. (the error not console error).also when navigating detail collection. can still scroll until index triggers new request throws error.

i hope explaining well. getting desperate @ moment. tried think of: request url still works when try in browser.

please help! if need more info ask.

collection view controller:

import uikit  // global variable holding search term. var searchterm: string?  // global variable hold instance of reachability. var reachability: reachability?  // enum changing textfield placeholder text. enum textfieldplaceholdertext: string {     case search = "search"     case searching = "searching..." }  class photosviewcontroller: uiviewcontroller {  // mark: - outlets @iboutlet var collectionview: uicollectionview! @iboutlet var searchtextfield: uitextfield!  // mark: - properties let photodatasource = photodatasource() let photostore = photostore()  // mark: - view setup override func viewdidload() {     super.viewdidload()      // sets data source , delegate.     collectionview.datasource = photodatasource     collectionview.delegate = self      // uses image add pattern collection view background.     collectionview.backgroundcolor = uicolor(patternimage: uiimage(named: "flickr.png")!) }  override func viewwillappear(animated: bool) {     super.viewwillappear(animated)      // checks if device connected internet.     checkforreachability() }  // mark: showalert func showalert(title: string, message: string) {      let alert = uialertcontroller(title: title, message: message, preferredstyle: .alert)     let okaction = uialertaction(title: "ok", style: .cancel, handler: { (nil) in         self.dismissviewcontrolleranimated(true, completion: nil)     })     alert.addaction(okaction)     self.presentviewcontroller(alert, animated: true, completion: nil) }  // mark: - segue override func prepareforsegue(segue: uistoryboardsegue, sender: anyobject?) {     if segue.identifier == "showphoto" {          if let selectedindexpath = collectionview.indexpathsforselecteditems()?.first {              let flickrphoto = photodatasource.flickrphotos[selectedindexpath.row]              let destinationvc = segue.destinationviewcontroller as! photodetailviewcontroller             destinationvc.flickrphoto = flickrphoto             destinationvc.photostore = photostore         }     } }  // mark: - checkforreachability func checkforreachability() {     {         reachability = try reachability.reachabilityforinternetconnection()     } catch {         print("unable create reachability")         return     }     reachability!.whenreachable = { reachability in         // called on background thread, ui updates must on main thread.         nsoperationqueue.mainqueue().addoperationwithblock({             if reachability.isreachableviawifi() {                 print("reachable via wifi")             } else {                 print("reachable via cellular")             }         })     }     reachability!.whenunreachable = { reachability in         // called on background thread, ui updates must on main thread.         nsoperationqueue.mainqueue().addoperationwithblock({             print("not reachable")              self.showalert("no internet connection", message: "make sure device connected internet.")         })     }     {         try reachability!.startnotifier()     } catch {         print("unable start notifier")     } } }  //mark: - extension uicollectionviewdelegate extension photosviewcontroller: uicollectionviewdelegate {  //mark: - willdisplaycell func collectionview(collectionview: uicollectionview, willdisplaycell cell: uicollectionviewcell, foritematindexpath indexpath: nsindexpath) {      let flickrphoto = photodatasource.flickrphotos[indexpath.row]      // downloads image data thumbnail.     photostore.fetchimageforphoto(flickrphoto,thumbnail: true) { (result) -> void in          // calls mainthread update ui.         nsoperationqueue.mainqueue().addoperationwithblock() {              // indexpath photo might have changed between time request started , finished, find recent indeaxpath             let photoindex = self.photodatasource.flickrphotos.indexof(flickrphoto)!             let photoindexpath = nsindexpath(forrow: photoindex, insection: 0)              // when request finishes, update cell if it's still visible             if let cell = collectionview.cellforitematindexpath(photoindexpath) as? photocollectionviewcell {                 cell.updatewithimage(flickrphoto.image)             }         }     } } }  //mark: - extension uitextfielddelegate extension photosviewcontroller : uitextfielddelegate {  func textfieldshouldreturn(textfield: uitextfield) -> bool {      // checks if textfield not empty.     if textfield.text!.isempty {         self.showalert("s😉rry", message: "no search term detected, please enter search term.")         return false     }     else {         let activityindicator = uiactivityindicatorview(activityindicatorstyle: .gray)         textfield.addsubview(activityindicator)         activityindicator.frame = textfield.bounds         activityindicator.startanimating()          textfield.placeholder = textfieldplaceholdertext.searching.rawvalue          // sets text user typed value searchterm property.         searchterm = textfield.text!          // fetches photos flickr using user's search term.         photostore.fetchphotosforsearchterm() {             (photosresult) -> void in              // calls mainthread update ui.             nsoperationqueue.mainqueue().addoperationwithblock() {                  switch photosresult {                  case let .success(photos):                      // checks if photos found using search term.                     if photos.count == 0 {                         self.showalert("s😞rry", message: "no images found matching search for: \(searchterm!), please try again.")                     }                     activityindicator.removefromsuperview()                     textfield.placeholder = textfieldplaceholdertext.search.rawvalue                      // sets result data source array.                     self.photodatasource.flickrphotos = photos                     print("successfully found \(photos.count) recent photos.")                  case let .failure(error):                      self.checkforreachability()                     activityindicator.removefromsuperview()                     textfield.placeholder = textfieldplaceholdertext.search.rawvalue                     self.photodatasource.flickrphotos.removeall()                     self.showalert("", message: "something went wrong, please try again.")                     print("error fetching photo's search term: \(searchterm!), error: \(error)")                 }                 self.collectionview.reloadsections(nsindexset(index: 0))             }         }         textfield.text = nil         textfield.resignfirstresponder()         self.collectionview?.backgroundcolor = uicolor.whitecolor()          return true     } } } 

the detail view controller:

import uikit import social  class photodetailviewcontroller: uiviewcontroller {      // mark: - outlets     @iboutlet var phototitlelabel: uilabel!     @iboutlet var photoidlabel: uilabel!     @iboutlet var datetakenlabel: uilabel!     @iboutlet var imageview: uiimageview!      // mark: properties     var flickrphoto: flickrphoto!     var photostore: photostore!     let formatter = flickrapi.dateformatter      // mark: - view setup     override func viewdidload() {         super.viewdidload()          //downloads image data large image         photostore.fetchimageforphoto(flickrphoto, thumbnail: false) { (result) -> void in             switch result {             case let .success(image):                  // calls mainthread update ui.                 nsoperationqueue.mainqueue().addoperationwithblock() {                     self.imageview.image = image                 }             case let .failure(error):                 print(" error fetching detail image photo: \(error)")             }         }         // formats date shorte date doesn't display time         formatter.datestyle = .mediumstyle         formatter.timestyle = .nostyle      }      override func viewwillappear(animated: bool) {         super.viewwillappear(animated)          // checks if device connected internet.         checkforreachability()          // configures ui.         configureview()     }      // mark: - checkforreachability     func checkforreachability() {         {             reachability = try reachability.reachabilityforinternetconnection()         } catch {             print("unable create reachability")             return         }         reachability!.whenreachable = { reachability in             // called on background thread, ui updates must on main thread, this:             nsoperationqueue.mainqueue().addoperationwithblock({                 if reachability.isreachableviawifi() {                     print("reachable via wifi")                 } else {                     print("reachable via cellular")                 }             })         }         reachability!.whenunreachable = { reachability in             // called on background thread, ui updates must on main thread, this:             nsoperationqueue.mainqueue().addoperationwithblock({                 print("not reachable")                  self.showalert("no internet connection", message: "make sure device connected internet.")             })         }         {             try reachability!.startnotifier()         } catch {             print("unable start notifier")         }     }      // mark: - configureview     func configureview() {         phototitlelabel.text = flickrphoto.title ?? "no title available"         photoidlabel.text = flickrphoto.photoid ?? "id unknown"         datetakenlabel.text = formatter.stringfromdate(flickrphoto.datetaken) ?? " date unknown"     }      // mark: - showshareoptions     @ibaction func showshareoptions(sender: anyobject) {          // configure action sheet show sharing options.         let actionsheet = uialertcontroller(title: "share photo", message: "", preferredstyle: uialertcontrollerstyle.actionsheet)         let tweetaction = uialertaction(title: "share on twitter", style: uialertactionstyle.default) { (action) -> void in             // check if sharing twitter possible.             if slcomposeviewcontroller.isavailableforservicetype(slservicetypetwitter) {                  let twittercomposevc = slcomposeviewcontroller(forservicetype: slservicetypetwitter)                 twittercomposevc.addimage(self.imageview.image)                 self.presentviewcontroller(twittercomposevc, animated: true, completion: nil)             }             else {                 self.showalert("flickr searcher", message: "you not logged in twitter account.")             }         }          // configure new action share on facebook.         let facebookpostaction = uialertaction(title: "share on facebook", style: uialertactionstyle.default) { (action) -> void in              if slcomposeviewcontroller.isavailableforservicetype(slservicetypetwitter) {                  let facebookcomposevc = slcomposeviewcontroller(forservicetype: slservicetypefacebook)                 facebookcomposevc.addimage(self.imageview.image)                 self.presentviewcontroller(facebookcomposevc, animated: true, completion: nil)              }             else {                 self.showalert("flickr searcher", message: "you not logged in facebook account.")             }         }          // configure new action show uiactivityviewcontroller         let moreaction = uialertaction(title: "more", style: uialertactionstyle.default) { (action) -> void in             let activityviewcontroller = uiactivityviewcontroller(activityitems: [self.imageview.image!], applicationactivities: nil)              self.presentviewcontroller(activityviewcontroller, animated: true, completion: nil)         }          let dismissaction = uialertaction(title: "cancel", style: uialertactionstyle.destructive) { (action) -> void in          }         actionsheet.addaction(tweetaction)         actionsheet.addaction(facebookpostaction)         actionsheet.addaction(moreaction)         actionsheet.addaction(dismissaction)          presentviewcontroller(actionsheet, animated: true, completion: nil)     }      // mark: showalert     func showalert(title: string, message: string) {         let alert = uialertcontroller(title: title, message: message, preferredstyle: .alert)         let okaction = uialertaction(title: "ok", style: .cancel, handler: { (nil) in             self.dismissviewcontrolleranimated(true, completion: nil)         })          alert.addaction(okaction)         self.presentviewcontroller(alert, animated: true, completion: nil)     } } 

my data source:

import uikit  class photodatasource: nsobject, uicollectionviewdatasource {      //mark: - properties     // array store flickr photos     var flickrphotos = [flickrphoto]()      // instance of photostore.     var photostore = photostore()      // mark: - numberofitemsinsection     func collectionview(collectionview: uicollectionview, numberofitemsinsection section: int) -> int {         return flickrphotos.count     }      // mark: - cellforitematindexpath     func collectionview(collectionview: uicollectionview, cellforitematindexpath indexpath: nsindexpath) -> uicollectionviewcell {          let identifier = "flickrcell"         let cell = collectionview.dequeuereusablecellwithreuseidentifier(identifier, forindexpath: indexpath) as! photocollectionviewcell          let photo = flickrphotos[indexpath.item]         cell.updatewithimage(photo.image)         print(indexpath.item)         // if close end of collection, fetch more photo's.         if indexpath.item == flickrphotos.count - 20 {              print("detected end of collection")              // fetch next batch of photos.             photostore.fetchphotosforsearchterm() {                 (photosresult) -> void in                  // calls mainthread update ui.                 nsoperationqueue.mainqueue().addoperationwithblock() {                     switch photosresult {                     case let .success(photos):                         print("successfully found \(photos.count) recent photos.")                         self.flickrphotos.appendcontentsof(photos)                     case let .failure(error):                         self.flickrphotos.removeall()                         print("error fetching more photos search term \(error)")                     }                     collectionview.reloadsections(nsindexset(index: 0))                 }             }          }         return cell     } } 

this method throws error. when navigated detail view first. staying in collection view method gets call on , on no problem:

photostore.fetchphotosforsearchterm() {                 (photosresult) -> void in                  // calls mainthread update ui.                 nsoperationqueue.mainqueue().addoperationwithblock() {                     switch photosresult {                     case let .success(photos):                         print("successfully found \(photos.count) recent photos.")                         self.flickrphotos.appendcontentsof(photos)                     case let .failure(error):                         self.flickrphotos.removeall()                         print("error fetching more photos search term \(error)")                     }                     collectionview.reloadsections(nsindexset(index: 0))                 }             } 


Comments

Popular posts from this blog

loops - Spock: How to use test data with @Stepwise -

amazon web services - S3 Pre-signed POST validate file type? -