Как создать пакет ресурсов iOS?

Я видел настраиваемый пакет ресурсов в оцениваемом мной проекте iOS, так что, по крайней мере, я знаю, что это возможно.

Моя проблема в том, что я использую CATiledLayer с примерно 22 000 плиток для данного образа, и его компиляция занимает очень много времени (полчаса чистой сборки, 5-10 минут для обычной сборки). Итак, я хочу взять все изображения и создать собственный пакет, чтобы сделать его переносимым и, надеюсь, не перекомпилировать каждый раз в пакет приложения.

Как мне это сделать? Я проверил документацию, но не увидел объяснений, как на самом деле создать пакет.


person michael    schedule 03.02.2011    source источник


Ответы (7)


Ответ глупо простой

Создайте папку в Finder, добавьте в нее файлы, переименуйте в bundlename.bundle

перетащить в Xcode - успех!

для доступа используйте форму PathToMainBundle + "/ bundlename.bundle"

person michael    schedule 11.03.2011
comment
У меня не работает. Я не могу получить доступ к файлам в пакете ресурсов, потому что пакет не загружен, и когда я загружаю пакет, я получаю сообщение об ошибке, в котором говорится, что пакет не может быть загружен, потому что его исполняемый файл не может быть найден. - person LandedGently; 09.07.2011
comment
@LandedGently, у меня была такая же проблема, но оказалось, что это не потому, что пакет не был загружен. Это произошло потому, что у меня были заглавные буквы для ofType части pathForResource:ofType (ofType:@"PNG"), которая работала на симуляторе, но не на реальном устройстве. Исходя из этого, я бы сказал, что вам нужно не вызывать метод загрузки для неисполняемых пакетов для извлечения ресурсов. - person Hari Honor; 19.11.2011
comment
Для справки, ни один из моих пользовательских пакетов не сообщает, что они загружены, и я никогда не пытаюсь загрузить их вручную. Тем не менее, они работают по назначению. - person michael; 21.11.2011
comment
Как мы можем использовать этот пакетный подход для UIImageView в построителе интерфейса (учитывая локализованные файлы). Мой вопрос размещен здесь stackoverflow.com/questions/33242187/ - person NNikN; 20.10.2015
comment
Но это не комплект. Это просто папка со связкой в ​​названии. - person matt; 15.10.2016
comment
@matt Каково ваше определение пакета и чего вы ожидаете от него? Он функционирует как пакет, он обрабатывается Xcode и ОС как пакет. iOS не поддерживает пакеты, которые загружают код. - person michael; 20.10.2016
comment
@michael, согласился, но тут не происходит ничего такого, чего бы не случилось, если бы это была просто папка. Другими словами, каково ваше определение пакета и ожидания от него? Если бы все, что вы хотели сделать, это перетащить папку с материалами в Xcode для включения в приложение, вы могли бы сделать это без переименования с суффиксом .bundle. - person matt; 20.10.2016
comment
@matt Ну, когда мне впервые это понадобилось много лет назад, в качестве варианта использования было заархивировать .bundle и доставить контент путем загрузки и распаковки такого файла. Каждый соответствовал одному формату и реализовал info.plist - infoDictionary работал, как ожидалось. При этом класс NSBundle был инициализирован путем указания пути к пакету, а загрузка ресурсов была закодирована для интерфейса NSBundle. В любом случае, пакет - это просто папка с расширением ... В более ранних версиях iOS NSBundle мог загружать только путь .bundle; он не работал с произвольными папками. - person michael; 21.10.2016
comment
В более ранних версиях iOS NSBundle мог загружать только путь .bundle; с произвольными папками он не работал. Извините, это неправда. Я использую iOS с iOS 3 и с первого дня читаю из папок. И вы двусмысленно относитесь к слову «нагрузка»; ничто в приведенном выше коде не загружает пакет, как в реальном механизме загрузки пакета. Вы просто читаете из папки. Суффикс пакета в названии не имеет значения. - person matt; 21.10.2016
comment
@matt Мое понимание инициализации NSBundle может быть основано на ошибке, которую я допустил при работе с iOS 3.2. Ты прав; NSBundle не загружается в контексте этого класса, потому что это потребует загрузки кода. В iOS использование папки с расширением .bundle по сравнению с обычной папкой может не иметь технических преимуществ. Тем не менее, это относительно обычное соглашение, которое сохраняется и по сей день, о чем свидетельствует его поддержка в Cocoapods. Это полезный способ упаковать вещи в отдельные пакеты и избежать конфликта имен файлов. На iOS оказывается, что все, что вам нужно сделать, это закрыть папку в .bundle. - person michael; 21.10.2016
comment
@michael Моя цель - не доставить вам неприятностей. Я искал, есть ли способ действительно загрузить реальный пакет в iOS, и долгое время был введен в заблуждение вашим вопросом и вашим ответом (и другими ответами здесь) . Мой комментарий призван предостеречь других. Ваш код не делает то, что вы описываете (на мой взгляд). Он просто ссылается на папку совершенно обычным образом. - person matt; 21.10.2016

Как создать пакет

  1. Создайте папку в Finder.
  2. Добавить файлы в папку
  3. Переименуйте папку так, чтобы ее расширение было .bundle (например, «Новая папка» -> «BundleName.bundle»).

