Search Results for: core data

 
27
Aug
2008
 

Cocoa Tutorial: Sync Services without Core Data

by Marcus Zarra

Sync Services have come a long way in Leopard. Before Leopard it was an extremely complex operation that was almost completely manual. Needless to say, this sucked and it was probably one of the reasons it was shunned by most developers.

If you are using Core Data in a Leopard application then Sync Services is so trivial that you should be syncing if it makes sense. In this article we are going to cover syncing in a non-Core Data situation as that is quite a bit more complex.

If you have read the Sync Services documentation then you know it is complex. Let me dispel an illusion right away. It is hard. It is not poor documentation, syncing is very hard and very few people get it right. Take a look at Omnifocus to see an example of a company thinking it is easy and losing data. Therefore if you are expecting this subject to be trivial you will be disappointed.

In this example we will be syncing with the bookmarks schema and displaying them in a simple outline view. The outline view itself will be editable and those edits can be synced back. Not terribly useful but provides a very simple example.
(more…)

 
29
May
2008
 

Coding Practice: Cleaning up the default Core Data project

by Marcus Zarra

In this entry I am going to do something a little different. Instead of showing some wicked code, I am going to reformat one of Apple’s default templates.

Apple writes some amazing code. Unfortunately a lot of their templates demonstrate simply terrible coding practices. What is worse, people take these templates and assume that they are the proper practice for coding in Objective-C and propagate that poor code into their own projects.

The first example I am going to tackle is the AppDelegate class that is auto generated in the Core Data template. This is not the Core Data Document template but the standard application template.

(more…)

 
10
May
2018
 

Response: The Laws of Core Data

by Marcus Zarra

Recently, I saw a post from Dave DeLong and knowing his history with the framework I read it with extreme curiosity.

Unfortunately, that read led to this post as I disagree strongly with a number of the laws he has laid down.

Since I know people are going to be asking me about this post (I am still getting asked about Simmons’ post from a VERY long time ago), better to get my thoughts out now.

1. Do not use Core Data as if it were a database

No disagreement; Core Data is your object model and it can persist to a database but that is not its biggest strength.

2. Do not use Core Data as if it were a SQLite wrapper

This is re-iterating #1. Core Data is your object model, not a thin wrapper around a database.

3. Your NSManagedObjectContext is your “stack”

Here is where we start to disagree. The NSManagedObjectContext is not your stack. It is a scratchpad. It is where you stage changes to the data objects and decide to persist them or not.

I have advocated putting an object around it for convenience and Apple added the NSPersistentContainer which is designed to be subclassed. That wrapper is a great place to handle migrations, importing, exporting, convenience methods for accessing data; the list goes on.

All of the internal workings of your Core Data stack, your persistence and data model absolutely should be stored in the persistent container and that container should be injected through your controllers in your application.

4. Never ever ever ever ever use an NSManagedObject outside its context’s queue

No disagreement. Core Data is designed to work in a threaded environment but most of the objects are NOT designed to work on multiple threads/queues. As with ANY object, assume it is thread locked unless you can demonstrably confirm that it is safe to use across threads.

5. Do not use NSManagedObject as if it were an NSObject

An NSManagedObject is an NSObject that has additional functionality added. It should absolutely be treated as if it is an NSObject because it is an NSObject. NSManagedObject instances are your data objects and should be treated as such. Creating Plain Old Objects on top of NSManagedObject instances is asking for pain and data corruption.

6. You usually don’t need parent-child contexts

If you are not accessing the network, exporting data, importing data or interacting with the outside world in any way, shape or form then this is correct.

If your app talks to anything else then you will want to use parent-child contexts.

The parent context should be on the user interface thread (the main thread) and when you need to do asynchronous work with your data objects (importing or exporting) then you want to do that on another thread and that work should be done in a child context.

A child context simplifies the transfer of notifications of data changes and greatly simplifies using Core Data in a multi-threaded environment.

7. Keep your main queue context read-only

The main queue is also known as the user interface queue. The context that is associated with that queue should be for the user. That context reads and writes data when the user is interacting with the application.

Should it be read-only? Absolutely not.

Should it be user-only? Absolutely.

