我找遍了所有的地方,都找不到一个如何使用Apple ITunesLibraryFramework的Swifty例子。 我一直在试图找出如何在Swift 5.2中使用这个框架。
我想直接从音乐库中获取信息,而不是依赖XML库导出文件。
我在我的游乐场里有下面的代码,但它打印出来的东西什么也看不清。 我如何访问播放列表和mediaItems的字段,并能够以人类可读的形式读取它们?
我已经在项目中安装了框架。 这是我的项目游乐场代码。
import Foundation
import iTunesLibrary
var library:ITLibrary
do {
let library = try ITLibrary(apiVersion: "1.1")
let mediaItems = library.allMediaItems
let playlists = library.allPlaylists
print("Media Folder Location - \(String(describing: library.mediaFolderLocation))")
print("\nPlaylists - \(playlists)")
print("\nTracks - \(mediaItems)")
} catch let error as NSError {
print(error)
}
这是ITLibrary.m文件,我导入了头部。
#import <Foundation/Foundation.h>
#import <iTunesLibrary/iTunesLibrary.h>
当我在项目中运行上述代码时 我得到的只是一堆播放列表和mediaItems的二进制数据。 我想做的就是在数据上迭代,从库中收集信息,以便在我的程序中使用。 这可能是很简单的事情,但我还没有找到。
EDIT: - 在使用了@Vincent的答案后,我在下面的代码中遇到了另一个问题。
import Foundation
import iTunesLibrary
let library = try ITLibrary(apiVersion: "1.1")
typealias tracks = [NSNumber:TrackInfo]
var trackInfo = TrackInfo()
struct TrackInfo {
var title = ""
var artist = ""
var album = ""
var totalTime = 0
var year = 0
var persistentID = ""
var location:URL!
}
let songs = library.allMediaItems
let playlists = library.allPlaylists
for playlist in playlists {
if playlist.name.lowercased().contains("test-") {
print("New Playlist---------------\nName: \(playlist.name)")
for song in playlist.items {
trackInfo.title = song.title
print("\n\nNew Track-----------------\nTitle: \(trackInfo.title)")
if song.artist?.name != nil {
trackInfo.artist = song.artist?.name as! String
}
print("Artist: \(trackInfo.artist)")
trackInfo.album = song.album.title!
print("Albumn Name: \(trackInfo.album)")
trackInfo.totalTime = song.totalTime
print("Total Time: \(trackInfo.totalTime)")
trackInfo.year = song.year
print("Year: \(trackInfo.year)")
trackInfo.location = song.location!
print("Location: \(trackInfo.location!)")
var persistentID = song.persistentID
tracks.updateValue(song.persistentID, trackInfo)
}
}
}
我遇到的问题是如何将轨道信息输入trackInfo字典中。 我试图使用track persistentID (NSNumber)作为字典的键,我已经声明了。 由于某些原因,它不允许我使用它。
下面是如何让它打印每个播放列表和曲目。
每个 ITLibPlaylist
或 ITLibMediaItem
对象包含了关于每个播放列表媒体项目的许多信息。要想只得到每个的nametitle,你必须遍历结果来检索它们。
对于下面这个例子,每个播放列表的名称都会被打印出来。
print("\nPlaylists -")
for playlist in playlists {
print(playlist.name)
}
其中会打印(例如)。
Playlists -
Library
Music
对于下面这个例子,每个曲目的名称被打印出来。
print("\nTracks -")
for mediaItem in mediaItems {
print(mediaItem.title)
}
将打印哪些内容(例如)。
Tracks -
Ev'ry Time We Say Goodbye
My Favorite Things
But Not for Me
Summertime
编辑...: 下面是次要问题的解决方法。
首先,应该先初始化一个字典,而不是使用 typealias
.
typealias
只为一个预先存在的类型创建一个别名,如
typealias NumberWithAlotOfDecimals = Double
let a: NumberWithAlotOfDecimals = 10.1
let b: Double = 10.1
两者都将 a
和 b
是 Double
作为 NumberWithAlotOfDecimals
的别称。Double
.
下面是如何初始化。
//typealias tracks = [NSNumber:TrackInfo] // not this
var tracks = [NSNumber:TrackInfo]() // but this
第二,应该正确处理可空对象
if let artistName = song.artist?.name {
trackInfo.artist = artistName
}
和
if let title = song.album.title {
trackInfo.album = title
}
if let location = song.location {
trackInfo.location = location
print("Location: \(location)")
}
而不是
if song.artist?.name != nil {
trackInfo.artist = song.artist?.name as! String
}
请不要使用 !
强制拆包可空对象,因为当对象被拆包时,会导致运行时崩溃。nil
.
最后,这是Swift中存储键值到字典的方法。
let persistentID = song.persistentID
//tracks.updateValue(song.persistentID, trackInfo) // not this
tracks[persistentID] = trackInfo // this