PS: Вы можете в любой момент щелкнуть папку правой кнопкой мыши и нажать «Показать содержимое пакета», чтобы добавить, удалить или изменить любой из файлов.

Как добавить пакет в Xcode

  1. Перетащите его в Xcode

Как использовать пакет

NSString *bundlePath = [[NSBundle mainBundle] pathForResource:@"BundleName" ofType:@"bundle"];
NSBundle *bundle = [NSBundle bundleWithPath:bundlePath]; 
NSString *resource = [bundle pathForResource:@"fileName" ofType:@"fileType"];

(Замените BundleName, fileName и fileType соответствующими именами)

person hfossli    schedule 27.05.2014

Два других полезных совета:

Во-первых, чтобы увидеть содержимое пакета в Xcode, вам необходимо установить его тип на панели служебной программы File Inspector на Application Bundle. Вы по-прежнему не сможете копировать в Xcode и обратно. Вам нужно будет использовать Терминал, но Xcode обновит его немедленно.

Во-вторых, чтобы использовать ресурсы в пакете, вот полезный фрагмент ...

NSString *bundlePath = [[NSBundle mainBundle] pathForResource:@"AquarianHarp" ofType:@"bundle"];
NSString *imageName = [[NSBundle bundleWithPath:bundlePath] pathForResource:@"trebleclef2" ofType:@"png"];
UIImage *myImage = [[UIImage alloc] initWithContentsOfFile:imageName];

Как упоминалось в моем комментарии выше, вам на самом деле не нужно загружать пакет (вы не можете, поскольку он не исполняемый), и ofType должен соответствовать регистру вашего фактического файла, чтобы он работал на устройстве . В симуляторе это будет работать в любом случае, так что пусть вас не вводит в заблуждение этот отвлекающий маневр!

Наконец, вам не нужно помещать свои ресурсы в подпапку Resources внутри пакета. Кажется, вы можете использовать произвольный макет, но это может повлиять на производительность.

person Hari Honor    schedule 19.11.2011
comment
Кроме того, если в вашем пакете есть папки, убедитесь, что имена папок НЕ содержат пробелов. Симулятор будет работать, но устройство не терпит пробелов в названиях папок. - person LandedGently; 07.04.2012

Вот как мне это удалось: в Xcode создать новый файл | Ресурс | Пакет настроек. Затем в Finder выберите этот пакет, выберите «Показать содержимое пакета» и добавьте файлы изображений.

Затем в коде укажите ссылку на изображение следующим образом:

NSString *imgName = @"bundlename.bundle/my-image.png";
UIImage *myImage = [UIImage imageNamed:imgName]; 
person LandedGently    schedule 10.07.2011
comment
Но нет никакого смысла в том, что это пакет. Это просто папка. Вы просто делаете то, что обычно делаете, чтобы загрузить изображение из папки. - person matt; 15.10.2016

Вот шаги по созданию актива или пакета ресурсов (например, FrameworkResources.bundle) - это на удивление неочевидно. Это особенно полезно, если вы создаете статические фреймворки.

  1. Нажмите File -> New -> Target в Xcode
  2. Выберите вкладку «macOS», выполните поиск «Bundle»
  3. Нажмите «Bundle» -> нажмите «Next» -> введите название продукта «MyResources» -> нажмите «Finish»
  4. Перейдите в «Настройки сборки» для только что созданного пакета. Измените «Базовый SDK» (SDKROOT) на «iOS»
  5. Перейдите в «Фазы сборки» для только что созданного пакета. Удалите «Источники компиляции» и «Связать двоичный файл с библиотеками» (это приведет к удалению исполняемого файла в пакете, что может вызвать всевозможные ошибки сборки и отправки приложения)
person kgaidis    schedule 05.02.2019

Создание загружаемого связанного проекта аналогично созданию приложения - вам просто нужно выбрать соответствующий шаблон проекта. Чтобы создать загружаемый пакетный проект, выполните следующие действия:

  1. Запустите Xcode.
  2. Выберите «Новый проект…» в меню «Файл».
  3. В списке шаблонов выберите Пакет какао.
  4. Нажмите "Далее.
  5. Выберите место для проекта и нажмите Готово.

При сборке и запуске в Xcode вы увидите файл пакета в папке «Продукты» в Project Navigator. Щелкните пакет правой кнопкой мыши и выберите «Показать в Finder».

person DàChún    schedule 24.04.2020

Мои заметки по объединению и чтению файлов в проекте Xcode

Шаги:

  1. Создайте файл test.txt и добавьте к нему текстовое тестирование, затем поместите его в папку с именем test.bundle.
  2. Перетащите его рядом с вашим файлом .app в Xcode (скопируйте)
  3. print(Bundle.main.resourcePath!+"/temp.bundle/test.txt") Вывод: /Users/James/Library/Developer/Xcode/DerivedData/GitSyncMac-heiwpdjbtaxzhiclikjotucjguqu/Build/Products/Debug/GitSyncMacApp.app/Contents/Resources/temp.txt.bundle

Пример:

print(content(Bundle.main.resourcePath!+"/temp.bundle/test.txt")) // testing
static func content(_ path:String)->String?{
    do {
        let content = try String(contentsOfFile:path, encoding:String.Encoding.utf8) as String//encoding: NSUTF8StringEncoding
        return content
    } catch {
        return nil
    }
}
person Sentry.co    schedule 31.07.2017