英文:
HTTP Request Fails Trying to Report Unwanted Communication Report via API
问题
我根据此处的描述创建了一个不受欢迎的通信报告扩展:https://developer.apple.com/documentation/sms_and_call_reporting/sms_and_call_spam_reporting
按照说明进行操作,并成功获得了扩展类中的报告回调,但当我尝试向我的HTTPS服务器发出API请求时,在控制台日志中的某个地方出现了以下错误:
nw_resolver_can_use_dns_xpc_block_invoke Sandbox does not allow access to com.apple.dnssd.service
Task <C31ADB51-B5C3-4E85-800E-405781F6A9ED>.<1> finished with error [-1003] Error Domain=NSURLErrorDomain Code=-1003 "A server with the specified hostname could not be found." UserInfo={_kCFStreamErrorCodeKey=-72000, NSUnderlyingError=0x282d5c600 {Error Domain=kCFErrorDomainCFNetwork Code=-1003 "(null)" UserInfo={_NSURLErrorNWPathKey=satisfied (Path is satisfied), interface: en0[802.11], ipv4, dns, _kCFStreamErrorCodeKey=-72000, _kCFStreamErrorDomainKey=10}}, _NSURLErrorFailingURLSessionTaskErrorKey=LocalDataTask <C31ADB51-B5C3-4E85-800E-405781F6A9ED>.<1>, _NSURLErrorRelatedURLSessionTaskErrorKey=(
"LocalDataTask <C31ADB51-B5C3-4E85-800E-405781F6A9ED>.<1>"), NSLocalizedDescription=A server with the specified hostname could not be found., NSErrorFailingURLStringKey=https://sub.domain.com/debug, NSErrorFailingURLKey=https://sub.domain.com/debug, _kCFStreamErrorDomainKey=10}
所以基本上由于沙箱限制,DNS查找失败了,但我无法允许应用程序访问沙箱,这似乎是OSX特定的能力。
以下是负责API报告的我的代码示例:
func reportToAPI(for request: ILClassificationRequest) {
let payload: [String: AnyHashable] = [
"data": "OK",
"test": "payload"
]
guard let url = URL(string: "https://sub.domain.com/debug") else {
return
}
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.httpBody = try? JSONSerialization.data(withJSONObject: payload, options: .fragmentsAllowed)
let task = URLSession.shared.dataTask(with: request) { data, _, error in
guard let data = data, error == nil else {
return
}
do {
let response = try JSONSerialization.jsonObject(with: data, options: .allowFragments)
print(response)
} catch {
}
}
task.resume()
}
我还在扩展和主应用程序的目标上设置了相关域,如classificationreport:sub.domain.com和domain.com,以及我的apple-app-site-association文件上传如下:
{
"classificationreport": {
"apps": ["L***.com.b***.smsreporting.unwantedreporting","L***.com.b***.smsreporting"]
}
}
如果需要帮助和指导,将不胜感激,因为我在这一点上被卡住了,缺乏文档使事情变得更加困难。
编辑:我正在测试自己的开发者帐户上,这是个人会员,不是组织性的,如果这有关系的话。
英文:
I created an Unwanted Communication Reporting Extension as per described here: https://developer.apple.com/documentation/sms_and_call_reporting/sms_and_call_spam_reporting
Followed the instructions and was able to get the report callback in my extension class, but when I try to make an API request to my HTTPS server, somewhere along the console log I get
nw_resolver_can_use_dns_xpc_block_invoke Sandbox does not allow access to com.apple.dnssd.service
and
Task <C31ADB51-B5C3-4E85-800E-405781F6A9ED>.<1> finished with error [-1003] Error Domain=NSURLErrorDomain Code=-1003 "A server with the specified hostname could not be found." UserInfo={_kCFStreamErrorCodeKey=-72000, NSUnderlyingError=0x282d5c600 {Error Domain=kCFErrorDomainCFNetwork Code=-1003 "(null)" UserInfo={_NSURLErrorNWPathKey=satisfied (Path is satisfied), interface: en0[802.11], ipv4, dns, _kCFStreamErrorCodeKey=-72000, _kCFStreamErrorDomainKey=10}}, _NSURLErrorFailingURLSessionTaskErrorKey=LocalDataTask <C31ADB51-B5C3-4E85-800E-405781F6A9ED>.<1>, _NSURLErrorRelatedURLSessionTaskErrorKey=(
"LocalDataTask <C31ADB51-B5C3-4E85-800E-405781F6A9ED>.<1>"), NSLocalizedDescription=A server with the specified hostname could not be found., NSErrorFailingURLStringKey=https://sub.domain.com/debug, NSErrorFailingURLKey=https://sub.domain.com/debug, _kCFStreamErrorDomainKey=10}
So basically the dns lookup fails due to a sandbox restriction, but I was not able to allow the app sandbox access, that seems like a OSX specific capability.
Here is my code example that is in charge of the API reporting:
func reportToAPI(for request: ILClassificationRequest) {
let payload: [String: AnyHashable] = [
"data": "OK",
"test": "payload"
]
guard let url = URL(string: "https://sub.domain.com/debug") else {
return
}
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.httpBody = try? JSONSerialization.data(withJSONObject: payload, options: .fragmentsAllowed)
let task = URLSession.shared.dataTask(with: request) { data, _, error in
guard let data = data, error == nil else {
return
}
do {
let response = try JSONSerialization.jsonObject(with: data, options: .allowFragments)
print(response)
} catch {
}
}
task.resume()
}
I also have my associated domains set up on both extension and main app's target as classificationreport:sub.domain.com and domain.com, as well as my apple-app-site-association file uploaded as this:
{
"classificationreport": {
"apps": ["L***.com.b***.smsreporting.unwantedreporting","L***.com.b***.smsreporting"]
}
Any help and guidance is appreciated as I am stuck at this point and lack of documentation on this is making things harder.
Edit: I am testing this on my own developer account, which is an individual membership, not organizational, if that matters.
答案1
得分: 1
在不需要的通信报告扩展中,似乎您调用了reportToAPI()
。
然而,如果您正确地在.entitlement
中添加了apple-app-site-association
和Association Domain
,则无需自己创建URLRequest
。苹果将代表您发送API请求。(我认为这是出于隐私原因,就像消息过滤扩展一样。)
因此,classificationResponse
应该如下所示:
override func classificationResponse(for request: ILClassificationRequest) -> ILClassificationResponse {
let payload: [String: AnyHashable] = [
"data": "OK",
"test": "payload"
]
let action: ILClassificationAction = .reportJunk // 或 .none、.reportNotJunk、.reportJunkAndBlockSender
let response = ILClassificationResponse(action: action)
response.userInfo = payload
return response
}
英文:
It seems you call reportToAPI()
in Unwanted Communication Reporting Extension.
However if you add apple-app-site-association
and Association Domain
in .entitlement
correctly. There is no need to create URLRequest
by yourself. Apple will send the API on your behalf. (I think it's for privacy reasons, like Message Filter Extension.)
So classificationResponse
should look like this:
override func classificationResponse(for request:ILClassificationRequest) -> ILClassificationResponse {
let payload: [String: AnyHashable] = [
"data": "OK",
"test": "payload"
]
let action: ILClassificationAction = .reportJunk // or .none, .reportNotJunk, .reportJunkAndBlockSender
let response = ILClassificationResponse(action: action)
response.userInfo = payload
return response
}
答案2
得分: -5
错误消息表明由于沙盒限制,DNS查找失败。
你遇到的错误,“Sandbox does not allow access to com.apple.dnssd.service”,表明你的应用在沙盒环境中受到限制,无法访问DNS服务。
你需要允许你的应用程序沙盒访问必要的功能。启用应用程序所需的功能可能不适用于个人开发者帐户。你可能需要组织成员资格。
关于你的代码,一切似乎都很正常。但是,我建议进行一些改进来处理错误。以下是你的代码的更新版本:
func reportToAPI(for request: ILClassificationRequest) {
let payload: [String: AnyHashable] = [
"data": "OK",
"test": "payload"
]
guard let url = URL(string: "https://sub.domain.com/debug") else {
print("Invalid URL")
return
}
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
do {
request.httpBody = try JSONSerialization.data(withJSONObject: payload, options: .fragmentsAllowed)
} catch {
print("Failed to serialize payload")
return
}
let task = URLSession.shared.dataTask(with: request) { data, response, error in
if let error = error {
print("Error: \(error.localizedDescription)")
return
}
guard let data = data else {
print("No data received")
return
}
do {
let json = try JSONSerialization.jsonObject(with: data, options: .allowFragments)
print("API response: \(json)")
} catch {
print("Failed to parse API response: \(error.localizedDescription)")
}
}
task.resume()
}
更改:
- 改进了错误处理:
- 添加了一个围绕负载序列化的do-catch块,以捕获任何序列化错误。
- 为从API请求中未接收到数据的情况添加了错误处理。
- 为解析API响应添加了错误处理。
- 在发生错误时打印具体的错误描述。
- 修改了打印语句,提供更多信息反馈,例如打印API响应或指示失败原因。
英文:
The error message suggests that the DNS lookup fails due to sandbox restrictions.
The error you encountered, "Sandbox does not allow access to com.apple.dnssd.service," indicates that your app is restricted from accessing DNS services within the sandbox environment.
You need to allow your app sandbox access to the necessary capabilities. Enabling capabilities required by your app might not be possible for an individual developer account. You may need an organizational membership.
Regarding your code, everything seems to be in order. However, I would suggest making a few improvements to handle errors. Here's an updated version of your code:
func reportToAPI(for request: ILClassificationRequest) {
let payload: [String: AnyHashable] = [
"data": "OK",
"test": "payload"
]
guard let url = URL(string: "https://sub.domain.com/debug") else {
print("Invalid URL")
return
}
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
do {
request.httpBody = try JSONSerialization.data(withJSONObject: payload, options: .fragmentsAllowed)
} catch {
print("Failed to serialize payload")
return
}
let task = URLSession.shared.dataTask(with: request) { data, response, error in
if let error = error {
print("Error: \(error.localizedDescription)")
return
}
guard let data = data else {
print("No data received")
return
}
do {
let json = try JSONSerialization.jsonObject(with: data, options: .allowFragments)
print("API response: \(json)")
} catch {
print("Failed to parse API response: \(error.localizedDescription)")
}
}
task.resume()
}
Changes
- Improved error handling:
- Added a do-catch block around the serialization of the payload to catch any serialization errors.
- Added error handling for the case where no data is received from the API request.
- Added error handling for parsing the API response.
- Printed specific error descriptions when errors occur.
- Modified the print statement to provide more informative feedback, such as printing the API response or indicating the failure reason.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论