Any non-user work (importing and exporting) should be done on a child context on a background thread (see response to #6 above).

8. Use an abstraction layer

Please do not do this. You are going to make the next developer curse your name in a very unpleasant manner.

Use Core Data in your user interface. Do not create dummy data objects on top of Core Data. That leads to a maintenance nightmare.

Your user interface can use Core Data without really knowing that it is using Core Data. Your user interface treats the NSManagedObject instances as if they were data objects because they are data objects.

Your user interface does not need to know any more about Core Data than it does for any other model structure. Your user interface should talk to your persistent container subclass and ask for the data it needs. The response to that request might be instances of NSManagedObject or might be an NSFetchedResultsController which then serves up the data objects in a consistent and reliable way.

9. Use Core Data as a local cache

I agree with the wording of this rule but I suspect the meaning is different. Core Data, like any local persistence, is a local cache of what is on the server. This is not specific to Core Data because that is what any local persistence does when you have data on a server.

Core Data is more than just a local cache.

Core Data is not complicated

Core Data is as complicated as you make it. Most of the time you do not need or want the advanced features of Core Data and can just grab an instance of NSPersistentContainer and be happy.

When you need to deal with more complicated or interesting situations there is a fair chance that Core Data has an advanced feature to handle that situation. For the 80%, you can ignore those advanced features and relax in the comfort knowing they are there for if/when you need them.

The harder your code is to write the harder it is going to be to maintain and debug.

Don’t make it harder on yourself. Keep it simple.

 
5
Feb
2013
 

Querying Objective-C Data Collections

by Matt Long

In my Xcode LLDB Tutorial, I mention using the debugger to interrogate data collections. Well, I wanted to elaborate on that idea a little because there are some techniques you can use for querying objective-c data collections that are very powerful.

If you develop apps for clients, you my be one of the lucky ones–the ones who actually get to model your data and use Core Data to store and access it. But I’m betting there are many of you who aren’t the lucky ones–or at least not on all of your projects. From time to time you have to deal with data in whatever format your client gives it to you. Maybe you’ve even suggested taking the CSVs or Plists (or whatever other formats clients have come up with to ruin your life) and actually loading those into Core Data. But they don’t get Core Data and they shoot down the idea. Well, you may want to just walk away from the gig. However, if you’re like me, you’ve got bills to pay and clients (the good ones at least) tend to help you accomplish that. Well, fortunately for us, Objective-C makes dealing with this kind of data manageable using a little technique known as KVC, Key-Value-Coding, with array filtering and sorting.

This is not an advanced topic, so if you’re already familiar with how KVC and array filtering and sorting works, this post may not help you as much. But for those of you who are fairly new to iOS development, you need to know about this magical feature of the language as all the senior iOS developers use it and you should too. (more…)

 
29
May
2012
 

Importing Data Made Easy

by Saul Mora

Importing data is a problem that feels like it should have a library of work ready for you to use. Especially when it comes to importing data into Core Data where you have a description of your data to work with. What if there was such a library, or reusable framework, of importing code that basically converts raw data to Core Data entities? Well, wonder no further because in this post, I’ll be discussing a new addition to the MagicalRecord toolset, MagicalImport available now on Github!

(more…)

 
17
Feb
2012
 

Extending NSData and (not) Overriding dealloc

by Tom Harrington

A couple of weeks ago Matt Long was having a problem with an app running out of memory. He had a ginormous data file he needed to load up and process, and that memory hit was more than the app could bear. It would load just fine, into an NSData, but before he could finish with it the app would run short of memory and die.

Until recently the obvious thing would have been to tell NSData to create a memory-mapped instance. Given NSString *path pointing to a file, you could create an NSData with almost no memory hit regardless of file size by creating it as:

NSData *data = [NSData dataWithContentsOfMappedFile:path];

Starting with iOS 5 though, this method has been deprecated. Instead, what you’re supposed to do is:

NSError *error = nil;
NSData *data = [NSData dataWithContentsOfFile:path options:NSDataReadingMappedAlways error:&error];

So, fine, whatever, it’s a different call, so what? Well, it wasn’t working. Instruments was showing that the app was taking the full memory hit when the NSData was created. Mapping wasn’t working despite using NSDataReadingMappedAlways. So what could he do? The wheels of my mind started turning.

(more…)

 
3
Feb
2009
 

Record Your Core Animation Animation

by Matt Long

Every once in a while I find a way to combine multiple technologies that, while they don’t produce anything terribly useful, are very interesting when combined. In this post I will be taking a look at combining Core Animation and QuickTime. As you may or may not be aware, you can draw in a graphics context while your Core Animation animation is running and add each image created to a QTMovie object from QTKit. This enables you to create a QuickTime movie of your Core Animation animation. Here’s how.
(more…)

 
10
Sep
2008
 

Core Animation Tutorial: Rendering QuickTime Movies In A CAOpenGLLayer

by Matt Long

I’ve been experimenting a great deal lately with OpenGL and QuickTime trying to see how the two technologies work together. It’s been a bit challenging, but fortunately Apple provides two really great resources–number one, sample code. I’ve been able to learn a lot just from the samples they provide in the development tools examples as well as online. And second, the cocoa-dev and quicktime-api lists are great. Lot’s of brilliant people there who are willing to share their knowledge. It’s very helpful, prohibition to discuss the iPhone SDK notwithstanding.

Getting two technologies to work together can be a challenge especially when the bridges between the two are not necessarily clearly laid out in documentation. As I pointed out Apple provides some excellent sample code to help you along, but there is no hand-holding approach to any of it. I actually appreciate that having come from the Windows world as it seems that there all you get sometimes is hand-holding where Microsoft doesn’t trust you, the developer to figure things out and really own what you’re doing. But I digress (wouldn’t be a CIMGF post if I didn’t dig on MS a bit).
(more…)

 

Core Animation Snippets

by Matt Long

Here are some snippets to help with performing different tasks using Core Animation.

Images

  • Convert NSImage to CGImageRef
    - (CGImageRef)nsImageToCGImageRef:(NSImage*)image;
    {
        NSData * imageData = [image TIFFRepresentation];
        CGImageRef imageRef;
        if(!imageData) return nil;
        CGImageSourceRef imageSource = CGImageSourceCreateWithData((CFDataRef)imageData, NULL);
        imageRef = CGImageSourceCreateImageAtIndex(imageSource, 0, NULL);
        return imageRef;
    }
    

Scaling

  • Scale Up Five Times
    CATransform3D transform = CATransform3DMakeScale(5.0f, 5.0f, 5.0f);
    [layer setTransform:transform];
    
  • Scale Down to Half Size
    CATransform3D transform = CATransform3DMakeScale(0.5f, 0.5f, 0.5f);
    [layer setTransform:transform];
    

 
5
Mar
2008
 

Core Animation Tutorial: QTMovieLayer and Image Animation

by Matt Long

QTMovieLayer App DesktopIn my first post I wrote about using NSOperation to grab an image of the current frame of a QuickTime movie while it was playing and save it out to the filesystem. Considering the excitement that is surrounding Core Animation these days, I thought it might be interesting to take that project and change it to instead grab the current frame and animate it across the screen using a Core Animation layer (CALayer). I had to employ a few tricks to get it to work, but the end result, while completely useless, is quite excellent.

 

(more…)

 
4
Mar
2008
 

MacDevNet Podcast: MDR005 Data

by Marcus Zarra

I had the pleasure recently of being on an episode of the Mac Developer’s Roundtable with Kevin Hoctor, Aaron Hillegas and Steve “Scotty” Scott. In this latest episode, Scotty introduced the topic of data, how to store it, access it, etc. To kick it off, Aaron delivered a fantastic history of Core Data or as it was originally called, Enterprise Objects.

I highly recommend this episode to anyone who is interested in Core Data and Cocoa in general.

You can get the episode from MacDevNet.com.

(more…)

 
21
Sep
2015
 

Massive View Controllers

by Marcus Zarra

While at Empirical Development and then MartianCraft I had been distanced from all of the inventive solutions that other development teams have been coming up with for the past few years. I was living in a bubble of our development teams.

Now that I am working independently again, I am being exposed to a large number of interesting code bases.

It came as quite a surprise to me that view controllers are considered bad by many developers and that they have been coming up with some rather intersting solutions to make them more “manageable”.

To me, this is an indication that many developers have lost the perspective on what should and what should not be in a view controller. For some reason there is a misconception going around that everything belongs in the view controller.

Madness!

Lets break it down.
(more…)

 
4
Aug
2015
 

The Next Chapter

by Marcus Zarra

Speaking at CocoaConfAs of August 1, 2015 I am no longer part of MartianCraft.

It is time to move on to the next chapter.

What is Next?

Long term I have some ideas that will take a bit of time to put into place. In the short time I am eager to help as many teams as possible through short term contracting, consulting and workshops. I really do enjoy helping teams get the most out of their persistence and networking layers.

Therefore…

Effective immediately, I am available for short term and possibly long term contract work.

While I can assist with any form of iOS or OS X development, my area of expertise is in networking and persistence; specifically Core Data.

If you are not familiar with my experience, here are a few highlights:

  • Wrote “The Book” on Core Data.
  • Taught at universities around the United States
  • Spoken at nearly every Apple related tech conference around the world
  • Provided workshops on persistence, Core Data and Networking at many conferences and large corporations in and around the United States.
  • Developed some of the most complex applications ever conceived for the iOS platform

What are the options?

I am looking for short term projects unless it is truly amazing, cutting edge, and never done before. I am looking to help your team provide a better experience for your users.

We can accomplish this either through a monthly, weekly, daily contract or through a workshop. The details of which we can discuss in detail. I am available to travel and can work on site for short periods of time.

Are you struggling with your persistence or networking layer?

Are you having performance issues that you are unable to isolate?

Would you like a fresh set of eyes on your project to get an idea of where things are?

Contact me; we can discuss the options.

 
1
Jan
2014
 

Fetched Properties; useful?

by Marcus Zarra

Core Data has a number of features and abilities that are not commonly used. Chief among those are fetched properties. In discussing them with a number of developers, most have never heard of them and those who have heard of them couldn’t come up with a viable use case for them.

To be honest, I don’t have a lot of use cases for them myself. They are definitely not one of the core features of Core Data that I recommend people learning when they are initially getting comfortable with the framework.

In this article we will discuss one use case for fetched properties and the impacts.

## The Use Case

The use case for fetched properties that I have run across a few times comes into play when you have more than one persistent store file on disk. Imagine you are building a recipe application (one of my favorite examples). You decide to include a pre-built read-only database with existing recipes. However, your application has the ability to add notes and social comments to a recipe.

You want to keep the recipe database as read only (you have a separate one for new recipes) but you want the user to be able to add comments. Where do we put the data?

In this contrived situation, storing the comments (and other metadata) in another store makes sense. Unfortunately we can’t have relationships across physically separate stores.

Enter the Fetched Property.

## Fetched Property

A fetched property is a property added to a `NSManagedObject` entity that instead of storing a value or a relationship, it stores a `NSFetchRequest`. When the property is accessed for the first time the `NSFetchRequest` is fired and the results are returned.

A fetched property always returns a `NSArray` (well a subclass but that is a minor detail) and it can be configured to sort the results.

Unfortunately, the editor in Xcode does not permit adding sort criteria so the only way to add a sort to a fetched property is to create the fetched property in code. Hopefully that will be corrected in some future release of Xcode.

What does a fetched property look like? In the Core Data model editor, a fetched property is added just like an attribute or a relationship. Then in the Data Model inspector you can configure the `NSFetchRequest`.

A Fetched Property shown in Xcode's data modeler

A Fetched Property shown in Xcode’s data modeler

The Destination is the entity that will be returned by the fetched property. The predicate is a string representation of the `NSPredicate` configured within the `NSFetchRequest`.

Further, the predicate can use one of two variables to help configure it:

`$FETCH_SOURCE` gets replaced by a reference to the entity that owns the fetched property. By using this variable we can reference properties in the owning entity.

`$FETCHED_PROPERTY` gets replaced by a reference to the the property description of the fetched property. The property description includes key value pairs that are accessible from within the predicate. I have not run across a situation where I have used this variable.

## The sharp edges

There are unfortunately some concerns with fetched properties.

Unlike a relationship, there is no way to pre-fetch a fetched property. Therefore, if you are going to fetch a large number of entities and then desire to access the fetched property for those properties, they are going to be fetched individually. This will drastically impact performance.

Fetched Properties are only fetched once per context without a reset. This means that if you add other objects that would qualify for the fetched property after the property has been fetched then they won’t be included if you call the fetched property again. To *reset* the fetched property requires a call to `-refreshObject:mergeChanges:`.

A fetched property always returns an array. While this is not a major issue if in fact you want more than one object returned. However, when that is not the case it is an additional method call that you need to make every time or add a convenience method. More code equals more bugs.

## To use or not to use

Fetched properties are not a main line piece of Core Data. It appears that even the Core Data team (or the Xcode team at least) agrees with that assessment based on how little effort is given to them in the model editor. Should you use them?

It depends. If you are joining two separate persistent stores and need a *soft* relationship between entities in those stores then yes, you can use them. They do work.

Be mindful of the edges, they are sharp.