Fixing: Cannot merge multiple root entity source tables into one destination entity root table

So I have an app called TimeTag that uses Core Data and I needed to migrate to a new core data model version. 

It uses a UIManagedDoc to manage the core data file (rather than having everything dumped in the AppDelegate). I did the usual first steps:

  1. I selected my ModelName.xcdatamodelId in my project list and went up to "Editor" and selected "Add Model Version"
  2. I had it inherit from my current model version
  3. Then I selected the ModelName.xcdatamodelId file in the project listing again, and went over to the right editor pane, and selected the "File Inspector" tab. 
  4. Here, you want to make sure that Model Version has the new version you just created in the dropdown.
All was business as usual. I made the changes in my model. In this case, I added a new abstract entity that everything was inheriting from, since I'm going to be using that for my syncing logic.

I ran the project, and got the dreaded error that the database file could not be opened. Since I was using a UIManagedDoc custom class, the error was actually masked. So I set a debug point, and came across the error: 

Cannot merge multiple root entity source tables into one destination entity root table

I was confused, because I had this code in my loading of my model:

NSDictionary *options = @{NSMigratePersistentStoresAutomaticallyOption: @YES

NSInferMappingModelAutomaticallyOption: @YES};

self.timeTagDB.persistentStoreOptions = options;

        

(TimeTagDB is my custom UIManagedDocument class). 

After googling around and looking at some Stackoverflow answers, it turns out all I had to do was creating a mapping model and add it to the project. 

1. To do that, simply Add a new file (Cmd+N) and select "Core Data" in the side pane, and finally select "Mapping Model":

2. Hit next, and now select the Data Model you are coming from.

3. Hit next again, and finally, Select the data model you are going to.

4. Name the file. I chose something like "Model24ToModel25".


Xcode should now have created a new .xcmappingmodel file in your project, and will have automatically migrated properties that kept the same name. It won't add a class for your new abstract class and that's okay. You don't need to worry about that.

Make any changes you might have to. In my case, I didn't need to do anything, but you might need to tweak some stuff, like if your abstract class will now take over certain properties.

Run the project now. It should be good to go! (At least it was in my case).

Thanks to Christian for his SO post!


The exciting times of being an app developer

