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.

 
25
Jun
2015
 

Core Data and Aggregate Fetches In Swift

by Matt Long

You can find other articles on the interwebs about NSExpression and NSExpressionDescription, however, I wasn’t really satisfied with the explanations I’ve seen. I decided to write a post myself after I recently had to become much more intimate with the way Core Data aggregate fetches work. I hope this will make clear what has to be done in order to harness this powerful feature of Core Data.

You’ve heard it said before and sometimes in a scolding tone, “CORE DATA IS NOT A DATABASE. IT’S AN OBJECT GRAPH!”. What normally follows is a discussion about what that means, if you’re lucky. Otherwise, you’re just on your own to go figure it out. In my mind, though, it’s not necessarily wrong to think of it as a database as they have enough things in common to make it a reasonable thing to do and at the end of the day Core Data is backed by a SQLite database. I think that if it helps you understand what is going on behind the scenes better, then go for it. You do have to remember some key differences that can bite you like the need to fetch before updating or deleting, for example. Though with recent additions–last year with iOS 8’s NSBatchUpdateRequest (link to iOS 8 API diff since it’s not currently documented) which allows you to perform a batch update similar to a SQL update query or this year with iOS 9’s NSBatchDeleteRequest (See WWDC 2015 session 220 for more info) which allows for batch deletes based on whatever predicate you give it, the lines seem to be blurring more and more. (more…)

 
26
May
2015
 

Setting up Jenkins CI on a Mac

by Eric Cerney

Image1Setting up a CI server can be nothing but pain and suffering, yet many of us take on this challenge to save time in the long run. Some things I would rather do than set up a CI server:

  1. Get a root canal at my desk waiting for Xcode SourceKit crashes to calm down.
  2. Submit an Apple Radar for one of my many Xcode crashes.
  3. Write a tutorial on how to set up a Jenkins CI server. (Oh hey!)

Whether you’re being a good developer and doing your unit testing, are tired of co-workers breaking your code, or have clients that can’t live without the latest and greatest build, CI will be your new best friend and butler.

There are tons of posts floating around the internet with bits and pieces on this topic; but none were comprehensive enough for me to get a server up and running. Because of this, I decided to write a thorough guide that will walk you through setting up a Jenkins CI Server on your machine of choice. In this instance we used a Mac Mini.

Note that our end goal with Jenkins was to build, test, and distribute apps for both the iOS and Android platforms. Some of the setup in this guide is aimed at accomplishing this goal.
Image2

What is Jenkins?

Jenkins is an open source continuous integration tool which aims to automate certain tasks that developers find themselves repeating. It runs as a local server on a host machine, like a Mac Mini, that can be dedicated to CI.

Generally, you would connect each Jenkins project to a SCM tool like Git. This allows you to trigger builds manually, based on a cron schedule, or whenever a source change is detected.

Jenkins supports over 1,000 plugins allowing you to work with many third party services. The best thing is that if you can’t find or use a plugin, you’re only limited by your own scripting ability as it’s able to run any arbitrary shell script.

Installing Jenkins

  1. Download the Jenkins Mac OS X native package from http://jenkins-ci.org.
  2. Double click the .pkg file to install Jenkins.
  3. Once done, your browser will open to http://localhost:8080 where Jenkins lives.

Note: If your browser opens up to a completely unstyled page (broken css), I recommend reinstalling Jenkins. You can uninstall Jenkins by running the script in /Library/Application Support/Jenkins called Uninstall.command.

Setting up the Jenkins User

Right now, Jenkins isn’t much of a butler. It’s more like the neighbor who moves your trash to the curb and waters your plants when you’re on vacation. Let’s promote it to an admin and give it the keys it needs to really help you out.

  1. Make the Jenkins user an admin:  sudo dseditgroup -o edit -a jenkins -t user adminAdd the Jenkins user to the

  2. Add the Jenkins user to the developer group: sudo dscl . append /Groups/_developer GroupMembership jenkins

  3. Make the Jenkins user automatically login when the computer is restarted:

  • a. Go to System Preferences\Users & Groups.
  • b. Unlock the settings by clicking the lock in the bottom left corner of the page and entering the login password for the current user.

