Lua in iOS and side-loading scripts - ios

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.

Related

Sharing data between apps on iOS

I have several small apps that share common data (images, sounds files, etc). This data bloats the size of each app. When the user installs 2 or more of these apps that will bloat the device space with duplicate data. Is there a way that I can share this data between my apps so that each app doesn't duplicate this data within its bundle?
You can have a common file space between apps by using app groups. An example of how to use them can be found here: Sharing data in between apps in IOS
You can use this as part of a solve for not duplicating the data in every bundle. One way might be to have the data hosted on a server somewhere and when the app is installed you can check the App Group for the common data, if it is not there, you can download it and store it there. Then the next app that is installed will have the data already available. This should help avoid having to include it in every small app.
You can set up the code to check the shared location and download the data in a framework and share it between all your apps making it a bit easier to maintain. If you do not already have a content management system then you could google for a few that have iOS support. There are many out there. You would then host the shared data there. This would give you the ability to update the data for each app while they are in the field which could be a time saver. If these apps are very small though, this may be overkill.
No, this is not currently possible. Ideally, this kind of resource-sharing would require creating a common framework bundle that would have to
be submitted separately to the App Store as a third-party framework, so that even if only one of your apps is present on the
device, it would be able to load the appropriate resources and function properly.
Apple currently only allows third-party frameworks embedded within the app bundle.
Even if two of your apps use the same exact version of your framework, they have to embed it separately.

iOS - make changes to app without requiring update via app store?

This may seem like an odd question, but I'm in the middle of creating an iOS app, and was wondering if there is a way to, in the future, roll out changes to the app without requiring all of the users to download an update.
I've noticed that Snapchat can do this with their filters - new filters are added regularly, without me updating the app.
I've read into 'Cloud code', something Parse had that apparently let you accomplish this. Obviously that's no longer an option.
Also, do Apple even allow this? Seeing as they need to approve every app before letting it onto the App Store, it would seem like they would need to approve any changes first too.
I've thought of strange things like storing a function in a database, then getting the app to download that function and run it - naturally if I were to now change the function in the database, it would change on all users devices instantly. Just how ridiculous is that idea? Thanks!
Depends on how much flexibility you want.
For example, Spotify does this for UI mainly - backend-driven UI, as they call it. They send a kind of layout from the server and convert it to a real iOS layout, based of a predefined mapping. You can find pretty more details in the Spotify's presentation.
Slides: http://www.slideshare.net/JohnSundell/backenddriven-native-uis
Video (more details): http://www.downvids.net/backend-driven-native-uis-john-sundell-and-diego-cristina-ca--777281.html
So actions can also be divided in similar pieces and abstractions, received from the server and interpreted - sort of scripting is needed. You can't compile and run arbitrary functions on the fly.
Hope it'll give you some ideas you can think of.
See Apple's app store review guidelines: https://developer.apple.com/app-store/review/guidelines/ section 2.4.5 (iv). Apps are not supposed to download code or resources to add functionality or significantly change the app from what Apple sees during the review process. And executable memory isn't even writable by sandboxed apps, which makes downloading compiled functions fairly useless. But downloading Javascript that complies with the above guidelines seems to be allowed.

How to create an iOS app add-on?

Is it possible to create an API inside an iOS app to let 3rd party developers create app add-on that are downloadable for users inside the app?
I could not find any ressources for this topic online.
I think that's going to go against the app store guidelines if your intention is that the 3rd party developers write code, which will be downloaded and executed.
There's something of a grey area between legitimate uses and illegitimate uses of downloaded code:
Legitimate Example 1: Something like Hopscotch where children are creating simple fun shared games. These can be considered user generated content.
Legitimate Example 2: A game which is driven by scripts allows for the run-time downloading of patches to fix bugs in the scripts or even to add new levels. I believe such usages have been rejected occasionally in the past, but are generally accepted these days.
The relevant guideline from the guidelines is (emphasis mine):
2.5.2 Apps should be self-contained in their bundles, and may not read or write data outside the designated container area, nor may they download, install, or execute code, including other iOS, watchOS, Mac OS X, or tvOS apps.
And the all-encompassing:
We will reject apps for any content or behavior that we believe is over the line. What line, you ask? Well, as a Supreme Court Justice once said, "I'll know it when I see it". And we think that you will also know it when you cross it.
If your idea is to create some sort of app-store within your app-store app, then I would abandon it immediately, because that's going to be way over Apple's line.
That said, you haven't given much detail about your app, so I might have made wrong assumptions about where you're thinking of going.

