iOS GHUnit and Core Data - ios

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.

Related

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!

Accessing UIApplication.sharedApplication() from a framework

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.

Exceptions in my iOS Framework Show Private Code?

I'm building an iOS framework where only a single header file is exposed, and the rest of the code is private. Within Xcode I have all objective-c exception breakpoints on, so normally when there's an exception I'm brought to where it occurred in the code.
During testing in a totally new project that is using this framework I created, every now and then when an exception is raised inside the framework, I'm brought to the otherwise private framework code, which is obviously not what I want.
I think this may be because the actual raw framework code/project exists in my environment and wouldn't occur for another person using my framework without access to the actual files, but unfortunately I don't have any way to currently test this theory. Does anyone know if this is something I need to be handling in order to truly keep the project files private that I intent to, or is this just a function of having the code exist locally?
I was able to get in another dev environment with a fresh project to drop in the framework and force an internal framework crash and it appears that if the otherwise private framework files exist on the same environment and a crash occurs when you have objective-c exception breakpoints enabled it will open the private framework file in question, BUT if you don't have those private framework files (which consumers of your framework wouldn't) you will simply be taken to the normal crash/stack trace view like below:

XCTest and the need for a special target to tweak App startup behaviour

I am trying to implement XCTest as I have a bug in an iOS App which I don't seem to figure out so want to start building up get cases.
The App however, when loaded, will automatically connect to a server to update data. For the tests however, I would like this not to happen, as I need to clear the CoreData database and populate for each test.
Is there a way to know when e.g. building (on the target) if tests are going to be ran? Ie so I can use a flag to to leave out certain actions when testing?
Or should I just duplicate my normal target specifically for tests, and put in a flag that way?
(e.g. #if TESTING instead of #if DEBUG)
Not a direct answer to your question, but it might be a solution to your problem.
You could mock your class that does the server connection (ie fake the server connection).
You can do this by using OCMock that you can find here or OCMockito that can be found here.
Currently, I find OCMock easier to implement with XCTest than OCMockito. However, there might be some issues with OCMock as well, but those can be ironed out be looking at this site.

Resources