Image3

  • c. Select the Jenkins user from the list of users. Note: On our install, the Jenkins user shows up as empty in the list of available users.

Image4

To fix this, right-click the empty user and select Advanced Options… which will show you details on the user. Set the Full Name to Jenkins and press OK.

Image5

    • d. Click Reset Password. Create a new password for the Jenkins user, and make sure to take note of it somewhere secure. This is just like any   other Mac user login that has admin access, and should be treated as such. If you are working for a team, use a secure shared password manager like 1Password so the password doesn’t just live in your head.
    • e. Select Login Options underneath the list of users.

Image6

    • f. Select Automatic login and choose Jenkins.
    • g. Enter the password you just created for the new Jenkins user.
    • h. Restart your computer. Once finished, you should be automatically logged in as the OSX Jenkins user.

 

Configure the Jenkins User

Now that you are logged in as Jenkins, you can customize the user account however you like. This includes all things from Dock settings to terminal configurations. One simple thing I like to setup is to have the Jenkins Dashboard open every time the computer is restarted.

  1. To do this, open Safari and go to Safari\Preferences\General…
  • a. Set Safari opens with to A new window.
  • b. Next set New windows open with to Homepage.
  • c. And lastly, set Homepage to http://localhost:8080.

Image7
2. Set your browser to open on startup. Go to System Preferences\User & Groups\Jenkins\Login Items and add Applications/Safari.app

Image8

Allow Jenkins to Run GUI Applications

By default, Jenkins is unable to run GUI applications because it runs as a Daemon. A daemon runs in the background as part of the overall system, and isn’t tied to a specific user. This would be like having a butler that couldn’t interact with anyone. Sure it could clean up after us, but what about answering the door or fetching my martini!

A big part of CI is running simulators and other GUI applications, so we’ll need another option. To fix this, you can change Jenkins to run as a Launch Agent. A launch agent runs in the background on behalf of a user.

To change how the Jenkins process is launched, you’ll need to edit the settings file and change its location so it will automatically start on reboots.

  1. Enter the following command to unload Jenkins as a Daemon: sudo launchctl unload /Library/LaunchDaemons/org.jenkins-ci.plist
  1. Next, move the .plist file, which defines how Jenkins will run, to the LaunchAgents folder: sudo mv /Library/LaunchDaemons/org.jenkins-ci.plist /Library/LaunchAgents/
  1. Now for the top secret step. The default .plist file that Jenkins creates adds a key-value pair called SessionCreate. This creates issues when running certain applications, such as iOS simulators. The reason for this? Honestly, I’m not sure. In the past, a fix to many Jenkins CI issues in the iOS world was to add this key manually. It seems that with Xcode 6 things have reversed and it’s now required that you remove the key which solves the issue. Open the file with the editor of your choosing, and remove them.
  • sudo vim /Library/LaunchAgents/org.jenkins-ci.plist
  • /* Remove the following lines */
  • <key>SessionCreate</key
  • <true />
  •  /* Save the file */
  1. Lastly, reload the Launch Agent to restart Jenkins.
  • sudo launchctl load /Library/LaunchAgents/org.jenkins-ci.plist

Keep Those Fingers Crossed

Image9
Now, restart your computer and make sure that Jenkins successfully starts on its own after the reboot. If working correctly, your Mac should automatically login to the Jenkins user and open Safari to http://localhost:8080 where you will see Jenkins ready at your beck and call!

If for some reason this isn’t happening, jump to the last section on Debugging Jenkins to try and remedy your sickly CI butler.

Setting up SSH

