Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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.

like image 562
Alan Moore Avatar asked May 14 '18 04:05

Alan Moore


1 Answers

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];
like image 196
chaunv Avatar answered Nov 14 '22 16:11

chaunv