Skip to content

Commit 1d24067

Browse files
committed
feat: get tracks query
1 parent 39d054d commit 1d24067

File tree

2 files changed

+103
-46
lines changed

2 files changed

+103
-46
lines changed

ios/models/AssetsOptions.swift

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,10 @@ public class TrackOptions: NSObject {
2222
super.init()
2323
}
2424

25+
public override var description: String {
26+
return "TrackOptions(after: \(after ?? "nil"), first: \(first), sortBy: \(sortBy), directory: \(directory ?? "nil"))"
27+
}
28+
2529
public func toDictionary() -> [String: Any] {
2630
return [
2731
"after": after ?? NSNull(),
@@ -44,6 +48,10 @@ public class AlbumOptions: NSObject {
4448
super.init()
4549
}
4650

51+
public override var description: String {
52+
return "AlbumOptions(after: \(after ?? "nil"), first: \(first), sortBy: \(sortBy))"
53+
}
54+
4755
public func toDictionary() -> [String: Any] {
4856
return [
4957
"after": after ?? NSNull(),
@@ -65,6 +73,10 @@ public class ArtistOptions: NSObject {
6573
super.init()
6674
}
6775

76+
public override var description: String {
77+
return "ArtistOptions(after: \(after ?? "nil"), first: \(first), sortBy: \(sortBy))"
78+
}
79+
6880
public func toDictionary() -> [String: Any] {
6981
return [
7082
"after": after ?? NSNull(),

ios/tracks/GetTracksQuery.swift

Lines changed: 91 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -10,87 +10,132 @@ import MediaPlayer
1010
internal class GetTracksQuery {
1111

1212
static func getTracks(options: TrackOptions) -> PaginatedResult<Track> {
13-
let query = MPMediaQuery.songs()
14-
15-
NSLog("🎵 [MusicLibrary] getTracks query: %@", query)
16-
17-
// 添加筛选条件
18-
var predicates: [MPMediaPredicate] = []
19-
20-
// 只查询音乐文件(排除其他音频)
21-
let musicPredicate = MPMediaPropertyPredicate(value: MPMediaType.music.rawValue,
22-
forProperty: MPMediaItemPropertyMediaType)
23-
predicates.append(musicPredicate)
24-
25-
// 如果有目录筛选,添加路径筛选
26-
if let directory = options.directory, !directory.isEmpty {
27-
// iOS中MediaPlayer框架不直接支持路径筛选,这里留作扩展
28-
// 可以通过assetURL进行后筛选
13+
// 检查权限
14+
if MPMediaLibrary.authorizationStatus() != .authorized {
15+
NSLog("🎵 [MusicLibrary] Music Library permission not authorized")
16+
return PaginatedResult<Track>(items: [], hasNextPage: false, totalCount: 0)
2917
}
3018

31-
// 应用所有筛选条件
32-
query.filterPredicates = Set(predicates)
33-
34-
// 设置排序
35-
query.groupingType = .title
19+
let query = MPMediaQuery.songs()
20+
NSLog("🎵 [MusicLibrary] getTracks query: %@", query)
3621

3722
// 获取所有项目
38-
guard let items = query.items else {
23+
guard var items = query.items else {
24+
NSLog("🎵 [MusicLibrary] No items found in query")
3925
return PaginatedResult<Track>(items: [], hasNextPage: false, totalCount: 0)
4026
}
4127

42-
let totalCount = items.count
43-
var tracks: [Track] = []
44-
var startIndex = 0
28+
NSLog("🎵 [MusicLibrary] Found %d total items", items.count)
4529

46-
// 处理分页:查找after位置
47-
if let after = options.after {
48-
for (index, item) in items.enumerated() {
49-
if "\(item.persistentID)" == after {
50-
startIndex = index + 1
51-
break
30+
// 处理排序 - 按照参考实现的方式
31+
if !options.sortBy.isEmpty {
32+
for sortString in options.sortBy {
33+
let components = sortString.components(separatedBy: " ")
34+
let key = components[0]
35+
let ascending = components.count > 1 && components[1] == "ASC"
36+
37+
NSLog("🎵 [MusicLibrary] Sorting by: %@ %@", key, ascending ? "ASC" : "DESC")
38+
39+
switch key.lowercased() {
40+
case "title", "default":
41+
items.sort { item1, item2 in
42+
let title1 = item1.title ?? ""
43+
let title2 = item2.title ?? ""
44+
return ascending ? title1 < title2 : title1 > title2
45+
}
46+
case "artist":
47+
items.sort { item1, item2 in
48+
let artist1 = item1.artist ?? ""
49+
let artist2 = item2.artist ?? ""
50+
return ascending ? artist1 < artist2 : artist1 > artist2
51+
}
52+
case "duration":
53+
items.sort { item1, item2 in
54+
return ascending ? item1.playbackDuration < item2.playbackDuration : item1.playbackDuration > item2.playbackDuration
55+
}
56+
case "createdat", "creationtime":
57+
items.sort { item1, item2 in
58+
return ascending ? item1.dateAdded < item2.dateAdded : item1.dateAdded > item2.dateAdded
59+
}
60+
case "modifiedat", "modificationtime":
61+
items.sort { item1, item2 in
62+
let date1 = item1.lastPlayedDate ?? Date(timeIntervalSince1970: 0)
63+
let date2 = item2.lastPlayedDate ?? Date(timeIntervalSince1970: 0)
64+
return ascending ? date1 < date2 : date1 > date2
65+
}
66+
default:
67+
NSLog("🎵 [MusicLibrary] Unknown sort key: %@", key)
5268
}
5369
}
5470
}
5571

56-
// 获取指定数量的记录
57-
let maxItems = min(options.first, 1000) // 限制最大查询数量
58-
let endIndex = min(startIndex + maxItems, totalCount)
72+
// 处理分页 - 按照参考实现的方式
73+
let first = options.first
74+
let after = options.after
5975

60-
for i in startIndex..<endIndex {
61-
let item = items[i]
76+
var startIndex = 0
77+
if let after = after, let afterId = UInt64(after) {
78+
if let foundIndex = items.firstIndex(where: { $0.persistentID == afterId }) {
79+
startIndex = foundIndex + 1
80+
}
81+
}
82+
83+
let endIndex = min(startIndex + first, items.count)
84+
let paginatedItems = startIndex < items.count ? Array(items[startIndex..<endIndex]) : []
85+
86+
NSLog("🎵 [MusicLibrary] Pagination: startIndex=%d, endIndex=%d, paginatedItems=%d",
87+
startIndex, endIndex, paginatedItems.count)
88+
89+
// 转换为Track对象
90+
let tracks = paginatedItems.map { item -> Track in
91+
// 详细调试 URL 信息
92+
NSLog("🎵 [MusicLibrary] Track: '%@'", item.title ?? "Unknown")
93+
NSLog("🎵 [MusicLibrary] - assetURL: %@", item.assetURL?.absoluteString ?? "nil")
94+
NSLog("🎵 [MusicLibrary] - isCloudItem: %d", item.isCloudItem)
95+
NSLog("🎵 [MusicLibrary] - hasProtectedAsset: %d", item.hasProtectedAsset)
96+
97+
// 尝试不同的 URL 获取方式
98+
var urlString = ""
6299

63-
// 跳过无效的音频文件
64-
guard let url = item.assetURL, item.playbackDuration > 0 else {
65-
continue
100+
if let assetURL = item.assetURL {
101+
urlString = assetURL.absoluteString
102+
NSLog("🎵 [MusicLibrary] - Using assetURL: %@", urlString)
103+
} else if item.isCloudItem {
104+
// 对于云端项目,我们可以使用 persistentID 作为标识符
105+
urlString = "ipod-library://item/item.m4a?id=\(item.persistentID)"
106+
NSLog("🎵 [MusicLibrary] - Cloud item, using custom scheme: %@", urlString)
107+
} else {
108+
// 尝试使用 persistentID 构造URL(某些播放器可能支持)
109+
urlString = "ipod-library://item/item.m4a?id=\(item.persistentID)"
110+
NSLog("🎵 [MusicLibrary] - No assetURL, using fallback scheme: %@", urlString)
66111
}
67112

68-
// 创建Track对象
69113
let track = Track(
70114
id: "\(item.persistentID)",
71115
title: item.title ?? "Unknown Title",
72116
artist: item.artist,
73117
artwork: getArtworkURL(for: item),
74118
album: item.albumTitle,
75119
duration: item.playbackDuration,
76-
url: url.absoluteString,
120+
url: urlString,
77121
createdAt: item.dateAdded.timeIntervalSince1970,
78122
modifiedAt: item.dateAdded.timeIntervalSince1970,
79123
fileSize: getFileSize(for: item)
80124
)
81125

82-
tracks.append(track)
126+
NSLog("🎵 [MusicLibrary] Created track: %@ with URL: %@", track.title, track.url)
127+
return track
83128
}
84129

85-
// 判断是否有下一页
86-
let hasNextPage = endIndex < totalCount
87-
let endCursor = tracks.last?.id
130+
// 返回结果
131+
let hasNextPage = endIndex < items.count
132+
let endCursor = paginatedItems.last.map { "\($0.persistentID)" } ?? after ?? ""
88133

89134
return PaginatedResult<Track>(
90135
items: tracks,
91136
hasNextPage: hasNextPage,
92137
endCursor: endCursor,
93-
totalCount: totalCount
138+
totalCount: items.count
94139
)
95140
}
96141

0 commit comments

Comments
 (0)