In order to add jobs linked to a Git repository, you will need to setup SSH keys for the Jenkins user. This will allow you to treat Jenkins as a real user in regards to cloning and committing code to your repositories.

  1. Although you are currently logged in as Jenkins, you need to explicitly substitute the user as follows:
  • a. su jenkins
  • b. Enter your Jenkins password
  1.  Follow the steps at https://help.github.com/articles/generating-ssh-keys to generate your own SSH keys for the Jenkins user. Note: Do not enter a passphrase while generating the key. I found that Jenkins was unable to authenticate with Git if a passphrase was needed.

  2.  Once done, you should have your newly generated key copied to the clipboard using:

  • a. pbcopy < ~/.ssh/id_rsa.pub
  1. Add this key to your Github, Bitbucket, or whatever Git service you use. I created a new user for our Github team to be used by Jenkins. Whenever     Jenkins pulls code, makes a change like incrementing build numbers, and pushes the code back up, it shows Jenkins as the committer as if its a real person. After all, we definitely want it to feel like part of our family. A happy Jenkins is a Jenkins that doesn’t ruin your life by blowing up after every build.

Debugging Jenkins

Image10
If after following all steps above Jenkins will not start, try the following:

  1. First check if the Launch Agent process failed:
  • a. From terminal, type: launchctl list and look for the org.jenkins.plist process.
  • b. If there is a status other than 0, you know it failed.
  1. If it failed to launch, it’s most likely due to a log file not being owned by the Jenkins user. You can verify this by typing: ls -l /var/log/jenkins to see who owns the jenkins.log file. If it says root, you need to change it to the Jenkins user.
  • a. Enter the following to change ownership: sudo chown jenkins /var/log/jenkins/jenkins.log
  1. Now try reloading the process to see if it worked:
  • launchctl unload /Library/LaunchAgents/org.jenkins.plist
  • launchctl load /Library/LaunchAgents/org.jenkins.plist

Hopefully this guide got you up and running with Jenkins without any problem. I’d like to keep this guide as up to date as possible, so feel free to email me with anything you find at eric@monsoonco.com.

Jenkins is an awesome tool will save you a ton of time in the long run. We currently have it enabled to do the following for both iOS and Android:

  • Nightly builds that automatically increment the build number and send it to the client using hockeyapp.
  • Repository hooks which run all testing frameworks whenever code is pushed to the repository.
  • Credentials to login remotely and manage Jobs

The possibilities are endless!

For more tech-related insight, please visit: Monsoon

About Eric Cerney:

Eric is the Head of iOS at Monsoon, an innovative software development company based out of Oakland, CA. As the Lead iOS engineer, Eric enjoys pushing the bounds of user interaction and finding ways to create awesome reusable components within a mobile environment.

To find out more about Monsoon visit: www.monsoonco.com

 

 

 

 

 
1
Apr
2015
 

Xcode Continuous Integration: “Server encountered an error with Apple Developer”

by Matt Long

If you get this message when you are adding your server to a team to implement continuous integration using Xcode bots and OS X server:

Server encountered an error with Apple Developer.

Please try again later. If the problem persists, contact Apple Developer Technical Support for help.

It could be a red herring. There’s a support note here: https://support.apple.com/en-us/HT203853 that states the issue has to do with making sure you login as an Agent or Admin. That’s probably a valid scenario, but it may not be as in my case. I got this error message simply because an updated program license agreement needed to be accepted on the web portal. Once that was done, I was able to add the server to the team and could continue on.

(Yes, I know it’s April first, but this is not a joke)

 
13
Feb
2015
 

MCE Conf 2015

by Marcus Zarra

Late last year I was contacted by the organizers of MCE Conf and was asked to speak. Since it fit within my schedule (which can be its own challenge these days) I accepted without thinking too much about it.

Shortly after my acceptance I had heard that there was some controversy surrounding the conference about a comment made by one of the organizers who had attended another conference. After reading up on the controversy I figured; “oh well, how bad can it be?”

