Solvedreact native track player App crash on iOS, even on mode debug

Configuration

Run react-native info in your project and share the content.
What react-native-track-player version are you using?

"react-native-track-player": "^1.1.8",

Issue

The app crash on ios when I run from terminal by react-native run-ios so I cannot see the log, then I run it from xcode and I got the error message. It is
Fatal error: Unexpectedly found nil while unwrapping an Optional value: file /Users/boypanjaitan/Desktop/React/TeduhKu/node_modules/react-native-track-player/ios/RNTrackPlayer/Models/MediaURL.swift, line 28

Code

this is my code

`setUpPlayer = async (tmpTrack) => {
let state = await TrackPlayer.getState();

    if (state === TrackPlayer.STATE_NONE) {
        TrackPlayer.setupPlayer().then(() => {
            TrackPlayer.updateOptions({
                // One of RATING_HEART, RATING_THUMBS_UP_DOWN, RATING_3_STARS, RATING_4_STARS, RATING_5_STARS, RATING_PERCENTAGE
                ratingType: TrackPlayer.RATING_5_STARS,

                // Whether the player should stop running when the app is closed on Android
                stopWithApp: true,
                alwaysPauseOnInterruption: true,
                capabilities: [
                    TrackPlayer.CAPABILITY_PLAY,
                    TrackPlayer.CAPABILITY_PAUSE,
                    TrackPlayer.CAPABILITY_STOP,
                    TrackPlayer.CAPABILITY_SKIP_TO_NEXT,
                    TrackPlayer.CAPABILITY_SKIP_TO_PREVIOUS
                ],

                // An array of capabilities that will show up when the notification is in the compact form on Android
                compactCapabilities: [
                    TrackPlayer.CAPABILITY_PLAY,
                    TrackPlayer.CAPABILITY_PAUSE,
                    TrackPlayer.CAPABILITY_STOP,
                    TrackPlayer.CAPABILITY_SKIP_TO_NEXT,
                    TrackPlayer.CAPABILITY_SKIP_TO_PREVIOUS
                ],
                notificationCapabilities : [
                    TrackPlayer.CAPABILITY_PLAY,
                    TrackPlayer.CAPABILITY_PAUSE,
                    TrackPlayer.CAPABILITY_STOP,
                    TrackPlayer.CAPABILITY_SKIP_TO_NEXT,
                    TrackPlayer.CAPABILITY_SKIP_TO_PREVIOUS
                ],
                icon    : require('../img/icon.png')
            });
        });
    }

    TrackPlayer.add(tmpTrack)
        .then(() => {
            if(state !== TrackPlayer.STATE_PLAYING){
                TrackPlayer.stop();
            }
        })
        .catch(err => {
            Alert.alert('Player Error', err.toString());
        });

    console.log('NOW : '+state);

};`
21 Answers

✔️Accepted Answer

Hi,
Disclaimer: I have touched Swift code from time to time, but I'm not an expert so please correct me if I did something wrong.

I received the exact same issue earlier today.

For me, the above solution by @zacharywenner looks like an extremely expensive workaround (basically building in a whole caching layer and extra latency + if the audio files you wanna play are over 1h in length you need to wait a long time).

Upon investigating the file in question that the issue references we find the following line throwing an exception:

value = URL(string: url.replacingOccurrences(of: "file://", with: ""))!

This is trying to parse an URL and for some reason many conventional URLs fail with this. Even ones with no formatting errors as I've seen on SO and other places while debugging the issue. You need to call a function that's in fact called a few lines above (I guess it was a different person writing the two pieces since they are very simlar solutions to the same problem).

Namely on line 23 you can find:

let encodedURI = uri.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)!

This is pretty much a perfect solution that encodes any special character it finds in the given URL. I am not sure why it wasn't called before line 28 but adding it solves the issue.

if you add this line right before line 28:
let encodedURL = url.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)!
and modify line 28 to use encodedURL instead of url the module works flawlessly.

With this the two lines would look like this:

let encodedURL = url.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)!
value = URL(string: encodedURL.replacingOccurrences(of: "file://", with: ""))!

And just in case beginners stumble on this issue here's a collapsed version of the whole file as of Jan 11 2020:

Instructions

The file is in XCode -> Pods/Development Pods/react-native-track-player/Models/MediaURL.swift

//
//  MediaURL.swift
//  RNTrackPlayer
//
//  Created by David Chavez on 12.08.17.
//  Copyright © 2017 David Chavez. All rights reserved.
//

import Foundation

struct MediaURL {
    let value: URL
    let isLocal: Bool
    private let originalObject: Any
    
    init?(object: Any?) {
        guard let object = object else { return nil }
        originalObject = object
        
        if let localObject = object as? [String: Any] {
            let uri = localObject["uri"] as! String
            isLocal = uri.contains("http") ? false : true
            let encodedURI = uri.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)!
            value = URL(string: encodedURI.replacingOccurrences(of: "file://", with: ""))!
        } else {
            let url = object as! String
            isLocal = url.lowercased().hasPrefix("file://")
            let encodedURL = url.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)!
            value = URL(string: encodedURL.replacingOccurrences(of: "file://", with: ""))!
        }
    }
}

I hope this will help someone save the hours I've spent with this.

@Guichaguri if you think this should be a PR let me know.

More Issues: