Is there a way to get the file size on disk of a PHAsset
without doing requestImageDataForAsset
or converting it to ALAsset
? I am loading in previews of a user's photo library - potentially many thousands of them - and it's imperative to my app that they know the size before import.
Asked
Active
Viewed 8,033 times
15

Ryan Daulton
- 1,159
- 1
- 11
- 22
4 Answers
30
You can grab the fileSize
of a PHAsset and convert it to human readable form like this:
let resources = PHAssetResource.assetResources(for: yourAsset) // your PHAsset
var sizeOnDisk: Int64? = 0
if let resource = resources.first {
let unsignedInt64 = resource.value(forKey: "fileSize") as? CLong
sizeOnDisk = Int64(bitPattern: UInt64(unsignedInt64!))
}
Then use your sizeOnDisk
variable and pass it into a method like this...
func converByteToHumanReadable(_ bytes:Int64) -> String {
let formatter:ByteCountFormatter = ByteCountFormatter()
formatter.countStyle = .binary
return formatter.string(fromByteCount: Int64(bytes))
}

Ryan Daulton
- 1,159
- 1
- 11
- 22
-
This is really an awesome solution! But didn't find this in any document. Will Apple approve this?!? – Erfan Sep 14 '17 at 20:45
-
4It's not in any documentation because it's accessing the header files. Technically this is a small piece of Apple's private APIs. However, we have submitted a build and received full approval without issue. – Ryan Daulton Sep 14 '17 at 22:24
-
@daulSwift How can we do this in Objective - C ? – Omkar Jadhav Nov 01 '17 at 15:49
-
will this private key filesize crash in iOS versions? – Chandra Lakkimsetty Feb 02 '18 at 05:49
-
@ChandraLakkimsetty not that I know of, that's what we used it for – Ryan Daulton Feb 02 '18 at 18:46
-
1Is it safety to take only first item? As apple said: " An asset can contain multiple resources - for example, an edited photo asset contains resources for both the original and edited images". – V.V.V Nov 21 '19 at 14:18
-
We'll probably need to check the `resources` for the image resources: `kUTTypeJPEG, AVFileType.heic.rawValue, kUTTypePNG, kUTTypeTIFF, kUTTypeRawImage` – SoftDesigner Jul 07 '20 at 09:02
-
UPD. But I noticed that the `resources.last` is always the most recent resource (iOS 13). – SoftDesigner Jul 07 '20 at 09:55
-
For iCloud albums video and images, I'm getting zero (0) as size. – Ganpat Sep 20 '21 at 13:59
4
SWIFT 5.0 Light & Easy:
private static let bcf = ByteCountFormatter()
func getSize(asset: PHAsset) -> String {
let resources = PHAssetResource.assetResources(for: asset)
guard let resource = resources.first,
let unsignedInt64 = resource.value(forKey: "fileSize") as? CLong else {
return "Unknown"
}
let sizeOnDisk = Int64(bitPattern: UInt64(unsignedInt64))
Self.bcf.allowedUnits = [.useMB]
Self.bcf.countStyle = .file
return Self.bcf.string(fromByteCount: sizeOnDisk)
}

Joshua Hart
- 772
- 1
- 21
- 31
2
A safer solution:
[asset requestContentEditingInputWithOptions:nil completionHandler:^(PHContentEditingInput * _Nullable contentEditingInput, NSDictionary * _Nonnull info) {
NSNumber *fileSize = nil;
NSError *error = nil;
[contentEditingInput.fullSizeImageURL getResourceValue:&fileSize forKey:NSURLFileSizeKey error:&error];
NSLog(@"file size: %@\nerror: %@", fileSize, error);
}];
Swift version:
asset.requestContentEditingInput(with: nil) { (contentEditingInput, _) in
do {
let fileSize = try contentEditingInput?.fullSizeImageURL?.resourceValues(forKeys: [URLResourceKey.fileSizeKey]).fileSize
print("file size: \(String(describing: fileSize))")
} catch let error {
fatalError("error: \(error)")
}
}
Inspired by How to get an ALAsset URL from a PHAsset?

qiz
- 869
- 1
- 9
- 14
-
-
Yes, so it is better to execute in a background thread and cache the result. – qiz Jul 15 '20 at 07:17
2
Please try this.
let resources = PHAssetResource.assetResources(for: YourAsset)
var sizeOnDisk: Int64 = 0
if let resource = resources.first {
let unsignedInt64 = resource.value(forKey: "fileSize") as? CLong
sizeOnDisk = Int64(bitPattern: UInt64(unsignedInt64!))
totalSize.text = String(format: "%.2f", Double(sizeOnDisk) / (1024.0*1024.0))+" MB"
}

Anna K.
- 61
- 4