Ошибка подкласса CLBeacon

Я хочу передать дополнительную информацию через CLBeacon поэтому я создаю подкласс этого называется CLBeaconExtender, проблема во время выполнения кода, это дает мне эту ошибку

Элемент NSArray не соответствует типу элемента Swift Array

это код:


Подкласс CLBeacon

class CLBeaconExtender: CLBeacon{
    var id: String!
}

MainClass

class beaconController_1: UIViewController, CLLocationManagerDelegate {

    var beacon_collection: UICollectionView!
    var location_manager = CLLocationManager()
    var beacon_manager = [CLBeaconExtender]()
    var beacon_region = [CLBeaconRegion]()

  // Other code that i don't paste

  func locationManager(_ manager: CLLocationManager, didRangeBeacons beacons: [CLBeacon], in region: CLBeaconRegion) {
        if !beacons.isEmpty {
            beacon_manager = beacons as! [CLBeaconExtender]
            beacon_manager[0].id = "hello world"  // here appear the error
            beacon_collection.reloadData()
        }
        else{
            if beacon_manager.count != 0 {
                beacon_manager = beacons as! [CLBeaconExtender]
                beacon_collection.reloadData()
            }
        }
    }

Кто-нибудь может решить эту проблему или показать пример?

редактировать

я думаю, что ошибка вызвана этой строкой:

beacon_manager = beacons as! [CLBeaconExtender]

Редактировать 2

Извините за мой английский, моя цель - создать collectionview которые отображают все маяки вокруг меня, и обновляют список каждый раз, когда didRangBeacons называется, кроме того, каждый collectionviewcell должен содержать определенный аудиофайл со ссылкой на соответствующий маяк. Поэтому, когда я нажимаю на определенную ячейку определенного маяка, он начинает воспроизводить определенный звук. Моя проблема - справиться с beacon_manager массив. В первом цикле didRangeBeacons все идет хорошо, потому что !beacon_manager.indices.contains(i) вернуть !false поэтому он выполнит if состояние, и оно будет заполнять все beacon_manager, чем во втором цикле didRangeBeacons условие if вернется !true поэтому исполняемый код будет else состояние. здесь происходит сбой системы beacon_manager.remove(at: i) где i 0 и beacon_manager[0] существует.

сбой показывает мне класс AppDelegate с ошибкой:

Код EXEC_BAD_ACCESS =1 адрес = 0x8

Надеюсь, вы поймете это сейчас.

   func locationManager(_ manager: CLLocationManager, didRangeBeacons beacons: [CLBeacon], in region: CLBeaconRegion) {
    if !beacons.isEmpty {
        var i = 0
        for beacon in beacons {
            let bx = CLBeaconExtender(b: beacon, sID: "hello world")
            if(!beacon_manager.indices.contains(i)){  //check if beacon_manager array exist at i if no create it, if yes update it
                beacon_manager.insert(bx, at: i)
            }
            else{
                beacon_manager.remove(at: i)
                beacon_manager.insert(bx, at: i)

            }
            print(beacon_manager[i].id)
            i+=1
        }

        print(beacon_manager.count,beacons.count)
        beacon_collection.reloadData()
    }
    else{
        if beacon_manager.count != 0 {
            //do other things
        }
    }
}

2 ответа

Решение

Вы не можете просто сказать "этот объект теперь другого типа" и волшебным образом изменить объект. Например:

    let x = UIView()
    let y = x as! UIImageView

Если вы попытаетесь запустить эти две строки, вы получите ошибку вроде:

Не удалось преобразовать значение типа "UIView" (0x107fa44c0) в "UIImageView" (0x107fa5c08).

Итак, вот что вы пытаетесь сделать здесь:

beacon_manager = beacons as! [CLBeaconExtender]

Вы говорите: "Я объявляю, что этот NSArray объектов CLBeacon теперь является массивом объектов CLBeaconExtender!" и все просто так не работает.

Один из подходов к тому, что вы пытаетесь сделать, - это определить класс CLBeaconExtender следующим образом:

class CLBeaconExtender: CLBeacon {
    var id: String!
    var bcn: CLBeacon!

    convenience init(b: CLBeacon, sID: String) {
        self.init()
        bcn = b
        id = sID
    }
}

Тогда в вашем didRangeBeacons функция:

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

    for beacon in beacons {
        let bx = CLBeaconExtender(b: beacon, sID: "hello world")
        beacon_manager.append(bx)
    }

    // other code...
}

Конечно, вы не захотите этого делать, так как в конечном итоге вы добавите множество одного и того же объекта маяка с идентификатором "hello world". Но, надеюсь, это поможет вам понять ошибку, которую вы получили, и поможет вам исправить ее.

Проблема с типом: -

1) Array является структурой, следовательно, это тип значения в Swift.

2) NSArray является неизменным классом Objective-C, следовательно, это ссылочный тип.

Другие вопросы по тегам