Сбой при добавлении строки из захвата регулярного выражения в приписанную строку - PullRequest
1 голос
/ 09 марта 2019

Я пытаюсь создать ссылку в атрибутивной строке, используя:

    matches = regex.matches(in: strings, options: [], range: NSRange(strings.startIndex..., in: strings))

        for match in matches {

            rangeBetweenQuotes = match.range(at: 1)

            let swiftRange = Range(rangeBetweenQuotes, in: strings)!

            let link:String = String(strings[swiftRange])

              attributedString.addAttribute(.link, value: link, range: rangeBetweenQuotes)

        }

Я знаю, что вышеизложенное работает, если я просто добавлю атрибут шрифта, а не ссылку. Так что мое регулярное выражение работает. Однако при добавлении атрибута ссылки у меня возникают проблемы. Когда я компилирую код, как написано выше, и запускаю приложение, я нажимаю на ссылку и получаю сообщение об ошибке: Поток 1: EXC_BAD_INSTRUCTION (code = EXC_I386_INVOP, subcode = 0x0. Он появляется в классе делегата приложения.

Насколько я могу судить, последние две строки кода выдают ошибку.

     let link:String = String(strings[swiftRange])

          attributedString.addAttribute(.link, value: link, range:  rangeBetweenQuotes)

Для отладки я поместил точку останова между двумя последними строками кода выше. Я вижу, что переменная link содержит правильную строку. Строка также находится в параметре value addAttribute.

Ошибка выдается во время выполнения при нажатии на ссылку. Я знаю, что это так, потому что я могу заменить или присвоить link строковым литералом, то есть "test", и ссылка работает нормально, и я могу использовать

func textView(_ textView: UITextView, shouldInteractWith URL: URL, in characterRange: NSRange) -> Bool {

для назначения строкового литерала «test» в розетку.

Используя отладчик, я обнаружил следующее, которое я нашел в раскрывающемся меню в переменной link в параметре value addAttribute.

(BridgeObject) _object = извлечение данных из значения не удалось

Это говорит о том, что с переменной что-то не так. Нет?

Я пытался использовать URL(string:"") для преобразования переменной link типа String в URL, которая тоже не работала.

Ответы [ 2 ]

0 голосов
/ 10 марта 2019

Я полагаю, что ответ касается того, совместим ли тип URL в следующей функции с любым типом, передаваемым в него.

 func textView(_ textView: UITextView, shouldInteractWith URL: URL, in characterRange: NSRange) -> Bool  

Код ниже работает без ошибок. Взгляните на URL (fileURLWithPath:)

     ... let swiftRange = Range(rangeBetweenQuotes, in: strings)!

        let link:String = String(strings[swiftRange])

          let link2 = URL(fileURLWithPath: link)

             attributedString.addAttribute(.link, value: link2, range: rangeBetweenQuotes)

Ошибка, которую я продолжал получать, не возникла из-за ошибки при выполнении функции addAttribute параметр значение , которая принимает Любой тип объекта. При отладке ошибки я обнаружил, что параметр значение в addAttribute содержит строковое значение, которое я передал в него. Как уже упоминалось выше, проблема возникла в функции:

func textView(_ textView: UITextView, shouldInteractWith URL: URL, in characterRange: NSRange) -> Bool 

, который принимает URL. Пока я пытался преобразовать строковый тип link в URL, используя

URL(string:"")

преобразование не сработало. Я продолжал получать нулевое значение, которое, конечно, выдавало ошибку при нажатии на ссылку. Тем не менее, я могу безопасно передать переменную в параметр shouldInteractWith URL: URL , когда переменная типа строки преобразуется в URL с использованием:

 URL(fileURLWithPath: link)

Я до сих пор не понимаю, почему shouldInteractWith URL: URL принимает строковый литерал, тогда как String (string [swiftRange]), supra , не работает. Есть мысли?

РЕДАКТИРОВАТЬ ... дальнейшее объяснение

Я знаю ответ, почему URL type принимает один строковый литерал, а другой - нет. Допустимый тип URL не может содержать пробел в строке. URL (fileURLWithPath:) работает, потому что он заполняет пустое пространство% 20.

Надеюсь, это поможет кому-то в будущем.

0 голосов
/ 09 марта 2019

Одной из причин может быть преобразование NSRange в Range<String.Index> и наоборот. Вам настоятельно не рекомендуется использовать string.count и обходной путь NSString.

Есть удобные API для безопасного преобразования типов

matches = regex.matches(in: string, range: NSRange(string.startIndex..., in: string))

и

let swiftRange = Range(rangeBetweenQuotes, in: string)!
let link = String(string[swiftRange])
...