Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Subclass of XMLParser crashes with the contentsOfURL initializer if there isn't connectivity, Internet or otherwise, to get the contents of the URL

I'm trying to sort out an issue where a feed parsing framework (FeedKit) crashes if there is no connectivity to get the contents of the specified URL (e.g. the app is offline).

So, it works when the App is online, and online only.

Whenever I try to instantiate my Parser class with the convenience initializer of the superclass XMLParser

convenience init?(contentsOf url: URL)

The framework crashes:

enter image description here

In order to try and isolate the problem, and exclude some error introduced in the framework, I have recreated the issue in a clean project:

A solution that works like a charm, using a plain vanilla XMLParser of the 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)")
}

And another that doesn't:

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)")
}

In the second example, all I'm doing is subclassing the XMLParser class. No overrides or custom code whatsoever. And it still crashes.

Am I missing something?

Thank you

Edit:

Submitted a bug report to Apple with number 28904764 and opened up a Radar to this issue.

I'm confident that this is a bug on Apple's end, but would prefer to be wrong and have a fix.

like image 689
nmdias Avatar asked Oct 22 '16 15:10

nmdias


1 Answers

This looks like a bug.

However, you can override the designated and convenience initializer of XMLParser class in Parser and implement your own logic

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
        }
    }
}

And call as

  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")
    }
like image 176
Anish Parajuli 웃 Avatar answered Nov 08 '22 13:11

Anish Parajuli 웃