Swift - чтение вложенных структур с помощью цикла for - PullRequest
0 голосов
/ 04 сентября 2018

Я пытаюсь читать вложенные структуры с циклом for в моем проекте BLE. Основная цель - обновить глобальную структуру новыми значениями из моего периферийного устройства. Всего у меня может быть 60 атрибутов, поэтому использование цикла мне очень поможет.

Структуры:

/* -----------------------------------------------------------------------------
 Attributes structure
 ----------------------------------------------------------------------------- */
struct IthetisAttribute
{
    let UUID: String
    let Length: UInt8
    let Service: String
    var Value: UInt32
}

/* -----------------------------------------------------------------------------
 Pump state profile
 ----------------------------------------------------------------------------- */
struct IthetisPump_state
{
    /* Steps from start: 0xFFF1 and 3 byte */
    static var StepsFromStart : IthetisAttribute =
        IthetisAttribute(UUID: "FFF1", Length: 3,
                         Service: IthetisConstant.STATE_SERVICE_UUID, Value: 0)

    /* Steps of current dose : 0xFFF2 and 3 byte */
    static var StepsCurrent : IthetisAttribute =
        IthetisAttribute(UUID: "FFF2", Length: 3,
                         Service: IthetisConstant.STATE_SERVICE_UUID, Value: 0)

/* ... */ 
}

Теперь я пытаюсь извлечь структуры атрибутов из IthetisPump_state, чтобы проверить UUID. Сначала я попробовал что-то подобное:

for attr: IthetisAttribute in IthetisPump_state
{
    /* ... */
}

Но это не работает, очевидно. Поэтому я попробовал что-то еще:

let Profile = IthetisPump_state()
for attr: IthetisAttribute in Mirror(reflecting: Profile).children
{
    /* ... */
}

Xcode сообщает мне, что Mirror.child не конвертируется в атрибут Ithetis. Я пробовал несколько других техник, но всегда получаю ошибку.

Как лучше всего пройти через вложенные структуры? Заранее спасибо!

- Обновление, после ответа Лоренцо ---

Я попробовал так: я создал новую структуру с массивами (она работала, но затем я попытался использовать указатели)

struct IthetisPump_profiles
{
    /* State profile */
    static var State: [UnsafePointer<IthetisAttribute>] =
    [
        &IthetisPump_state.StepsFromStart,
        &IthetisPump_state.StepsCurrent,
        /* ... */
    ]
}

В моем основном коде теперь я использую что-то вроде этого:

var Attribute_counter = 0
for attr: IthetisAttribute in IthetisPump_profiles.State
{
    if characteristic.uuid.description.isEqual(attr.UUID)
    {
        let temp: UInt32 = SharedMethods.ConvertDataToUInt32(characteristic.value!,
                                                             byteLength:attr.Length)

        IthetisPump_profiles.State[Attribute_counter].Value = temp

        if(attr.UUID == "FFF1")
        {
            print("UUID \(IthetisPump_state.StepsFromStart.UUID)
                value is \(IthetisPump_state.StepsFromStart.Value)")
            print("UUID \(IthetisPump_profiles.State[0].UUID)
                value is \(IthetisPump_profiles.State[0].Value)")
        }
    }
    Attribute_counter = Attribute_counter + 1
}

Первая строка (с state.StepsFromStart) дает мне 0, а другая (с State [0]) дает правильное число. Я могу использовать перечисление, потому что это просто, но как я могу реализовать решение с указателями? Еще раз спасибо!

1 Ответ

0 голосов
/ 04 сентября 2018

Добро пожаловать на SO. Прежде всего вы смешали static с объявлениями экземпляров. Я бы немного изменился.

По вашему вопросу вы можете использовать KVC. Вот простой пример:

struct IthetisAttribute {
    let UUID: String
    let length: UInt8
    let service: String
    var value: UInt32
}

struct IthetisPump_state {
    let states = [
        IthetisAttribute(UUID: "1", length: 9, service: "", value: 1),
        IthetisAttribute(UUID: "2", length: 9, service: "", value: 1),
        IthetisAttribute(UUID: "3", length: 9, service: "", value: 1),
        IthetisAttribute(UUID: "4", length: 9, service: "", value: 1),
        IthetisAttribute(UUID: "5", length: 9, service: "", value: 1)
    ]
}

let pump = IthetisPump_state()    
for i in 0..<pump.states.count {
    print(pump[keyPath:\IthetisPump_state.states[i].UUID])
}

Если вам нужно обработать что-то более сложное, вы можете использовать enum со связанными значениями.

Дайте мне знать, что угодно.

P.S. Переменная экземпляра должна иметь начальные строчные буквы. например service вместо Service

...