iink SDK on Device

Answered

Background/Main thread issues on iOS

Hi All,

I'm trying to get on-device recognition working in an iOS 13 app.  Using the sample app to guide me through the process of creating a fresh app, I've now managed to get the pod installed, the header file created, and I've got a basic app which starts up and lets me scribble on the editorviewcontroller.  However, as soon as I've finished writing the first character, the app crashes with the following issues:


2019-12-10 17:42:50.632667+0000 iInkSB[33156:4581595] [Assert] Cannot be called with asCopy = NO on non-main thread.

 

 

2019-12-10 17:42:50.632940+0000 iInkSB[33156:4581595] Warning: Attempt to present <UIAlertController: 0x7fd61000d000> on <SmartGuideViewController: 0x7fd60e82d800> whose view is not in the window hierarchy!

 

2019-12-10 17:45:54.501666+0000 iInkSB[33156:4581595] [Animation] +[UIView setAnimationsEnabled:] being called from a background thread. Performing any operation from a background thread on UIView or a subclass is not supported and may result in unexpected and insidious behavior.

 

2019-12-10 17:45:54.509063+0000 iInkSB[33156:4581595] [Assert] Unsupported use of UIKit view-customization API off the main thread. -setHasDimmingView: sent to <_UIAlertControllerView: 0x7fd60d50c580; frame = (0 0; 768 1024); layer = <CALayer: 0x60000137b2c0>>

 

2019-12-10 17:45:54.509367+0000 iInkSB[33156:4581595] [Assert] Unsupported use of UIKit view-customization API off the main thread. -setShouldHaveBackdropView: sent to <_UIAlertControllerView: 0x7fd60d50c580; frame = (0 0; 768 1024); layer = <CALayer: 0x60000137b2c0>>

 

2019-12-10 17:45:54.509543+0000 iInkSB[33156:4581595] [Assert] Cannot be called with asCopy = NO on non-main thread.

2019-12-10 17:45:54.509746+0000 iInkSB[33156:4581595] [Assert] Unsupported use of UIKit view-customization API off the main thread. -setAlignsToKeyboard: sent to <_UIAlertControllerView: 0x7fd60d50c580; frame = (0 0; 768 1024); layer = <CALayer: 0x60000137b2c0>>

 

2019-12-10 17:45:54.514238+0000 iInkSB[33156:4581595] This application is modifying the autolayout engine from a background thread after the engine was accessed from the main thread. This can lead to engine corruption and weird crashes.


I suspect that this is something to do with the fact that Apple are now enforcing the fact that background threads can't change the foreground ones as I ran afoul of something similar in another project, which I managed to fix by using this in my code:


DispatchQueue.main.async{

//Code goes here...

}

Any clues as to how to fix this please? Aside from the obvious build it to an earlier version of iOS?



Best Answer

Dear Robert,


currently, I tried to build your project, but was not able to, the iinkSDKInstall directory was missing, and even after trying to re-build it, I was not able to build and run your project.


Meanwhile, I looked at your project, and it appears you are adding the en_GB assets in your project, but you do not set the "lang" variable accordingly in your code.


Can you please try to set it as follows: engine.configuration.setStringArray("en_GS", forKey:"lang")


If this doesn't work, can you please provide again your full project, including the "iinkSDKInstall" directory?


Thank you,


Best regards,


Olivier


Answer

Dear Robert,


currently, I tried to build your project, but was not able to, the iinkSDKInstall directory was missing, and even after trying to re-build it, I was not able to build and run your project.


Meanwhile, I looked at your project, and it appears you are adding the en_GB assets in your project, but you do not set the "lang" variable accordingly in your code.


Can you please try to set it as follows: engine.configuration.setStringArray("en_GS", forKey:"lang")


If this doesn't work, can you please provide again your full project, including the "iinkSDKInstall" directory?


Thank you,


Best regards,


Olivier

Hi Olivier,

I've zipped a copy of the test project here:


https://www.eyeseet.com/xcode/iInkSB.zip


I'm trying to compile and run it from Xcode Version 11.3 (11C29)


Hopefully you should be able to recreate the error from the file.


Cheers,


Rob


Dear Rob,


thank you for the update.


Indeed, if you could provide the project, that would be of help.


Thank you,


Best regards,


Olivier

Hi Olivier,

I can't see any reference to smartGuideView in my project or the GettingStartedSwift project?

What version of Xcode are you using, and what version of iOS are you building for?

I can upload a copy of my project somewhere if you want to try and replicate the issue?


Rob


Dear Robert,


based on your first message, it seems the crash was occuring when trying to display the smartGuideView. In this project, did you do any change on the latter?


Best regards,


Olivier

Dear Robert,


currently, we tried with the default Demo sample on iOS, and were not able to reproduce.


Did you do any change? Is it possible to learn more?


Best regards,


Olivier

So that I can better understand how to integrate it into my own project, I've created a brand new Xcode project. This project has:

1)  Main Storyboard file which contains a UIView which has the editorviewcontroller embedded in it.

2) Bridging Header which includes all of the iink header files

3) Certificate for the project

4) recognition-assets group with the conf and languages folders required.

5) AppDelegate swift file which uses the code from the getting-started-swift AppDelegate to initialise the engine

6) ViewController swift file which uses the code from the getting-started-swift Home View Controller file:

import UIKit


class ViewController: UIViewController {


    weak var editorViewController: EditorViewController!

    

    

    

    override func viewDidLoad() {

        super.viewDidLoad()

        // Do any additional setup after loading the view.

    

    

        editorViewController = (children.first as! EditorViewController)

        

        

           if let appDelegate = UIApplication.shared.delegate as? AppDelegate {

               if (appDelegate.engine == nil)

               {

       

                   let alert = UIAlertController(title: "Certificate error",

                                                 message: appDelegate.engineErrorMessage,

                                                 preferredStyle: UIAlertController.Style.alert)

                   alert.addAction(UIAlertAction(title: "OK",

                                                 style: UIAlertAction.Style.default,

                                                 handler: {(action: UIAlertAction) -> Void in

                                                     exit(1)

                                                 }))

                    self.present(alert, animated: true, completion: nil)

                

                   return

               }

               editorViewController.engine = appDelegate.engine

        

        

    }

    editorViewController.inputMode = .forcePen  // We want the Pen mode for this GetStarted sample code. It lets the user use either its mouse or fingers to draw.

    // If you have got an iPad Pro with an Apple Pencil, please set this value to InputModeAuto for a better experience.

    

    do {

        if let package = try createPackage(packageName: "New") {

            try editorViewController.editor.part = package.getPartAt(0)

        }

    } catch {

        print("Error while creating package : " + error.localizedDescription)

    }


    }

    

    func createPackage(packageName: String) throws -> IINKContentPackage? {

        // Create a new content package with name

        var resultPackage: IINKContentPackage?

        let fullPath = FileManager.default.pathForFile(inDocumentDirectory: packageName) + ".iink"

        if let engine = (UIApplication.shared.delegate as? AppDelegate)?.engine {

            resultPackage = try engine.createPackage(fullPath.decomposedStringWithCanonicalMapping)

            

            // Add a blank page type Text Document

            if let part = try resultPackage?.createPart("Text") /* Options are : "Diagram", "Drawing", "Math", "Text Document", "Text" */ {

                self.title = "Type: " + part.type

            }

        }

        return resultPackage

    }

    

    

    

}


The engine seems to run, or at least it shows as having activated a licence in the dashboard?

Dear Robert,


thank you for your post.


Currently, in order to better understand, is it occurring while using our "getStarted" sample, or you did some changes in the latter? If so, what are these?


Thank you,


Best regards,


Olivier