Могу ли я получить NSURL из пакета XCAssets?

Я в ситуации, когда я перечисляю вложения из сообщения. Каждое вложение имеет связанный с ним NSURL, который представляет собой путь к данным вложения. В случае прикреплений без изображения я хочу загружать предварительно созданные пиктограммы значков вместо предварительного просмотра (то есть Excel, PDF, word и т.д.).

В настоящее время у меня есть эти изображения в моем проекте, в комплекте 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;
}

Ответы

Ответ 1

Если вы ориентируетесь на iOS 7+, Xcode 5 теперь переносит активы в новый формат. 1 для всех активов. Это означает, что вы не можете напрямую получить доступ к файлу.

Если вам нужно получить доступ к файлу напрямую, вы можете включить его как обычный образ вне каталога активов.

Ответ 2

Я хотел получить доступ к некоторым векторным ресурсам для создания 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
    }

}

Ответ 3

Swift 3 и Swift 2.3 версии ответ от @tadija:

Swift 3:

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

}

Swift 2.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
    }

}

Ответ 4

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
}