TLDR当我将电话号码硬编码到URL中时,它会在监视消息中正确打开,但当我使用一个变量字符串,其中的数字键入方式完全相同时,它不会。
示例:
NSURL(string: "sms:/open?addresses=8888888888,9999999999,3333333333&body=Test")
以上代码有效,但以下代码无效:
let hardCode = "8888888888,9999999999,3333333333"
NSURL(string: "sms:/open?addresses=(hardCode)&body=Test")
详细信息:我正在从变量中创建一个URL,以便在Apple Watch上打开预先填充内容的消息。我正在从通讯录中获取电话号码,并将其存储在一个数组中。它们以以下格式提供:
(####)###-####但需要##########
我通过将电话号码硬编码到URL中来测试代码,它可以与所有联系人和完整的正文一起正常工作:
if let urlSafeBody = urlSafeBody, url = NSURL(string: "sms:/open?addresses=8888888888,9999999999,3333333333&body=(urlSafeBody)") {
print("FINAL URL: (url)")
WKExtension.sharedExtension().openSystemURL(url)
}
但当我以编程方式构建电话号码值时,它不起作用:
//holds phone numbers without special chars
var tempArray: [String] = []
//if I can access the unformatted numbers
if let recips = saveData["recips"] as? [String] {
//for each number provided
recips.forEach { (person: String) in
//remove all non-numerical digits
//person is now (###) ###-####
let newPerson = person.digitsOnly()
//newPerson is ##########
print(person)
print("->(newPerson)")
//add formatted number to tempArray
tempArray.append(newPerson)
}
}
//combine all numbers with "," between as a string
let recipString = tempArray.joinWithSeparator(",")
//recipString contains ##########,##########,##########...
extension String {
func digitsOnly() -> String{
let stringArray = self.componentsSeparatedByCharactersInSet(
NSCharacterSet.decimalDigitCharacterSet().invertedSet)
let newString = stringArray.joinWithSeparator("")
return newString
}
}
然后,我在下面的代码中将"recipString"变量添加到NSURL中:
let messageBody = "test"
let urlSafeBody = messageBody.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLHostAllowedCharacterSet())
if let urlSafeBody = urlSafeBody, url = NSURL(string: "sms:/open?addresses=(recipString)&body=(urlSafeBody)") {
print("FINAL URL: (url)")
WKExtension.sharedExtension().openSystemURL(url)
}
FINAL URL打印显示正确的字符串,但消息应用程序无法正确打开,并显示快速回复菜单,而不是合成消息窗口。它与正常工作的硬编码数字版本完全匹配,但行为不同。
完全迷路了,希望有人能帮忙!
更新1以下是URL的两个版本的调试打印:
手动声明(不是从recipString创建的,而是在URL字符串中显式声明的):
此版本适用于
最终网址:sms:/open?地址=0000000001111111122222222333333333344444444&body=测试
创建的变量(使用recipString):
这个版本没有
最终网址:sms:/open?地址=0000000001111111122222222333333333344444444&body=测试
我还尝试过使用下面的iflet将url编码应用于"recipString"变量:
if let urlSafeRecip = recipString.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLQueryAllowedCharacterSet()) {
if let urlSafeBody = urlSafeBody, url = NSURL(string: "sms:/open?addresses=(urlSafeRecip)&body=(urlSafeBody)") {
print("FINAL URL: (url)")
WKExtension.sharedExtension().openSystemURL(url)
}
}
更新2我通过以下代码测试了数字的硬编码版本是否与recipString完全匹配:
let hardCode = "0000000000,1111111111,2222222222,3333333333,4444444444"
let isEqual = (hardCode == recipString)
if isEqual {
print("hardCode matches recipString")
}
else {
print("hardCode does not match recipString")
}
调试打印:
hardCode与recipString 匹配
更新3
我已经确认:
当URL是用硬编码的数字与我从变量中生成的数字进行比较时,在它们之间检查==将返回true。
在我能在两个版本的url之间进行的每一次测试中,它都是匹配的。
找到正确答案后的注意事项:
这种类型的URL格式仅适用于URL中的多个地址。如果你没有多个地址,你需要做以下操作,这是没有记录的,但仍然有效。我在键盘上敲了几个小时的脸才发现这一点,所以如果这对你有帮助,那就应该得到支持票:)
按照下面标记的答案,然后在他提到的doItButton()函数中生成URL之前使用这种类型的逻辑检查:
func setupAndSendMsg(saveData: NSDictionary) {
if let urlSafeBody = createBody(saveData) {
let theNumbers = createNumbers(saveData).componentsSeparatedByString(",")
print(theNumbers.count-1)
if theNumbers.count-1 > 0 {
if let url = NSURL(string: "sms:/open?addresses=(createNumbers(saveData))&body=(urlSafeBody)") {
print(url)
WKExtension.sharedExtension().openSystemURL(url)
}
} else {
if let url = NSURL(string: "sms:/open?address=(createNumbers(saveData)),&body=(urlSafeBody)") {
print(url)
WKExtension.sharedExtension().openSystemURL(url)
}
}
}
}
我的猜测是问题不是实际的openSystemUrl
调用。我相信代码中一定有某种东西在以编程方式构建数字字符串。
下面的代码是您发布的所有代码的简化版本。我已经确认它正在我的Apple Watch上运行。它打开消息应用程序与预先填充的数字&正文。
再看一眼你的代码,看看是否有你遗漏的东西。如果你找不到任何东西,只需删除代码并重新编写,可能会比发现奇怪的问题更快。
下面的代码再一次被确认按预期工作,所以你应该能够让它工作。(或者只是复制粘贴我的代码):)
class InterfaceController: WKInterfaceController {
@IBAction func doItButton() {
if let urlSafeBody = createBody() {
if let url = NSURL(string: "sms:/open?addresses=(createNumbers())&body=(urlSafeBody)") {
print(url)
WKExtension.sharedExtension().openSystemURL(url)
}
}
}
private func createBody() -> String? {
let messageBody = "hello test message"
return messageBody.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLHostAllowedCharacterSet())
}
private func createNumbers() -> String {
let numbers = ["(111) 222-3333", "(444) 555-6666"]
var tempArray: [String] = []
numbers.forEach { (number: String) in
tempArray.append(number.digitsOnly())
}
return tempArray.joinWithSeparator(",")
}
}
extension String {
func digitsOnly() -> String{
let stringArray = self.componentsSeparatedByCharactersInSet(
NSCharacterSet.decimalDigitCharacterSet().invertedSet)
let newString = stringArray.joinWithSeparator("")
return newString
}
}
如上所述,出于评论中已经提到的原因,我建议你不要在应用商店上使用任何未经证明的苹果功能。