Сбой подкласса XMLParser с инициализатором contentsOfURL, если нет подключения, Интернет или иным образом, для получения содержимого URL

#ios #swift #swift3 #nsxmlparser

#iOS #swift #swift3 #nsxmlparser

Вопрос:

Я пытаюсь устранить проблему, из-за которой платформа синтаксического анализа каналов (FeedKit) выходит из строя, если нет подключения для получения содержимого указанного URL (например, приложение отключено).

Итак, это работает, когда приложение подключено к Сети, и только к Сети.

Всякий раз, когда я пытаюсь создать экземпляр своего Parser класса с помощью инициализатора удобства суперкласса XMLParser

 convenience init?(contentsOf url: URL)
  

Фреймворк завершает работу:

введите описание изображения здесь

Чтобы попытаться изолировать проблему и исключить некоторые ошибки, внесенные в фреймворк, я воссоздал проблему в чистом проекте:

Решение, которое работает как шарм, используя простой ванильный XMLParser Foundation framework:

 let feedURL = URL(string: "http://images.apple.com/main/rss/hotnews/hotnews.rss")!

if let parser = XMLParser(contentsOf: feedURL) { // Works as expected
    print("Got instance (parser)")
}
  

И другой, который не работает:

 class Parser: XMLParser { }

let feedURL = URL(string: "http://images.apple.com/main/rss/hotnews/hotnews.rss")!

if let parser = Parser(contentsOf: feedURL) { // Crash!
    print("Got instance (parser)")
}
  

Во втором примере все, что я делаю, это подклассирование XMLParser класса. Никаких переопределений или пользовательского кода вообще. И он все еще завершается сбоем.

Я что-то упускаю?

Спасибо

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

Отправил в Apple отчет об ошибке с номером 28904764 и открыл радар для этой проблемы.

Я уверен, что это ошибка со стороны Apple, но предпочел бы ошибаться и иметь исправление.

Ответ №1:

Это похоже на ошибку.

Однако вы можете переопределить назначенный и удобный инициализатор XMLParser класса в Parser и реализовать свою собственную логику

 class Parser: XMLParser {
    override init(data: Data)
    {
        super.init(data: data) 
    }

    convenience init?(contentsOf url: URL){
        //return data or null examining data from url
        do{
            let data = try Data(contentsOf: url)
            self.init(data: data)

        }catch{
            return nil
        }
    }
}
  

И вызывайте как

   let feedURL = URL(string: "http://images.apple.com/main/rss/hotnews/hotnews.rss")
  if let parser = Parser(contentsOf: feedURL!){
        print("Got instance (parser)")
    }else{
        print("no data in url")
    }
  

Комментарии:

1. Уже предлагался этот подход в качестве временного решения в исходной проблеме github.com/nmdias/FeedKit/issues/4 . Я не хочу предоставлять пользовательскую реализацию инициализатора во фреймворке, поскольку это противоречит цели инициализации super. Тем временем, получил ответ от Apple с запросом журналов сбоев. Обновится, когда получит больше отзывов.

2. @nmdias в любом случае, что вы пытались узнать, отправляя вопрос? Альтернативное решение?

3. Решение проблемы. Я думаю, что обходной путь настолько хорош, насколько это возможно. Я принимаю ваш ответ.

Ответ №2:

Я думаю, что это была проблема с URL. Я попробовал использовать ваш код, я получил ошибку.

 Unable to read data
  

Я попытался заменить URL,

 feedURL = NSURL(string:"http://images.apple.com/main/rss/hotnews/hotnews.rss#sthash.fuVEonEt.dpuf")!
parser = XMLParser(contentsOf:feedURL as URL)!
parser.delegate = self
parser.parse()
  

Все работает нормально. (Я использую Swift 3)

Комментарии:

1. Я не уверен, что вы повторяете проблему. Почему вы используете NSURL? Это в Swift3? А XMLParser в вашем коде, что это? Где это определено? Если это Swift 3, не похоже, что вы используете подкласс.

2. Да … его Swift 3

3. Используете ли вы подкласс XMLParser?