1

The following code exports a file from my app's 'tmp' folder to other apps using UIActivityViewController.

private func exportFile(_ fileURL: URL) {
    let items: [Any] = [fileURL]

    let activityViewController = UIActivityViewController(activityItems: items, applicationActivities: nil)

    present(activityViewController, animated: true, completion: nil)
}

This code was working fine and I could export to iCloud, Google Drive, Mail, Outlook and iZip (the latter using 'Copy to iZip').

However, my app has recently started crashing after selecting 'Copy to iZip' when exporting, though exporting to the other apps works fine. Between it working and crashing there have been updates to iOS, iZip and my app.

Crashlytics reports the following, but this looks deep in iOS and it's difficult to know what the root cause of the problem is:

Fatal Exception: NSInvalidArgumentException *** -[__NSArrayM insertObject:atIndex:]: object cannot be nil

ShareSheet __79-[UIActivityViewController willPerformInServiceActivityWithRequest:completion:]_block_invoke_3

This occurs on an iPhone running iOS 13.3.1

Debugger report on breaking on NSInvalidArgumentException:

> (lldb) bt
* thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
    frame #0: 0x0000000189ffdf6c libobjc.A.dylib`objc_exception_throw
    frame #1: 0x000000018a32c360 CoreFoundation`_CFThrowFormattedException + 112
    frame #2: 0x000000018a32b9f4 CoreFoundation`-[__NSArrayM insertObject:atIndex:].cold.1 + 48
    frame #3: 0x000000018a1ae120 CoreFoundation`-[__NSArrayM insertObject:atIndex:] + 1104
    frame #4: 0x0000000195914e80 ShareSheet`__79-[UIActivityViewController willPerformInServiceActivityWithRequest:completion:]_block_invoke_3 + 1512
    frame #5: 0x00000001089497fc libdispatch.dylib`_dispatch_call_block_and_release + 24
    frame #6: 0x000000010894abd8 libdispatch.dylib`_dispatch_client_callout + 16
    frame #7: 0x0000000108958c34 libdispatch.dylib`_dispatch_main_queue_callback_4CF + 1316
    frame #8: 0x000000018a2545e4 CoreFoundation`__CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 12
    frame #9: 0x000000018a24f5d8 CoreFoundation`__CFRunLoopRun + 2004
    frame #10: 0x000000018a24eadc CoreFoundation`CFRunLoopRunSpecific + 464
    frame #11: 0x00000001941ef328 GraphicsServices`GSEventRunModal + 104
    frame #12: 0x000000018e35c63c UIKitCore`UIApplicationMain + 1936
  * frame #13: 0x00000001024f1078 xApp`main at AppDelegate.swift:41:7
    frame #14: 0x000000018a0d8360 libdyld.dylib`start + 4
(lldb) 

Code at frame #4 breakpoint (0x195914e80):

> WTFLogLevel, WTF::Logger::LogSiteIdentifier const&, char const (&) [7], unsigned long const&) (.cold.1)   
0x195914e80 <+1512>: mov    x28, x23
0x195914e84 <+1516>: ldr    x0, [x23, #0xba0]
0x195914e88 <+1520>: ldr    x1, [sp, #0x38]
0x195914e8c <+1524>: mov    x2, x25
0x195914e90 <+1528>: mov    x3, x20
0x195914e94 <+1532>: bl     0x193904be4               ; symbol stub 

Any idea what the problem might be? I'm not sure whether it's a problem with my app, iOS or iZip.

gimbal
  • 63
  • 8
  • Looks like you are trying to insert something that is `nil` into an array. So based on the code you shared, what does `items` look like, is it maybe `nil` ? – koen Mar 06 '20 at 20:26
  • @koen, thanks but items is an array holding the file's URL and isn't nil. It seems that an attempt is made to write nil to another array later on somewhere deep in iOS, but this only happens when sharing the file via 'Copy to iZip', but not when sharing to the other apps mentioned. – gimbal Mar 06 '20 at 21:19
  • Can you post the code that contains the offending line? You can add an exception breakpoint in Xcode which will tell you where it crashes. https://stackoverflow.com/questions/17802662/how-to-add-exception-breakpoint-in-xcode – koen Mar 06 '20 at 23:18
  • I've added the exception breakpoint info suggested by @koen. Gives the impression its crashing in a WebKit function - https://github.com/WebKit/webkit/blob/master/Source/WTF/wtf/Logger.h – gimbal Mar 07 '20 at 12:31
  • Did you contact the iZip developer? – koen Mar 08 '20 at 15:07
  • @koen - not yet but thanks for the hint re the breakpoint which seems to point to WebKit. Not sure why WebKit is being called in this situation if it really is being called. I'll look at contacting the WebKit team and/or the iZip developer when I've gathered some more info. – gimbal Mar 10 '20 at 08:36
  • not sure if it is still the case but `WebKit` is used under the hood for the drawing of other UI elements. – koen Mar 10 '20 at 11:45
  • You can try to move a file to /Library directory before pass it to UIActivityViewController. /tmp folder can purge your file at some point, especially while iOS talks to some other app. – Iliyan Kafedzhiev Mar 13 '20 at 23:06
  • Have now looked at the debug more carefully and the crash actually happens in ShareSheet`__79-[UIActivityViewController willPerformInServiceActivityWithRequest:completion:]_block_invoke_3 as reported by Crashlytics, rather than crashing in WebKit as I suggested earlier. Have also got a solution which I'll post as an answer. – gimbal Mar 14 '20 at 12:34

1 Answers1

0

Thanks to the suggestion from @koen, I contacted iZip support and had a very quick and helpful response. It also ties in with @WILL K. 's suggestion of trying a different directory.

The problem basically seems to be associated with directory permissions. Apparently some apps like iZip open the shared file in situ and so need permission to do so. As can be seen here https://developer.apple.com/library/archive/documentation/FileManagement/Conceptual/FileSystemProgrammingGuide/FileSystemOverview/FileSystemOverview.html , the Documents/ directory "can be made available to the user through file sharing" whereas the tmp/ directory is more restricted.

So instead of using the tmp/ directory I tried using the Documents/ directory and the problem was solved. Thanks to iZip support for their rapid response and highlighting the issue with permissions.

For interest, on using the /Documents folder, more options came up for sharing with other apps.

There is also a useful article on how app extensions work (host apps, app extensions and container apps) here: https://developer.apple.com/library/archive/documentation/General/Conceptual/ExtensibilityPG/ExtensionOverview.html

gimbal
  • 63
  • 8