Отображение локального XML-файла в XCode

Мне нужно разобрать локальный XML-файл. Думаю, у меня есть все необходимое для отображения кода, проблема в его собственном разборе. У меня есть код из предыдущего проекта, который анализирует ссылку на XML-файл, однако это локальный файл с именем «Recipes.xml».

Что нужно изменить, так это функцию parseFeed(), я пробовал несколько способов проанализировать ее как локальный файл, но до сих пор не нашел решения.

XMLParser класс:

struct Recipe {
let title: String
let calories: String
let ingredients: String
}

class FeedParser: NSObject, XMLParserDelegate {
private var rssItems: [Recipe] = []
private var currentElement = ""
private var currentTitle: String = "" {
    didSet {
        currentTitle =
            currentTitle.trimmingCharacters(in: CharacterSet.whitespacesAndNewlines)
    }
}
private var currentCalories: String = "" {
    didSet {
        currentCalories =
            currentCalories.trimmingCharacters(in: CharacterSet.whitespacesAndNewlines)
    }
}
private var currentIngredients: String = "" {
    didSet {
        currentIngredients =
            currentIngredients.trimmingCharacters(in: CharacterSet.whitespacesAndNewlines)

    }
}

private var parserCompletionHandler: (([Recipe]) -> Void)?

func parseFeed(url: String, completionHandler: (([Recipe]) -> Void)?) {
    self.parserCompletionHandler = completionHandler

    let request = URLRequest(url: URL(string: url)!)
    let urlSession = URLSession.shared
    let task = urlSession.dataTask(with: request) { (data, response, error) in
        guard let data = data else {
            if let error = error {
                print (error.localizedDescription)
            }
            return
        }

        /// Parse our xml data
        let parser = XMLParser(data: data)
        parser.delegate = self
        parser.parse()
    }

    task.resume()
}

// MARK: - XML Parser Delegate

func parser(_ parser: XMLParser, didStartElement elementName: String,
            namespaceURI: String?, qualifiedName qName: String?, attributes attributeDict:
    [String : String] = [:]) {
    currentElement = elementName
    if currentElement == "dish" {
        currentTitle = ""
        currentCalories = ""
        currentIngredients = ""
    }
}

func parser(_ parser: XMLParser, foundCharacters string: String) {
    switch currentElement {
    case "title": currentTitle += string
    case "calories": currentCalories += string
    case "ingredients": currentIngredients += string
    default: break
    }
}

func parser(_ parser: XMLParser, didEndElement elementName: String,
            namespaceURI: String?, qualifiedName qName: String?) {
    if elementName == "item" {
        let rssItem = Recipe(title: currentTitle, 
                              calories: currentCalories, ingredients: currentIngredients)
        self.rssItems.append(rssItem)
        print(rssItem)
    }
}

func parserDidEndDocument(_ parser: XMLParser) {
    parserCompletionHandler?(rssItems)
}

func parser(_ parser: XMLParser, parseErrorOccurred parseError: Error) {
    print(parseError.localizedDescription)
}
}

Это табличное представление, которое получает и отображает XML-файл. Здесь функция fetchData() вызывает функцию parseFeed() для возврата данных XML. Строка «Recipes.xml» в fetchData() будет ссылкой. Я знаю, что заменить его на имя локального файла не получится, это просто заполнитель.

RecipeTableViewController:

class RecipeTableViewController: UITableViewController, XMLParserDelegate {

@IBOutlet var myTableView: UITableView!

private var recipeItems: [Recipe]?

override func viewDidLoad() {
    super.viewDidLoad()

    myTableView.dataSource = self
    myTableView.delegate = self

    fetchData()

   /* if let path =  Bundle.main.url(forResource: "Recipes", withExtension: "xml") {
        if let parser = XMLParser(contentsOf: path) {
            parser.delegate = self
            parser.parse()
        }
    } */
}

private func fetchData() {
    let feedParser = FeedParser()
    feedParser.parseFeed(url:
    "Recipes.xml") { (recipeItems) in
        self.recipeItems = recipeItems

        OperationQueue.main.addOperation {
            self.tableView.reloadSections(IndexSet(integer: 0), with: .left)
        }
    }
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()

}

// Table View Delegates

override func numberOfSections(in tableView: UITableView) -> Int {
    // #warning Incomplete implementation, return the number of sections
    return 1
}

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

    guard let recipeItems = recipeItems else {
        return 0
    }

    print(recipeItems.count)
    return recipeItems.count
}

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! RecipeTableViewCell

    if let item = recipeItems?[indexPath.item] {
        cell.item = item
    }

    return cell
}

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    let Storyboard = UIStoryboard(name: "Main", bundle: nil)
    let resultsVC = Storyboard.instantiateViewController(withIdentifier: "ResultsViewController") as! ResultsViewController

    // Information to be passed to ResultsViewController

    resultsVC.getTitle = recipeItems![indexPath.row].title
    resultsVC.getIngredients = recipeItems![indexPath.row].ingredients

    // Push to next view
    self.navigationController?.pushViewController(resultsVC, animated: true)

}

override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    return 100
}

}

результаты от print(recipeItems.count) возвращает 0

добавьте print (rssItems.count) внутри parserDidEndDocument () перед обработчиком и напишите о результате

Sergey Hleb 14.04.2018 22:15

читает ошибку, в которой говорится, что значение типа "Рецепт" не имеет элемента "счетчик". Однако он все равно ничего не печатал, потому что я еще не подключил локальный файл, это моя единственная проблема. Если бы мой локальный файл был ссылкой, все бы запустилось, но это не так.

miranda 15.04.2018 19:07
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
2
259
0

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