Apple Watch Messages URL 可以硬编码但不能使用变量

AppleWatch Messages URL works hard coded but not with variables

TLDR 当我将 phone 数字硬编码到 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 上打开带有预填充内容的消息。我从联系簿中获取 phone 号码并将它们存储在一个数组中。它们以这种格式提供:

(###) ###-#### 但需要是 ##########

我通过将 phone 数字硬编码到 URL 中来测试代码,它可以与所有联系人和完整的正文一起正常工作:

if let urlSafeBody = urlSafeBody, url = NSURL(string: "sms:/open?addresses=8888888888,9999999999,3333333333&body=\(urlSafeBody)") {
        print("FINAL URL: \(url)")
        WKExtension.sharedExtension().openSystemURL(url)
    }

但是当我以编程方式构建 phone 数值时它不起作用:

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

最终 URL 打印显示正确的字符串,但消息应用程序无法正常打开,并且显示快速回复菜单而不是组合消息 window。它与功能硬编码数字版本完全匹配,但行为不同。

完全迷路,希望有人能帮助!

更新 1 以下是 URL:

两个版本的调试打印

手动声明(不是从 recipString 创建但实际上在 URL 字符串中显式声明):

这个版本有效

FINAL URL: sms:/open?addresses=0000000000,1111111111,2222222222,3333333333,4444444444&body=test

已创建变量(使用 recipString):

这个版本没有

FINAL URL: sms:/open?addresses=0000000000,1111111111,2222222222,3333333333,4444444444&body=test

我也尝试过使用下面的 if let 将 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 matches recipString

更新 3

我已经确认:

当 URL 是用硬编码数字与我从变量中得到的数字相比时,检查它们之间的 == returns true。

在每个我能做的两个版本之间的测试中url,它匹配。

找到正确答案后的注释:

这种 URL 格式仅适用于 URL 中的多个地址。如果您没有多个地址,则需要执行以下操作,该操作未记录但 none-the-less 有效。我是通过在键盘上猛击我的脸几个小时才发现这一点的,所以如果它对你有帮助,那就值得点赞:)

按照下面标记的答案,然后在他提到的 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
  }
}

综上所述,出于评论中已经提到的原因,我建议不要将未记录的 Apple 功能用于您计划放在 App Store 上的任何内容。