Last night I was doing one of the things I normally do throughout the day: Search Twitter for my app names to see if anyone is tweeting about my company or one of my apps. But tonight, unlike many other nights, there were tons of tweets all in Japanese with just the word 'TimeTag' in English. I got excited: Someone wrote about us in Japan, so I clicked the link (http://cyblog.jp/modules/weblogs/12443)

It was a blog post that (translated) seems to be all about using TimeTag (Available on the iOS store here) to stay productive, and why this person really likes the app. It was so cool to see my app with Japanese characters in its labels instead of English like I normally see it. 

Our ranks blew up overnight, and we're now #8 for iPhone productivity apps for Japan and floating around #120 for the entire iPhone store. The iPad version is also growing in popularity and is now #80 for productivity apps. Very exciting stuff. Whatever blog this is, it seems to be pretty popular in Japan. (I really wish I could get a properly translated version).

Honestly, what makes me most excited about things like this is not the financial reward--it's the fact of seeing something I created on my laptop being used (and appreciated) by people all around the world. We live in such an amazing time where an individual or group of individuals can get together, come up with an idea, and with a click of a mouse send it across the entire world. 

So here's to the life of a programmer/designer/app maker/coder/whatever title you choose. It's not always the most glamorous life, but it's certainly very rewarding at times like this. We really do live in an amazing time.

Big day for me: my first iPhone game launched

This is an exciting Friday. My first game, Doodle Space Fighter ( https://itunes.apple.com/us/app/doodle-space-fighter/id657189824?mt=8) launched for the iPhone today. I'm doing a soft launch this weekend with just my own personal blogs and friends/family, and then doing a bigger one this upcoming week. Honestly I don't care if it only sells 5 copies, it was so much fun to write.

I started working on games a few months back, around April. I wrote the whole game using Cocos2d, and added a few UIKit menus in it to make some of the more traditional stuff easier (emailing developer, reviewing the app, etc). I wrote a few times on this blog about some of the things I ran into while developing the game, and now that it's out, I plan to write a lot more on the topic.

Now that Apple introduced SpriteKit, I plan to switch gears to using that, and developing a cross platform game for the Mac and iPhone (and iPad). Even though Cocos2d is being replaced by the cross platform C++ based one, it seems like SpriteKit is very similar--it has the same general style of update timers, layers, and scenes. 

Overall, the experience of creating and writing a game is unlike any other traditional programming I've done in the past few years. I've mostly spent my time creating productivity style apps (time sheets, writing tools, apps for enterprise) and so having to learn all about game design was a huge change. After a week or two though of tutorials and putting together a real basic game mechanism, I got way more into it and just kept iterating until it was ready for launch.

I'm excited to keep doing game dev as a side hobby (a bit of a weekend/evenings thing), because I've always loved games and it's so cool to be able to create your own. Definitely an exciting day indeed.

Putting Game logic in a plist file

Since "Doodle Fighter" (working title) is the first game I've ever worked on, a lot of the code started off as you might expect: tons of things cobbled together, none of it properly encapsulated, and a lot of it hard coded. 

The last week I've been focused on pulling a lot of this data out and I decided that one thing I wanted to do (after reading that others recommended doing this) is put a lot of the game logic and design choices into a plist that comes loaded with the app. This lets me do a couple of cool things:

1. It lets me create different plists for shipping, testing, and experimental versions of the game without changing a single line of code.

2. It lets me tweak game settings quickly. In fact, depending on how motivated you are, you can program the game to live-update settings without doing a rebuild of your code. For example, every time you un-pause (in testing mode), your app could re-read the plist and get the updated values. That gives you great testing speed and power to tweak all those details that will make or break your game.

The actual code to read a plist is trivial stuff:

NSBundle *bundle = [NSBundle mainBundle];
NSString *plistPath = [bundle pathForResource:@"GameDesignInformation" ofType:@"plist"];

NSDictionary *plistDictionary = [NSDictionary dictionaryWithContentsOfFile:plistPath];

Then you can enumerate the dictionary using blocks:

    [plistDictionary enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) { 
// Do things here

}];

How you decide to design your plist is up to you. I created a few arrays for ship types, levels, and then a dictionary defining general game modifiers. I read them into a singleton called LevelManager that stores them in memory while the app is open, so that I don't have to constantly read off the disk. 

When I started with this plist, I first used it to create the game modifiers dictionary as well as a basic array of enemy ship types. Then I expanded it to include things like starting default values, costs for upgrades for my ships, developer only things (like putting on invincibility mode), and other useful testing things like multipliers on speed of enemies, laser firings, and so on. 

It was several hours of doing this work, but because of that I can tweak and modify my game with great ease now!

My Doodle iPhone Game: Part 1

I've been working on developing my first iPhone game for a couple of months now but recently I've been able to commit more time to coding it, since I finished school earlier this month. In short, the game is like Galaga, but it's with doodle graphics and includes the ability to upgrade your ship throughout the levels.

The idea will be that your ship is a fighter escorting a delivery freighter through the "doodle space zone". Every delivery will take longer than the last and become more treacherous. You earn money with each delivery (naturally) which you can spend to upgrade your ship's defenses/offenses.

Coding a game has been something I've wanted to do since I first starting working on iOS several years ago. I started with a few Cocos tutorials (located at http://www.raywenderlich.com/tutorials ) and then decided it was time to just start creating something. I sketched out a ton of ideas but settled on a fun space shooter game that included RPG elements. I've always enjoyed games that let me change my player in some way throughout the game, so that as I got better and got to harder levels, I could have a better character to deal with the challenge (and something to show for it).

Right now, you can upgrade the ship's shield, regen time (since the shield regenerates through time), and its weapon systems. It's been so much fun coding this game and has been such a huge challenge too. I felt like I was starting to learn how to code all over again working in game development and design, vs. all the work I've done doing productivity based apps.

If this game works out, I'm going to be hard pressed to not continue working on games exclusively!

I'm going to be blogging about some of the technical things I've learned as well as the general lessons learned from learning how to code games using Cocos2d. 

Here's a screenshot of the game right now (yes, it says 0HP, but since it's in testing ,the ship is invincible right now :) )

DoodleSpaceShooterGame

















Migrating Core Data to new UIManagedDocument in iOS 5

I have an app that has been on the store since iOS 3.1, so there is a large install base out there that still uses Core Data loaded up in my AppDelegate. In the most recent set of updates, I raised the minimum version to 4.3 but still kept the same way of loading the data. Recently, I decided it's time to make the minimum version 5.1 (especially with 6 around the corner), so I wanted to start using the new fancy UIManagedDocument way of using Core Data.

