【问题标题】:Get file size of PHAsset without loading in the resource?在不加载资源的情况下获取 PHAsset 的文件大小?
【发布时间】:2017-12-20 00:18:00
【问题描述】:

有没有办法在不执行requestImageDataForAsset 或将其转换为ALAsset 的情况下获取PHAsset 磁盘上的文件大小?我正在加载用户照片库的预览 - 可能有数千个 - 我的应用程序必须在导入之前知道它们的大小。

【问题讨论】:

    标签: swift image phasset photolibrary


    【解决方案1】:

    您可以获取 PHAsset 的 fileSize 并将其转换为人类可读的形式,如下所示:

          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!))
          }
    

    然后使用您的 sizeOnDisk 变量并将其传递给这样的方法...

    func converByteToHumanReadable(_ bytes:Int64) -> String {
         let formatter:ByteCountFormatter = ByteCountFormatter()
         formatter.countStyle = .binary
    
         return formatter.string(fromByteCount: Int64(bytes))
     }
    

    【讨论】:

    • 这真是一个很棒的解决方案!但是在任何文档中都没有找到这个。苹果会批准吗?!?
    • 它不在任何文档中,因为它正在访问头文件。从技术上讲,这只是 Apple 私有 API 的一小部分。但是,我们已经提交了一个构建版本,并且毫无问题地获得了完全批准。
    • @daulSwift 我们如何在 Objective-C 中做到这一点?
    • 这个私钥文件大小会在 iOS 版本中崩溃吗?
    • 只拿第一件物品安全吗?正如苹果所说:“一个资产可以包含多个资源——例如,一个编辑过的照片资产包含原始图像和编辑后图像的资源”。
    【解决方案2】:

    更安全的解决方案:

    [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 版本:

    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)")
        }
    }
    

    灵感来自How to get an ALAsset URL from a PHAsset?

    【讨论】:

    • 这个方法太重了。不适用于成千上万的资产。
    • 可以,所以最好在后台线程中执行并缓存结果。
    【解决方案3】:

    请试试这个。

    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"
    }
    

    【讨论】:

      【解决方案4】:

      SWIFT 5.0 轻巧:

      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)
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-31
        • 2010-12-05
        • 2011-03-24
        • 1970-01-01
        • 1970-01-01
        • 2011-08-28
        相关资源
        最近更新 更多