AVCaptureSession Crashing when using webRTC - webrtc

I am using WebRTC and its using AVCaptureSession. It works fine a few times but sometimes its getting crashed with this Exception.
Assertion failed: (_internal->figCaptureSession == NULL), function
-[AVCaptureVideoPreviewLayer attachToFigCaptureSession:], file /BuildRoot/Library/Caches/com.apple.xbs/Sources/EmbeddedAVFoundation/EmbeddedAVFoundation-1187.37.2.1/Aspen/AVCaptureVideoPreviewLayer.m

I recently had this problem aswell. In my code i kept an instance of AVCaptureOutput and added and removed it. When trying to add the same AVCaptureOutput instance to the same capture session again, this error appeared.
This is how i solved it:
private var _captureOutput: AVCaptureOutput?
var captureOutput: AVCaptureOutput {
guard let captureOutput = _captureOutput else {
let photoOutput = AVCapturePhotoOutput()
photoOutput.isHighResolutionCaptureEnabled = true
_captureOutput = photoOutput
return photoOutput
}
return captureOutput
}
Initialize the instance once when needed and when removed, also nullify it.
captureSession.outputs.forEach { [weak self] output in
self?.captureSession.removeOutput(output)
self?._captureOutput = nil
}

Before using instance of RTCCameraPreviewView you have to nill'ify its captureSession and assert will go away. Faced same issue.

Related

Mac OSX app : Issue Related to NSArrayController NSTableView Core data Adding Record

I have using NSArrayController NSTableView and Core data binding.
I have take one button and connect add: method of NSArrayController to its action.
On Adding new record
TableView added and shows new record.
NSArrayController's add: method called
Problem :
Value is not added into core data (Sqlite type).
On application relaunching shows old data.
This is an apple example code. Basically it tries to save the context before app is terminated. Depending on your specific case you might move the functionality to somewhere else.
func applicationShouldTerminate(_ sender: NSApplication) -> NSApplication.TerminateReply {
// Save changes in the application's managed object context before the application terminates.
let context = persistentContainer.viewContext
if !context.commitEditing() {
NSLog("\(NSStringFromClass(type(of: self))) unable to commit editing to terminate")
return .terminateCancel
}
if !context.hasChanges {
return .terminateNow
}
do {
try context.save()
} catch {
let nserror = error as NSError
// Customize this code block to include application-specific recovery steps.
let result = sender.presentError(nserror)
if (result) {
return .terminateCancel
}
let question = NSLocalizedString("Could not save changes while quitting. Quit anyway?", comment: "Quit without saves error question message")
let info = NSLocalizedString("Quitting now will lose any changes you have made since the last successful save", comment: "Quit without saves error question info");
let quitButton = NSLocalizedString("Quit anyway", comment: "Quit anyway button title")
let cancelButton = NSLocalizedString("Cancel", comment: "Cancel button title")
let alert = NSAlert()
alert.messageText = question
alert.informativeText = info
alert.addButton(withTitle: quitButton)
alert.addButton(withTitle: cancelButton)
let answer = alert.runModal()
if answer == .alertSecondButtonReturn {
return .terminateCancel
}
}
// If we got here, it is time to quit.
return .terminateNow
}
You're probably missing setting the managedObjectContext and entityName on NSArrayController.

Having Trouble Getting the UIDocumentBrowserController to open docs in a Document based app