The issue with this though is that the old database file is still sitting in the iOS app, so there is no migrating to the new document. You have to basically subclass UIManagedDocument with a new model class, and override a couple of methods to do it for you. Here's a tutorial on what I did for my app TimeTag.

 Step One: Add a new class file in Xcode and subclass "UIManagedDocument"

Go ahead and also add a method to get the managedObjectModel out of this class. It should look like:

 

@interface TimeTagModel : UIManagedDocument

 

- (NSManagedObjectModel *)managedObjectModel;

 

@end

 

Step two: Writing the methods in the implementation file (.m)


I first added a shortcut method for the applicationsDocumentDirectory, which returns the URL of the app directory. 

- (NSURL *)applicationDocumentsDirectory

{

    return [[[NSFileManagerdefaultManager] URLsForDirectory:NSDocumentDirectoryinDomains:NSUserDomainMask] lastObject];

}

 

The next step was to pull the managedObjectModel file itself (.momd file). In my project, it's called "minimalTime".

- (NSManagedObjectModel *)managedObjectModel

{

    NSString *path = [[NSBundlemainBundle] pathForResource:@"minimalTime"ofType:@"momd"];

    NSURL *momURL = [NSURL fileURLWithPath:path];

    NSManagedObjectModel *managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:momURL];

    

    return managedObjectModel;

}

 

After that, I need to check for a legacy installation and migrate it to the new UIManagedDocument file instead. This is the overridden method:

- (BOOL)configurePersistentStoreCoordinatorForURL:(NSURL *)storeURL ofType:(NSString *)fileType modelConfiguration:(NSString *)configuration storeOptions:(NSDictionary *)storeOptions error:(NSError **)error

{

    // If legacy store exists, copy it to the new location

    NSURL *legacyPersistentStoreURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"minimalTime.sqlite"];

    

    NSFileManager* fileManager = [NSFileManagerdefaultManager];

    if ([fileManager fileExistsAtPath:legacyPersistentStoreURL.path])     {

        NSLog(@"Old db exists");

        NSError* thisError = nil;

        [fileManager replaceItemAtURL:storeURL withItemAtURL:legacyPersistentStoreURL backupItemName:niloptions:NSFileManagerItemReplacementUsingNewMetadataOnlyresultingItemURL:nilerror:&thisError];

    }

    

    return [superconfigurePersistentStoreCoordinatorForURL:storeURL ofType:fileType modelConfiguration:configuration storeOptions:storeOptions error:error];

}

 

Basically what's happening above is that it checks for the minimalTime.sqlite file inside the app's bundle on the iOS device. 

If the file exists, it tells you inside the console, and then tells the fileManager to replace the storeURL (inside the method parameter) with the legacy URL. This basically gives your app access to all the existing data the user has generated (otherwise they would load into a blank app, which would be disastrous).

