App Transport Security issue with AVAudioPlayer loading local file objective-C, XCode 9

655 views Asked by At

I have an app which loads a bundled m4a audio file as a local resource and it has worked well for many years now. I'm updating the app to iOS 11.3/XCode 9.3 and it is now failing on iPad (works on iPhone) when I press my play button:

2018-05-13 20:45:24.437626-0700 my app[6175:218735] App Transport Security has blocked a cleartext HTTP (http://) resource load since it is insecure. Temporary exceptions can be configured via your app's Info.plist file.
2018-05-13 20:45:24.437791-0700 my app[6175:218735] Cannot start load of Task <117E064E-ABB3-45F2-8D64-76397B140092>.<0> since it does not conform to ATS policy
2018-05-13 20:45:24.437948-0700 my app[6175:218732] NSURLConnection finished with error - code -1022

My code:

NSURL *medURL   = [[NSBundle mainBundle] URLForResource: @"MyFile"
                                          withExtension: @"m4a"];
NSError *playerError = nil;
AVAudioPlayer *newPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL: medURL error: &playerError];
self.appSoundPlayer = newPlayer;

// "Preparing to play" attaches to the audio hardware and ensures that playback
//      starts quickly when the user taps Play
[appSoundPlayer prepareToPlay];

It fails on the prepareToPlay.

Reading other answers I've found a lot of information on the ATS error so I added this to my plist file for the app, cleaned, rebuilt and ran it -- but I am still getting the error:

<key>NSAppTransportSecurity</key>
<dict>
    <key>NSAllowsLocalNetworking</key>
    <true/>
    <key>NSAllowsArbitraryLoadsForMedia</key>
    <true/>
    <key>NSAllowsArbitraryLoads</key>
    <true/>
    <key>NSAllowsArbitraryLoadsInWebContent</key>
    <true/>
    <key>NSExceptionAllowsInsecureHTTPLoads</key>
    <true/> </dict>

I can't use the NSExceptionDomain key because this is a local resource, there is no domain. How can I fix this?

Note: to be clear, this file is bundled into the app and has not been downloaded at any time. This is not an "http" url, it is a "file:" url.

Update: Looking at the CFNetworkLog I realized that there was a NSURLConnection to the network happening just before the audio prep in AppDelegate. When I removed this call everything started working. Since both work independently, it appears to me that there is some sort of conflict in NSURLConnection which is happening -- possibly a bug in the API? It would be good to know what the proper work-around is for this, I have gotten it to work well enough by removing the prepareToPlay call above -- this is not ideal as it takes longer when the user goes to play the audio file.

Another update: the app started working today for no apparent reason, I hadn't changed anything since the last time I tried it. Unfortunately I can't determine if fixes work at this point! To be sure, it does appear that my plist keys are working in my iOS 11.3 simulator.

1

There are 1 answers

0
chaunv On

In my project is using AVAudioPlayer to play audio, and my source code:

NSString *soundFilePath = [[NSBundle mainBundle] pathForResource:@"MyFile"  ofType:@"m4a"];
NSURL *soundFileURL = [NSURL fileURLWithPath:soundFilePath];
AVAudioPlayer* audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:soundFileURL error:nil];
audioPlayer.numberOfLoops = -1; //Infinite
[audioPlayer setVolume:1];
[audioPlayer play];