Apple Music API集成遇401未授权及数据解析错误求助
Apple Music API 401未授权与解析错误的解决思路
核心问题
调用Apple Music API获取曲目详情时,同时出现两个问题:
- 请求返回401未授权状态码
- 解析响应时提示
Error parsing Apple Music track details: The data couldn't be read because it isn't in the correct format.
已尝试的排查步骤(用户提供)
- 确认App ID已启用MusicKit App Service
- 确认bundle identifier与App ID配置一致
- 测试设备/模拟器已登录有效Apple ID
针对性解决步骤
一、先修复401未授权问题
你的代码完全遗漏了Apple Music API的认证逻辑,这是401的核心原因:
- Apple Music API的所有请求必须在请求头中携带
Authorization: Bearer [开发者令牌] - 补充令牌获取与请求头配置的代码,替换原有的
URLSession.dataTask逻辑:
// 替换原有的URLSession.shared.dataTask(with: lookupURL) {...}部分 var request = URLRequest(url: lookupURL) SKCloudServiceController().requestDeveloperToken { token, error in guard let token = token else { print("获取开发者令牌失败: \(error?.localizedDescription ?? "未知错误")") completion(nil) return } request.setValue("Bearer \(token)", forHTTPHeaderField: "Authorization") URLSession.shared.dataTask(with: request) { (data, response, error) in // 原有的响应处理逻辑放在这里 }.resume() }
- 额外检查:在Xcode的
Signing & Capabilities中确认已添加MusicKit权限
二、修复数据解析格式错误
解析错误是因为401返回的是错误文本而非预期JSON,同时你的解析逻辑混淆了Apple Music API和iTunes Search API的结构:
- Apple Music API的响应结构是
{ "data": [ {...} ] },曲目信息嵌套在data[0].attributes中,替换原解析代码:
do { let responseJSON = try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any] let dataArray = responseJSON?["data"] as? [[String: Any]] let trackData = dataArray?.first guard let attributes = trackData?["attributes"] as? [String: Any], let title = attributes["name"] as? String, let artist = attributes["artistName"] as? String, let album = attributes["albumName"] as? String, let artworkDict = attributes["artwork"] as? [String: Any], let artworkURLTemplate = artworkDict["url"] as? String, let artworkURL = URL(string: artworkURLTemplate.replacingOccurrences(of: "{w}", with: "100").replacingOccurrences(of: "{h}", with: "100")), let trackURLString = attributes["previewUrl"] as? String, let trackURL = URL(string: trackURLString) else { completion(nil) return } // 原有的 artwork 下载逻辑保持不变 } catch { print("解析Apple Music曲目详情失败: \(error.localizedDescription)") completion(nil) }
- 移除
fetchStorefront中的正则处理和编码逻辑,requestStorefrontCountryCode返回的是两位国家码(如US),可直接拼接URL:
func fetchStorefront(completion: @escaping (String?) -> Void) { SKCloudServiceController().requestStorefrontCountryCode { countryCode, error in if let error = error { print("获取商店区域失败: \(error.localizedDescription)") completion(nil) return } completion(countryCode) } }
三、额外检查项
- 确保测试设备/模拟器登录的Apple ID已开通Apple Music订阅(免费试用也可)
- 确认
Info.plist中添加了NSAppleMusicUsageDescription字段,说明应用使用Apple Music的目的
内容的提问来源于stack exchange,提问作者fun lab
相关产品推荐
相关产品推荐