It returns a YES if successful (by calling it's [super] method).

Final step: Actually load this database

Due to how my app works, I actually have to load the database at launch (instead of shortly after, which would be ideal). I call a method called loadDatabase, which looks like this:

-(void)loadDatabase

{

    static dispatch_once_t onceToken;

    

    // Only do this once!

    dispatch_once(&onceToken, ^{

        // Get the URL

        // The minimalTimeDB name is just something I call it

        NSURL *url = [[selfapplicationDocumentsDirectory] URLByAppendingPathComponent:@"minimalTimeDB"];

        // Init the TimeTagModel (our custom class we wrote above) with the URL

        self.timeTagDB = [[TimeTagModel alloc] initWithFileURL:url];

 

        // Setup the undo manager if it's nil

        if (self.timeTagDB.undoManager == nil){

            NSUndoManager *undoManager = [[NSUndoManager  alloc] init];

            [self.timeTagDB setUndoManager:undoManager];

        }

        

        // You have to actually check to see if it exists already (for some reason you can't just call "open it, and if it's not there, create it")

        if ([[NSFileManagerdefaultManager] fileExistsAtPath:[url path]]) {

            // If it does exist, try to open it, and if it doesn't open, let the user (or at least you) know!

            [self.timeTagDB openWithCompletionHandler:^(BOOL success){

                if (!success) {

                    // Handle the error.

                    NSLog(@"Error opening up the database");

                }

                else{

                    NSLog(@"Opened the file--it already existed");

                    [self refreshData];

                }

            }];

        }

        else {

            // If it doesn't exist, you need to attempt to create it

            [self.timeTagDBsaveToURL:url forSaveOperation:UIDocumentSaveForCreatingcompletionHandler:^(BOOL success){

                if (!success) {

                    // Handle the error.

                    NSLog(@"Error opening up the database");

                }

                else{

                    NSLog(@"Created the file--it did not exist");

                    [self refreshData];

                }

            }];

        }

    });

}

 

If you're curious what refreshData looks like, it sends out a NSNotification that the database has been loaded:

-(void)refreshData {

    NSNotification* refreshNotification = [NSNotificationnotificationWithName:kNotificationCenterRefreshAllDatabaseData object:self.timeTagDB.managedObjectContext  userInfo:nil];

    [[NSNotificationCenter defaultCenter] postNotification:refreshNotification];    

}

 

The kNotificationCenterRefreshAllDatabaseData is just a constant I have defined elsewhere that keeps track of all the NSNotification names I use.

I pass the managedObjectContext of the newly created file so that my view controllers can have access to it, and start passing it around to one another.

The reason we do this as a Notification is because this is being run in the background, so we can't know exactly when it finishes. Make sure you design your app for this! Have some kind of loading indicator, or make sure your user can't attempt to create a record before the database actually exists, because it will crash the app.

 

UITableView and UIViewcontroller as a subview

This drove me nuts for a few hours, but finally figured it out. I wanted to go ahead and share, since the web results I found when I was searching were only a few pieces here and there, and still didn't offer a final solution.

So the scenario I encountered was that I have a UIViewController that will sometimes host a subview (that is another viewcontroller) and it has a UITableView in it. The idea is that sometimes the user will tap a button, and it will add a subview of that UIViewController.

Originally I created a file that subclassed UITableViewController but I've recently found that I prefer to create UIViewControllers that have tableViews in them. They're easier to manage, and give you more control over the view. For example, you can add subviews a lot easier to a UIViewController than you can a UITableViewController.

The major issue I was having was that the UITableView did not resize properly when added as a subview. It would show some of the rows, but when the list became very long, it wouldn't let the user flick down to them. In general it was just being very strange and didn't seem to respond to any kind of frame setting.

What worked was that I created a new UIViewController (without a nib file) and implemented the following code in the loadView:

// Implement loadView to create a view hierarchy programmatically, without using a nib.

- (void)loadView

{

 

UIView *contentView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 480)];

contentView.autoresizesSubviews = YES;

contentView.autoresizingMask = (UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight);

contentView.backgroundColor = [UIColor clearColor];

 

[self setView:contentView];

[contentView release];

 

tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, 320, 440) style:UITableViewStylePlain];

[tableView setAutoresizesSubviews:YES];

[tableView setAutoresizingMask:(UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight)];

 

 

[tableView setDataSource:self];

[tableView setDelegate:self];

 

[[self view] addSubview:tableView];

}

 

So in the loadView method, I create a UIView programmatically and set it to a full size frame. I then create a tableView and this is where I create the custom frame size that my app required. (I set it to be 440 instead of the full 480 for height). If you wanted, you could make this a variable that you initialize the UIViewController with.

If you're curious what the header file looks like, here it is:

@interface SelectPeopleViewController : UIViewController <UITableViewDelegate, UITableViewDataSource> {

 

UITableView *tableView;

}

 

@property (nonatomic, retain) UITableView *tableView;

 

By doing this, I was finally able to add the UIViewController as a subview and have it be sized properly, and the tableview finally rendered the list properly.

Hope this info helps!

Creating an In-App Help Menu with a .plist file