The short answer? It was amazing. I absolutely loved every minute of the conference.
(more…)

 
12
Jan
2015
 

We’ll Miss You Jordan

by Matt Long

Until today we had no category for a post like this. It now exists…

We offer our deepest condolences, thoughts, and prayers for all those affected by the tragic loss of such a great friend to this community, Jordan Breeding. He lost his fight with cancer this morning and we grieve deeply along with the rest of you. Jordan will be sorely missed.

Sincerely and with heavy hearts,

  • Marcus, Matt, and the rest of the CIMGF family.

 
2
Dec
2014
 

Beginning iOS Development With Swift

by Matt Long

Many years ago now, I wrote a tutorial for the beginner to learn how to use outlets and actions as this is often one of the least familiar aspects for new developers who are wanting to learn iOS. It’s simple once you’ve seen it, but until then, there’s a gap. This time around I’m presenting an application that is similar to the one I did back then, however, it’s up to date with Xcode 6 and Swift. If you are new to iOS development, this should help get you going.

Beginning iOS Application Development with Swift from Skye Road Systems on Vimeo.

 
5
Nov
2014
 

Swift and valueForKeyPath: You Can’t Keep A Good API Down!

by Matt Long


tl;dr; Download the Value For Key Path Playground


I was incredibly disappointed in Swift when I started to look into how key value coding might be preserved in the transition from Objective-C. Of course, Apple would preserve that, right? And I don’t mean by resorting to using Foundation classes–you know all type-casty and everything (yeah, type-casty). Are we progressing forward or looking to the past, after all? I shouldn’t have to rely on NSArray like this:

Right? Who wants to do that? What’s the proper Swift way?

Well, my early assumption from what I was seeing in Swift was that valueForKeyPath: was gone and no longer did we have a convenient way to grab only the fields we needed from a collection of objects. It appeared that it couldn’t be done–at least not in any idiomatic elegant way. Then I downloaded some sample code from the Apple developer site and noticed they were doing what I needed, but using map to do it. The answer was map. Here’s an example:

Now the lastNames variable contains a list of strings with just the last name property of my items array. Given an array of dictionaries like this, you can see how that is providing pretty much what we used to get from valueForKeyPath:

lastNames now contains:

Notice we also have an address property that points to a dictionary. If want to get the street property inside of address, we can drill down the same way:

Now, you can see we had to force-unwrap the address property in order to access the street property. This works perfectly and is a fine replacement for valueForKeyPath: of old. When the call succeeds we now have all of the street addresses in the streetAddresses array:

Take a look at the Value For Key Path Playground if you want to see it in action.

What About Safety?

In Objective-C, if you message nil, it’s a no-op. In Swift, however, if we unwrap an optional that is nil, we will crash. So, on this line:

when we unwrap using the bang ! operator, if that value doesn’t exist, we’re in trouble. Say our data was changed to this:

Notice the address field has been changed to addr. This causes a crash.

Playground Crash

Meanwhile, with the old Foundation way, we do this:

but look what the output is. NSNull!

No crash. So which is better?

Well, if your data can be unpredictable, which really shouldn’t happen, then the Foundation outcome is “safer” from a crash perspective. However, your data should be nailed down, so a crash would actually tell you what’s wrong with your data pretty quickly.

What, though, is the safe Swift way of handling this? We can coerce our objects to optionals and use optional chaining instead:

So our first optional operator says to return the object or nil and the second operator says that is should be an optional of type String. This call returns an array of optionals that has this output in our playground:

Assuming the following data:

Notice the first two use the bad addr field and the last two use the correct address field.

For my applications, I think I would prefer to see a crash so I know my data is bad. It’s the server developer’s problem. Am I right? ;-)

Taking Map() Farther

