app crashes when no iBeacon is detected - Swift iOS -


i working on app uses ibeacons cllocation , light blue bean ios sdks. if run app battery out of beacon app works well. if insert battery beacon app detects beacon , works well. problem when remove battery beacon ( or when no beacon detected or beacon out of range) app crashes , gives me following error,

fatal error: array index out of range.

i understand error coming cllocationmanagerdelegate method didrangebeacons, im not sure how prevent app crashing? code below,

func locationmanager(manager: cllocationmanager!, didrangebeacons beacons: [anyobject]!, inregion region: clbeaconregion!) {      self.listbeans = beacons;     nsnotificationcenter.defaultcenter().postnotificationname("updatebeacontableview", object: self.listbeans)      if beacons.count == 0{         println("no beacons nearby")         manager.stopupdatinglocation()         manager.stopmonitoringforregion(lightblueregion)      }else{          let knownbeacons = beacons.filter{$0.proximity != clproximity.unknown} // proximity = 0         let closestbeacon = knownbeacons[0] as! clbeacon         if(closestbeacon.proximity == lastproximity ||             closestbeacon.proximity == clproximity.unknown) {                 return;         }         lastproximity = closestbeacon.proximity;          if (knownbeacons.count > 0){              switch closestbeacon.proximity {             case clproximity.far:                 println("you far away beacon")              case clproximity.near:                 println("you near beacon")              case clproximity.immediate:                 println("you in immediate proximity of beacon")              case clproximity.unknown:                 println("the proximity of beacon unknown")              }         } else {             println("no beacons nearby")         }      } }  func locationmanager(manager: cllocationmanager!, didenterregion region: clregion!) {      /* detected every 1 second */     println("region discovered")     var enteredregion = true }  func locationmanager(manager: cllocationmanager!, didexitregion region: clregion!) {      var enteredregion = false }   func locationmanager(manager: cllocationmanager!, diddeterminestate state: clregionstate, forregion region: clregion!) {      switch state {     case clregionstate.inside:         /* in .inside case first notification         displayed when user inside region         , opens app.          second notification shown when app in background         , user enters region*/         if enteredregion == true{             message = "diddeterminestate = inside region"         }         sendlocalnotificationwithmessage(message)      case clregionstate.outside:         /* similar logic follows .outside case. should noted further beacons longer take signal propagate means may take few seconds notifications displayed when leave or enter region.*/          if enteredregion == false{             message = "diddeterminestate = outside region"         }         sendlocalnotificationwithmessage(message)      case clregionstate.unknown:         sendlocalnotificationwithmessage("diddeterminestate = unknown region")      default:         break;     } }   func beanmanagerdidupdatestate(beanmanager: ptdbeanmanager!) {      switch beanmanager.state {     case .unsupported:         var unsupportedalert = uialertcontroller(title: "error", message: "this device unsupported.", preferredstyle: uialertcontrollerstyle.alert)          unsupportedalert.addaction(uialertaction(title: "ok", style: uialertactionstyle.default, handler: nil))          self.presentviewcontroller(unsupportedalert, animated: true, completion: nil)      case .poweredoff:          var ppoweredoffalert = uialertcontroller(title: "error", message: "please turn on bluetooth.", preferredstyle: uialertcontrollerstyle.alert)          ppoweredoffalert.addaction(uialertaction(title: "ok", style: uialertactionstyle.default, handler: nil))          self.presentviewcontroller(ppoweredoffalert, animated: true, completion: nil)      case .poweredon:         beanmanager.startscanningforbeans_error(nil);     default:         break     } }  func beanmanager(beanmanager: ptdbeanmanager!, diddiscoverbean bean: ptdbean!, error: nserror!) {      self.beanname = bean.name string     self.beanuuidnum = bean.identifier.description } 

thanks

update:

i ended following code,

let knownbeacons:anyobject? = beacons.filter{$0.proximity != clproximity.unknown} // proximity = 0      if let knownbeacons_:anyobject = knownbeacons {          if knownbeacons_.count == 0 {             return         }      if let closestbeacon = knownbeacons_[0] as? clbeacon{             if(closestbeacon.proximity == lastproximity ||                 closestbeacon.proximity == clproximity.unknown) {                     return;             }             lastproximity = closestbeacon.proximity;              if (knownbeacons_.count > 0){                  switch closestbeacon.proximity {                 case clproximity.far:                     println("you far away beacon")                  case clproximity.near:                     println("you near beacon")                  case clproximity.immediate:                     println("you in immediate proximity of beacon")                  case clproximity.unknown:                     println("the proximity of beacon unknown")                  }             } else {                 println("no beacons nearby")             }         }else{             println("no beacons nearby")             manager.stopupdatinglocation()             manager.stopmonitoringforregion(lightblueregion)           }       } 

if knownbeacons empty, code crash. before trying access knownbeacons[0], need check whether or not array empty. try wrapping more code in if (knownbeacons.count > 0) block more safety, this.

    let knownbeacons = beacons.filter{$0.proximity != clproximity.unknown} // proximity = 0      if (knownbeacons.count > 0){          let closestbeacon = knownbeacons[0] as! clbeacon         if(closestbeacon.proximity == lastproximity || closestbeacon.proximity == clproximity.unknown) {             return;         }         lastproximity = closestbeacon.proximity;           switch closestbeacon.proximity {         case clproximity.far:             println("you far away beacon")          case clproximity.near:             println("you near beacon")          case clproximity.immediate:             println("you in immediate proximity of beacon")          case clproximity.unknown:             println("the proximity of beacon unknown")          }     } 

Comments

Popular posts from this blog

yii2 - Yii 2 Running a Cron in the basic template -

asp.net - 'System.Web.HttpContext' does not contain a definition for 'GetOwinContext' Mystery -

mercurial graft feature, can it copy? -