This is just a quick tutorial to help you write in an in-app help menu using a .plist file. As apps become more complicated (especially if you continue to add onto your 1.0 version with more features), it's easy to get lost in them. And a good built-in support system is appreciated by everyone. I also prefer to keep it in-app because then it's formatted properly and your users won't have to open up a browser and check, which isn't always available (or isn't always formatted properly).

Ok so I decided to use a .plist file because it'd be the easiest way to structure the document and make changes. If you wanted to get really fancy, you could host the .plist file online (and have it pull from there) so that you can make edits to it without having to re-submit the app. But that's out of the scope of this particular post.

Begin by adding the .plist to your project. You can do this easily by right clicking on your project and clicking "Add.." and then "Add New File..." :

AddNewPlist.jpg

For my plist, I decided to make the root object an array and have each object in that array be a dictionary. The reason for choosing an Array (instead of the default Dictionary) is that you can order the menu items in the file itself, without having to do any extra work once you parse it. Dictionaries result in un-ordered lists, which would be silly, since you typically would want your help menu to be organized in a logical manner (going from the most basic to advanced features, for example.) So in each dictionary, I make the first item keyed to "Title" with the value of the title that the section will have. In this manner, I can create a help menu that uses the UITableViewGroup display, and have several sections with rows in each. (Once you see some pictures, I think it'll be pretty clear.)

Here is what my final demo plist looks like. I've used my app (Compositions) as an example: PlistFile.jpg

And just as a preview of what this will end up looking like, here is the final tableview in my app:

FinalHelpTableView.jpg

Ok, so to get from the file to that screenshot is actually pretty easy. I added a new UITableViewController to my project and named it HelpViewController. I checked the box to subclass it from the UITableViewController class so that it would add in the methods that I need.

I am using a custom class that I wrote called "MenuItem". MenuItem is a generic class I use for any time I need to write a custom UITableView item list. It has the ability to chain indefinitely, so that I can easily create sections and rows with it, and also include a subtitle, description, item name, a key (which is useful when your positioning is independent of the order you add the items), etc. Here is the class definition:

As I mentioned, the subMenuItems is useful to add another array of MenuItems, so that I can easily create a hierarchy in a menu.

@interface MenuItem : NSObject {

 NSUInteger itemKey;

 NSString *itemDescription;

 NSString *itemSubtitle;

 NSMutableArray *subMenuItems;

}

@property (nonatomic, assign) NSUInteger itemKey;

@property (nonatomic, retain) NSString *itemDescription;

@property (nonatomic, retain) NSString *itemSubtitle;

@property (nonatomic, retain) NSMutableArray *subMenuItems;


Back to my HelpViewController! I create a NSMutableArray to hold my menu items:

 NSMutableArray *menuItems;

And I initialize it in my -(id)init method:

-(id)init {
 [super initWithStyle:UITableViewStyleGrouped];
 menuItems = [[NSMutableArray alloc] init];
 return self;
}


I'm choosing to create the actual menu in my ViewDidLoad method, so that if I run low on memory while I'm off the screen, I can dump it and re-create it if they come back to it.

 

Here is the code to build the menu, using my custom class and the plist file. I'll explain everything after:

-(void)loadHelpChapters {
 NSBundle *bundle = [NSBundle mainBundle];
 NSString *plistPath = [bundle pathForResource:@"HelpList" ofType:@"plist"];
 NSArray *rootArray = [[NSArray alloc] initWithContentsOfFile:plistPath];
 MenuItem *mi = nil;
 int k = 0;

 for (NSDictionary* chapter in rootArray ) {
 NSString *chapTitle = [chapter valueForKey:@"Title"];
 mi = [[MenuItem alloc] initWithKey:k andDescription:chapTitle];

 [chapter enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
 if (![key isEqualToString:@"Title"]) {

 MenuItem *subMi = [[MenuItem alloc] initWithKey:k andDescription:key andSubtitle: obj];
 [[mi subMenuItems] addObject:subMi];
 [subMi release];

 }

 }];

 [menuItems addObject:mi];

 [mi release]; mi = nil;

 k++;

 } 

 [rootArray release];

}


So what's happening here?  First I'm getting a reference to my bundle (which is your packaged app, essentially) and then getting the address of the actual .plist. I've named my HelpList so that's what's happening in line 2. I then initialize an array (which is the root object of the file) using NSArray's initWithContentsOfFile: method. That will open up the file and load all the root objects into an array.

 

Each object is now a NSDictionary, which I'm calling "chapter". I'm going to enumerate through each one and do a couple things.

First I'm going to create my section MenuItem. This is going to represent the tableView section and will have several rows in it. I ask for dictionary for the "Title" value and initialize a MenuItem with that. I am not using the key for anything in this instance (the key is just an int value) but I am adding an int k to it, just in case I ever want to use its position for anything.

Next comes the really cool part--using blocks! I need to go through the rest of the dictionary, getting everything but the Title value, to add each row to this section. I use the method -enumerateKeysAndObjectsUsingBlock which essentially goes through each dictionary item and exposes both its key and value. The key in this case is the section title, and the value in my example is the text that will appear when the user taps on the item.

For each of these enumerated dictionary values, I create a child MenuItem (called subMi) and add it to my current section MenuItem. Once added, I release it.

Once I'm done enumerating, I add this section MenuItem to my ViewController's array and release that as well, to be a good memory citizen.

Once it's done going through all the root objects, I release the rootArray object I created, freeing up that memory as well.

Now for the tableView methods. As I've mentioned, we now have a top level array of MenuItems that represents all the sections. And inside each of those, we have children MenuItems that represent rows. So this is basically an exact mirror to how tableViews work, with NSIndexPath. So it's pretty simple:

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
 // Return the number of sections, which is just how many items we have in our menuItems array.
return [menuItems count];
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
 // Return the number of rows in the section.
 // First get the top level item using section
MenuItem *mi = [menuItems objectAtIndex:section];
// Then return the number of children items from the top level one.
 return [[mi subMenuItems] count];
}

 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

