Пользование Библиотекой iPod
Вашему приложению, возможно, понадобится больше управления управлением и выбором элементов носителей, чем Вы добираетесь со средством выбора элемента носителей. Если Вы хотите предоставить настроенный пользовательский интерфейс библиотеке iPod устройства, выполнить определенные запросы или связать пользовательские метаданные с элементами носителей, Вам нужны классы доступа к базе данных этого API.
Рисунок 4-1 иллюстрирует, как Ваше приложение и классы доступа к базе данных взаимодействуют для получения элементов носителей.
Во-первых, займите одну минуту для замечания подобия между этим числом и рисунком 1-5. Более ранняя фигура помогла объяснить, каков запрос. Это число помещает класс мультимедийного запроса среди его когорт, показывая, как все классы доступа к базе данных касаются друг друга.
Число иллюстрирует два сценария взаимодействия между Вашим приложением и библиотекой iPod устройства. Во-первых, двигущийся против часовой стрелки от значка «Your application», число изображает создание и конфигурацию запроса, поочередно определяющего набор элементов носителей. Точки сбора к определенному подмножеству элементов от библиотеки. Несмотря на то, что не показанный в числе, набор является возвращаемым значением вызова запроса. Каждому элементу носителей принадлежит объект иллюстраций элемента носителей, как показано в числе, среди его других свойств.
Второй сценарий на рисунке 4-1 является Вашим приложением, получающим уведомления изменения от библиотеки iPod посредством MPMediaLibrary
класс. Путем регистрации для получения этих уведомлений изменения приложение может обновить любой кэш содержания библиотеки, если пользователь синхронизирует их устройство, в то время как работает приложение.
Получение разгруппированных элементов носителей
Получение элементов носителей от библиотеки iPod устройства начинается с построения мультимедийного запроса. Самый простой запрос является обобщением “everything
” запрос, показанный в Перечислении 4-1, соответствующем все содержание библиотеки. Пример тогда регистрирует заголовки элементов носителей к консоли отладки XCode, демонстрируя использование items
свойство, чтобы вызвать запрос и получить элементы носителей это соответствует.
Создание перечисления 4-1 и использование универсального мультимедийного запроса
MPMediaQuery *everything = [[MPMediaQuery alloc] init]; |
NSLog(@"Logging items from a generic query..."); |
NSArray *itemsFromGenericQuery = [everything items]; |
for (MPMediaItem *song in itemsFromGenericQuery) { |
NSString *songTitle = [song valueForProperty: MPMediaItemPropertyTitle]; |
NSLog (@"%@", songTitle); |
} |
Для построения более определенного запроса примените один или несколько предикатов свойства носителей к универсальному запросу. Предикат указывает единственное логическое условие протестировать элементы носителей против.
Перечисление 4-2 создает предикат, содержащий условие, что свойство «художника» элемента носителей должно иметь определенное значение. Перечисление тогда добавляет предикат к запросу.
Построение перечисления 4-2 и применение предиката свойства носителей
MPMediaPropertyPredicate *artistNamePredicate = |
[MPMediaPropertyPredicate predicateWithValue: @"Happy the Clown" |
forProperty: MPMediaItemPropertyArtist]; |
MPMediaQuery *myArtistQuery = [[MPMediaQuery alloc] init]; |
[myArtistQuery addFilterPredicate: artistNamePredicate]; |
NSArray *itemsFromArtistQuery = [myArtistQuery items]; |
Если необходимо было выполнить этот код, itemsFromArtistQuery
массив содержал бы только те элементы от библиотеки iPod, которые являются Счастливым Клоуном.
Можно создать и добавить многократные предикаты к запросу для сужения то, что соответствует запрос. Перечисление 4-3 показывает этот метод с помощью двух предикатов.
Перечисление 4-3 , Применяющее многократные предикаты к существующему мультимедийному запросу
MPMediaPropertyPredicate *artistNamePredicate = |
[MPMediaPropertyPredicate predicateWithValue: @"Sad the Joker" |
forProperty: MPMediaItemPropertyArtist]; |
MPMediaPropertyPredicate *albumNamePredicate = |
[MPMediaPropertyPredicate predicateWithValue: @"Stair Tumbling" |
forProperty: MPMediaItemPropertyAlbumTitle]; |
MPMediaQuery *myComplexQuery = [[MPMediaQuery alloc] init]; |
[myComplexQuery addFilterPredicate: artistNamePredicate]; |
[myComplexQuery addFilterPredicate: albumNamePredicate]; |
Вы создаете каждый предикат с помощью значения по Вашему выбору (такого как имя художника) вместе с надлежащим ключом свойства элемента носителей. Эти ключи описаны в Ссылке класса MPMediaItem в General Media Item Property Keys
и Podcast Item Property Keys
.
При применении больше чем одного предиката к запросу запрос комбинирует их использующий логическую операцию И.
Можно также добавить предикаты к запросу на инициализацию, как показано в Перечислении 4-4. (Эти два предиката в этом примере, как предполагается, ранее определяются.)
Перечисление 4-4 , Применяющееся многократные предикаты при инициализации мультимедийного запроса
NSSet *predicates = |
[NSSet setWithObjects: artistNamePredicate, albumNamePredicate, nil]; |
MPMediaQuery *specificQuery = |
[[MPMediaQuery alloc] initWithFilterPredicates: predicates]; |
Перечисление 4-4 сначала определяет NSSet
объект, содержащий два предиката, затем выделяет и инициализирует мультимедийный запрос с помощью initWithFilterPredicates:
метод класса.
Только определенные ключи свойства могут использоваться для создания допустимых предикатов. Эти ключи тегируются как «поддающиеся фильтрованию» в Ссылке класса MPMediaItem. При попытке использовать запрос, содержащий недопустимый предикат, получающееся поведение не определено.
Перечисление 4-5 показывает, как использовать canFilterByProperty:
метод класса проверить ключ свойства элемента носителей перед использованием его в предикате.
Тестирование перечисления 4-5, если ключ свойства может использоваться для предиката свойства носителей
if ([MPMediaItem canFilterByProperty: MPMediaItemPropertyGenre]) { |
MPMediaPropertyPredicate *rockPredicate = |
[MPMediaPropertyPredicate predicateWithValue: @"Rock" |
forProperty: MPMediaItemPropertyGenre]; |
[query addFilterPredicate: rockPredicate]; |
} |
В Перечислении 4-5, только если обозначенный ключ свойства элемента носителей (в этом примере, MPMediaItemPropertyGenre
) может использоваться для построения допустимого предиката, будет организация, если выполнится оператор. Apple рекомендует всегда выполнить проверку как это прежде, чем создать предикат свойства носителей.
Получение наборов элементов носителей
Мультимедийный запрос полезен не только для получения разгруппированных элементов носителей. Можно также использовать мультимедийный запрос для получения сортированных и расположенных наборов элементов носителей. Расположение, которое Вы получаете, зависит от значения, которое Вы устанавливаете для мультимедийного запроса grouping
свойство.
Перечисление 4-6 показывает, как получить все песни определенным художником с теми песнями, расположенными в альбомы. Пример регистрирует результаты к консоли отладки XCode.
Перечисление 4-6 Используя группирующийся тип для указания наборов элементов носителей
MPMediaQuery *query = [[MPMediaQuery alloc] init]; |
[query addFilterPredicate: [MPMediaPropertyPredicate |
predicateWithValue: @"Moribund the Squirrel" |
forProperty: MPMediaItemPropertyArtist]]; |
// Sets the grouping type for the media query |
[query setGroupingType: MPMediaGroupingAlbum]; |
NSArray *albums = [query collections]; |
for (MPMediaItemCollection *album in albums) { |
MPMediaItem *representativeItem = [album representativeItem]; |
NSString *artistName = |
[representativeItem valueForProperty: MPMediaItemPropertyArtist]; |
NSString *albumName = |
[representativeItem valueForProperty: MPMediaItemPropertyAlbumTitle]; |
NSLog (@"%@ by %@", albumName, artistName); |
NSArray *songs = [album items]; |
for (MPMediaItem *song in songs) { |
NSString *songTitle = |
[song valueForProperty: MPMediaItemPropertyTitle]; |
NSLog (@"\t\t%@", songTitle); |
} |
} |
Вы видите в Перечислении 4-6 что значение мультимедийного запроса collections
свойство является массивом массивов. Внешнее для цикла выполняет итерации по альбомам, выполнил указанного художника. Внутреннее для цикла выполняет итерации по песням в текущем альбоме.
MPMediaQuery
класс включает несколько конструкторов удобства для создания запросов, предварительно сконфигурированных с группирующимся типом. Следующее утверждение, например, присоединяет «альбомы», группирующие тип к недавно выделенному запросу:
MPMediaQuery *query = [MPMediaQuery albumsQuery]; |
Для описаний всех конструкторов удобства посмотрите Ссылку класса MPMediaQuery.
Используя иллюстрации элемента носителей
Один из самых полезных и свойства высокого влияния элемента носителей являются своими иллюстрациями. Для отображения иллюстраций Вы используете Интерфейсного Разработчика, а также XCode. Шаги следующие:
Добавьте a
UIImageView
возразите против своего расположения представления в Интерфейсном Разработчике.Добавьте переменную экземпляра IBOutlet к своему классу контроллера представления для соединения с
UIImageView
объект.Получите иллюстрации от элемента носителей, которому принадлежат они (ранее получавший элемент носителей, как описано в этой главе).
Преобразуйте иллюстрации в a
UIImage
объект, затем присвойте его своему расположениюUIImageView
объект.
Перечисление 4-7 показывает, как сделать шаги 3 и 4.
Перечисление 4-7 , Выводящее на экран иллюстрации альбома для элемента носителей
MPMediaItemArtwork *artwork = |
[mediaItem valueForProperty: MPMediaItemPropertyArtwork]; |
UIImage *artworkImage = |
[artwork imageWithSize: albumImageView.bounds.size]; |
if (artworkImage) { |
albumImageView.image = artworkImage; |
} else { |
albumImageView.image = [UIImage imageNamed: @"noArtwork.png"]; |
} |
noArtwork.png
файл, используемый в последней строке Перечисления 4-7, является изображением нейтрализации, которое Вы добавляете к своему проекту XCode для использования, когда элемент носителей не имеет никаких связанных иллюстраций.