如何从 Siri Intent Extension 拨打网络电话?

Posted

技术标签:

【中文标题】如何从 Siri Intent Extension 拨打网络电话?【英文标题】:How to make network calls from Siri Intent Extension? 【发布时间】:2019-10-15 11:52:46 【问题描述】:

我正在尝试从我的应用程序中集成 Siri。实际上我的要求是对我的服务器进行一些 UDP 调用,但由于它没有发生,我尝试使用 URLSession 和 URLRequest 进行简单的网络调用。为了进行测试,我尝试访问 google.com 并打印响应,但是从完成处理程序返回的 data 不能转换为 String 并且返回 nil。我需要在Info.plist 文件或其他地方添加额外的东西以使Intent Extension 中的网络调用成功吗?

在官方文档中也没有提到这一点。我使用的代码实际上很简单,但我仍然将其粘贴在下面:

let session = URLSession.shared
let task = session.dataTask(with: URLRequest(url: URL(string: "https://www.google.com/")!), completionHandler:  (tcpData, response, error) in
    if error != nil 
        print("tcp error \(error!.localizedDescription)")
    
    if let res = response as? HTTPURLResponse 
        print(res.statusCode)
    
    if tcpData != nil 
        print(String(data: tcpData!, encoding: String.Encoding.utf8) ?? "N/A")
    
)

task.resume()
completion(TurnOnNodeAppIntentResponse.init(code: TurnOnNodeAppIntentResponseCode.success, userActivity: nil))

这里的响应总是nil,尽管statusCode200

【问题讨论】:

【参考方案1】:

您的代码没有任何问题。并非所有数据都可以转换为字符串。您可以在this answer 中阅读更多相关信息。只需点击https://www.google.com/ 不会返回字符串。但是,如果您真的想打印来自https://www.google.com/ 的数据字符串,只需使用print(tcpData!.base64EncodedString()),您会得到类似:PCFkb2N0eXBlIGh0bWw+PGh0bWwgaXRlbXNjb3BlPSIiIGl0ZW10eXBlPSJodHRwOi8vc....

