Loading Objective C code dynamically - ios

I am looking for a possibility of loading Obj C based source dynamically and show the view in my iOS application. For example: I have a set of code written for showing a view, i want to dynamically load this code and show this view.
Some thing like,
I'll have a service running in the background of my iOS app.
It will get a set of Obj C code from my server in text format
This dynamic Obj C code should get executed dynamically and show the respective iOS view
From Comments Not released in the appstore.. its for internal
Is this possible?

Short answer: No
Not so short answer:
You could—in theory—include either the C, or C++ interface to the Clang compiler toolchain in your project, have that library compile the code you download, and then (through either NSBundle or direct interaction with dlopen) link that compiled code into your app.
In practice, if what you want to achieve is submitting to the App Store, this is explicitly prohibited by the Terms and Conditions.

You can't do this for deployment to the app store.
You wouldn't use plain text for this, you'd use a bundle (NSBundle). A bundle can contain both file (graphics, NIBs) resources and code so you can create your view classes and any associated NIBs, compile the bundle and then store it on your server. The app can then download the bundle and load it at runtime.

You can do it for non-app store apps. I have not tried this approach.
From Apple Docs:
The key to loading code from an external bundle is finding an
appropriate entry point into the bundle’s executable file. As with
other plug-in schemes, this requires some coordination between the
application developer and the plug-in developer. You can publish a
custom API for bundles to implement or define a formal plug-in
interface. In either case, once you have an appropriate bundle or
plug-in, you use the NSBundle class (or the CFBundleRef opaque type)
to access the functions or classes implemented by the external code.
Loading Objective-C Classes If you are writing a Cocoa application,
you can load the code for an entire class using the methods of
NSBundle. The NSBundle methods for loading a class are for use with
Objective-C classes only and cannot be used to load classes written in
C++ or other object-oriented languages.

Related

Can I package entire iOS app as a Framework?

I have an app implemented in native iOS (Swift). There is a web version of the app as well. A client wants to embed my app to its own app and suggested I use an iFrame and load the web version.
I understand this is a tricky solution as Apple might reject the app for not using native implementation.
What I want to ask is if there is a way to package my app entirely as a Framework and load it that way (app size is fairly big, with several viewControllers and functionality).
I understand that I won't have access to App-load functions like the AppDelegate.
Also what happens if my app has Library dependencies ? (such as Alamofire)
Any other things I should be concerned about ?
Thank you
There are obviously a lot of options around this as far as design/approach.
I've done this multiple times (with apps live on the app store) and really it's just like developing any Framework.
First: AppDelegate. The easy way around this is to have the app's AppDelegate subclass your Framework's AppDelegate:
#UIApplicationMain class ParentAppDelegate: FrameworkAppDelegate { }
Just make sure the App calls super on all the relevant methods.
Second: Dependencies. This is probably the most annoying part since Frameworks can't embed other frameworks. But you still have a few easy options:
Have the enclosing app embed the needed framework
Add the sources of the needed framework directly to your framework.
Use a dependency manager (e.g. cocoapods) that takes care of this for you.
Other Concerns: One trap you can easily run into is working with Bundles. Anytime you dynamically load images/strings/IB references/etc. you will need to specify you're using the Framework's bundle, as at times it can default to using the app's bundle. The easiest way to do this is with this init e.g. Bundle(for: self.self)
Also keep in mind that the settings in info.plist and entitlements your framework needs will need to be added by the parent app.
General Comments on Approach: My advice (take it or leave it ☺️) would be caution around simply adding your full application to a client's application. Aside from IP and App-Review concerns, it can result in adding a lot of complexity or a fork of your current application to support it, making future maintenance a hassle.
Instead I would recommend putting only the portions of the application your client requires into a separate framework that both you and your client use for your separate applications.

How to control embedded Unity app from native iOS app

I want to create an iOS app that contains Unity3D elements. I also want to control these elements, to change colors and set specific properties on them.
I want to do this controlling from UIKit elements, so that I can create my interface easily (using native elements such as UINavigationController).
Is there a way to integrate a Unity3D view as a subview in a native (or Xamarin) app?
I have found a way to take the exported build code from Unity and put it inside another project so that I can instantiate that UIWindow and display it when I need it, but I have not found a way to interact with it or use it as a subview in my view hierarchy.
Does anyone have some experience with this? Or a way to do this?
Edit: I have a structure in my mind: create a unity app, take the main window (or even the view that is contained inside it, if that does not mess with the contents), and then use the view in the view hierarchy as I like. I think I might be able to use the Native Plugin Interface to talk to my Unity view then.
Edit2: I found a video explaining the entire process I had in mind: https://vimeo.com/145572230
This interaction will require iOS plugin to be written for Unity. A bit tough job but definitely possible.
Have a look here should answer your questions.
https://docs.unity3d.com/Manual/PluginsForIOS.html
Define your extern method in the C# file as follows:
[DllImport ("__Internal")]
private static extern float FooPluginFunction();
Set the editor to the iOS build target
Add your native code source files to the generated Xcode project’s “Classes” folder (this folder is not overwritten when the project is updated, but don’t forget to backup your native code).
If you are using C++ (.cpp) or Objective-C++ (.mm) to implement the plugin you must ensure the functions are declared with C linkage to avoid name mangling issues.
extern "C" {
float FooPluginFunction();
}
to call Unity from native code
UnitySendMessage("GameObjectName1", "MethodName1", "Message to send");
Hope that helps

