Shekar
Shekar

Reputation: 250

cloudkit error no authToken received for asset

Why do I get this error when I run the following code? :

"Internal Error" (1/1000); "No authToken received for asset"

I think it has something to do with the setObject code in the last line.

let documentsDirectoryPath:NSString = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] as NSString
var imageURL: URL!

let imageData = UIImageJPEGRepresentation(self.newImage, 1.0)
let path:String = documentsDirectoryPath.appendingPathComponent(self.newImage.description)
try? UIImageJPEGRepresentation(self.newImage, 1.0)!.write(to: URL(fileURLWithPath: path), options: [.atomicWrite])
imageURL = URL(fileURLWithPath: path)
try? imageData?.write(to: imageURL, options: [.atomicWrite])

let imageAsset:CKAsset? = CKAsset(fileURL: URL(fileURLWithPath: path))


curImages = record["Images"] as! [CKAsset]
curImages.append(imageAsset!)

print("saving image")
record.setObject(curImages as CKRecordValue?, forKey: "Images")

Upvotes: 3

Views: 561

Answers (2)

Reinhard Männer
Reinhard Männer

Reputation: 15227

This is not an answer to the specific problem (which as been solved by the accepted answer), but it solves another problem that creates the same error message, so it might be useful for somebody else:

I have an app that uses CoreData+Cloudkit with a .public database, i.e. my description for the NSPersistentCloudKitContainer uses

description.cloudKitContainerOptions!.databaseScope = .public  

Whenever I change my CloudKit schema, I have to re-initialize it using

do {
    try self.initializeCloudKitSchema()
} catch {
    print("Could not initialize schema, error \(error)")
}

This creates the error

"Internal Error" (1/1000); "No authToken received for asset"  

although I do not use any asset in my model.

I now realized that it has something to do with the .public database:
As soon as I out-comment the instruction that sets the database scope to .public, the re-initialization works without problems.
Now the CloudKit schema is independent of the database type (.private or .public). Thus, a re-initialization of the schema requires the following:

  • Set the database to .private (the default)
  • Execute the init code
  • Set the database to .public
  • Disable the init code

PS: I know I should write now a bug report, but I stopped doing so: Nearly none of my bug reports (about 15) have ever been answered or processed, so it is not worth the effort.

Upvotes: 4

Thunk
Thunk

Reputation: 4177

I've encountered this, too. It appears to be a bug in cloudkit, and--from what I can tell--it happens when you try to re-use any part of the "asset creation chain."

In other words, you have some initial data, you create an image from that data, you write it to a file, you load that file into a CKAsset, then you load the CKAsset into the CKRecrod. In my experiments, if you re-use any of those components... or if they just happen to be the same (that is, you create an image, then you happen to create a new-but-identical image later) you'll see this error.

For example, the following code reliably recreates the "no auth token" error when saving a record. All it does is create an array of assets and places it into the record:

for (int i = 0; i <= maxPlayers; i++)
{
    int tempVal = 0xf;
    NSData *tempData = [[NSData alloc] initWithBytes:&tempVal length:sizeof(tempVal)];
    NSString *tempDataFilepath = [documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:@"temp%d.dat",i]];
    [tempData writeToFile:tempDataFilepath atomically:YES];
    NSURL *tempDataURL = [NSURL fileURLWithPath:tempDataFilepath];
    someArray[i] = [[CKAsset alloc] initWithFileURL:tempDataURL ];
}

someRecord[SOME_FIELD_NAME] = someArray; 

Simply changing the third line to:

int tempVal = i; //force the temp value to be different every time

Completely solves the error.

Furthermore, this error occurs even when I tried to use a value in a different CKAsset **that was already used in a prior CKAsset For example, using int tempVal = 0xf in the first asset, then using int secondTempVal = 0xf in another CKAsset also produces the "no auth token" error.

In my case, I was able to force the asset value to always be a unique value, and completely solved the problem. In your case, I suggest the following possible work arounds:

  1. Check if you're using identical images for your assets. If you are, try slightly modifying the images for each new CKAsset.
  2. If you must re-use identical images, try saving the record after you set each asset. I do not know if that will solve the issue, and it certainly increases your network traffic. But it's worth an experiment to see if it helps.
  3. In this question Saving CKAsset to CKRecord in CloudKit produces error: "No authToken received for asset" the OP was able to create separate copies of the image file that ultimately solved the problem.
  4. Open a bug with Apple. I didn't bother doing this, as I've grown jaded watching similar bug reports sit open for years without attention. But who knows, you might have better luck.

Upvotes: 6

Related Questions