我可以从XCAssets包中获得NSURL吗?

时间:2014-02-14 01:17:25

标签: ios objective-c cocoa-touch

我正处于列出邮件附件的情况。每个附件都有一个与之关联的NSURL,表示附件数据的路径。在非图像附件的情况下,我想在预览的位置加载预先生成的图标缩略图(即excel文档,PDF,单词等)。

我目前在我的项目中,在XCAssets包中有这些图像。我可以使用[UIImage imageNamed:@"someName"]来了解他们。我似乎无法通过NSBundle的各种资源查找方法来获取它们。 XCAssets捆绑是否会以某种方式更改我正在寻找的图标图像的文件名?

这是我目前正在使用的代码。路径每次都是零。在这种情况下,我是否需要不使用XCAssets?

+ (NSURL *)mediaURLWithMessage:(SRMediaMessage*)message
{
  NSURL *url = message.mediaURL;

  // if this is an image URL or non-existant, there is no work left to do, return it.
  if (!url || (message.secureFile.secureFileMimeType & SRSecureFileMimeTypeImage))
    return url;

  NSString *filename = @"unknown";

  switch (message.secureFile.secureFileMimeType)
  {
    case SRSecureFileMimeTypeDOC:
      filename = @"doc";
      break;

    case SRSecureFileMimeTypePPT:
      filename = @"ppt";
      break;

    case SRSecureFileMimeTypePDF:
      filename = @"pdf";
      break;

    case SRSecureFileMimeTypeXLS:
      filename = @"exl";
      break;

    case SRSecureFileMimeTypeCSV:
      filename = @"csv";
      break;

    case SRSecureFileMimeTypeTXT:
      filename = @"txt";
      break;

    case SRSecureFileMimeTypeRTX:
      filename = @"rtf";
      break;

    default:
    case SRSecureFileMimeTypeMP4:
      // unknown icon for now.
      break;

      // unused but available:
//      @"ilife"

  }

  NSString *path = [[NSBundle mainBundle] pathForResource:filename ofType:nil];
  if (path)
    url = [NSURL fileURLWithPath:path];

  return url;
}

5 个答案:

答案 0 :(得分:14)

我想访问一些使用本地资源创建UNNotificationAttachment的矢量资产,所以我想出了这个帮助类。它基本上只是从资产中获取图像,将其数据保存到磁盘并返回文件URL。我希望能帮助别人。

import UIKit

class AssetExtractor {

    static func createLocalUrl(forImageNamed name: String) -> URL? {

        let fileManager = FileManager.default
        let cacheDirectory = fileManager.urls(for: .cachesDirectory, in: .userDomainMask)[0]
        let url = cacheDirectory.appendingPathComponent("\(name).png")

        guard fileManager.fileExists(atPath: url.path) else {
            guard
                let image = UIImage(named: name),
                let data = UIImagePNGRepresentation(image)
            else { return nil }

            fileManager.createFile(atPath: url.path, contents: data, attributes: nil)
            return url
        }

        return url
    }

}

答案 1 :(得分:10)

如果您的目标是iOS 7+,Xcode 5现在会将资源置于新的文件格式中。所有资产都有1个文件。这意味着您无法直接访问该文件。

如果您需要直接访问该文件,可以将其作为资产目录之外的普通图像包含。

答案 2 :(得分:5)

Swift 5

它作为 URL 扩展对我来说更有意义。

extension URL {
    static func localURLForXCAsset(name: String) -> URL? {
        let fileManager = FileManager.default
        guard let cacheDirectory = fileManager.urls(for: .cachesDirectory, in: .userDomainMask).first else {return nil}
        let url = cacheDirectory.appendingPathComponent("\(name).png")
        let path = url.path
        if !fileManager.fileExists(atPath: path) {
            guard let image = UIImage(named: name), let data = image.pngData() else {return nil}
            fileManager.createFile(atPath: path, contents: data, attributes: nil)
        }
        return url
    }
}

用法:

if let url = URL.localURLForXCAsset(name: "MyIcon") {
  // code
}

答案 3 :(得分:4)

Swift 3 Swift 2.3 版本derived

Swift 3

import UIKit

class AssetExtractor {

    static func createLocalUrl(forImageNamed name: String) -> NSURL? {

        let fileManager = NSFileManager.defaultManager()
        let cacheDirectory = fileManager.URLsForDirectory(.CachesDirectory, inDomains: .UserDomainMask)[0]
        guard
            let url = cacheDirectory.URLByAppendingPathComponent("\(name).png"),
            let path = url.path
            else { return nil }

        guard fileManager.fileExistsAtPath(path) else {
            guard
                let image = UIImage(named: name),
                let data = UIImagePNGRepresentation(image)
                else { return nil }

            fileManager.createFileAtPath(path, contents: data, attributes: nil)
            return url
        }

        return url
    }

}

Swift 2.3

{{1}}

答案 4 :(得分:0)

Swift 3.x

static func createLocalUrl(forImageNamed name: String) -> URL? {

    let fileManager = FileManager.default
    let cacheDirectory = fileManager.urls(for: .cachesDirectory, in: .userDomainMask)[0]
    let url = cacheDirectory.appendingPathComponent("\(name).png")
    let path = url.path

    guard fileManager.fileExists(atPath: path) else {
        guard
            let image = UIImage(named: name),
            let data = UIImagePNGRepresentation(image)
            else { return nil }

        fileManager.createFile(atPath: path, contents: data, attributes: nil)
        return url
    }

    return url
}