10

Similar to this this question,

I am having issues and my app is crashing in the same way. I would assume the same answer as on the other question: memory issue; except I am getting the crash during an AVAssetExportSession call.

guard let exporter = AVAssetExportSession(asset: mixComposition, presetName: AVAssetExportPresetHighestQuality) else { return }
        exporter.outputFileType = AVFileTypeMPEG4
        exporter.outputURL = url
        exporter.videoComposition = mainComposition
        print("done")

        exporter.exportAsynchronously(completionHandler: {
            DispatchQueue.main.async(execute: {
                self.exportDidFinish(exporter)
                print("removing AI")
                self.removeAI()
                print("removed AI")
                completion()
            })
        })

func exportDidFinish(_ exporter:AVAssetExportSession) {
    if(exporter.status == AVAssetExportSessionStatus.completed) {
        print("cool")
    }
    else if(exporter.status == AVAssetExportSessionStatus.failed) {
        print(exporter.error as Any)
    }
}

It prints "done" but it never prints "removing AI". It also doesn't print "cool" or "(error)"; it crashes and says at the top of XCode "Lost connection to iPhone..." just as the other question states.

I would assume it is a memory issue, but there is nothing happening in between (to my knowledge of how this works) during the asynchronous exporting as I am just waiting for the completion handler to be called. But nothing gets called in between and I am unsure how to handle this. Any thoughts?

impression7vx
  • 1,728
  • 1
  • 20
  • 50
  • try putting try ,catch block , and post the stack trace of crash ? – Saket Kumar Aug 22 '17 at 12:50
  • 1
    Umm. If you referenced the above post, you would see there is no way to catch it. It just crashes and says it cannot connect to the device. And the app crashes. There is no log, there is no "problem" it shows me. That is why I assume from the other post it might be memory. – impression7vx Aug 22 '17 at 15:42
  • to be able to better assist you I suggest you create the smallest code that reproduces the issue so we can also test it. Additionally I suggest a heuristic method that is: you remove some chunk of your code and see if it fails...if it doesn't then put that part back and remove another part or more parts of your code until it doesn't crash. Then you may be able to identify the source of the problem – mfaani Aug 22 '17 at 15:59
  • That sounds nice and all, but the crash doesn't happen every time. It would be hard to test the capabilities of such. – impression7vx Aug 22 '17 at 16:27
  • I solve a similar issue using the Memory Allocation template in Instruments to find which method was allocating a lot of memory. It can help you locate what is going wrong even if it doesn't crash every time. – Sparga Aug 22 '17 at 21:43
  • Do you receive at least a memory warning in Logs? – Sakshi Aug 27 '17 at 12:00
  • Do you load any Any gif Or High resolution image in project? – Hitesh Surani Aug 28 '17 at 10:01

2 Answers2

4

I think that AVAssetExportSession object may be deallocated while running async task. Consider put it as a class variable to make sure that async block can finish it's task. It will be something like:

class myClass {
    var exporter: AVAssetExportSession?

    func export() {
        exporter = AVAssetExportSession(asset: mixComposition, presetName: AVAssetExportPresetHighestQuality)
        guard exporter != nil else { return }
        exporter.outputFileType = AVFileTypeMPEG4
        exporter.outputURL = url
        exporter.videoComposition = mainComposition
        print("done")

        exporter?.exportAsynchronously(completionHandler: { 
            DispatchQueue.main.async {
               self.exportDidFinish(exporter)
               print("removing AI")
               self.removeAI()
               print("removed AI")
               completion()
           }
        }
    }
}

I'm really not sure why you also put everything on a main thread in completion block, but maybe you want to do something with UI later, so I leave it there.

But most import is - make your AVAssetExportSession not stored on method that may dealloc it. It's a memory issue that could cause this.

Jakub
  • 13,712
  • 17
  • 82
  • 139
  • You think that would cause a crash completely as discussed in the other question? I would think this MIGHT cause issues with something being nil. And inside the completion block I do a lot with UI, therefore I need the main thread. That is what most completion blocks have (in my experiences) – impression7vx Aug 22 '17 at 19:01
  • Yes, I do, just try it out. main tread is ok, but store object outside func to prevent deallocation while task is running on async thread. The same case is for example for CoreLocation, when you create internal func object that can range a beacons and try to force ranging on it it will lead to object deallocation and in the end not return any values. – Jakub Aug 22 '17 at 19:05
  • Yea, dealt with that issue before. But when I used CoreLocation, it provided an error and said it couldn't be found in which there was a crash log. This just shows a "Device disconnected from XCode" – impression7vx Aug 22 '17 at 19:06
  • This would depend on how it is internally implemented in the framework. Just because CoreLocation produces a "proper crash" doesn't mean it's not the same issue here. Your code snippet in the question doesn't actually show how/if you store the exporter somewhere, but from what I can see it looks like the scope you defined it might not be valid anymore when it finishes. I have seen this lead to losing connection to the phone when debugging. Also, when implementing Kuba's solution, ensure the class instance doesn't get dealloc'ed too early (that would be the same problem then). – Gero Aug 23 '17 at 07:55
  • Yep, for testing if that was a problem you can even store `myClass` as variable in `AppDelegate` to make sure that it will be not deallocated, but please move it if this fix an issue :D – Jakub Aug 23 '17 at 07:57
  • This answer still doesn't make sense because the crash doesn't happen every time. Theoretically, the exporter should be deallocated every time causing an issue – impression7vx Aug 29 '17 at 18:43
  • "Theoretically, the exporter should be deallocated every time causing an issue" - no, that's not true. You don't have any control when object is deallocated from the memory. That's most of the issues when something "sometimes happen" – Jakub Aug 30 '17 at 11:10
  • Haha okay. It's just hard to wrap my head around it. I will try it out over a period of time and reopen the question to reward if it works. Thank you – impression7vx Aug 30 '17 at 15:57
3

I had this issue before, it wasn't a memory issue for me. I don't know how exactly I got resolved, but I these are the things I did:

I deleted the app, hard reset the phone, cleaned build on Xcode, restarted Xcode, deleted derived data, and if I remember correctly changed the USB port until it got fixed.

I also had console and a VM open, I closed them as well.

mfaani
  • 33,269
  • 19
  • 164
  • 293
  • This happens on Test Flight/Running from the computer and on multiple devices including simulator and tester's phones. – impression7vx Aug 22 '17 at 12:27
  • @impression7vx ohhh. Weird. Kindly add that info to your question as I thought this happens only on device. But I don't know any more – mfaani Aug 22 '17 at 12:35
  • I did, when I said "similar to this question" and the other question immediately states "My app crashes and I need some advice to find and fix the problem. It is not a device or cable problem because it happens with all devices and not only when debugging". No point in me restating the problem for my own conditions in its entirety. – impression7vx Aug 22 '17 at 15:43