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 4,941 times
11
![](../../users/profiles/4635181.webp)
Ryan Daulton
- 849
- 10
- 21
3 Answers
25
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))
}
![](../../users/profiles/4635181.webp)
Ryan Daulton
- 849
- 10
- 21
-
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". – Gringo Russo 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
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"
}
![](../../users/profiles/11995238.webp)
Anna K.
- 41
- 4
1
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?
![](../../users/profiles/889524.webp)
qiz
- 709
- 1
- 7
- 13
-
-
Yes, so it is better to execute in a background thread and cache the result. – qiz Jul 15 '20 at 07:17