我想使用服务器到服务器的cloudkit js。保存资产字段中的记录。
资产字段是m4a音频。保存后,音频文件无法播放
“苹果文档”的“资产”字段不清楚。
在保存到数据库的记录中,“资产”字段的值必须是window.Blob类型。在上面的代码片段中,assetFile变量的类型为window.File。
文件: https://developer.apple.com/documentation/cloudkitjs/cloudkit/database/1628735-saverecords
但是在nodejs中,没有 Blob 或 .file ,我用如下代码填充了缓冲区:
var dstFile = path.join(__dirname,"../test.m4a");
var data = fs.readFileSync(dstFile);
let buffer = Buffer.from(data);
var rec = {
recordType: "MyAttachment",
fields: {
ext: { value: ".m4a" },
file: { value: buffer }
}
}
//console.debug(rec);
mydatabase.newRecordsBatch().create(rec).commit().then(function (response) {
if (response.hasErrors) {
console.log(">>> saveAttachFile record failed");
console.warn(response.errors[0]);
} else {
var createdRecord = response.records[0];
console.log(">>> saveAttachFile record success:", createdRecord);
}
});
记录成功保存。
但是当我从icloud.developer.apple.com/dashboard下载音频时。
音频文件已播放。
它出什么问题了。感谢您的答复。
答案 0 :(得分:2)
我遇到了同样的问题,并且找到了可行的解决方案!
记住CloudKitJS需要您定义自己的fetch
方法,所以我实现了一个自定义方法以查看发生了什么。然后,我在自定义fetch
上附加了调试器,以检查通过它的数据。
单步调用者之后,我发现当库嵌入到NodeJS中时,所有资产值都使用其toString()
方法 转换。这取决于缺少全局window
对象。
在toString()
上调用Buffer
时,其内容编码为UTF-8(默认),这会导致二进制资产格式错误。如果您在node-fetch
实现中使用fetch
,则它支持Buffer
和stream.Readable
,因此此toString()
调用只会带来伤害。
我发现的最简单的解决方法是在作为资产字段值传递的任何toString()
或Buffer
实例上交换stream.Readable
方法。顺便说一下,您可能应该使用stream.Readable
,以便在上传时不会将整个资产加载到内存中。
无论如何,这是实际的样子:
// Put this somewhere in your implementation
const swizzleBuffer = (buffer) => {
buffer.toString = () => buffer;
return buffer;
};
// Use this asset value instead
{ asset: swizzleBuffer(fs.readFileSync(path)) }
请注意,此解决方法会以丑陋的方式更改Buffer
(因为Buffer
显然无法扩展)。设计一个不使用Buffer
参数的API可能是个好主意,这样您就可以对仅由您自己创建的实例进行变异,以避免代码中其他地方的意外副作用。
此外,请确保在您的项目中供应CloudKitJS(在本地复制),因为将来的行为可能会改变。
原始答案
我遇到了同样的问题,并通过使用Base64编码数据解决了该问题。看来,他们的SDK中存在一个错误,该错误会处理Buffer
个包含非ASCII字符的实例(嗯,这似乎是有问题的)。
无论如何,尝试这样的事情:
const assetField = { value: Buffer.from(data.toString('base64')), 'ascii') }
旁注:
您需要先在设备上解码资产,然后再使用它们。没有编写自己的例程就无法有效地做到这一点,因为Data
/ NSData
实例中包含的方法要求所有数据都在内存中。
这是CloudKitJS(而不是本地CloudKit客户端/服务)的问题,因此另一种选择是编写自己的例程来上传资产。
这两个选项似乎都不是特别好,但是如果您自己选择至少一个选项,则意味着客户无需采取其他步骤即可使用资产。