static NSString *CellIdentifier = @"Cell";
 UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

if (cell == nil) {
 cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
 // Get the top level first from the section
 MenuItem *mi = [menuItems objectAtIndex:[indexPath section]];
 // Then get the child level item from the row

 MenuItem *subMi = [[mi subMenuItems] objectAtIndex:[indexPath row]];
 [[cell textLabel] setText:[subMi itemDescription]];

 return cell;
}

-(NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {

 // Pull from the top level to get the section title
 MenuItem *mi = [menuItems objectAtIndex:section];

 return [mi itemDescription];
}


I hope this proves helpful for someone! It might seem like a lot of work, but it's really not too bad. And as I said, now you have a code-independent method of adding and removing help items. You can do all your text editing in your .plist editor, and even put it online to update it there. You could design a system that checks for an updated help file on load (if network is present) and pull it down real quick. Plists are small text files essentially, so it would be pretty quick.

 

_OBJ_CLASS_$ Error (Symbol(s) missing) with Full and Free iOS apps

I am currently working on making a free version of my iOS application. I followed a fantastic tutorial a while back (http://www.bit-101.com/blog/?p=2098 ) which got me up and running with a free and regular version, sharing the same code base. This is great, because changes made will be mirrored across both versions, so you don't have the nightmare of maintaining two sets of code.

I shelved the free version for a while and then decided to come back to it, and hopefully get it out in time for 4.2's release next month. I had added several new classes and some views since the last time I built the free version and thought it would compile just fine. I was wrong!

I ran into the error with several of those new classes/views (OBJ_CLASS_$) saying the symbols were missing. I was confused, since I saw them right there in my project.

Turns out that I had to manually copy these over to the free version so that it would build along with all the other classes. XCode doesn't automatically do this if you've been working in one target and then switch to the other.

It's a simple fix though. Lets say you're getting an error that a class called "ProgramSettings" is referenced but missing. Follow these steps:

1) Find "Targets" in the left side of your Xcode window ,and expand it. You should see something like "MyApp" and "MyApp Free".

2) Expand the "MyApp Free" (or whatever version that you're getting the error in).

3) You should see lots of folders, named "Copy Bundle Resources", "Compile Sources", and "Link Binary With Libraries." You will want to find the class (ProgramSettings.m) in your project above, and simply drag and drop them into "Compile Sources", along with all the other classes.

You can repeat step #3 for what is missing. Classes go in the Compile Sources and nibs (.xib) go in the Copy Resource Bundle.

4) Clean, build and launch!

it should now be error free, assuming you had no other errors on build and in your code.

 

quick fix: Predicatebuilder not stacking queries issue inside for loop

I ran into this problem this morning and thought I’d share in case someone else has this issue .So I’m using PredicateBuilder with the EntityFramework and doing some pretty basic query building.

I have a list of business types that the person can select (a checkboxlist) and then it returns everything that matches. I was having an issue because it was only ever returning the businesses that matched the last item I selected—it wasn’t stacking the query at all.

Finally, I noticed what was going on. Inside my for loop:

foreach (int bTypeId in businessTypeIds)
            {
              
                businessTypes = SearchHelper.Or(businessTypes,
                    m => m.BusinessType.BusinessTypeID == bTypeId);
                businessFiltered = true;
            }

 

I was never casting bTypeId to its own variable. So if I ran a query to search for business type Ids 23 and 24, it was going through once ,and asking for == 23. Then it went through the second time, and changed the reference to both to be == 24. So the query ended up just saying does the business type equal 24 two times, instead of saying does it equal 23 or 24.

The quick fix? Add in a temporary variable and use that instead:

foreach (int bTypeId in businessTypeIds)
            {
                int tempId = bTypeId;
                businessTypes = SearchHelper.Or(businessTypes,
                    m => m.BusinessType.BusinessTypeID == tempId);
                businessFiltered = true;
            }

 

Now the tempId holds the proper Id for each type, and the query will essentially read “does it equal 23 or 24”.