将该 URL 切换到像 SpaceX API 这样的开放 API,您将获得一个有效的字符串。


  "flight_number": 83,
  "mission_name": "Amos-17",
  "mission_id": [

  ],
  "launch_year": "2019",
  "launch_date_unix": 1565131920,
  "launch_date_utc": "2019-08-06T22:52:00.000Z",
  "launch_date_local": "2019-08-06T18:52:00-04:00",
  "is_tentative": false,
  "tentative_max_precision": "hour",
  "tbd": false,
  "launch_window": 5280,
  "rocket": 
    "rocket_id": "falcon9",
    "rocket_name": "Falcon 9",
    "rocket_type": "FT",
    "first_stage": 
      "cores": [
        
          "core_serial": "B1047",
          "flight": 3,
          "block": 5,
          "gridfins": false,
          "legs": false,
          "reused": true,
          "land_success": null,
          "landing_intent": false,
          "landing_type": null,
          "landing_vehicle": null
        
      ]
    ,
    "second_stage": 
      "block": 5,
      "payloads": [
        
          "payload_id": "Amos-17",
          "norad_id": [

          ],
          "reused": false,
          "customers": [
            "Spacecom"
          ],
          "nationality": "Israel",
          "manufacturer": "Boeing Satellite Systems",
          "payload_type": "Satellite",
          "payload_mass_kg": 6500,
          "payload_mass_lbs": 14330.05,
          "orbit": "GTO",
          "orbit_params": 
            "reference_system": "geocentric",
            "regime": "geostationary",
            "longitude": 17,
            "semi_major_axis_km": null,
            "eccentricity": null,
            "periapsis_km": null,
            "apoapsis_km": null,
            "inclination_deg": null,
            "period_min": null,
            "lifespan_years": 15,
            "epoch": null,
            "mean_motion": null,
            "raan": null,
            "arg_of_pericenter": null,
            "mean_anomaly": null
          ,
          "uid": "UerI6qmZTU2Fx2efDFm3QQ=="
        
      ]
    ,
    "fairings": 
      "reused": false,
      "recovery_attempt": true,
      "recovered": true,
      "ship": "GOMSTREE"
    
  ,
  "ships": [
    "GOMSTREE",
    "GONAVIGATOR"
  ],
  "telemetry": 
    "flight_club": null
  ,
  "launch_site": 
    "site_id": "ccafs_slc_40",
    "site_name": "CCAFS SLC 40",
    "site_name_long": "Cape Canaveral Air Force Station Space Launch Complex 40"
  ,
  "launch_success": true,
  "links": 
    "mission_patch": "https://images2.imgbox.com/a0/ab/XUoByiuR_o.png",
    "mission_patch_small": "https://images2.imgbox.com/f1/4a/WAkSmKfY_o.png",
    "reddit_campaign": "https://www.reddit.com/r/spacex/comments/cjaawx/amos17_launch_campaign_thread",
    "reddit_launch": "https://www.reddit.com/r/spacex/comments/cmedgn/rspacex_amos17_official_launch_discussion_updates",
    "reddit_recovery": null,
    "reddit_media": "https://www.reddit.com/r/spacex/comments/cmppne/rspacex_amos17_media_thread_videos_images_gifs",
    "presskit": "https://www.spacex.com/sites/spacex/files/amos-17_mission_press_kit_8_6_2019.pdf",
    "article_link": "https://spaceflightnow.com/2019/08/07/spacex-launches-israeli-owned-telecom-satellite/",
    "wikipedia": "https://en.wikipedia.org/wiki/Spacecom",
    "video_link": "https://youtu.be/fZh82-WcCuo",
    "youtube_id": "fZh82-WcCuo",
    "flickr_images": [
      "https://live.staticflickr.com/65535/48478269312_58dd3dc446_o.jpg",
      "https://live.staticflickr.com/65535/48478269747_353dcb2e62_o.jpg",
      "https://live.staticflickr.com/65535/48478119901_2de0441026_o.jpg",
      "https://live.staticflickr.com/65535/48478120646_ab72c2c6c3_o.jpg",
      "https://live.staticflickr.com/65535/48478120031_5aae1f6131_o.jpg",
      "https://live.staticflickr.com/65535/48478269442_08479bed36_o.jpg"
    ]
  ,
  "details": "SpaceX will launch Boeing built Amos-17, a geostationary communications satellite for Israeli company Spacecom. The satellite will be delivered to GTO from KSC LC-39A or possibly CCAFS SLC-40, and will replace the defunct Amos-5 at 17° E. Amos-17 carries multi-band high throughput and regional beams servicing Africa, Europe and the Middle East. The cost of this launch is covered for Spacecom by SpaceX credit following the Amos-6 incident. A recovery of the booster for this mission is not expected.",
  "upcoming": false,
  "static_fire_date_utc": "2019-08-01T00:00:00.000Z",
  "static_fire_date_unix": 1564617600,
  "timeline": null,
  "crew": null

此外,您可能希望停止强制展开,而是使用 if letguard

let session = URLSession.shared
let task = session.dataTask(with: URLRequest(url: URL(string: "https://api.spacexdata.com/v3/launches/latest")!), completionHandler:  (tcpData, response, error) in
    if let err = error 
        print("tcp error \(err.localizedDescription)")
    

    if let res = response as? HTTPURLResponse 
        print(res.statusCode)
    

    if let data = tcpData 
        print(String(data: data, encoding: String.Encoding.utf8) ?? "N/A")
    
)

task.resume()
completion(TurnOnNodeAppIntentResponse.init(code: TurnOnNodeAppIntentResponseCode.success, userActivity: nil))

【讨论】:

那么Siri Intent Extension目标不需要做额外的工作吗?从目标的能力来看,没有什么比得上“背景模式”了吗?网络呼叫可以开箱即用地扩展意图吗? 您的请求已经通过,只是没有返回字符串数据。使用print(tcpData!.base64EncodedString()) 查看数据响应。不过,您可能希望启用后台获取。

以上是关于如何从 Siri Intent Extension 拨打网络电话?的主要内容,如果未能解决你的问题,请参考以下文章

SwiftUI:如何从 Siri Intent 添加 CoreData 记录

在我让 iPhone 闲置后 Siri Custom Intent 停止工作

Siri Intent 请求访问令牌 OAUTH 令牌

当我询问 siri 时,我的 Intent UI 扩展不显示

尝试提交带有 Siri 扩展的应用时,来自 App Store 的“Invalid Intent Vocabulary”错误

在 xcode 中编辑 Intent 方案时,Siri Intent Query 输入字段不可用