Cloud Function annotateImage() returns 'Unexpected token o in JSON at position 1' 到原生 iOS 应用程序
Cloud Function annotateImage() returns 'Unexpected token o in JSON at position 1' to native iOS app
我正在使用 Firebase Cloud Functions 为本机 iOS 移动应用创建 ImageAnnotator,遵循 iOS client and Cloud Function 的 Firebase 文档。然而,在调用 'annotateImage' 客户端时,错误 'Unexpected token o in JSON at position 1' 被 returned。我正在使用 XCode 13.
我的客户代码:
import Foundation
import Firebase
import Resolver
class ImageAnnotator: ObservableObject {
@LazyInjected var functions: Functions
@Published var annotatedText: String?
@Published var error: NSError?
func annotateImage(imageData: Data) {
let base64encodedImage = imageData.base64EncodedString()
let requestData = [
"image": ["content": base64encodedImage],
"features": ["type": "DOCUMENT_TEXT_DETECTION"],
"imageContext": ["languageHints": ["en"]]
]
functions.httpsCallable("annotateImage").call(requestData) { (result, error) in
if let error = error as NSError? {
self.error = error
return
}
DispatchQueue.main.async {
guard let annotation = (result?.data as? [String: Any])?["fullTextAnnotation"] as? [String: Any]
else {
return
}
print("%nComplete annotation:")
let text = annotation["text"] as? String ?? ""
print("%n\(text)")
self.annotatedText = text
}
}
}
}
我的index.js云函数代码:
const functions = require('firebase-functions');
const vision = require('@google-cloud/vision');
const client = new vision.ImageAnnotatorClient();
exports.annotateImage = functions.https.onCall(async (data, context) => {
if (!context.auth) {
throw new functions.https.HttpsError(
"unauthenticated",
"annotateImage must be called while authenticated."
);
}
try {
return await client.annotateImage(JSON.parse(data));
} catch (e) {
throw new functions.https.HttpsError("internal", e.message, e.details);
}
});
什么可能导致此错误从 annotateImage() 调用 return?
我能够使用建议的解决方案解决错误 here:
- 将requestData的'features'字典值改为数组。
- 将 requestData 作为编码字符串 JSON 传递给 annotateImage()。
但还是行
guard let annotation = (result?.data as? [String: Any])?["fullTextAnnotation"] as? [String: Any]
return为零。
该行未正确解析结果对象。我通过将 result.data 串行向下转换为 NSArray,然后将 NSArray 的索引 0 索引为 NSDictionary 来解决 nil return。然后我能够以 [String: Any].
的形式访问 NSDictionary 的 fullAnnotatedText 字段
完整代码:
import Foundation
import Firebase
import Resolver
class ImageAnnotator: ObservableObject {
@LazyInjected var functions: Functions
@Published var annotatedText: String?
func annotateImage(imageData: Data) {
struct requestData: Encodable {
let image: [String: Data]
let features = [["type": "DOCUMENT_TEXT_DETECTION"]]
init(imageData: Data) {
image = ["content": imageData]
}
}
let encoder = JSONEncoder()
let encodedData = try! encoder.encode(requestData(imageData: imageData))
let string = String(data: encodedData, encoding: .utf8)!
functions.httpsCallable("annotateImage").call(string) { (result, error) in
if let error = error as NSError? {
if error.domain == FunctionsErrorDomain {
let code = FunctionsErrorCode(rawValue: error.code)
let message = error.localizedDescription
let details = error.userInfo[FunctionsErrorDetailsKey]
print("ERROR \(String(describing: message)), CODE \(String(describing: code)), DETAILS \(String(describing: details))")
}
return
}
print("Success.")
DispatchQueue.main.async {
/* Parse result object */
guard let nsarray = result?.data as? NSArray
else {
return
}
guard let nsdictionary = nsarray[0] as? NSDictionary
else {
return
}
guard let fullTextAnnotation = nsdictionary["fullTextAnnotation"] as? [String: Any]
else {
return
}
let text = fullTextAnnotation["text"] as? String ?? ""
print("Recognized text: \(text)")
}
}
}
}
我正在使用 Firebase Cloud Functions 为本机 iOS 移动应用创建 ImageAnnotator,遵循 iOS client and Cloud Function 的 Firebase 文档。然而,在调用 'annotateImage' 客户端时,错误 'Unexpected token o in JSON at position 1' 被 returned。我正在使用 XCode 13.
我的客户代码:
import Foundation
import Firebase
import Resolver
class ImageAnnotator: ObservableObject {
@LazyInjected var functions: Functions
@Published var annotatedText: String?
@Published var error: NSError?
func annotateImage(imageData: Data) {
let base64encodedImage = imageData.base64EncodedString()
let requestData = [
"image": ["content": base64encodedImage],
"features": ["type": "DOCUMENT_TEXT_DETECTION"],
"imageContext": ["languageHints": ["en"]]
]
functions.httpsCallable("annotateImage").call(requestData) { (result, error) in
if let error = error as NSError? {
self.error = error
return
}
DispatchQueue.main.async {
guard let annotation = (result?.data as? [String: Any])?["fullTextAnnotation"] as? [String: Any]
else {
return
}
print("%nComplete annotation:")
let text = annotation["text"] as? String ?? ""
print("%n\(text)")
self.annotatedText = text
}
}
}
}
我的index.js云函数代码:
const functions = require('firebase-functions');
const vision = require('@google-cloud/vision');
const client = new vision.ImageAnnotatorClient();
exports.annotateImage = functions.https.onCall(async (data, context) => {
if (!context.auth) {
throw new functions.https.HttpsError(
"unauthenticated",
"annotateImage must be called while authenticated."
);
}
try {
return await client.annotateImage(JSON.parse(data));
} catch (e) {
throw new functions.https.HttpsError("internal", e.message, e.details);
}
});
什么可能导致此错误从 annotateImage() 调用 return?
我能够使用建议的解决方案解决错误 here:
- 将requestData的'features'字典值改为数组。
- 将 requestData 作为编码字符串 JSON 传递给 annotateImage()。
但还是行
guard let annotation = (result?.data as? [String: Any])?["fullTextAnnotation"] as? [String: Any]
return为零。
该行未正确解析结果对象。我通过将 result.data 串行向下转换为 NSArray,然后将 NSArray 的索引 0 索引为 NSDictionary 来解决 nil return。然后我能够以 [String: Any].
的形式访问 NSDictionary 的 fullAnnotatedText 字段完整代码:
import Foundation
import Firebase
import Resolver
class ImageAnnotator: ObservableObject {
@LazyInjected var functions: Functions
@Published var annotatedText: String?
func annotateImage(imageData: Data) {
struct requestData: Encodable {
let image: [String: Data]
let features = [["type": "DOCUMENT_TEXT_DETECTION"]]
init(imageData: Data) {
image = ["content": imageData]
}
}
let encoder = JSONEncoder()
let encodedData = try! encoder.encode(requestData(imageData: imageData))
let string = String(data: encodedData, encoding: .utf8)!
functions.httpsCallable("annotateImage").call(string) { (result, error) in
if let error = error as NSError? {
if error.domain == FunctionsErrorDomain {
let code = FunctionsErrorCode(rawValue: error.code)
let message = error.localizedDescription
let details = error.userInfo[FunctionsErrorDetailsKey]
print("ERROR \(String(describing: message)), CODE \(String(describing: code)), DETAILS \(String(describing: details))")
}
return
}
print("Success.")
DispatchQueue.main.async {
/* Parse result object */
guard let nsarray = result?.data as? NSArray
else {
return
}
guard let nsdictionary = nsarray[0] as? NSDictionary
else {
return
}
guard let fullTextAnnotation = nsdictionary["fullTextAnnotation"] as? [String: Any]
else {
return
}
let text = fullTextAnnotation["text"] as? String ?? ""
print("Recognized text: \(text)")
}
}
}
}