Ошибка дополнительного аргумента при инициализации NSXMLDocument

Я пытаюсь создать NSXMLDocument в Swift, но я получаю "Дополнительный аргумент" contentsOfURL "в вызове, когда я пытаюсь создать свой NSXMLDocument, вот мой код:

var url = NSURL(string: "http://api.openweathermap.org/data/2.5/weather?q=\(self.cityField.stringValue)&mode=xml")
var category = NSXMLDocumentContentKind.XMLKind.rawValue
var error: NSError? = NSError()

var document = NSXMLDocument(contentsOfURL: url, options: category, error: &error)

Что я делаю неправильно? Спасибо.

РЕДАКТИРОВАТЬ: На самом деле, заменив инициализацию с этим:

var document = NSXMLDocument(contentsOfURL: url!, options: kNilOptions, error: &error)

Работает, это был прежде всего параметр параметров, который был проблематичным (а также мне пришлось развернуть URL), но теперь я не понимаю, как выбрать конкретный параметр, если я хочу? В чем здесь проблема?

2 ответа

Решение

Проверьте вывод типа для url, (Это можно сделать, щелкнув опцию по имени переменной в любом месте.) Вы найдете, что она имеет тип NSURL? (ака Optional<NSURL>) не NSURL, NSXMLDocument инициализатор init?(contentsOfURL:options:error:) требуется необязательный URL-адрес, поэтому ваш вызов этого инициализатора не проходит проверку типа... и затем выдает ложное сообщение об ошибке.

(Поскольку он не прошел проверку типа, он предполагает, что вы пытаетесь вызвать другой инициализатор... если бы это было так, ваша проблема действительно заключалась бы в том, что вы указали неверные аргументы. Возможно, стоит сообщить об ошибке.)

Вы получаете дополнительный из вашего NSURL(string:) вызов, потому что этот инициализатор неисправен. Если вы передаете строку, которая не является допустимым URL, этот инициализатор возвращает nil вместо действительного NSURL пример. Swift очень серьезно относится к тому, чтобы вы знали и правильно обрабатывали возможные нули в вашем коде, потому что в противном случае они могут вызвать проблемы для вашего приложения.

Ваше решение принудительной распаковки необязательно (путем передачи url! в NSXMLDocument) "работает" в том смысле, что он удовлетворяет компилятору: вы убедились, что значение передается NSXMLDocument не является обязательным NSURL тип. Но вы на самом деле не обрабатывали возможный ноль - если ваш URL действительно ноль, ваше приложение будет зависать на этой строке. Перед тем как использовать их, безопаснее всего тестировать опциональные значения на nil, и вам действительно следует сделать это в этом случае, потому что содержимое вашей строки может измениться во время выполнения, возможно, создав поддельный URL.

Кроме того, у вас есть несоответствие типов на options параметр также: необработанный тип NSXMLDocumentContentKind enum is UInt, но тип, ожидаемый этим параметром, Int, Вы можете конвертировать его с Int(NSXMLDocumentContentKind.XMLKind.rawValue), (Об этом определенно стоит сообщить об ошибке - интерфейсы Apple должны убедиться, что типы enum и initializer совпадают.)


Наконец, несвязанный совет: вы используете var для всего, но вы (насколько вы показали) никогда не меняете то, на что указывают ваши переменные. использование let для вещей, которые не меняются, как url, categoryи, вероятно, document (помните, вы можете иметь постоянную ссылку на изменяемый объект). Это позволяет компилятору помочь вам убедиться, что ваш код корректен, и может (по крайней мере, теоретически) помочь ему генерировать оптимизированный код также во время сборки.

Я разобрался, что не так, было две проблемы:
- Мне пришлось развернуть NSURL
- Самая большая проблема заключалась в том, что мой NSXMLDocumentContentKind.XMLKind.rawValue был UInt в то время как init ожидал Int поэтому я заменил свой код на это:

var url = NSURL(string: "http://api.openweathermap.org/data/2.5/weather?q=\(self.cityField.stringValue)&mode=xml")
var category = Int(NSXMLDocumentContentKind.XMLKind.rawValue)
var error:NSError?
var document = NSXMLDocument(contentsOfURL: url!, options: category, error: &error)

И это прекрасно работает:)

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