I've been working on a new Document-based app, and was super glad about the new UIDocumentBrowserController...trying to roll my own solution for the document browser UI was tricky!
I'm having some trouble getting the browser to open documents after they've been created.
What happens now is that when I choose to create a new document in the document browser, the document is created and opened as expected, although an error message is logged. However, after the doc is closed, I cannot reopen the file, either immediately or upon subsequent launches, even though the document is displayed. However, a weird clue here is that if I stop running the app after creating the document, but without adding new information to it (triggering the save cycle), and run the project again, I can open the file correctly. Whuch makes me think that there's something in the way the files are being saved that is the issue.
(Note: At this phase, I'm working on getting the local, non/icloud implentation working, before I move on to the icloud implementation.)
Here is the error message at any point in the code whenthe document is saved to disk (or at least most of the time!):
2017-06-20 13:21:58.254938-0500 Sermon Design 2 iOS[22454:5000138] [default] [ERROR] Could not get attribute values for item file:///Users/stevenhovater/Library/Developer/CoreSimulator/Devices/9A4364F2-B3A1-4AD9-B680-FB4BC876C707/data/Containers/Data/Application/DD534ED8-C4A3-40FE-9777-AED961976878/Documents/Untitled-9.sermon. Error: Error Domain=NSFileProviderInternalErrorDomain Code=1 "The reader is not permitted to access the URL." UserInfo={NSLocalizedDescription=The reader is not permitted to access the URL.}
I suspect that the issue lies somewher in my document types plists, which I've tried to set up by imitating the setup in the video for wwdc 2017 session 229.
My docs are encapuslated by an NSData object, using what I take to be a pretty standard subclass implentation of UIDocument. (I'm omitting the code to generate the thumbnails)
override func contents(forType typeName: String) throws -> Any {
print("Saving Document Changes")
if sermon != nil {
let newData = NSKeyedArchiver.archivedData(withRootObject: sermon!)
return newData
} else {
let newData = NSKeyedArchiver.archivedData(withRootObject: Sermon())
return newData
}
}
override func fileAttributesToWrite(to url: URL, for saveOperation: UIDocumentSaveOperation) throws -> [AnyHashable : Any] {
let thumbnail:UIImage = self.createThumbnail()
let thumbnaildict = [URLThumbnailDictionaryItem.NSThumbnail1024x1024SizeKey : thumbnail]
let dict = [URLResourceKey.thumbnailDictionaryKey:thumbnaildict]
return dict
}
override func load(fromContents contents: Any, ofType typeName: String?) throws {
guard let newSermon:Sermon = NSKeyedUnarchiver.unarchiveObject(with: contents as! Data) as? Sermon else{
throw documentErrors.invalidFile
}
self.sermon = newSermon
}
In my subclass of UIDocumentBrowserViewController, Here is my code for getting a local filename and for creating the new document.
func documentBrowser(_ controller: UIDocumentBrowserViewController, didRequestDocumentCreationWithHandler importHandler: #escaping (URL?, UIDocumentBrowserViewController.ImportMode) -> Void) {
var newDocumentURL: URL? = nil
print("creating new local document")
guard let target = self.newLocalFilename() else {
return
}
let targetSuffix = target.lastPathComponent
let tempURL = URL(fileURLWithPath: NSTemporaryDirectory() + targetSuffix)
let newDocument:SDDocument = SDDocument(fileURL: tempURL)
newDocument.sermon = Sermon()
/
newDocument.save(to: tempURL, for: .forCreating) { (saveSuccess) in
/
guard saveSuccess else {
/
importHandler(nil, .none)
return
}
/
newDocument.close(completionHandler: { (closeSuccess) in
/
guard closeSuccess else {
/
importHandler(nil, .none)
return
}
/
importHandler(tempURL, .move)
})
}
}
func newLocalFilename() -> URL? {
let fileManager = FileManager()
guard let baseURL = self.localDocumentsDirectoryURL.appendingPathComponent("Untitled")
else {return nil}
var target = baseURL.appendingPathExtension(DocumentBrowserViewController.documentExtension)
var nameSuffix = 2
while fileManager.fileExists(atPath: target.path) {
target = URL(fileURLWithPath: baseURL.path + "-\(nameSuffix).\(DocumentBrowserViewController.documentExtension)")
nameSuffix += 1
}
let targetSuffix = target.lastPathComponent
print("Target name: \(targetSuffix)")
print("new url: \(target)")
return target
}
After four or five hours of work banging my head against this problem, I discovered a simple solution: don't test in the Simulator. I switched to testing on my device and instantly everything started working as advertised.
[I can't speak from experience here, but it may be that the "doesn't work in the Simulator" problem is confined to Sierra, but that the Simulator does work in High Sierra. This would explain why some users see this issue and others don't, and especially why Apple seems blissfully unaware of it in the WWDC video.]
I had exactly the same issue when I was trying to save to NSTemporaryDirectory().
If you instead save to the documents directory ([[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] firstObject]), it appears to work fine!
Update: it looks like this issue is fixed in iOS 11 beta 3, and you can now save newly created documents to NSTemporaryDirectory() correctly.
Here is my current theory.
This error
Error Domain=NSFileProviderInternalErrorDomain Code=1 "The reader is not permitted to access the URL."
shows up when first creating a UIDocument at a new URL using -initWithFileURL. It's basically saying "this URL doesn't exist yet," but in a way that makes it sound more like a permissions issue.
As far as I can tell, it doesn't prevent you from saving, opening, editing, or closing the file. So I think it's just a superfluous error that Apple should have taken out.
I found that the error happens on simulator when LSSupportsOpeningDocumentsInPlace property is set to YES in the info.plist.
Turn this property to NO, then it starts working, in my case.
On the real device, it works anyway without having error.
Had similar problem, and tried the method for providing a default Core Location in the Schemes settings and it works now. The method was mentioned in this answer: IOS 9 Error Domain=kCLErrorDomain Code=0 "(null)"

call can throw error message Swift 2

I just converted my app to Swift 2, and of course, am getting one error message:
"Call can throw, but it is not marked with 'try' and the eror is not handled"
I did search here for how to fix this, but the answers are even more confusing to me than the error itself. LOL.
My application worked perfectly until I converted it into Swift 2. Wonderful...
var myPlayer = AVAudioPlayer()
var yourSound1 = NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource("RemSound_01", ofType: "wav")!)
func initYourSound() {
myPlayer = AVAudioPlayer(contentsOfURL: yourSound1, fileTypeHint: nil)
myPlayer.prepareToPlay()
myPlayer.volume = 1.0 // < for setting initial volume, still not perfected.
}
The error throws in the following line:
myPlayer = AVAudioPlayer(contentsOfURL: yourSound1, fileTypeHint: nil)
How am I supposed to fix this? I understand that Swift is trying to "universalize" error handling, but doing so by breaking even the simplest of code seems silly to me.
Thank you for your help.
Here is the pattern you are looking for.
<throwing function> // compiler error in Swift 2
do { try <throwing function> } catch { }
In catch you usually get an error that you can handle further.
This works in Swift 2.0, put it in your viewDidLoad method ...
do {
try AudioPlayer = AVAudioPlayer(contentsOfURL: ButtonAudioURL, fileTypeHint: nil)
} catch {
print("errorin do-try-catch")
}
where ButtonAudioURL is
var ButtonAudioURL = NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource("Besides", ofType: "mp3")!)

Establish callback in Swift for PubNub 4.0 to receive messages

It appears to me that the documentation PubNub has for getting started in Swift don't apply to versions earlier than PubNub 4.0. I can't successfully establish a callback to register with PubNub.
My code:
class Communicator: NSObject, PNObjectEventListener {
var pubNubClient: PubNub
override init(){
let config = PNConfiguration(
publishKey: "my_publish_key",
subscribeKey: "my_subscribe_key"
)
pubNubClient = PubNub.clientWithConfiguration(config);
super.init()
pubNubClient.addListener(self)
pubNubClient.subscribeToChannels(["my_channel"], withPresence: false)
}
func didReceiveMessage(client: PubNub!, message: PNMessageResult!){
/* THIS METHOD NEVER GETS REACHED */
}
}
Digging into the PubNub source a bit, this is the area that seems to be having problems:
- (void)addListener:(id <PNObjectEventListener>)listener {
dispatch_async(self.resourceAccessQueue, ^{
if ([listener respondsToSelector:#selector(client:didReceiveMessage:)]) {
/* this block is never reached!!! */
[self.messageListeners addObject:listener];
}
/* Remaining Lines Stripped Away */
});
}
I'm still relatively new to Swift and integrating with Objective C. I'm curious if there's a problem with the respondsToSelector since the Objective C code is referencing Swift code.
The messages are definitely getting passed; there's another lower level function in the PubNub library that's logging all the messages received.
Any help would be much appreciated.
Versions prior to 4.0 are deprecated and wont work exactly how they used to.
I would recommend migrating over to the newest (4.0) SDK entirely, the new iOS SDK has removed a lot of bloat and compiles much faster. To get started view this tutorial.
To summarize, instantiating a PubNub client look as follows:
let config = PNConfiguration(
publishKey: "Your_Pub_Key",
subscribeKey: "Your_Sub_Key")
client = PubNub.clientWithConfiguration(config)
client?.addListener(self)
client?.subscribeToChannels(["Your_Channel"], withPresence: false)
And the new didReceiveMessage function looks as follows:
func client(client: PubNub!, didReceiveMessage message: PNMessageResult!, withStatus status: PNErrorStatus!) {
//Do Something like
//println(message)
}
Resolved by adding:
func client(client: PubNub!, didReceiveMessage message: PNMessageResult!) {
}
The documentation on how to parse the received PNMessageResult is scant. Here's how I handled it:
func client(client: PubNub!, didReceiveMessage message: PNMessageResult!) {
let encodedMessage = message.data.valueForKey("message") as! NSDictionary
let messageType = encodedMessage["meta"]! as! String
let messageString = encodedMessage["data"]!["msg"]! as! String
print("PubNub: [\(messageType)] \(messageString)")
}
add _ client works for me!
func client(_ client: PubNub, didReceiveMessage message: PNMessageResult) {
print("Pubnub Message: \(message)")
}

Monotouch: UIAlertView and WCF services, debugger.StackTrace

I'm currently using WCF in monotouch to call an existing service and a custom UIAlertView.
The problem is that if I create an UIAlertView as class instance and the I do the following:
public override void ViewDidAppear()
{
_alertView.Message = "Loading...";
_alertView.Show();
_client.GetDataAsync("test");
_client.GetDataCompleted += GetDataCompletedDelegate;
base.ViewDidAppear();
}
void GetDataCompletedDelegate(object sender, GetDataEventArgs)
{
// do someting with data
_alertView.Hide();
}
it works but this advice is written in console : UIAlertView: wait_fences: failed to receive reply: 10004003
else, if I try to run this code:
public override void ViewDidAppear()
{
using(CustomAV _alertView = new CustomAV())
{
_alertView.Message = "Loading...";
_alertView.Show();
_client.GetDataAsync("test");
_client.GetDataCompleted += delegate{
InvokeOnMainThread(delegate{
// do someting with data
_alertView.Hide();
});
};
}
base.ViewDidAppear();
}
the first time the code run, but now alert is shown. The second time the simulator can't startup. Couldn't register "com.yourcompany.wcftest" with the bootstrap server. Error: unknown error code. This generally means that another instance of this process was already running or is hung in the debugger.StackTrace. In this case I have to reboot the machine.
Thank you in advance.
EDIT:
Thank you Geoff, I've checked my code and into GetDataCompletedDelegate I've inserted a function that runs inside the UI Thread.
InvokeOnMainThread(delegate{
doSomething();
});
private void doSomething()
{
// do stuff here
_alertView.Hide();
}
The fency error continues to appear. If I use your solution inside doSomething() method, it works
_alertView.InvokeOnMainThread(delegate{
_alertView.Hide();
});
Why? Maybe I didn't understand, but in the first snippet of code do something() works in the UI thread!! Isn't true?
You have 2 seperate problems here.
1: _alertView.Hide () is not running on the UI thread (this is what causes the fences error)
2: In your second example you're disposing the UIAlertVeiw immediately after creating it, but you have a instance delegate dangled off it. This crashes the runtime in a hard way, and then when you run it again since the old crashed process is still running the simulator wont let you start a second instance.
Use case #1 but do _alterView.InvokeOnMainThread (delegate { _alertView.Hide (); });