肇鑫的技术博客

业精于勤,荒于嬉

An Error Causing by IndexSet

I got an error of 3301 of PHPhotosError, when using insertAssets(_:at:).

The Limits of Photo Library

The first mistake I found was that my result was reordered by date, but there were two photos with the same date. That meant I had inserted two indexes with the same value to the indexSet, which meant the count of indexSet was smaller than the companied array.

So I created a placeholder date to replace the date matched the item of the array, that made the count of the indexSet and array equal.

But the error was still shown. So I had to investigate again. This time I found the two photos with the same date were the same photo. So when inserting the photos, when the second copy of the same photo was inserted, the photo library had no change and the indexes behind the second copy were all mismatched.

The fix was to excluded the photos from the inserted album that existed in the container, like:

var albumPhotoSet = ...
let containerPhotoSet = ...
albumPhotoSet.substract(containerPhotoSet)
let albums = Array(albumSet)
...

The error still existed.

IndexSet Behaviors Differently from Set

After reading the document of insertAssets(_:at:), I found that IndexSet is a set, but behaviors differently.

let set:Set<Int> = [1, 3, 2, 4, 5]
print(set) // [3, 1, 2, 4, 5], [1, 4, 3, 5, 2], result is radom of 1...5

let indexSet:IndexSet = [1, 3, 2, 4, 5]
print(indexSet) // 5 indexes
print(indexSet.map {$0}) // [1, 2, 3, 4, 5], always

Since the IndexSet is sorted automatically instead of the order it is given. The array it is companied must have the same order.

var albums = Array(albumSet)
albums.sort() // by date
...

This time everything worked.

Conclusion

When inserting photos to an album, there are three steps.

  1. Sorted the photos of the album the same order you wanted for the final result.
  2. Exclude the photos already existed in the album from the inserting photos.
  3. Reorder the inserting photos.
  4. Merge the photos in the album and the inserting photos, reorder the result, and get the indexes of the inserting photos.
  5. Insert the inserting photos to the album.