Swift错误消息:条件绑定的初始化程序必须具有可选类型,而不是' [CLBeacon]'

时间:2015-10-08 17:38:40

标签: ios swift

在这里搜索论坛和Swift文档仍然卡住了。我跟随tutorial一起跟随整个过程很好,但现在进入最后阶段并且它发出错误说:

  

条件绑定的初始化程序必须具有可选类型,而不是' [CLBeacon]'。

我已经尝试过这里发布的所有解决方案,但仍然没有运气。对此特定教程/代码段的任何帮助都会很棒。这是代码:

//
//  ViewController.swift
//  BeaconSpot
//
//  Created by Gabriel Theodoropoulos on 10/3/15.
//  Copyright (c) 2015 Appcoda. All rights reserved.
//

import UIKit
import QuartzCore
import CoreLocation

class ViewController: UIViewController,CLLocationManagerDelegate {
    var beaconRegion: CLBeaconRegion!
    var locationManager: CLLocationManager!
    var isSearchingForBeacons = false
    var lastFoundBeacon: CLBeacon! = CLBeacon()
    var lastProximity: CLProximity! = CLProximity.Unknown

    @IBOutlet weak var btnSwitchSpotting: UIButton!
    @IBOutlet weak var lblBeaconReport: UILabel!
    @IBOutlet weak var lblBeaconDetails: UILabel!

    override func viewDidLoad() {
        super.viewDidLoad()

        locationManager = CLLocationManager()
        locationManager.delegate = self

        let uuid = NSUUID(UUIDString: "6E400001-B5A3-F393-E0A9-E50E24DCCA9E")
        beaconRegion = CLBeaconRegion(proximityUUID: uuid!, identifier: "com.appcoda.beacondemo")

        beaconRegion.notifyOnEntry = true
        beaconRegion.notifyOnExit = true

        // Do any additional setup after loading the view, typically from a nib.

        lblBeaconDetails.hidden = true
        btnSwitchSpotting.layer.cornerRadius = 30.0
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    // MARK: IBAction method implementation

    @IBAction func switchSpotting(sender: AnyObject) {
        if !isSearchingForBeacons {
            locationManager.requestAlwaysAuthorization()
            locationManager.startMonitoringForRegion(beaconRegion)
            locationManager.startUpdatingLocation()

            btnSwitchSpotting.setTitle("Stop Spotting", forState: UIControlState.Normal)
            lblBeaconReport.text = "Spotting beacons..."
        }
        else{
            locationManager.stopMonitoringForRegion(beaconRegion)
            locationManager.stopRangingBeaconsInRegion(beaconRegion)
            locationManager.stopUpdatingLocation()

            btnSwitchSpotting.setTitle("Start Spotting", forState: UIControlState.Normal)
            lblBeaconReport.text = "Not running"
            lblBeaconDetails.hidden = true
        }

        isSearchingForBeacons = !isSearchingForBeacons
    }

    func locationManager(manager: CLLocationManager, didStartMonitoringForRegion region: CLRegion) {
        locationManager.requestStateForRegion(region)
    }

    func locationManager(manager: CLLocationManager, didDetermineState state: CLRegionState, forRegion region: CLRegion) {
        if state == CLRegionState.Inside {
            locationManager.startRangingBeaconsInRegion(beaconRegion)
        }
        else {
            locationManager.stopRangingBeaconsInRegion(beaconRegion)
        }
    }

    func locationManager(manager: CLLocationManager, didEnterRegion region: CLRegion) {
        lblBeaconReport.text = "Beacon in range"
        lblBeaconDetails.hidden = false
    }

    func locationManager(manager: CLLocationManager, didExitRegion region: CLRegion) {
        lblBeaconReport.text = "No beacons in range"
        lblBeaconDetails.hidden = true
    }

    func locationManager(manager: CLLocationManager, didRangeBeacons beacons: [CLBeacon], inRegion region: CLBeaconRegion) {
        var shouldHideBeaconDetails = true

        if let foundBeacons = beacons {
            if foundBeacons.count > 0 {
                if let closestBeacon = foundBeacons[0] as? CLBeacon {
                    if closestBeacon != lastFoundBeacon || lastProximity != closestBeacon.proximity  {
                        lastFoundBeacon = closestBeacon
                        lastProximity = closestBeacon.proximity

                        var proximityMessage: String!
                        switch lastFoundBeacon.proximity {
                        case CLProximity.Immediate:
                            proximityMessage = "Very close"

                        case CLProximity.Near:
                            proximityMessage = "Near"

                        case CLProximity.Far:
                            proximityMessage = "Far"

                        default:
                            proximityMessage = "Where's the beacon?"
                        }

                        shouldHideBeaconDetails = false

                        lblBeaconDetails.text = "Beacon Details:\nMajor = " + String(closestBeacon.major.intValue) + "\nMinor = " + String(closestBeacon.minor.intValue) + "\nDistance: " + proximityMessage
                    }
                }
            }
        }

        lblBeaconDetails.hidden = shouldHideBeaconDetails
    }

    func locationManager(manager: CLLocationManager, didFailWithError error: NSError) {
        print(error)
    }

   func locationManager(manager: CLLocationManager?!, monitoringDidFailForRegion region: CLRegion!, withError error: NSError!) {
        print(error)
    }

    func locationManager(manager: CLLocationManager!, rangingBeaconsDidFailForRegion region: CLBeaconRegion!, withError error: NSError!) {
        print(error)
    }
}

1 个答案:

答案 0 :(得分:0)

您正试图安全地展开beacons,就像它是一个可选项一样:

if let foundBeacons = beacons {

但是beacons 是可选的,因为您的locationManager方法签名指定:

func locationManager(manager: CLLocationManager, didRangeBeacons beacons: [CLBeacon], inRegion region: CLBeaconRegion) {

所以beaconsCLBeacon个对象的数组:[CLBeacon],它不是可选数组。

在这种特定情况下,请不要使用if let,并直接使用beacons

func locationManager(manager: CLLocationManager, didRangeBeacons beacons: [CLBeacon], inRegion region: CLBeaconRegion) {

    var shouldHideBeaconDetails = true

    if beacons.count > 0 {

        if let closestBeacon = beacons[0] as? CLBeacon {

当然会相应调整其余的代码。