Что находится внутри URLComponents.queryItems. Как изменить свои данные в ForEach.onDelete - PullRequest
0 голосов
/ 10 июля 2020

Я пытаюсь сделать приложение API Tester спокойным. в моей модели хранилось несколько свойств , протокол схемы, например «http», , хост, например «www.google.com», путь, например «/ search», и параметр запроса, например «? q = keyword».

Когда я меняю источник данных в List.ForEach.onDelete {}. Это cra sh. И консоль показывает ошибку ниже :

Неустранимая ошибка: индекс вне допустимого диапазона: файл /AppleInternal/BuildRoot/Library/Caches/com.apple.xbs/Sources/swiftlang/swiftlang-1103.8.25.8/swift/stdlib/ public / core / ContiguousArrayBuffer.swift, строка 444

Я почти уверен, что мой код не является проблемой ниже. Если вы обнаружите ошибку в моем коде, сообщите мне.

class URLComponentsModel: ObservableObject {
    @Published var urlComponents = URLComponents.init()        
    ...
    var urlString: String {
        get {
            return urlComponents.string ?? ""
        }
        set {
            guard !newValue.isEmpty else {
                return
            }
            urlComponents = URLComponents.init(string: newValue) ?? urlComponents
        }
    }
    var host: String {
        get {
            return urlComponents.host ?? ""
        }
        set {
            urlComponents.host = newValue
        }
    }
    var urlQueryItems: [URLQueryItem] {
        get {
            urlComponents.queryItems ?? [URLQueryItem].init()
        }
        set {
            urlComponents.queryItems = newValue
        }
    }
    ...    
}

struct APIView: View {
    @ObservedObject var urlComponentsModel = URLComponentsModel.init()
    var body: some View {
        ...
        QueryParametersView.init(urlComponentsModel: self.urlComponentsModel)
        ...
    }
}

struct QueryParametersView: View {
    @ObservedObject var urlComponentsModel: URLComponentsModel    
    var body: some View {
        ...
        EditButton.init()
        List.init {
                ForEach.init(self.urlComponentsModel.urlQueryItems.indices, id: \.self) { index in
                    ParameterView.init(urlQueryItem: self.$urlComponentsModel.urlQueryItems[index])
                }
                .onDelete { (indexSet) in
                    guard !self.urlComponentsModel.urlQueryItems.isEmpty && self.urlComponentsModel.urlQueryItems.count > 0 else {
                        return
                    }
                    indexSet.forEach { index in
                        guard index < self.urlComponentsModel.urlQueryItems.count else {
                            return
                        }
                        self.urlComponentsModel.urlQueryItems.remove(at: index)
                    }
                }
            }
    }
}

struct ParameterView: View {
    @Binding var urlQueryItem: URLQueryItem
    var body: some View {
        ZStack {
            ...
            HStack {
                ...
                if self.urlQueryItem.value != nil {
                    TextField("Value", text: Binding.init(get: {
                        (self.urlQueryItem.value ?? "")
                    }, set: { (value) in
                        self.urlQueryItem.value = value
                    }))
                }
            }
        }
    }
}

Странно, если мое свойство модели URLComponents.queryItems в URLComponentsModel заменить массивом другого источника данных , это сработает. Наконец , Я прочитал документацию URLComponents.queryItems , Думаю, это может быть связано с URLComponents.queryItems. Но я до сих пор не знаю, что не так с моим кодом. Кто угодно может мне помочь? Это документация по URLComponents.queryItems. Декларация ниже :

Каждый URLQueryItem представляет одну пару ключ-значение,

Обратите внимание, что имя может появляться более одного раза в одной строке запроса , поэтому уникальность значений имени не гарантируется. Если URLComponents имеет пустой компонент запроса, возвращает пустой массив. Если URLComponents не имеет компонента запроса, возвращается nil.

Установщик объединяет массив, содержащий любое количество URLQueryItems, каждый из которых представляет одну пару ключ-значение, в строку запроса и устанавливает свойство запроса URLComponents. Передача пустого массива устанавливает компонент запроса URLComponents в пустую строку. Передача nil удаляет компонент запроса URLComponents.

Примечание

Если пара имя-значение в запросе пуста (т.е. строка запроса начинается с '&', заканчивается на '&' или содержит «&&»), вы получите URLQueryItem с именем нулевой длины и значением nil. Если в паре "имя-значение" запроса нет ничего перед знаком равенства, вы получаете имя нулевой длины. Если в паре «имя-значение» после знака равенства ничего не указано, вы получите значение нулевой длины. Если пара имя-значение запроса не имеет знака равенства, строка пары имя-значение запроса представляет собой имя, и вы получаете нулевое значение.

...