我有一个主题标签解析器 UITextView 扩展,可以将前面带有“#”的任何单词转换为可点击的蓝色链接。除了点击阿拉伯语主题标签时,它工作正常。
extension UITextView {
func resolveHashAndMentionTags(){
// turn string in to NSString
let nsText:NSString = self.text as NSString
// this needs to be an array of NSString. String does not work.
let words:[NSString] = nsText.components(separatedBy: " ") as [NSString]
// you can't set the font size in the storyboard anymore, since it gets overridden here.
let attrs = [
NSAttributedStringKey.font : UIFont(name: "Avenir-Light", size: 14.0)!//UIFont.systemFont(ofSize: 13.0)
]
// you can staple URLs onto attributed strings
let attrString = NSMutableAttributedString(string: nsText as String, attributes:attrs)
// tag each word if it has a hashtag or mention
for word in words {
// found a word that is prepended by a hashtag!
if word.hasPrefix("#") {
// a range is the character position, followed by how many characters are in the word.
// we need this because we staple the "href" to this range.
let matchRange:NSRange = nsText.range(of: word as String)
// convert the word from NSString to String
// this allows us to call "dropFirst" to remove the hashtag
var stringifiedWord:String = word as String
// drop the hashtag
stringifiedWord = String(stringifiedWord.dropFirst())
print(stringifiedWord)
attrString.addAttribute(NSAttributedStringKey.link, value: "hash://\(stringifiedWord)", range: matchRange)
// }
} else if word.hasPrefix("@") {
// a range is the character position, followed by how many characters are in the word.
// we need this because we staple the "href" to this range.
let matchRange:NSRange = nsText.range(of: word as String)
// convert the word from NSString to String
// this allows us to call "dropFirst" to remove the mention@
var stringifiedWord:String = word as String
// drop the hashtag
stringifiedWord = String(stringifiedWord.dropFirst())
attrString.addAttribute(NSAttributedStringKey.link, value: "mention://\(stringifiedWord)", range: matchRange)
// }
}
}
// we're used to textView.text
// but here we use textView.attributedText
// again, this will also wipe out any fonts and colors from the storyboard,
// so remember to re-add them in the attrs dictionary above
self.attributedText = attrString
}
然后在我的帖子单元格中调用 UITextViewDelegate功能。
func textView(_ textView: UITextView, shouldInteractWith URL: URL, in characterRange: NSRange) -> Bool {
let path = URL.absoluteString
switch URL.scheme! {
case "hash" :
let hash = path.removingPercentEncoding?.components(separatedBy: "://").last
print(hash!) // ---> Retriving tapped on hash name correctly
delegate?.hashTableViewCell(self, shouldSelectTag: hash!)
case "mention" :
let mention = path.removingPercentEncoding?.components(separatedBy: "://").last
print(mention!) // ---> Retriving tapped on mention name correctly
delegate?.mentionTableViewCell(self, shouldSelectTag: mention!, userId: nil)
default:
print("Just a regular link \(path.removingPercentEncoding!)")
}
return true
}
正如我上面提到的代码,它对英文字母工作正常,但是当点击阿拉伯语标签或提及它时,它会在 AppDelegate 中崩溃。 .
Thread 1: EXC_BREAKPOINT (code=1, subcode=0x1030fcb94)
我尝试使用断点进行调试以了解错误的确切位置,但实际上我发现它甚至在进入 UITextViewDelegate 之前就崩溃了。功能。所以现在我完全不知道错误可能在哪里。
也许在 UITextView 中使用阿拉伯字母作为链接可能存在某种问题?
这是堆栈跟踪。
- thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BREAKPOINT (code=1, subcode=0x1030fcb94) frame #0: 0x00000001030fcb94 libswiftFoundation.dylib
function signature specialization <Arg[0] = Owned To Guaranteed, Arg[1] = Dead> of static Foundation.URL._unconditionallyBridgeFromObjectiveC(Swift.Optional<__ObjC.NSURL>) -> Foundation.URL + 288 frame #1: 0x0000000103045f24 libswiftFoundation.dylibstatic Foundation.URL._unconditionallyBridgeFromObjectiveC(Swift.Optional<__ObjC.NSURL>) -> Foundation.URL + 20 frame #2: 0x0000000101199c68 OOL@objc PostTableViewCell.textView(_:shouldInteractWith:in:) at PostTableViewCell.swift:0 frame #3: 0x000000018e1e397c UIKit-[_UITextViewInteractableLink allowInteraction:] + 360 frame #4: 0x000000018e1e2698 UIKit-[_UITextViewInteractableItem handleTap] + 40 frame #5: 0x000000018db64548 UIKit-[UITextGestureClusterLinkInteract smallDelayRecognizer:] + 296 frame #6: 0x000000018db7ccd0 UIKit-[UIGestureRecognizerTarget _sendActionWithGestureRecognizer:] + 64 frame #7: 0x000000018db812c4 UIKit_UIGestureRecognizerSendTargetActions + 124 frame #8: 0x000000018d659aa8 UIKit_UIGestureRecognizerSendActions + 320 frame #9: 0x000000018d510c38 UIKit-[UIGestureRecognizer _updateGestureWithEvent:buttonEvent:] + 732 frame #10: 0x000000018db6ab34 UIKit_UIGestureEnvironmentUpdate + 1084 frame #11: 0x000000018db6a6a4 UIKit-[UIGestureEnvironment _deliverEvent:toGestureRecognizers:usingBlock:] + 404 frame #12: 0x000000018db69800 UIKit-[UIGestureEnvironment _updateGesturesForEvent:window:] + 276 frame #13: 0x000000018d50ef44 UIKit-[UIWindow sendEvent:] + 3180 frame #14: 0x000000018d4dff64 UIKit-[UIApplication sendEvent:] + 340 frame #15: 0x000000018de3531c UIKit__dispatchPreprocessedEventFromEventQueue + 2364 frame #16: 0x000000018de378a8 UIKit__handleEventQueueInternal + 4760 frame #17: 0x000000018de307c0 UIKit__handleHIDEventFetcherDrain + 152 frame #18: 0x0000000183fa697c CoreFoundation__CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 24 frame #19: 0x0000000183fa68fc CoreFoundation__CFRunLoopDoSource0 + 88 frame #20: 0x0000000183fa6184 CoreFoundation__CFRunLoopDoSources0 + 204 frame #21: 0x0000000183fa3d5c CoreFoundation__CFRunLoopRun + 1048 frame #22: 0x0000000183ec3e58 CoreFoundationCFRunLoopRunSpecific + 436 frame #23: 0x0000000185d70f84 GraphicsServicesGSEventRunModal + 100 frame #24: 0x000000018d54367c UIKit`UIApplicationMain + 236
- frame #25: 0x0000000101063348 OOL
main at AppDelegate.swift:22 frame #26: 0x00000001839e056c libdyld.dylibstart + 4
最佳答案
我猜可能是问题所在(标签或哈希)...
你这样做:
attrString.addAttribute(NSAttributedStringKey.link, value: "hash://\(stringifiedWord)", range: matchRange)
但是如果你使用一个 URL 对象 (let url = URL.init(string:"hash://\(stringifiedWord)")) 你你会看到它可能是 nil 如果字符串 url 无效,在你的情况下阿拉伯字符似乎无效。
委托(delegate)方法 func textView(_ textView: UITextView, shouldInteractWith URL: URL, in characterRange: NSRange) -> Bool 在参数中给出一个 URL 对象,并且因为当您没有有效的 url 时不会调用您的方法,所以我猜 Apple 代码中的内线假设它是一个有效的 url,不检查它并崩溃。这可以解释为什么你的方法在进入你的方法之前没有被调用并崩溃。
解决方案:使用百分比转义字符。
不要放置 value: "hash://\(stringifiedWord)",而是执行 value: "hash://\(stringifiedWord.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed))" 或其他允许的字符集。
在委托(delegate)方法中,您已经删除了转义百分比:let hash = path.removingPercentEncoding?.components(separatedBy: "://").last 因此您不必添加那里有任何东西。
补充说明:
你正在做 if word.hasPrefix("#") 和 `if word.hasPrefix("@") 几乎是同一件事(只是方案改变),你可以简化/分解,示例代码未测试:
let dict = ["#":"mention://", "@": "hash://"]
for (key, value) in dict
{
if word.hasPrefix(key)
{
let matchRange:NSRange = nsText.range(of: word as String)
var stringifiedWord:String = word as String
stringifiedWord = String(stringifiedWord.dropFirst(key.count))
let espcapedWord = stringifiedWord.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed
let stringURL = "\(value)\(escapedWord)"
if let url = URL.init(string:stringURL) //That should you avoid any crash just in case
{
attrString.addAttribute(.link, value: stringURL, range: matchRange)
}
else
{
print("Oooops with \(stringifiedWord) invalid URL: \(stringURL)")
}
}
}
编辑:根据 iOS 版本(在模拟器上测试),它可能会崩溃,或者因为无效的 URL 而根本不调用委托(delegate)方法。
关于ios - 阿拉伯语的标签会使应用程序崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48154641/
我需要在客户计算机上运行Ruby应用程序。通常需要几天才能完成(复制大备份文件)。问题是如果启用sleep,它会中断应用程序。否则,计算机将持续运行数周,直到我下次访问为止。有什么方法可以防止执行期间休眠并让Windows在执行后休眠吗?欢迎任何疯狂的想法;-) 最佳答案 Here建议使用SetThreadExecutionStateWinAPI函数,使应用程序能够通知系统它正在使用中,从而防止系统在应用程序运行时进入休眠状态或关闭显示。像这样的东西:require'Win32API'ES_AWAYMODE_REQUIRED=0x0
对于具有离线功能的智能手机应用程序,我正在为Xml文件创建单向文本同步。我希望我的服务器将增量/差异(例如GNU差异补丁)发送到目标设备。这是计划:Time=0Server:hasversion_1ofXmlfile(~800kiB)Client:hasversion_1ofXmlfile(~800kiB)Time=1Server:hasversion_1andversion_2ofXmlfile(each~800kiB)computesdeltaoftheseversions(=patch)(~10kiB)sendspatchtoClient(~10kiBtransferred)Cl
Rackup通过Rack的默认处理程序成功运行任何Rack应用程序。例如:classRackAppdefcall(environment)['200',{'Content-Type'=>'text/html'},["Helloworld"]]endendrunRackApp.new但是当最后一行更改为使用Rack的内置CGI处理程序时,rackup给出“NoMethodErrorat/undefinedmethod`call'fornil:NilClass”:Rack::Handler::CGI.runRackApp.newRack的其他内置处理程序也提出了同样的反对意见。例如Rack
我想用ruby编写一个小的命令行实用程序并将其作为gem分发。我知道安装后,Guard、Sass和Thor等某些gem可以从命令行自行运行。为了让gem像二进制文件一样可用,我需要在我的gemspec中指定什么。 最佳答案 Gem::Specification.newdo|s|...s.executable='name_of_executable'...endhttp://docs.rubygems.org/read/chapter/20 关于ruby-在Ruby中编写命令行实用程序
为了将Cucumber用于命令行脚本,我按照提供的说明安装了arubagem。它在我的Gemfile中,我可以验证是否安装了正确的版本并且我已经包含了require'aruba/cucumber'在'features/env.rb'中为了确保它能正常工作,我写了以下场景:@announceScenario:Testingcucumber/arubaGivenablankslateThentheoutputfrom"ls-la"shouldcontain"drw"假设事情应该失败。它确实失败了,但失败的原因是错误的:@announceScenario:Testingcucumber/ar
我构建了两个需要相互通信和发送文件的Rails应用程序。例如,一个Rails应用程序会发送请求以查看其他应用程序数据库中的表。然后另一个应用程序将呈现该表的json并将其发回。我还希望一个应用程序将存储在其公共(public)目录中的文本文件发送到另一个应用程序的公共(public)目录。我从来没有做过这样的事情,所以我什至不知道从哪里开始。任何帮助,将不胜感激。谢谢! 最佳答案 无论Rails是什么,几乎所有Web应用程序都有您的要求,大多数现代Web应用程序都需要相互通信。但是有一个小小的理解需要你坚持下去,网站不应直接访问彼此
我尝试运行2.x应用程序。我使用rvm并为此应用程序设置其他版本的ruby:$rvmuseree-1.8.7-head我尝试运行服务器,然后出现很多错误:$script/serverNOTE:Gem.source_indexisdeprecated,useSpecification.Itwillberemovedonorafter2011-11-01.Gem.source_indexcalledfrom/Users/serg/rails_projects_terminal/work_proj/spohelp/config/../vendor/rails/railties/lib/r
我试图使用yard记录一些Ruby代码,尽管我所做的正是所描述的here或here#@param[Integer]thenumberoftrials(>=0)#@param[Float]successprobabilityineachtrialdefinitialize(n,p)#initialize...end虽然我仍然得到这个奇怪的错误@paramtaghasunknownparametername:the@paramtaghasunknownparametername:success然后生成的html看起来很奇怪。我称yard为:$yarddoc-mmarkdown我做错了什么?
刚入门rails,开始慢慢理解。有人可以解释或给我一些关于在application_controller中编码的好处或时间和原因的想法吗?有哪些用例。您如何为Rails应用程序使用应用程序Controller?我不想在那里放太多代码,因为据我了解,每个请求都会调用此Controller。这是真的? 最佳答案 ApplicationController实际上是您应用程序中的每个其他Controller都将从中继承的类(尽管这不是强制性的)。我同意不要用太多代码弄乱它并保持干净整洁的态度,尽管在某些情况下ApplicationContr
当我在Rails控制台中按向上或向左箭头时,出现此错误:irb(main):001:0>/Users/me/.rvm/gems/ruby-2.0.0-p247/gems/rb-readline-0.4.2/lib/rbreadline.rb:4269:in`blockin_rl_dispatch_subseq':invalidbytesequenceinUTF-8(ArgumentError)我使用rvm来管理我的ruby安装。我正在使用=>ruby-2.0.0-p247[x86_64]我使用bundle来管理我的gem,并且我有rb-readline(0.4.2)(人们推荐的最少