The map() function really goes far beyond this trivial little valueForKeyPath: replacement example. You can really massage your data into any form you want with it. Say for example you wanted to create an transformed array of dictionaries from your array of dictionaries that had some of the same data, but organized differently. For example:

This returns an array of dictionaries that contain a single key value pair with a key called full_name and value of the first name and last name of each item in the original array concatenated together. The output looks like this in our playground:

As you can see, there really are a lot of possibilities for massaging your data structures using map. The tough part is imagining how it might be used and often that just comes from experience. The more you use it, the more obvious the solutions will become.

Swift Is Not So Bad

There are certain complaints about Swift I still have, however, I am finding that it is growing on me. I am starting to have much more success making my code pure Swift–pulling back from my old habits and considering how problems should be solved in this brave new Swift world. It’s getting better and some of the language aspects are actually better than Objective-C. I couldn’t see that forest for the trees just a couple short months ago. Until next time.

 
29
Oct
2014
 

Protocols in Swift With Core Data

by Matt Long

Sometimes you have a set of objects you want to display in the same form–say, for example, in a table view controller. What if those objects have, by design, nothing in common and nothing to do with each other? This is a case where you can create and conform to a protocol–known in some languages as an interface–to provide a simple way to have each class type provide a display name that can be displayed in your table view controller.

Recently while using this language feature writing Swift code, I ran into a few snags and learned from the process. I figured I would document it in this screencast. It walks you all the way through from project creation, so it’s about 35 minutes.

Here’s what you will learn:

  • How to setup CoreData entities in the data model
  • How to add a run script action to build your managed object classes using mogenerator
  • How to create a protocol in Xcode 6
  • How to implement a protocol in the various managed object classes
  • How to preload your CoreData store with test objects in code
  • How to load each object type generically into a table view controller

And if you want to just cut to the chase, grab the code from github.

Protocols in Swift With Core Data from Skye Road Systems on Vimeo.

 
8
Jun
2014
 

The Core Data stack in Swift

by Marcus Zarra

swift-heroWhenever Apple releases a new version of Xcode one of the first things that I do is look at the default templates and see if there are any new or interesting things.

This year, with the release of Swift, there are some pretty radical changes. Yet the Core Data stack initialization code is still the same.

There is nothing wrong with the default template code but there isn’t really anything right about it either. It is far better than it once was but it is still overly verbose and hard to follow.

Therefore, I present my Swift Core Data stack code that I will be using as I grok this language.

(more…)

 
25
Feb
2014
 

Deleting Objects in Core Data

by Marcus Zarra

I very rarely speak out against another blog post. I find the resulting argument back and forth draining. However, there are exceptions and one occurred over the weekend.

Brent Simmons has been blogging about his conversion of Vesper to a Core Data application. A recent post of his titled Core Data and Deleting Objects set my teeth on edge. Brent says:

“The best advice I’ve heard about deleting managed objects is to 1) not do it, or 2) do it only at startup, before any references to those to-be-deleted objects can be made.”

I do not know who is giving Brent advice but he must be playing tricks with him or just trying to wind him up. The advice was simple; don’t delete Core Data objects or if you are going to delete them, delete them at launch.

Will that work? Sure. Is it the right answer? Not even close.

(more…)

 
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.

 
17
Dec
2013
 

Automating OS X app test build distribution across multiple OS versions

by Fraser Hess

With Apple now shipping OS X upgrades every 12-15 months, Mac developers are very quickly finding themselves supporting their apps on multiple OS X versions. Until recently, my approach to testing on multiple OS X versions involved partitioning an external USB drive and installing the OS X versions onto it and booting off the partitions to test.

While this approach is inexpensive, the test-discover-reboot-fix-build-test cycle just got to be too much for even this frugal Scot.

Enter the Mac mini

My new solution has 2 parts: a maxed out Mac mini with VMware Fusion to support all the targeted OS X versions and a scripted piece that will sync new test builds to the VMs.

