Accessing UIApplication.sharedApplication() from a framework - ios

I use a framework to share common code between my main application and a Today Extension. I frequently run into scenarios where I am attempting to access UIApplication.sharedApplication() (the main application singleton) that is running from my framework, to show alerts, open URLs, show image pickers, show spin selectors, etc.
As a temporary solution I have a global variable in the framework that I set to the UIApplication when the application starts, then the framework relies on that variable. This method feels wrong to me and I would love to know of a better solution.
What is the best practice for accessing the UIApplication singleton from my framework?

Most likely you are missing the following import statement:
#import <UIKit/UIKit.h>

If you can build your framework, when it uses UIApplication.sharedApplication(), it is good solution as far as I can see than saving UIApplication.sharedApplication() in some variable.

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.

can one enable CoreData in ready app?

Is there a way to enable an app to use the CoreData framework if the box "use CoreData" was not checked?
I know it could be done by altering AppDelegate.swift but I am trying to find a way to do it automatically
Checking the box "use CoreData" just causes Xcode to generate some boilerplate CoreData code for you (a persistentContainer property and a saveContext() method) and dump it into your AppDelegate. It doesn't need to go in AppDelegate, however, and you can certainly write or import your own persistent container into your app (and frankly, you should).
Checking the box also creates an empty CoreData .xcdatamodeld file to get you started with adding your own entities. Something you can just add yourself at any time.
So if by "automatically" you mean can you add couple files to your app to give you the equivalent code of checking the "use CoreData" box, then the answer is yes.
And you should hunt around for good CoreData swift boilerplate code that fits with the needs of your app. Apple's is just to get you started, and they rudely dump it into your AppDelegate rather than isolating it into a separate singleton, just to simplify for people just getting started with it.

How to wrap existing iOS code in a new Appcelerator module?

This seems like a basic request, but I can't find the answer to it anywhere. I want to wrap some existing iOS code that I wrote, in a Appcelerator module. That's it. Important points:
I am NOT wrapping a pre-existing 3rd party iOS SDK.
I wrote the iOS code being wrapped.
Code is verified as working within xcode.
There are no .a files. There are 2x .h files and 2x .m files though.
There are no UI elements in the iOS code as it is only designed to connect the native bluetooth hardware to the app.
I have created a generic appcelerator iOS module project, built it, and successfully called the generic ID function within my app.
I cannot figure out how to successfully edit the generic module so that it utilizes my code. Every attempt results in it refusing to compile, and it's maddening.
I do not have access to Hyperloop.
Once I can successfully build the wrapped module, I would call an initialization function which triggers a native bluetooth hardware search. Once connected, there are functions within the module to send commands to the hardware and receive data back. This is the official documentation I've followed so far:
http://docs.appcelerator.com/platform/latest/#!/guide/iOS_Module_Quick_Start
That helped me build the blank module, include it in the app, and ensure that it worked by calling the built in test property. From there it stops short of actually telling me what I need to know. These are the closest things I've found so far, while still not being what I need:
http://docs.appcelerator.com/platform/latest/#!/guide/iOS_Module_Project-section-43288810_iOSModuleProject-AddaThird-PartyFramework
appcelerator module for existing ios project sdk
Heck, I still don't even know if I can do this within studio or if I have to edit the generic module in Xcode. Help! :) Many thanks in advance.
so first of all, this is not best practice and will cause possible problems in the future when the SDK changes and your module still relies on outdated core API's.
Regarding your question, you could either create a new component that subclasses the existing class, e.g.
class TiMyModuleListViewProxy : TiUiListViewProxy {
}
and call it with
var myList = MyModule.createListView();
or you write a category to extend the existing API with your own logic, e.g.
#interface TiUIListViewProxy (MyListView)
- (void)setSomethingElse:(id)value;
#end
#implementation TiUIListViewProxy (MyListView)
- (void)setSomethingElse:(id)value
{
// Set the value of "somethingElse" now
}
#end
I would prefer the second option since it matches a better Objective-C code-style, but please still be aware of the possible core-changes that might effect your implementation in the feature. Thanks!

Unity IOS integration

For a project I need to integrate Unity3d in an existing app I know Unity acts as a UIApplicationDelegate. I found an interesting article about this topic but it is not really clear to me how I can resolve my problems this way. Is it possible restart the delegation process from a ViewController? So when I switch to a viewController from my delegate and I want to navigate back then initialize the UIApplicationDelegate again?
Article I found:
http://alexanderwong.me/post/29949258838/building-a-ios-unity-uiview-uiviewcontroller
Thanks in advance
Have you tried using Unity to build a "standard" Unity iOS application, then integrating your existing code into that?
When you build for iOS from Unity, Unity will automatically stick a hook in your Application Delegate, in the following method:
- (BOOL)application:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions
You can do other stuff in there, but down the bottom you should see the important line:
[self startUnity:application];
So what you can do is just take that line out of the didFinishLaunching method and put it ... wherever you want. You'll also want to keep a reference to the UIWindow* Unity draws to in your application delegate, so you can switch in and out of it as you please.
So, I'm not completely clear about exactly the things you want to do, but I definitely recommend as a first step you start with an integrated Unity build and work from there, or at least use it as a map if you want to roll your own implementation.
Its been a while, but better late then never ;)
You can not "restart" the delegation stuff. The UnityAppController is an AppDelegate, not a ViewController.
But you can decide when unity is started the first time. After that, unity is running and you have to either use the applicationDidEnterBackground call in the UnityAppController (for pre Unity 5) or just call setPause:true (using Unity 5) which stops the unity render loop. Just dont forget to reactivate it once you navigate back to the UnityViewController.
For the "how to start unity when u want to": Either subclass UnityAppController and override startUnity:(UIApplication*) application with an empty implementation. Then you call [super startUnity..] once you want to activate it.
The other way is not to subclass but create your own UnityAppController object and call all the methods (applicationDidFinsishLaunching etc.). Then you just wait with the initialization till you need unity for the first time. But i would recommend the first option.
You can also look here for a more detailed Description how i did it: http://www.markuszancolo.at/2014/05/integrating-unity-into-a-native-ios-app

iOS GHUnit and Core Data

ers,
I recently integrated CoreData into my existing iOS application. I have previously existing tests written around some domain and network functionality; that now needs to be retrofitted to use CoreData (instead of storing in userDefaults).
I have GHUnitIOS.framework included in my project. However, all my tests are failing because the TestAppDelegate knows nothing about CoreData's managedObjectContext. For reference as to what I'm seeing:
[GHUnitIOSAppDelegate managedObjectContext]: unrecognized selector sent to instance
This makes sense - the test app delegate doesn't have managedObjectContext as a property. I'd love to add it, but since I only have access to the header files when using the framework, I can't really modify it for my needs. I could download the GHUnit source and modify the implementation files, but I'd rather not do that if there's another option.
How have others solved this problem? IE, how can I fix my tests to support CoreData using GHUnit?
Much thanks.
I had this issue before. GHUnit testing framework uses its own app delegate. So calling the delegate does not call the code you wrote within the app delegate, and its behavior can be erratic.
Generally speaking you should always handle calling your managedObjectContext(s) in a singleton that is not your app delegate. Recently I switched to GHUnit from OCunit and had to abstract all the of that functionality into a different class. It was a pain, but worth it.

Resources