Hi,
I’m experiencing an issue with my iOS app that uses ReadyPlayerMe for custom avatar creation. The problem started a few days ago, and I’m hoping you can help me identify the cause.
Setup Overview
- Platform: iOS
- Language: Swift
- ReadyPlayerMe Integration: Using WebView for avatar creation
- Authentication: Using tokens for guest accounts
Issue Description
While the WebView loads correctly and I can see the avatar selection interface, the avatar assets (such as clothing, hair, etc.) are not loading. This issue began suddenly a few days ago, despite no changes to my implementation.
Here’s a screenshot of the problem:
Relevant Code Snippets
Here are some key parts of my implementation:
- AvatarCreatorConfig and URL generation:
struct AvatarCreatorConfig {
var subdomain: String = “ardia”
var clearCache: Bool = true
var quickStart: Bool = true
var gender: Gender = .MALE
var bodyType: BodyType = .SELECTABLE
var language: Language = .DEFAULT
var avatarID: String?
var token: String?
}
class AvatarCreatorSettings {
private let config: AvatarCreatorConfig
init(config: AvatarCreatorConfig) {
self.config = config
}
func generateUrl() -> URL {
var components = URLComponents(string: "https://\(config.subdomain).readyplayer.me/")!
components.path = "/avatar"
var queryItems: [URLQueryItem] = [
URLQueryItem(name: "frameApi", value: ""),
URLQueryItem(name: "source", value: "ios-swift-avatar-creator")
]
if let token = config.token {
queryItems.append(URLQueryItem(name: "token", value: token))
}
// ... [other query items]
components.queryItems = queryItems
return components.url!
}
}
-
Token retrieval:
func getToken() async throws → String {
if let currentToken = currentToken, let expirationTime = tokenExpirationTime, Date() < expirationTime {
return currentToken
}return try await requestNewToken()
}
private func requestNewToken() async throws → String {
do {
let userId = try await createOrRetrieveRPMUserId()
let urlString = “(baseURL)/auth/token?userId=(userId)&partner=(subdomain)”
// ... [request setup]
let (data, response) = try await URLSession.shared.data(for: request)
// ... [response handling]
await MainActor.run {
self.currentToken = token
self.tokenExpirationTime = Date().addingTimeInterval(14) // 14 seconds to be safe
}
return token
} catch {
// ... [error handling]
}
}
- WebView setup:
private func setupWebView() {
let webViewConfig = WKWebViewConfiguration()
let script = WKUserScript(source: source, injectionTime: .atDocumentStart, forMainFrameOnly: false)
webViewConfig.userContentController.addUserScript(script)
webViewConfig.userContentController.add(self, name: “iosListener”)
webView = WKWebView(frame: self.bounds, configuration: webViewConfig)
webView.accessibilityLabel = "Avatar Creator"
webView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
webView.allowsBackForwardNavigationGestures = true
self.addSubview(webView)
loadAvatarCreator()
}
private func loadAvatarCreator() {
let url = AvatarCreatorSettings(config: config).generateUrl()
print(“Loading Avatar Creator with URL: (url)”)
webView.load(URLRequest(url: url))
}
Questions
- Has there been any recent change to the ReadyPlayerMe API or asset delivery system that could cause this issue?
- Are there any known issues with asset loading for iOS implementations?
- Could this be related to token generation or authentication? If so, how can I troubleshoot this?
- Are there any specific logs or error messages I should be looking for to diagnose this problem?
Any assistance or guidance would be greatly appreciated. Thank you for your time!