The current $799 Mac mini has a quad-core Intel Core i7, a 1TB HD and is expandable to 16GB of RAM. Our local MicroCenter had a $749 sale on that model so I picked one up along with a 16GB RAM upgrade. After I setup 4 VMs, one for each of 10.6 – 10.9, I found the performance to be incredibly slow. Analyzing the issue quickly identified the speed of the stock HD as a bottleneck, so after considering returning the whole kit for a BTO Fusion Drive model, I picked up an OWC 240GB Mercury EXTREME™ Pro 6G SSD, and now the performance is great. (Installing an extra HD in a Mac mini is possible, but if you do, make sure you watch and understand the videos on the topic and make sure you order the correct parts to install in your Mac mini.)

Moving the builds around

Each of my Mac Xcode projects now has an extra scheme called MyApp test build. The following scheme settings are used: In Run MyApp.app, I’m using the Release build configuration and I’ve set Launch to Wait for MyApp.app to launch since I don’t intend to run these builds from Xcode. Most importantly, in Build->Post Actions, I’ve added a Run Script Action with Provide build settings from set to the app. The script below creates a new uniquely-named folder in the $root_destination_folder every time you build and will copy the resulting product into that newly created folder. The folder name combines date/time, product name, and the current git describe. The $root_destination_folder should be in a folder that is synced by a service. I used Dropbox at first, but it doesn’t seem optimized for the large number of small files that compose a Mac application bundle, even with LAN syncing turned on. I’m now using BitTorrent Sync, which uses the BitTorrent protocol. Even as a beta release, I had great success with it. By adding the shared folder to the BitTorrent Sync client on each test VM, every time I make a test build, it automatically appears on each VM.

By running multiple OS X versions in VMs simultaneously and syncing test builds, I’ve nearly eliminated all the waiting involved in testing and iterating across multiple OS X versions.

Note 1: For testing on Mac OS X 10.6 Snow Leopard, only Snow Leopard Server is supported in VMware Fusion. Apple has made Snow Leopard Server available to paid Mac developers as a free download. The provided serial number expires at the end of 2014.

 
10
Dec
2013
 

Using GIT In Xcode

by Joe Keeley

Git has become a very popular version control system in iOS and Mac development. Git comes with a set of command line tools to check status, commit changes, view logs, make and merge branches, and coordinate commits with a remote repository.  There are a number of desktop apps that can perform these functions, including Xcode.  When I ask other iOS and Mac developers how they interact with Git, most say they use the command line or a separate desktop app like Tower.  I find very few developers use Xcode for even some basic Git tasks, and many developers are not aware of the Git support Xcode offers.

For my own workflow, I like to minimize the number of tools used and number of switches between apps needed to complete a task.  So, I decided to attempt to use Xcode exclusively to interact with Git and share my results.  So far I have been pleasantly surprised at what all Xcode can do with Git. If you have not taken a look at Xcode’s support for Git, you may be surprised how much you can accomplish.

This article assumes basic familiarity with Xcode and Git, and describes Git functionality present in Xcode version 4.6.2. (more…)

 
20
May
2013
 

Creating A Happy Appy Song

by Matt Long

App developers need ways to promote their apps and audio and video provide a way to do that. At a recent iOS developer camp in Colorado I gave a talk in which I demonstrated some ways developers can create their own creative content like audio and video in-house. In one segment I demonstrated a technique that I refer to as creating a Happy Appy Song. What is it, you ask. You’ve heard it. It’s a happy sounding fanciful tune that plays in the background as some narrator describes the wonders and benefits of an app (or other product for that matter). The basic premise of the happy appy song is that, first of all, it’s easy to create, but second there’s a simple formula. Here is all you need:

1. A happy chord progression in a major key
2. A simple drumbeat
3. A glockenspiel sound

And now I present to you, Creating a Happy Appy Song

[ylwm_vimeo height=”400″ width=”600″]66576979[/ylwm_vimeo]