Hiding CoreML model (.mlmodel) files - ios

I am working on a project which involves adding AI object detection capabilities to an existing iOS APP. I was able to train my own DNN models and converted to the CoreML's .mlmodel format.
Now I need to transfer my work which includes the .mlmodel files to another developer for integration. However, I don't want them to use my trained .mlmodel files outside of this project (according to contract). Is there any way that I can do to just "hide" the .mlmodel files so they can only be used for this particular APP and can't be simply copied and saved for other uses?
I have done some quick research on iOS library and framework, but I am still not sure if that's the solution I am looking for.

Nope. Once someone has access to your mlmodel file or the compiled version, mlmodelc, they can use it elsewhere.
For example, you can download an app from the App Store, look inside the IPA file, copy their mlmodelc folder into your own app, and start using the model right away.
To prevent outsiders from stealing your model, you can encrypt the model (just like you'd encrypt any other file) but that only works if you can hide the decryption key. You can also add a custom layer to the model, so that it becomes useless without the code for this custom layer.
However, those solutions don't work if you're hiring an external developer to work on your app because they will -- out of necessity -- need to have access to these decryption keys and source code files.
I'm not sure what exactly you want this other developer to do, but if you don't trust them, then:
get a new developer that you do trust,
be prepared to enforce the contract, or
give them a version of your mlmodel file with the weights replaced by random numbers. The model will still work but give nonsense predictions. Once that developer is done with their work, replace the model with the real one. Obviously, this is not a good solution if they need to use the model for whatever work they need to do.

Related

Load a heavy CoreML model from a remote source

We have a situation where we have a heavy CoreML model (170MB~) that we want to include in our iOS app.
Since we don't want the app size to be that large, we created a smaller model (that has lesser performance) that we can include directly and our intention is the download the heavy model upon app start and switch between the two when the heavy model is downloaded.
Our initial thought was to go to Apple's CoreML Model Deployment solution but it quickly turned out to be impossible for us as Apple requires MLModel archives to be up to 50MB.
So the question is, is there an alternative solution to loading a CoreML model from a remote source, similar to Apple's solution, and how would one implement it?
Any help would be appreciated. Thanks!
Put the mlmodel file on a server you own, download it into the app's Documents folder using your favorite method, create a URL to the downloaded file, use MLModel.compileModel(:at) to compile it, initialize the MLModel (or the automatically generated class) using the compiled model.

Is it possible to use Core Data in a document-based application?

I'm working on an iOS app that will need to save data onto files. I chose to go for a Document Based app, precisely an app based on a UIDocumentBrowserViewController so that I can easily save and load files from the system's Files app.
Since the data I need to save/load on a file is quite complex: big hierarchy of different objects, with meta-data, image files, etc. I'm wondering what is the best technology to use going forward.
I came across NSFileWrapperand its ability to save different files as one. And I could definitely use that. But I also saw UIManagedDocument and the ability to use Core Data in my project while maybe saving the content of the Core Data database (I know it's not quite a database, but you know what I mean) into a file that I could write somewhere in the File App.
Is this a behavior I can expect?
To reformulate: I'm wondering if I can read/write files through a UIDocumentBrowserViewController, with data described by a UIManagedDocument that works with Core Data.
Thank you in advance. 🙂
As you have discovered, UIManagedDocument is there for your kind of application. And it does feature methods to write and read additional content like the metadata or image files you have, within the document package.
That being said, I have never used UIManagedDocument, and have never seen it used by others. A quick search of GitHub finds only this one project with two contributors who wrote a wrapper around it in 2013. Also, there does not seem to be any sample code from Apple, and the remark in the the writeAdditionalContent(_:to:originalContentsURL:) documentation that Additional content is not supported on iCloud leaves me a little concerned, but maybe it's a good sign that the Core Data team knows where to draw the line.
I have used the macOS counterpart of UIManagedDocument, NSPersistentDocument. It is in a similar situation of not being used very much, but with many more known technical issues. So a few years ago I switched to BSManagedDocument, which purportedly mimics UIManagedDocument to support Core Data in all its modern glory. I have been happy with BSManagedDocument.
In summary, if I was in your situation, yes I would give UIManagedDocument a try. But don't be surprised if you need to use a DTS support incident or two during your development.

Where to store some private data inside Swift Module, Cocoa Touch framework?

I need to store some private data (current session ticket or settings) inside my current Swift module. For the simple app the options usually are NSUserDefaults or some file on the disk so I don't need any app using my Cocoa Touch Framework to be able to access (at least modify) this data from outside, cause some app may clean it's own documents folder for some reasons and developer might simply not know about my data stored here. Same situation with NSUserDefaults.
Do modules have it's own documents folder?
I'm just wondering, what is the correct way to do that?
Any help would be great, thanks!
A Swift module defines a framework. Frameworks get their own bundle (which they can use for static assets that ship with the framework) but I believe that there is no API guidance or convention defining where they should persist data that the framework wants to hide from the app.
If you look at Apple's File System Programming Guide, it only has a section on defining "App-specific" locations for persisting data. The Framework Programming Guide doesn't seem to say anything about defining locations that are per-framework.
Given that, what I would do in my framework code is just use the app-specific storage location, but put all of my framework's data under a subdirectory or distinctive key string that clearly marked it with the name of the framework and was likely to be unique. So instead of saving to the Application Support/ directory, I'd save to Application Support/MyFramework/.
This will stop your framework from stomping on the hosting application's data. It won't stop a malicious hosting application from inspecting what your framework is saving, but that's a much harder problem to solve. Also, a clumsily-written hosting application could erase your data if it just erased all of its own data with a wildcard, but that might be its intent.
UPDATE:
As the commenter suggested, the keychain is also a reasonable place. But the keychain's security infrastructure does not (I believe) actually cryptographically protect you from the hosting app. Nonetheless it is a key value store that the hosting app is less likely to completely purge by accident.
If you really want to try to hide larger quantities of your framework's data from the hosting app then, alternatively, you could explore using URLForDirectory(_:inDomain:appropriateForURL:create:) to find a system-wide (rather than app-specific) temporary directory, and then hide your framework's data in there. But I think all of those directories are subject to deletion at will by the system, so it would only work if you were saving data that your framework could regenerate later, perhaps based on a smaller seed of data, stored in a place like the keychain.
The bottom line is if you're shipping a framework for other people to use, you cannot strongly hide anything from an application developer using the framework. They can attach a debugger. Then you lose. (If you want to go into the deep end on this, there's a whole area called "white box cryptography" that describes protecting data from an adversary that can completely observe your operations. This is the basis of modern DRM systems.)

Creating PDFs from iOS text fields

I'm working on the requirements & specifications for a new iOS app intended for use by certain professionals working "in the field". All day long for weeks on end, these folks have a sizable reporting burden to their superiors using standardized forms that track all different kinds of information. Traditionally, those forms are in PDF, and are simply printed and filled out in ink and then shared with the dozens to hundreds of others working the same operation. Sometimes they'll use a PDF with form fields so the data can be typed and then printed as part of the form. Either way, given their workflow, time and stress pressures, and other factors, it's not a very productive way to get the standardized reporting forms done.
The app we're spec'ing would offer an iOS (and Android, if possible -- but secondary or even tertiary requirement at this point) user interface for tracking the data they enter in the field, organizing it in a logical manner for each individual user, and with the press of a button, take all that data and automatically create a PDF file of it using the standardized form.
Of course, the forms are STRICTLY and rigidly standardized in this industry, and any deviation in format, structure, or presentation is simply not tolerable.
So I was approaching the project by thinking the app would maintain an internal repository of the original standardized forms from the accrediting organization, with each possible data area defined as a field. The app would:
open the necessary PDF form for the task at hand;
parse its dictionary to identity the specific data fields;
for every single field, identify the relevant data from the iOS app's own user interface and data tables, and assign that data to the corresponding field from the PDF/dictionary
export the PDF to a NEW PDF file, which the app would either email or store through iCloud, Dropbox, or some other form of file sharing.
The catch with #4 is that that PDF file must remain editable by standard PDF applications on Windows and Mac (Acrobat, Preview, etc.), so all the fields need to remain. And the PDF should be viewable just the same on either Windows or Mac.
Now, at NO time will the PDF (neither the original nor the exported final document) EVER need to be displayed inside the iOS app, nor would it make much sense to be able to do so.
I don't know if any of this is possible. This is our first iOS project, and we've been leaning towards building the app using Moai or Corona or some other framework to save development time and make porting across platforms easier. That said, if it cannot be done using Lua and one of these frameworks (I remain skeptical...they seem HIGHLY geared towards games), we're not opposed to doing it directly in Objective C and building an Android version some time down the road.
But either way, I'm at a loss in assessing whether this is even a practical undertaking. Our requirements are clear, and frankly if this can't be done, the project won't be pursued any further. But I could definitely use some help from you folks in identifying what my options are, whether I can do it in Lua, and what SDK(s) would be most useful in accomplishing this.
Based on what you've said, it seems that there is little reason to do the PDF-based part of the work on the mobile device itself since:
you don't need to display it on the ipad
you plan to email it or store it in the cloud
if you write this for iOS you will have to write again for Android as you've mentioned
Can you simplify the mobile part of your requirement by focusing on the data-collection and validation, then firing off to a server to do the document production? That will give you a lot more flexibility in the tools that you can use to merge the data into PDF docs. If so you could look at creating PDFs or populating the fields from code using something like iText (C# or Java). If you don't want to build your own back end server you could try something like Docmosis Cloud - but that might not allow you to get your precise layouts.
Certainly the catch you mentioned - needing to keep the PDFs editable with their fields is a significant gotcha in all cases. If you could convince the stakeholders that it is better to generate the final documents from your system (generate draft, review, update data, generate again etc) - rather than generating editable documents that you then lose control and tracability over, then you will be miles ahead.
Hope that helps.
Did you consider just generating a new pdf using an image of the form as the background to the pdf and just writing the user's data into the required areas over the form image. Would reduce the complexity of trying to parse the original form PDFs.
That's a point of worthwhile discussion, but one we don't have an ideal answer on. I tend to think of that as the almost perfect scenario -- it'd be considerably easier to develop. There are two key issues with this approach that have made us table it except as a very last resort:
The users of this product would be working in the field. That field could be quite literally anywhere--the streets of Manhattan, a disaster-stricken area with infrastructure that's been severely damaged or even destroyed, or the most war-ravaged third world country. If it were the streets of, say, Manhattan, there's no problem--their iOS or Android device will have 3G or Wi-Fi access just about anywhere they go. In the latter two scenarios (which are arguably more common in this industry), that connectivity may be very limited. The concern is whether the end user's ability to be productive or to see and share data with their colleagues will be too greatly restricted if they don't have a decent signal. To be fair though, even today they often aren't even using mobile devices, forcing them to go back to a headquarters type location or use radios to share information, effectively negating my point here. But if we're not going to significantly increase their productivity in the field, it just gives us pause to think through whether or not we have enough of a value proposition to ask them to fairly significantly change their methods of doing things.
To your latter point, no there's no convincing the stakeholders that this new system is the better approach. Even if there were, it would take years to do so. These forms are a part of a well-defined, decades-old standard used by literally thousands of organizations.

Lua in iOS and side-loading scripts

The latest game by Gameloft called Order&Chaos starts with a Checking for Update screen, which indicates that they're able to update certain data without updating the entire binary.
I'm quite certain that they're using some kind of scripting language like Lua in their app and updating these scripts to e.g. change certain values (like buying price of items).
What's your experience with side-loading or updating scripts in your iOS application?
I don't mean loading new graphics or other contents, but game logic like my path finding implementation in Lua.
Apple cleary states that this isn't allowed
3.3.2 An Application may not download or install executable code.
Interpreted code may only be used in
an Application if all scripts, code
and interpreters are packaged in the
Application and not downloaded. The
only exception to the foregoing is
scripts and code downloaded and run by
Apple's built-in WebKit framework.
This happens in most of these applications TinyChef, RestaurantStory, HotelStory, etc..
They update content, but not the core program. Just adds new content or modifies the existing using external files and DB updates from a remote server.
Example, what they do is download new graphics and add a new item to their Desserts table of their DB and finally when they show all their Desserts the new one shows up and its ready to be cooked as if it was in the app from the beginning.
I could elaborate more info if you need.
UPDATE
If you are using lua, you could easily add, say new levels to your games, just by downloading a file containing your level data. Im sure that you are familiar with using external files one per level/item/character with a common format you then parse in your app.
You can have your path finding algorithm in another file as i said, and update (download and replace) that unique file whenever you improve it.
I haven't tried this, yet, but wouldn't it be as easy as querying a server, getting back a string, then parsing that into the database?
That might not violate Apples policy, since it wouldn't be executable code, just delimited text.
You could probably do more complicated stuff that way too. It wouldn't be a whole lot different than DropBox downloading files to your phone so you can view them. But instead of a document file, it would be a 3D object.
I think 3.3.2 clausule is to prevent that anyone can download/buy from appStore an engine like Love2D for iPhone, create games/apps in Lua, download it on the iPhone via web and execute with this engine, because it means develop and deploy apps on iPhone using an intermediate SDK instead of the official SDK, and of course, without paying anything to Apple.
Think about it, you can create your own App Store with this system and that is what Apple wants to prevent. but i think Apple doesn't take care of this type of downloads, where you want to update your own apps logic or levels.

Resources