iOS Framework Concept: QR Code Scanning

I have been reading framework tutorial as I need to separate UI and implementation by packaging implementation into framework. I am struggling to grab the concept.
For example I need to create a QR framework, when I click a button, it will launch the QR page > Catch the text string > Populate it into a label.
From the code in appCoda, how to I separate the UI? How's about the camera screen view(code in UI/Framework)?
Can frameworks include other frameworks?
Updated
I am trying to get my hands on the QR but merging the framework with the QR.
I am getting error:
NSBundle </var/mobile/Containers/Bundle/Application/5B97C76C-06E0-4E5A-821C-502477239962/UIControlDevApp.app/RWUIControls.bundle> (not yet loaded)
At this line
NSBundle *bundle = [NSBundle bundleWithURL:[[NSBundle mainBundle] URLForResource:#"RWUIControls" withExtension:#"bundle"]];
I have included my source code in here.
Hang in there and keep re-reading the tutorials. They are pretty meaty and take a bit of effort. Frameworks are great and worth the effort. Especially for something like the scanner that you will use again and again.
Yes frameworks can contain other frameworks and they can as well and....
When you create the framework you will end up with two output files. The framework itself as well as a bundle that contains your resources (this is the storyboard and image files.)
You will need to add both of these to the project you want to use them in.
First initialize an instance of your framework by referencing it whatever initializer you have created and supply the bundle name so it can find the resources.
In your framework you can use delegation to return the string that is decoded. Register the instance of your class in the main app (the one you just initialized) to receive delegate messages from your framework.
Finally push the view controller from your framework onto the stack for display within your main application.
self.qrScanner = [[QRScanner alloc] initWithBundleName:#"QRSCanner.bundle" navigationControllerRequired:NO];
self.qrScanner.delegate = self;
if ([self.delegate respondsToSelector:#selector(pushCustomViewController:)])
{
[self.delegate pushCustomViewController:self.qrScanner.qrScannerMainViewController];
}
This is is short code sample of what those three steps look like. Assuming you have created the framework and bundle this will allow you to reference them from your main application.

Xcode storyboards: Load localizable strings from different file

I'm trying to build a library that will allow for dynamic loading of Localizable.strings files. If the views are being developed programmatically, then it's not a problem, as I could build a separate NSBundle, store the .strings files inside, and use NSLocalizedStringFromTableInBundle.
The problem I'm having lies with Storyboards. I haven't managed to find a way to specify which .strings file to load from (rather than using the default .strings that Apple uses).
Does anyone know of a solution for this? It doesn't even have to follow the same approach, as long as I can dynamically update the strings on a Storyboard. (The strings will be pulled down from an external source via API call upon app launch)
Loading strings from a separate bundle/strings source
In order to overcome the issue I had, I created IBOutlets for each object on the Storyboard's collection of views. Within each view's implementation file, I programmatically set the text/values of each object by using NSLocalizedStringFromTableInBundle, which allows me to specify a custom bundle, which can be populated with strings files.
In the event that a project has both programmatic and storyboard developed views, this approach also allows for the usage of only one Localizable.strings file, rather than mixing Storyboard-generated files, and files used only for programmatic views (if applicable).
Loading strings into an app via API call
Unfortunately, the above approach doesn't allow for strings to be downloaded from an external source via API call. The reason for this being, Apple doesn't allow for any files in the app bundle to be edited after being built.
Because of this, the solution would be to build out a data structure within the app's DocumentsDirectory, and edit this whenever necessary, then force the app to use this file/library in order to get localized strings. Not a pretty solution, but it's the best approach I can think of.

Validate resources and generate getter code for iOS app in Xcode

I’m looking for a tool that can validate my images and fonts in a iOS application.
Problem:
We have a lot of different images and fonts in our application. Sometimes some of those files are replaced or renamed. We don’t get compile warnings or errors just missing images scattered around the app.
I guess this is part of Objective C dynamic nature but I would really like some static check here.
Does there exist any tools that can validate content or autogenerate getter code? (preferable open source)
Thanks!
warning: Shameless self promovation ahead:
We have created a tool, IDAssetManager, (not open source, however), that creates a static interface to resources.
This tool integrates heavily with Xcode. It manages and organizes resources, and generates a class with getter code for images, font and colors.
It also comes with a Xcode plugin that allow you to preview images directly from the Xcode codeview:
The tool will also register fonts in the info.plist file.
To get the kind of validation you are looking for you will have to:
Add all images to IDAsssetManager
Use the getter code generated by the tool
Hit the refresh button on the tool.
You will now get compile warnings for all missing resources.
You can try it here: https://itunes.apple.com/us/app/idassetmanager-lite-for-xcode/id830464758?mt=12
Edit
You can see a video of the tool in action here

Resources