I’ve been wrestling with this drawback for over a month now on Xamarin Types iOS.
I am writing an audio participant which saves securityscoped urls into my very own library saved within the sandbox. (The urls are picked from a UIDocumentPickerViewController
and saved as MinimalBookmark
s to NSData
.)
When the person selects one of many bookmarks, the app:
- Recovers the url from the
NSData
- Begins accessing the securityscoped useful resource
- Copies the file to a temp file situated within the sandbox
- Creates an
AVAudioFile
from the temp file - Seeks to 2 secs into the file
- Makes an attempt to play, at which level the above exception is thrown
Surprisingly sufficient, when a person downloads the app from the App Retailer, it appears to work wonderful for a couple of hours.
After one or two hours the exception is constantly thrown and the one option to get the playback working once more is to re-install from the App Retailer.
What is likely to be the issue right here?
Additionally be aware:
- I’ve learn articles suggesting this exception happens when the system routes to a different speaker, e.g. bluetooth speaker. This isn’t the case with my drawback, as my person is all the time utilizing the iPhone on-board speaker
My code is beneath with feedback indicating observations I’ve made when analysing the issue:
AVAudioEngine engine;
AVAudioPlayerNode participant;
AVAudioFile file;
void Play()
{
AVAudioFormat format = null;
bool restarted = false;
NSUrl url = null;
NSError err;
string tempFile;
attempt
{
url = UrlMgr.GetAudioNSUrl();
if (url == null)
return;
if (UrlMgr.IsAudioUriSecurityScoped)
{
//that is wonderful, getting entry by no means fails
if (!url.StartAccessingSecurityScopedResource())
{
AppCenterMgr.TrackWarning("Play safety error", true, "message");
return;
}
}
//get tempaudiopath copies the safety scoped file into inner storage which
//is within the app sandbox. This by no means fails
tempFile = GetTempAudioPath(url);
file = new AVAudioFile(tempFile, out err);
if (UrlMgr.IsAudioUriSecurityScoped)
url.StopAccessingSecurityScopedResource();
//these all the time give official values indicating the
//AVAudioFile has been created efficiently
_lengthSamples = file.Size;
format = file.ProcessingFormat;
_sampleRate = format.SampleRate;
//put this right here simply in case engine has been stopped unexpectedly
//however that is by no means an issue, engine is all the time working
if (!engine.Operating)
restarted = RestartEngine(true);
SetAudioPlaybackPosition();
//this works for a couple of hours, however after that fails repeatedly and
//thereafter by no means works once more
participant.Play();
//by no means reaches right here
timer.Begin();
}
catch (Exception e)
{
//Goal-C exception thrown. Title: com.apple.coreaudio.avfaudio Motive: participant didn't see an IO cycle.
AppCenterMgr.TrackError(e, "msg", e.Message,
"enginerunning", engine.Operating,
"restarted", restarted, //false
"audiofilelen", file.Size); //8691712 -> file appears to be legitimate
if (UrlMgr.IsAudioUriSecurityScoped)
url?.StopAccessingSecurityScopedResource();
}
}
uint remainingSamples;
lengthy startSample;
void SetAudioPlaybackPosition()
{
//begin playback 2 seconds in
int time = 2000;
startSample = (lengthy)(time * _sampleRate / 1000);
remainingSamples = (uint)(_lengthSamples - startSample);
participant.ScheduleSegment(file, startSample, remainingSamples, null, AVAudioPlayerNodeCompletionCallbackType.PlayedBack, OnEndReached);
}
public NSUrl GetTempAudioPath(NSUrl url)
{
string path = null;
FileInfo fi;
utilizing (FileStream s = new FileStream(url.Path.ToString(), FileMode.Open))
{
path = Path.Mix(FileSystem.AppDataDirectory, "temp.mp3");
utilizing (FileStream fileStream = File.Create(path))
{
s.Search(0, SeekOrigin.Start);
s.CopyTo(fileStream);
}
}
//examine -> this by no means fails
fi = new FileInfo(path);
if (fi.Size < 100)
{
AppCenterMgr.TrackWarning("Small Audio File", false, "path", path, "len", fi.Size);
}
return new NSUrl(path);
}
MS App Middle dump
Basis.MonoTouchException: Goal-C exception thrown. Title: com.apple.coreaudio.avfaudio Motive: participant didn’t see an IO cycle. Native stack hint: 0 CoreFoundation 0x00000001a364cf2c 00E76A98-210C-3CB5-930B-F236807FF24C + 540460 1 libobjc.A.dylib 0x000000019b552018 objc_exception_throw + 60 2 CoreFoundation 0x00000001a374b66c 00E76A98-210C-3CB5-930B-F236807FF24C + 1582700 3 AVFAudio 0x00000001bd1c4198 A161186B-22A2-3A88-B6AE-3A022764AE54 + 16792 4 AVFAudio 0x00000001bd2b23a0 A161186B-22A2-3A88-B6AE-3A022764AE54 + 992160 5 AVFAudio 0x00000001bd1c4608 A161186B-22A2-3A88-B6AE-3A022764AE54 + 17928 6 AVFAudio 0x00000001bd2aea84 A161186B-22A2-3A88-B6AE-3A022764AE54 + 977540 7 Xamarin.Sdk 0x000000010ab95510 wrapper_managed_to_native_ObjCRuntime_Messaging_objc_msgSend_intptr_intptr_6 + 128 8 Xamarin.Sdk 0x000000010ab25964 AVFoundation_AVAudioPlayerNode_Play + 36 9 MyApp.iOS 0x00000001029e0324 sqlite3_sourceid + 4210204 10 MyApp.iOS 0x0000000102a724c0 sqlite3_sourceid + 4808632 11 MyApp.iOS 0x00000001029df924 sqlite3_sourceid + 4207644 12 MyApp.iOS 0x0000000102895598 sqlite3_sourceid + 2855056 13 MyApp.iOS 0x0000000102a623f8 sqlite3_sourceid + 4742896 14 MyApp.iOS 0x0000000102894fa4 sqlite3_sourceid + 2853532 15 MyApp.iOS 0x00000001028868b0 sqlite3_sourceid + 2794408 16 Xamarin.Sdk 0x000000010aaaded4 Foundation_NSAsyncActionDispatcher_Apply + 36 17 Xamarin.Sdk 0x000000010a1b49a0 wrapper_runtime_invoke_object_runtime_invoke_dynamic_intptr_intptr_intptr_intptr + 272 18 Mono 0x000000010720fc4c mono_jit_runtime_invoke + 1136 19 Mono 0x00000001072ca41c mono_runtime_invoke_checked + 148 20 Mono 0x00000001072cdc5c mono_runtime_invoke + 144 21 MyApp.iOS 0x00000001027b9f2c sqlite3_sourceid + 1956388 22 MyApp.iOS 0x00000001027bede0 sqlite3_sourceid + 1976536 23 Basis 0x00000001a2529aa4 3D3A12E3-F5E9-361F-B00A-4A5E8861AA55 + 740004 24 CoreFoundation 0x00000001a361f834 00E76A98-210C-3CB5-930B-F236807FF24C + 354356 25 CoreFoundation 0x00000001a361f7c8 00E76A98-210C-3CB5-930B-F236807FF24C + 354248 26 CoreFoundation 0x00000001a361d298 00E76A98-210C-3CB5-930B-F236807FF24C + 344728 27 CoreFoundation 0x00000001a361c484 00E76A98-210C-3CB5-930B-F236807FF24C + 341124 28 CoreFoundation 0x00000001a361bcd8 CFRunLoopRunSpecific + 608 29 GraphicsServices 0x00000001e84cc1a8 GSEventRunModal + 164 30 UIKitCore 0x00000001a5c5490c 1741FA37-4E53-371E-8DAE-D611AAB0043D + 4237580 31 UIKitCore 0x00000001a5d089d0 UIApplicationMain + 340 32 Xamarin 0x00000001066274d8 xamarin_UIApplicationMain + 24 33 Xamarin.Sdk 0x000000010ab90ac8 wrapper_managed_to_native_UIKit_UIApplication_xamarin_UIApplicationMain_int_intptr_intptr_intptr_intptr_ + 152 34 Xamarin.Sdk 0x000000010aae07bc UIKit_UIApplication_UIApplicationMain_int_string___intptr_intptr + 76 35 Xamarin.Sdk 0x000000010aae0960 UIKit_UIApplication_Main_string___System_Type_System_Type + 224 36 MyApp.iOS 0x00000001029eb054 sqlite3_sourceid + 4254540 37 Xamarin.Sdk 0x000000010a1b49a0 wrapper_runtime_invoke_object_runtime_invoke_dynamic_intptr_intptr_intptr_intptr + 272 38 Mono 0x000000010720fc4c mono_jit_runtime_invoke + 1136 39 Mono 0x00000001072ca41c mono_runtime_invoke_checked + 148 40 Mono 0x00000001072d0724 mono_runtime_exec_main_checked + 128 41 Mono 0x00000001071ed308 mono_jit_exec + 376 42 Xamarin 0x000000010663ab84 xamarin_main + 1064 43 MyApp.iOS 0x00000001027f65bc sqlite3_sourceid + 2203828 44 dyld 0x00000001c6ccde4c 71846EAC-EE65-3697-BF7D-790B6A07DCDB + 249420