There are quite a few subjects on this already, but I have yet to find a solution that is workable for Swift (Xcode 6.2).
To test Core Data backed classes in Swift, I generate new Managed Object Contexts that I then inject into my classes.
//Given
let testManagedObjectContext = CoreDataTestComposer.setUpInMemoryManagedObjectContext()
let testItems = createFixtureData(testManagedObjectContext) as [TestItem]
self.itemDateCoordinator.managedObjectContext = testManagedObjectContext
//When
let data = self.itemDateCoordinator.do()
//Then
XCTAssert(data.exists)
The issue comes from passing a MOC created in the Test to the class that's doing. Because entity classes are namespaced, Core Data won't fetch your the appropriate ManagedObject subclass and instead hands back a NSManagedObject set. When looping or doing anything with these objects (which in your class would be an array of test items ([TestItem]).
For example, the offending class ItemDateCoordinator would execute this loop (after pulling the relevant data from a NSFetchRequest)"
for testItem in testItems {
testItem.doPart(numberOfDays: 10)
}
would result in:
fatal error: NSArray element failed to match the Swift Array Element type
Also, I have come across a collection of information without much of a solid answer:
To cast entities when creating them, I have been using a solution by Jesse, but that doesn't work on a larger scope of testing.
A solution has been posted on another question that involved swapping out the classes at runtime, but that hasn't worked for me with entity inheritance.
Is there another method to testing your objects with Core Data in this case? How do you do it?
I was about to point you toward Swift, Core Data, and unit testing but see you've already found it. :)
That post doesn't elaborate much on where your files should exist (i.e., in which Target). You should not add NSManagedObject subclasses (or any files really) to both targets. I've found that this leads to all kinds hard discover bugs and cryptic errors.
And definitely DO NOT do this. That is a terrible hack.
Instead, make your classes public and import MyAppTarget in your XCTestCase files. Better yet, your model should be in its own framework as I mention in my recent talk (a video will be posted in a few weeks on realm.io). Doing this makes your models namespace very clear and generally easier to deal with. Then you'll need to import MyAppModel everywhere you access your managed objects.
I also have a new framework, JSQCoreDataKit that intends to make Core Data easier to use in Swift. One key part of this framework is the CoreDataStack which you can initialize using an in-memory store for your tests. There's demo app with examples, and well-commented unit tests.
I believe this was updated recently (iOS 9/Swift 2.0) to have the testable keyword on an imported target, mean that the target's internal classes (the default) become public. From the docs:
So to add to jessesquires answer above, append #testable to your import, and this should solve the unit test errors:
#testable import MyAppTarget
Related
I am creating an iOS framework that internally uses CoreData. I've created a CoreData entity model to declare the entities. For each entity, I've declared that a corresponding class is created through codegen. Is there any way to mark these class definitions as internal, instead of public since I don't need apps using this framework to see these classes?
I know that I can manually create the class definitions, but this seems unnecessarily tedious to solve this problem.
Given that I have a class managed by the CoreData stack,
I am currently writing a Framework, and I want to be able to create my objects through dependency injection (ideally, only through DI).
I am also designing with "fail fast" mentality (i.e. crash as soon as possible), and following closely SOLID principles.
That framework will be iOS 9-10 compatible, and could be used in either ObjC and Swift (or mixed targets), therefore I ideally do not want to rely on non cross compatible features in either ObjC or Swift.
This piece of code is meant to be used internally, and not exposed to the consumer of the framework as Jonah points out that exposing such functionalities is not a very solid choice.
Question :
I have here 2 different ways to create my object, and I am not sure if
either of them are corrects, if there is a "preferred" solution, or one that has less pitfalls in usage ?
Here is a code snippet to illustrate my case :
import CoreData
class Example: NSManagedObject {}
class DependencyClass: NSObject {}
extension Example
{
public convenience init(with someDependency:DependencyClass,
context:NSManagedObjectContext)
{
let description = NSEntityDescription.entity(forEntityName: "Example", in: context)
self.init(entity: description!, insertInto: context)
//Configure the result object here
}
class func NotAConvenienceInit(with someDependency:DependencyClass,
context:NSManagedObjectContext) -> Example
{
let selfClassName = String(describing: self)
let result = NSEntityDescription.insertNewObject(forEntityName: selfClassName, into: context) as! Example
//Configure the result object here
return result
}
}
let context = NSManagedObjectContext(concurrencyType: .privateQueueConcurrencyType)
let dependency = DependencyClass()
//Usecase A
let myExample = Example(with: dependency, context: context)
//Usecase B
let anotherExample = Example.NotAConvenienceInit(with: dependency, context: context)
I have been thinking about failable initializers for the convenience init, I am quite seduced by the idea that once the init method is over, I am "guaranteed" my object is valid. I think both ways can guarantee that through various mechanisms.
Apple seems to prefer +insertNewObjectForEntityForName:inManagedObjectContext: in their documentation and that is why I came up with those 2 methods.
PS : I'm still learning Swift, my apologies in advance if this seems like an already solved question. After reading many articles on various websites, I did not find a conclusive solution, and therefore am turning to SO.
I've tried to do the same thing and my conclusion was that it's better to avoid this approach and instead keep behavior, especially behavior which requires other dependencies off of the models.
Why?
Swift and Objective-C really don't give you any tools to prohibit the use of existing constructors so while you can provide alternatives with your DI arguments there's very little you can do to ensure that NSManagedObject or NSEntityDescription are not used to create instances of your model.
Additionally NSManagedObject.init(entity:insertInto:) and NSEntityDescription.insertNewObject(forEntityName:into:) are used to insert new model instances but are not the only ways in which instances of your model classes can be created. Take a look at NSManagedObject's awakeFromFetch() and awake(fromSnapshotEvents:) (and awakeFromInsert()).
Suppose I create a NSFetchedResultsController with a fetch request returning one of your framework models. If I call controller.fetchedObjects I'll get instances of your model. Similarly I could execute a NSFetchRequest directly. You might use a singleton container to supply dependencies in an awake... implementation but that limits the creating code's ability to specify those dependencies and leads to another problem:
Managed object context queues. Since NSManagedObjects are tied to a content and must be used on that context's queue you need to watch out for dependencies introducing access to a model on the wrong queue and often want dependencies scoped to a particular context.
Instead I'd consider:
Have your framework return non-NSManagedObject models which are (perhaps immutable) snapshots of state from your Core Data store. If you can avoid exposing use of Core Data to consumers of your framework then you can give them models which are not constrained to a particular concurrency queue and you can completely own the lifecycle of these models.
Avoid any external dependencies in models and move such behavior into service classes or other interfaces which can then use DI more easily. Make sure these service classes respect the concurrency queue of any models they are given so all of your interfaces will probably need to be asynchronous.
First of all i know MVC well and have been using it in project but when it comes to organizing classes and there role i am bit not sure of there proper implementation. Lets take a scenario to proceed with:
A sample which will display All Employee and Department. Data will be fetched from Web Services(Json) and will be stored as offline(Core Data).
So MVC pattern would be:
View will be my storyboard with Employee and Department UIViewController.
Controller will be EmployeeViewController.swift and DepartmentViewController.swift
Model will be Employee.swift and Department.swift
class Employee: NSObject {
var name: String?
}
class Department: NSObject {
var departmentName: String?
}
ServiceManager which will make calls to the web service.
ParseData which will parse the web service response and convert it into Employee and Department objects
CoreDataManager is singleton class to manage CRUD operation on offline DB.
Here are series of question on the above scenario which i have:
Is my understanding correct? Is the structure which i am trying to build follows proper MVC?
How the controller will interact with these components (Service Manager, ParseData, CoreDataManager). Should there be another class which will facilitate the communication between controller and data management(if controller does this then it will a tightly-coupled structure and massive as well).
Should Model be having any code other then property and initialization method as most of the model which i have seen only have property declaration?
Should there be separate UIView classes instead of storyboard to create a proper MVC structure?
Is my understanding correct? Is the structure which i am trying to
build follows proper MVC?
First I will say that "proper" MVC will depend on who you're asking. Its origin is commonly attributed to Trygve Reenskaug when he introduced this into Smalltalk in the 70's. However, his type of MVC was widely different from the bloated versions most commonly used today. The modern way of thinking about MVC is
Model = mostly a dumb class which primarily encapsulates data
View = whatever we present on the screen
Controller = the big lump of code that does almost everything,
sometimes offloaded by a manager class or two of some sort
Reenskaug, however, would have a model and a view and a controller for a button. For a label. For a field. I'm not saying that is what we should strive for, but there should be better ways to structure a project than using the Massive ViewController pattern (as it is jokingly referred to in the iOS community).
Luckily, there are.
Uncle Bob is preaching Clean Architecture. There are several implementations of this, and various people have made their own implementations of this for iOS, like VIPER and Clean Swift.
How the controller will interact with these components (Service
Manager, ParseData, CoreDataManager). Should there be another class
which will facilitate the communication between controller and data
management(if controller does this then it will a tightly-coupled
structure and massive as well).
Following the principles of Clean Architecture, you should encapsulate these functionalities into layers, in a way that enables you not just to split the code into multiple components, but also enables you to replace them with other components when that is needed. (But yes, at the very least avoid putting all of this in your controller!)
Should Model be having any code other then property and initialization
method as most of the model which i have seen only have property
declaration?
Again, there is not a single answer here. Some proponents of "real" OOP will say that each object should be self-served (i.e. a model object should know how to persist itself), while others extract the knowledge of such operations into "managers". Putting code to persist an object into the object could mean littering persistence functionality into many objects, or require you to rely on subclassing or other solutions to avoid this coupling.
Should there be separate UIView classes instead of storyboard to
create a proper MVC structure?
Storyboard or not does not determine whether you're using "proper" MVC. Also, what kind of class you're choosing (UIView or UIViewController) to represent the View is also not important. Your ViewController can be dumbed down to such a degree that it contains no logic (forwarding the logic that it DOES have to another class, i.e. the Presenter in VIPER).
I would recommend reading about the Clean Architecture and maybe watch a video of Uncle Bob explaining it, read other people's reports on implementing it, and then consider whether MVC is the correct pattern for your iOS project.
Is it ok to create dependencies between categories in Objective C? Also between the categories and their base class?
I know that there should be no difference at runtime, they probably are just merged together at compile-time. For instance, let us say i break down my class B into:
B(base class)
B+categ1
B+categ2
B+categ3
My question is, is it wrong to either:
a) import B+categ2 and B+categ3 in B.m
b) import B+categ1 in B+categ3?
I'm asking both performance-wise and conceptually.
EDIT:
What would you suggest for a single screen app? Categories or Extending that class?
There's nothing deeply wrong with it, but it may suggest an overuse of categories. While they are a powerful tool for certain problems, and definitely can create some conveniences, I generally wouldn't build a complex system on them.
I usually find that overuse of categories is based on too much IS-A thinking rather than HAS-A thinking. In other words, if you're putting a lot of categories on an class to act as a fancy kind of subclassing, you may be better off using composition instead. Rather than adding lots of category methods to NSArray (as an example), you would want an data object that has an NSArray property and provides the interface you want.
But this is just advice if you're overusing categories. There's no fundamental problem with having categories import other categories. However, this claim is incorrect:
I know that there should be no difference at runtime, they probably are just merged together at compile-time.
Categories are resolved at runtime, not compile-time. The one major danger of that is that if two categories implement the same method, then the behavior is undefined. This is why you should never use categories to override methods, only to add them.
Avoid having a base class depend on a category of itself. Exceptions to this rule are made for private categories (use extensions instead) and categories intended to be used by subclasses of the base class. These are specialized exceptions and should not be thought of as a proper general purpose solution.
For categories depending on categories, if you make sure the dependency graph never has a cycle, then you should be fine.
As a final bit of advice, be explicit about dependencies.
// A+c2
#import "A+c1.h" // A(c2) relies on A(c1) declared methods/properties.
…
// A+c3
#import "A+c1.h" // A(c3) relies on A(c1) declared methods/properties.
#import "A+c2.h" // A(c3) relies on A(c2) declared methods/properties.
Even though A(c3) is implicitly including A(c1) by importing "A+c2.h", I still explicitly import it. This will save frustration as code changes in the future.
I have an application using the Entity Framework code first. My setup is that I have a core service which all other services inherit from. The core service contains the following code:
public static DatabaseContext db = new DatabaseContext();
public CoreService()
{
db.Database.Initialize(force: false);
}
Then, another class will inherit from CoreService and when it needs to query the database will just run some code such as:
db.Products.Where(blah => blah.IsEnabled);
However, I seem to be getting conflicting stories as to which is best.
Some people advise NOT to do what I'm doing.
Other people say that you should define the context for each class (rather than use a base class to instantiate it)
Others say that for EVERY database call, I should wrap it in a using block. I've never seen this in any of the examples from Microsoft.
Can anyone clarify?
I'm currently at a point where refactoring is possible and quite quick, so I'd like some general advice if possible.
You should wrap one context per web request. Hold it open for as long as you need it, then get rid of it when you are finished. That's what the using is for.
Do NOT wrap up your context in a Singleton. That is not a good idea.
If you are working with clients like WinForms then I think you would wrap the context around each form but that's not my area.
Also, make sure you know when you are going to be actually executing against your datasource so you don't end up enumerating multiple times when you might only need to do so once to work with the results.
Lastly, you have seen this practice from MS as lots of the ADO stuff supports being wrapped in a using but hardly anyone realises this.
I suggest to use design principle "prefer composition over inheritance".
You can have the reference of the database context in your base class.
Implement a singleton for getting the DataContext and assign the datacontext to this reference.
The conflicts you get are not related to sharing the context between classes but are caused by the static declaration of your context. If you make the context an instance field of your service class, so that every service instance gets its own context, there should be no issues.
The using pattern you mention is not required but instead you should make sure that context.Dispose() is called at the service disposal.