AppStore / iOS apps and interpreted code - where do they draw the line?

Apple's iOS developer guidelines state:
3.3.2 — An Application may not itself install or launch other executable code by any means, including without limitation through the use of a plug-in architecture, calling other frameworks, other APIs or otherwise. No interpreted code may be downloaded or used in an Application except for code that is interpreted and run by Apple’s Documented APIs and built-in interpreter(s).
Assuming that downloading data - like XML and images, or a game level description, for example - at run-time is allowed (as is my impression?), I am wondering where they draw the line between "data" and "code". Picture the scenario of an app that delivers interactive "presentations" to users (like a survey, for instance). Presentations are added continuously to the server and different presentations are made available to different users, so they cannot be part of the initial app download (which would be the whole point). They are described in XML format, but being interactive, they might contain conditional branching of this sort (shown in pseudo form to exemplify):
<options id="Gender">
<option value="1">Male</option>
<option value="2">Female</option>
</options>
<branches id="Gender">
<branch value="1">
<image src="Man" />
</branch>
<branch value="2">
<image src="Woman" />
</branch>
</branches>
When this XML is interpreted and "played" within the app, the above would be presented in two steps. First a selection screen is shown, where the user can click on either of the two choices ("Male" or "Female"). Next, an image will be [downloaded dynamically] and displayed based on the choice made in the previous step.
Now, from this, it's easy to imagine additional tags, describing further logic still. For example, a containing tag could be added:
<loop count="3">
<options... />
<branches... />
</loop>
The result here being that the selection screen / image screen pair would be sequentially presented three times over, of course.
Or imagine some format describing a level in a game. It is perhaps natural to view that as passive "data", but if it includes, say, several doorways that the user can go through and with various triggers, traps and points attached to them etc - isn't that the same as using a script (or, indeed, interpreted code) - to describe execution sequences, options and their conditional responses?
Assuming that the interpretation engine for the data is already present in the app and that such "presentations" can only be consumed (not created or edited) in the app, how would this fare against Apple's iOS guidelines? Doesn't XML basically constitute a scripting language in this sense (couldn't any program in an interpreted language be described in XML)?
Would it be OK if the proprietary scripting language (ref the XML used above) was strictly sandboxed (how can they tell?) and not given access to the operating system in any way (but able to download content - like a survey or a game level - dynamically as well as upload results - answers or scores - to the authoring server)?
Where does the line go?
Update as of WWDC 2017
Programming tools such as Codea mentioned below are now explicitly allowed to download code. The App Store Guidelines currently say (emphasis mine):
2.5.2 Apps should be self-contained in their bundles, and may not read or write data outside the designated container area, nor may they download, install, or execute code, including other apps. Apps designed to teach, develop, or test executable code may, in limited circumstances, download code provided that such code is not used for other purposes. Such apps must make the source code provided by the Application completely viewable and editable by the user.
There is also this tweet citing more details on the relaxed clauses.
Original
Does your interpreted download allow the user to write infinite loops or recursion?
Apple allow Javascript because they provide the interpreter and can kill your code. I have a feeling I've read that it's a 10 second limit but I couldn't find it on the site with a few minutes searching. (Yes, my self-imposed timeout for writing an answer kicked in.)
I think you're pretty safe if what you do is declarative and doesn't allow obvious looping in the interpreter.
I would also avoid the use of the word "interpreter" in any descriptions visible to Apple including public discussion. Maybe "parser" would be safer.
Codea have skated along the edge of these definitions with their Lua environment and cannot download code. They had to remove a feature for downloading new packages as ".codea" files.
Based on 3.3.2, they could reject an app for this. However, the scarier thing is that you could create the app, get it approved, have it be downloaded and used by many users, and then Apple could pull the app from the store.
Did you ever publish the app you described?
There's a major difference between the Guidelines and actual practice by the App Review team.
The current Guidelines state:
2.7 Apps that download code in any way or form will be rejected
2.8 Apps that install or launch other executable code will be rejected
So, the old ban on interpreted code is gone, and replaced by a ban on apps that could be considered to be IDEs or self-modifying.
However in practice there are a number of apps which do this, hence the difference between theoria and praxis.
You should take a look at what Apple has enabled in iOS7. It is now allowed to download and run JavaScript within your app.
I think what Apple means is your application should not depend in another module, compiled product or executable in order to work that will be downloaded from a website/server and that compiled add-on was not reviewed by Apple.
Basically when I asked something similar they told me something like: "If your application will download another executable compiled code that such a ftp downloader, key decryption tool or something of this kind that was not approved my Apple. You are available to download data or files (such as XML, HTML, PDF files, images) that does not represents an application.
The concept of the differences between 'code' and 'data' has been discussed on SO before.
Please see this answer: https://stackoverflow.com/a/642476/200696
From Apple's perspective, this ban prevents un-reviewed executable content from the app store. It would be trivial to create a program which is approved by Apple, and then downloads executable content that changes the pre-approved behavior.
All I can tell you is I've released products which use XML to script behavior within the app and Apple has always approved them.

Rewrite native iOS app with Titanium or Rhodes

I have an iOS app in the AppStore, built with Xcode a while ago, but I am thinking of rewriting it from scratch to iron out some bad decisions and this time use some cross-platform framework such as Appcelerator Titanium or Rhodes to add Android support also.
Is it possible for my current iOS users to seamlessly upgrade to the new version, retaining their userdata (of course a migrator is required in the new app). I think I have to retain some app identifier or other data in the new version.
Or should I create it as totally new app and let the users migrate their data (possibly using the Open in... scheme).
The downside of this is that current users must re-purchase the app, which might drive some of them away.
Is it possible for my current iOS users to seamlessly upgrade to the new version, retaining their userdata (of course a migrator is required in the new app). I think I have to retain some app identifier or other data in the new version.
In principle, it is possible. The fact that you are moving to a different development platform will not affect your ability to access data already stored by the user. In the end, it greatly depends on how you stored that data: if it is through NSUserDefaults, it will be pretty much transparent; if it is in XML/JSON files, you will need to add some XML/JSON parser to you new app (provided Appcelerator Titanium or Rhodes do not already provide one); if it is through sqlite, I know that, e.g., Titanium supports it; if it is through Core Data, maybe you will need to write some kind of converter for the existing data. But, in the end, it is definitely possible.
Or should I create it as totally new app and let the users migrate their data (possibly using the Open in... scheme). The downside of this is that current users must re-purchase the app, which might drive some of them away.
What you should take into account here is how much the new app will differ from the old one. If there is a risk of disappointing your customer base, maybe you can go for a separate version. It is clear that doing so will bother some users that will have paid for the old version. One scheme that has been applied in at least one case I know of is offering the app for free during an initial period. But whether this is sensible or not depends entirely on the prospects of your apps.
Maybe the best approach is striving for a largely improved new version, so that disappointed customers will be the least possible number, and keep the same bundle id for a seamless update.
I would suggest refactoring your current iOS codebase as opposed to rewriting it from scratch. Rewriting from scratch is almost always the wrong decision when you can refactor and clean up code as you go. It will always be harder than you expect, take longer than you expect, and often won't end up providing the benefit you expected it to. Refactoring is cheaper, faster, and safer.
In my opinion you would be doing your users a disservice by rewriting the app using cross-platform framework after they are used to a fully native app written in Objective-C. You would be doing yourself a disservice by throwing away code. Bad code can be fixed, no matter how ugly it is now.
I would suggest writing your Android app using Java and refactor your iOS app once the Android app is finished. You can provide the best experience for both platforms this way. The reason to add Android support first is because you already have a working iOS app in the store, so you're 1/2 way there already without touching a cross-platform framework. Writing the Android app should also allow you to flesh out ideas of how to refactor the iOS app.
As far as upgrading your current users, you need to keep the bundle ID the same in order for users to be able to seamlessly upgrade via the app store. Upgrading their data is also possible, but you need to provide more details on how that data is stored within your current app. If at all possible, the automatic upgrade is preferable to an Open In... scheme that requires the user to manually load their settings.

Resources