Using xcodebuild To Export a .ipa From an Archive

Xcode 6 changes how you export a .ipa from an archive for adhoc distribution. It used to be that you could export the archive to a .ipa as long as you had the right provisioning profile and distribution certificate on your machine. Starting with Xcode 6 you need to be a team member of the particular Developer Program account and you need to have the rights to make a distribution build. This means you need to be a team agent. However, I work with a number of clients who don’t have the clue what Xcode is much less are willing to make distribution builds, so I need to way to make distribution builds within this new limitation from Xcode 6.

Making distribution builds hasn’t been a problem for me in the past. I ask the client to provide me1 with the necessary provisioning profile, distribution certificate, and public private key pair so I can make the distribution build for them. Then I use Xcode Organizer to export the archive to a .ipa that I can distribute.2 But it seems I can no longer export using Organizer without having the right team access, so I had to search out an alternative approach.

Turns out starting with Xcode 5, xcodebuild includes parameters for exporting from an archive. This is exactly what I need so I can continue making adhoc distribution builds for clients without being a team member or team agent under their Developer Program account.

So how do I do it?

The How To

My build script starts by performing a clean.

xcodebuild clean -project $projectname.xcodeproj -configuration Release -alltargets

Then the script builds and archives the app. I specify the archive path using the -archivePath parameter in the command line so the script will know where the archive file is located.

xcodebuild archive -project $projectname.xcodeproj -scheme $schemename -archivePath $projectname.xcarchive

Finally my script exports the archive into a .ipa file.

xcodebuild -exportArchive -archivePath $projectname.xcarchive -exportPath $projectname -exportFormat ipa -exportProvisioningProfile “Provisioning Profile Name”

I let the provisioning profile imply the signing identity, but you can specify the signing identity using the -exportSigningIdentity parameter.

The Gotcha

The one major gotcha that cost me a more than an hour of time was figuring out the parameter value for -exportProvisioningProfile. I initial thought it should be the file name to the provisioning profile. I tried it with and without the .mobileprovision file extension, but it did not work. I included a relative path as well as an absolute path to the provision profile. I tried using the UUID for the provision profile instead of the file name. I even I tried not including a path at all thinking it would look up the provision profile in the ~/Library/MobileDevice/Provisioning Profiles/ directory, but still no luck.

Turns out I needed to specify the name of the provisioning profile as defined in the file itself. This is the same name assigned to the profile in the provisioning portal. Once I figured this out I was able to export the .ipa from the archive using the my build script, and I don’t have to be a team agent under my client’s Developer Program account to make the distribution build.

  1. I usually assist my clients with this by guiding them through the steps, or I ask them to give me the account credentials with a temporary password so I can perform the necessary steps. Then I have the client reset the password.

  2. I don’t export when I host the test app on HockeyApp. It takes care of exporting the .ipa from the archive for you. I only export when the client requests that the test app be hosted on their own server.)

Posted in ios, programming.

Reporting Errors in Cross Post Part 2

Yesterday I talked about options for reporting errors (and statuses) from the server back to the Cross Post app. Later I came up with a third option, which I like the best…hosting the error reports on Cloud Files.

The Cross Post server is scalable, which means I cannot rely on the server’s file system. Data on the file system for one server is not synced to the other servers, and it’s possible that the server reporting the error is not the same server as the one that caught the error.

The obvious solution is to use a database server, but using a database server is overkill for Cross Post. But as I thought about it more I realized I all I need is a scalable file system, and that’s exactly what cloud storage systems like S3 and Cloud Files do. They provide a scalable file storage system.

I came to this realization while thinking about how a CMS in a scalable environment might store uploaded files. Uploaded files would likely be stored on a scalable file storage system like S3. And that’s exactly what I need for reporting errors, a scalable file system. As I keep saying, a database is overkill for the current needs of Cross Post.

Cloud Files

So why Cloud Files instead of S3? Two reasons. 1) I already use Cloud Files as my CDN for my websites. And 2) the price. I don’t expect to have a lot of error reports, and once the error has been reported to the app the report is deleted, so I estimate my total storage cost will be pennies.

A GB of Cloud Files storage is only 10 cents a month, and bandwidth is only 12 cents per GB per month. The total space needed for my error reports will certainly be less than a GB each month, so my estimated cost is only 22 cents per month, well within an affordable range for a snowboard bum like me.

The How Tos

So exactly how will this work? Cross Post sends a payload to the server. Once the server receives the payload the HTTP connection ends. The server then processes the payload posting the status update and photos to the selected social networks.

If an error occurs while posting to a social network, it is captured and stored in a JSON file. The file name is the unique id generated by the Cross Post app when packaging up the payload. The server will then take the JSON file and post it to Cloud Files. The next time the Cross Post app is launched, it will check Cloud Files to see if an error report exists. If it does, then the app will report the error to the user, and it will send a request to the Cross Post server telling it to delete the error report from Cloud Files1.

So what happens if an error occurred and the person never launches Cross Post ever again? For starters I’ll be sad, but with regards to the error report I can set an expiration date on the file, say 30 days. Cloud Files will take care of deleting the file when it expires. This means less work for my server and less code for me to write.

Not Just For Errors

What I like about the approach is that it is not limited to reporting errors. I can use this approach to report any status back to the app, though at the moment the only status type I need to report is an error status. I subscribe to the “no news is good news” mindset meaning that once the server receives the payload, unless an error is reported, it’s safe to assume the post was sent to the different social networks without a problem.

  1. I let the Cross Post server delete the file from Cloud Files CDN so I don’t have to include the api key in the iOS app.

Reporting Errors in Cross Post

A friend sent me suggestions on handling error reporting for Cross Post. I decided write up my current thinking here to see if my approach makes sense. Besides, trying to explain it in a set of 140 character tweets is less than ideal.

The challenge I face is reporting errors, or any status reporting for that matter, that happen once the server takes over the process. A timeout error, for example, could occur while the server is uploading a photo to Twitter. At this point the server no longer has a connection to the app, so trickling the error up to the app is not an option.

One option is to let the server eat the error. I know of a few similar solutions that eat the error, and I stopped using those apps for that very reason. If I ask an app to post something to Facebook, and the post never appears, then I want to know why. Letting the server eat the error is not an option for Cross Post. But how does the Cross Post app learn about the error?

One option is to use push notifications. When an error occurs the server can notify the user via a push notification. But this isn’t a trivial task to implement and it’s a path I don’t care to pursue unless absolutely necessary.

Another option, and the one I’m considering at the moment, is having the app include a unique identifier in the payload sent to the server. You can think of the identifier as a handle that the app can use to query to server for the status of the post.

If an error occurs on the server, the server will store the error with the identifier provided by the app as the primary key. The next time the app launches, it will check with the server to see if there were any errors. Once the app learns about the error, the server deletes the error from its data store.

This is a more reactive approach to reporting errors instead of a proactive approach, but it’s a cleaner solution than going down the push notification route. Beside, push notifications are not guaranteed so this approach is as reliable if not more reliable.

There are problems with this approach. First starters, only the device that sent the post will know to check for the error. Say I send a new post to Facebook using my iPhone. The post fails to make its way to Facebook. I launch Cross Post on my iPad. The iPad does not know about the post sent from iPhone, so it does not know to check for an error.

Now there are ways around this new problem. I could ask each user for a unique identifier such as an email address or username, but that’s another road I don’t care to travel down. People have more than enough logins to remember without me asking them to setup yet another online account and log into Cross Post. Besides, Cross Post can use iCloud to sync the unique identifier for each post between devices. In fact, this is what I will likely do. Key-value syncing using iCloud has been reliable for some time now, so why take advantage of it.

The other problem with having the app check the server for error reports is that now the server must persist the error report. This means I need to have some type of data persistence store. I could use the file system on the server, but I’ve configured my server app to scale. This means a load balancer is in place and as traffic increases OpenShift will spawn new server instances. This means it is possible that the server that caught the error will not be the server that the app queries for error reports. So storing the error report on the server’s file system is not an option. An additional server, aka a database server, is needed to persist the error reports.

Having an additional server for data persistence isn’t a big deal for OpenShift, but it is just one more server that must always be available. And now the backend for Cross Post is starting to grow. A couple of weeks ago the entire Cross Post solution ran on an iOS device. Now the solution spans the device and a server environment, and next I have to throw in a database server just for error reporting!?

Having the database does seem a bit overkill at the moment, but there might be a need for a database for persistent storage down the road anyways. So it looks like I will be adding a MongoDB database to the mix very soon. That is unless someone has a better idea to share with me.

Update: I came up with a third option that is by far my favorite.

Cross Posting to App.net, Facebook, and Twitter

Last year my wife told me more family and friends would “like” my photos on Facebook if I posted the them directly to Facebook. At the time I was using ifttt to selectively cross post to App.net and Facebook. This meant my photos on Facebook were actually links to the App.net, which is where the photos were being stored, and this required my Facebook followers to tap the link to see the photos. Not the best experience for my followers.

I decided to test my wife’s theory by posting photos directly to Facebook. Turns out she was right. I started getting more likes. Not only that, I found that family and friends posted more comments when I posted the photos directly. My wife was right. Posting photos directly to the social site is the best experience for followers and the best to become more engaged with your followers.

Now I could have setup an ifttt recipe that cross posted my Facebook photos to App.net, but that means my followers on App.net would have the less than ideal experience reading my posts and viewing my photos. So I started down the path of exploring different options for cross posting between different social networks.

After exploring options for nearly six months, I learned there is no single solution that will cross post to different social networks while giving the followers on each network the best viewing experience. So I set out to write my own app.

I quickly learned why no cross post solution that posts natively to each social network existed. It’s hard, and in the case of Facebook, nearly impossible to make the post look as if it were posted from the official app. But I figured it out and for the past few months I have been making posts using Cross Post.

Cross Post is the app I’ve been working on for the last few months. I’ve also been using it almost daily for months. The app was ready for public release back in August, but I decided to wait until the iOS 8 release. The primary reason for this is to avoid annoying iPhone 4 users. iPhone 4 cannot run iOS 8, and I had planned to drop support for iOS 7 the moment iOS 8 is released. So I decided to delay the release of Cross Post.

The delayed release gave me time to work on adding some new iOS 8 only features. One feature in particular that I’m very excited about is the share extension. This feature makes it possible for a person to cross post to different social networks from other apps running on their iPhone or iPad. This feature alone makes Cross Post much more useful than I ever imagined 6 months ago.

When I started learning the ins and outs of share extensions I thought to myself, “This will be a snap.” But as I got deeper into the code I realized Cross Post has one major issue that makes the Cross Post share extension suck. It takes Cross Post too damn long to post photos to multiple social sites.

Consider the scenario where you want to post 4 photos to App.net, Facebook, and Twitter. Each photo must be uploaded to each network. That means 12 different uploads, which is not speedy. This performance problem is acceptable in the Cross Post app because it performs the uploads even when the app is no longer active. A share extension, on the other hand, should return almost immediately. It should not, or have to, wait for the uploads to complete.

Extensions that need to upload data should do so using a background NSURLSession. Unfortunately this is not an option for Cross Post because it uses the Facebook SDK to post to Facebook and SLRequest to post to Twitter. Cross Post does use NSURLSession to post to App.net, but I want to be able to post to Facebook and Twitter via the share extension as well. So I needed to come up with a better way to post status updates and photos across different social networks.

To solve this problem I decided to create a Cross Post server. I was trying to avoid having a server for Cross Post, but it’s unavoidable if I want to provide the best user experience. With the server in place Cross Post can upload the post and photos once and let the server handle uploading the content to the selected networks. Best of all, the upload from the app can be accomplished using a single NSURLSession request, and it can be performed in a background session. This means the Cross Post share extension can return almost immediately. It also means that Cross Post now only needs to make one HTTP request whereas previously it had to make numerous requests. For instance, the previous scenario of posting 4 photos to 3 different social sites required 15 HTTP requests. Now Cross Post app accomplishes the same thing using a single HTTP request1, and the Cross Post server handles making all the other requests on behalf of the app.

This performance boost does have some disadvantages. First and foremost, I’m now responsible for keeping the server environment up and running. But thanks to OpenShift, I’m not too worried about that.

Another disadvantage is that reporting errors back to the iOS app is going to be more challenging. Cross Post and the share extension sends off the request to the server. Once the server receives the payload the HTTP connection ends. The server, however, continues working by posting the payload to the selected social sites. If there is an error posting to, say, Twitter, there is no way for the server to tell the Cross Post app because that connection no longer exist. I have some ideas on how to solve this problem, but it’s not going to happen in the first release.

Still, the improved user experience outweighs the disadvantages of using a server. And I have to admit, I’m enjoying getting back into server-side programming. So much as changed, for the better, over the years.

  1. I was able to reducing the number of calls to the server down to one by packaging the post and photos into a single .zip file, which is sent to the server.

Posted in apps, cross post, ios.

iPhone 6 and 6 Plus Pocket Test

I printed out this iPhone 6 and 6 Plus paper template. I cut out each template and taped cardboard to the back. Then I did a pocket test with each one. I tested each template with different pants and shorts that I wear often. I found that both the iPhone 6 and iPhone 6 Plus fit in all my pockets, but a corner of the iPhone 6 Plus cutout does stick out of the pocket on my gym shorts. I also found that while the iPhone 6 Plus does fit in the pockets of my Levis 501, my jeans of choice, the cutout was annoyingly noticeable when I sat down.

For those wondering, I’m 5 foot 6 and typically wear 32 inch waist pants and shorts. Taller folks with roomier pants and shorts might not notice the size difference of the Plus as much as I did.

As for holding the two cutouts, I found that the iPhone 6 cutout fits comfortably and securely in my hand. The iPhone 6 Plus cutout, on the other hand, just feels too big to hold and use with one hand. Granted I have small hands, but in acting like I’m interacting with a real iPhone I found I kept using two hands with the iPhone 6 Plus whereas I was comfortable using only one hand with the iPhone 6 cutout.

Conclusion: I will be buying the iPhone 6. The larger display of the iPhone 6 Plus would be nice for reading and watching shows and movies, but it’s just too damn large to be pocket device for me.

Posted in general, ios.

Dear Simple. It's You, Not Me.

For more than a year and a half I’ve been in love with Simple, my online bank. From the very beginning it was as if Simple were designed specifically for me. Safe-to-spend and Goals changed how I managed and saved money, and it worked. It worked really well. So well in fact that I have more cash on hand today than I’ve had in years, and it’s all thanks to Simple. But something went wrong.

A month ago Simple did a major update to their backend system/platform, and since that dreadful day my financial world has been turned upside down. Payments were not sent while other scheduled payments simply disappear. My account balance has been all over the place. My account activity shows payments with the wrong payee name. And there have been times where the same debit appears in the account activity multiple times. It’s been a total nightmare.

For the last month I’ve been patient with Simple in hopes that they would resolve the problems caused by the platform upgrade, but instead of seeing improvements I continue to find and have more problems. I loved the Simple before the upgrade, but today I have zero confidence in Simple. And I don’t know how long it will be before I can trust Simple for my banking needs. Who knows, I may never trust them with my money again.

Following the advice of Simple’s own customer support representative, who said I should seek “alternative means of payment for the time being,” I decided to open a new account at Ally. It will take about a week before I have all my money moved over, but at least then I will know payments are going out as scheduled, and I do not have to worry about being late paying my rent.

I have to say I’m not thrilled about my breakup with Simple. Ally’s online experience is the same experience found with most other banks. Simple spoiled me with a better way (before the upgrade) to bank, and going back to a more traditional experience really sucks. But I would rather have a sucky online experience with a reliable bank than to have to worry about whether or not my bills are being paid on time.

Sorry Simple, but I must break up with you now. And it’s you, not me, that has caused this to happen. There might be a day in the future when we can get back together, but for the moment I need a bank I can trust.

Posted in general, rant.

Amy Bradstreet

I learned this morning that a friend of mine, Amy Bradstreet, was murdered last night by her boyfriend and father of her kids. I’m left without words. I’m sad, stunned, stocked, and some what angry. Amy was one of the most fun loving people on this earth, and she did not deserve to die this way. My heart goes out to Amy’s family.

You will be missed, Amy.

Posted in life.

It's About More Than Shipping an App

There have been a number of recent blog posts about the doom and gloom of being an indie developer especially in the iOS world. The theme of these posts are basically the same. A developer spends some time building an app. The app is released into the wild, and sales are much lower than expected. Some developers give up while others will try again.

The problem as I see it after reading these doom and gloom posts is that the developer has no strategy for building and running a business beyond releasing an app. Releasing an app should not be your only plan for building a business. Releasing an app is just one part of being an indie developer. Another part, a much bigger part of being an indie developer, is being a business owner. And as a business owner you must have a plan consisting of short and long term strategies for building and running your business.

Have a Plan

Running a business, even as an indie, requires much more than building and releasing an app. For starters, you need a business plan. Even if it’s not something you write down, you need to know what your plans are for making money and surviving the dry spells. Your plan should change and evolve over time as your business changes and grows.

When I started White Peak Software, I had no plan. I was fed up with others controlling my life and career. I knew I wanted to control those things, so I started my company. In some ways taking control of my life and career was my initial business plan but that didn’t help pay the bills. And at the rate I was going using that plan I knew my company would not last twelve months with me as a full time employee.

After six months of having no real plan or strategy for building my business, I hired a small business coach. A small business coach is like a life coach or therapist for your business.1 The coach doesn’t necessarily tell you what to you do. Instead the coach gives you the steps and guidance needed to help you figure out what your short term and long term plans are for your company.

For three months, my small business coach and I met once a week to talk about my business. During these talks it became clear to me that I wanted to write and sell my own software, but more importantly I wanted to write software that I could be proud of, software that I could call my baby.2 These talks gave me short and long terms goals for my company, and a plan for how I will make it happen.

With the help of my coach I came up with a 3 month plan, 6 month plan, 1 year plan, 5 year plan, and a 10 year plan. I’m coming up on the end of the 10 year plan, and I admit I’m not likely to reach my goals from my 10 year plan. But that fine because before I had these plans the likelihood that I would still be in business for myself in 2014 looked grim.

Have a Structure

Another key component to running your own business is having the right company structure for your situation. Should you operate your business as a sole proprietor, an LLC, an S-Corp or even a C-Corp? Picking the right structure for your situation is key if you want your company to last. The company structure effects how and when you get paid, how and when taxes are paid, how much money you can stash away for retirement, and much more.

Talk to an accountant when deciding on a company structure. An accountant will look at your current financial situation, your short and long plans, and help you decide what company structure best suits your situation. And like your business plan, your company structure might change over time. It might be best for your business to start out as a sole proprietorship, then when revenues hit a certain amount change to an S-Corp. Or maybe your company should be a C-Corp on day one. Your accountant can help you decide what is best for you.

I made the mistake of setting up the company structure for White Peak Software without talking with an accountant. White Peak Software is an S-Corp, and I made that choice without consulting anyone else. Turns out I might have been better off setting up White Peak Software as a C-Corp, but even after all these years I still haven’t converted my company.

While being an S-Corp would not have been my accountant’s first choice for my business, it has worked out fine. Still, I wish I had gotten advice on the best company structure for my business when I first got started.

Speaking of my accountant…

Hire an Accountant

You need an accountant, a really good one! A really good accountant is the virtual CFO of your company. Your accountant should do more than just file your taxes for you. You accountant should provide you with advice and direction on managing cash flow, handling and paying off debt, and all other financial areas of your business (and personal life).

The one thing that sticks in my mind after reading Jared Sinclair’s post about Unread’s first year is that 40% of his first years net revenue went towards self-employment taxes. I don’t know Jared’s particular situation or the type of company structure he was operating under, but I believe a really good accountant could have brought the amount he paid in taxes down sufficiently, maybe even down to 0%.

For the first three years I spent working full time for White Peak Software, the company took huge losses. Now this didn’t mean revenue wasn’t coming in - revenue was certainly coming in. It just meant company expenses were greater than the income…on paper. “On paper” is key here.

When I started my company I had a bedroom dedicated as my company office. White Peak Software paid me rent for the space, and this counted as a company expense. Did I actually have more money because my company was paying me rent? No. But on paper the purpose of that money impacted how much, or how little, I paid in taxes.

As my accountant likes to say, “Tax evasion is illegal. Tax avoidance is not.” Because the company took a loss those first three years, I was able to avoid paying incoming tax.

Now I don’t know Jared’s particular situation, but from reading that one blog post I can’t help but wonder, had Jared had the right company structure in place and a really good accountant, could he have kept 100% of that net revenue. It’s possible and that would have given him a better chance at staying indie longer.

This is why it’s important to have a really good accountant. And the earlier you get your accountant involved in your business the better.

Always Seek Advice From Others

My accountant isn’t the only person who helps advise me on financial matters. I also have a financial advisor who helps oversee my money.

My financial advisor is responsible for managing my retirement plan and other investments, but he is also involved with what is going on with my business. He provides a kind of “check and balance” with financial decisions and suggestions my accountant will make. If, for example, my accountant suggests a strategy for saving money or paying off debt, I run the suggestion by my financial advisor to get his feedback. And I make sure my accountant and financial advisor talk at least one a year to make sure everyone is on the same page.

A Tip That Has Saved My Ass More Than Once

And speaking of financial advice, one piece of advice that has saved White Peak Software on more than one occasion is having a business line of credit with my bank. My accountant suggested this years ago. I was against the idea because 1) at the time I was debt free and had no need for the line of credit, and 2) I saw it as an easy opportunity to potentially go into debt. But White Peak Software would not be in business today if not for this outstanding piece of advice.

During long dry spells when cash isn’t flowing, I have access to a large sum of money that will help me weather the storm. However, I should note that I must be very diligent to pay back the borrowed money as quickly as possible once cash is flowing again, and this is sometimes not an easy thing to do. So having a business line of credit may or may not be a good thing for you and your business.

It’s About More Than the App

Being an indie developer, nay a business owner is not for everyone. It takes a lot of hard work. It takes planning and requires not only strategies for making money but strategies on how to survive when the money isn’t coming in. For the software developer turned business owner, writing the app is the easiest part, but it’s about more than the app. To survive, you need to give the business side of your company just as much attention as you give your app. Your company’s survival depends on it.


  1. A small business coach is someone who can help mentor you and help you take your company to the next level. It can be someone who does coaching for a living or even a friend who is wise in the ways of running a business. My coach happens to be a business savvy friend of mine. And yes, I paid him for his time during those three months of coaching, which I easily earned back using his advice.

  2. While making a living from my own products is the ultimate goal for my company, the reality is I still rely on consulting and contract programming to help supplement my income. However, as a business owner I can be very selective with who I work with and the types of projects I work on. This allows me to say true to writing software that I’m proud of and that I can call my baby.

Posted in apps, opinion, work.

I Am Not The Android Expert You Seek

I do not own an Android device. I have spent less than 2 hours in my entire life playing with an Android device. I have never written an app for Android. Heck, I have never even written a single line of Java code in a shipping app. So, for the love of god, please stop asking me if I can look into problems related to Android and Android apps. I am the last person in the world you want to ask to help you with Android related problems.

Disclaimer: I have nothing against Android. It’s just not an area of interest to me.

Posted in work.

Enjoy Less and Love More

To some my life seems like a non-stop vacation. I’m a ski bum, a slacker, someone who rarely works. I’m always off on some adventure, snowboarding in the winter months, hiking and kayaking in the summer months. And from one point of view this is true. Over the last 12 months I have spent a great deal of my time snowboarding, hiking and kayaking. But I’ve also been focused on writing code and building apps.

Writing code and building software is a passion of mine. It’s the one thing I’m most passionate about. I’ve been writing code for more than 30 years, and I cannot image doing anything else with my life.

Over the last year I’ve been enjoying my passion more than ever. I’ve written more code in the last year than I did in the previous 3 years combined. I realized just this morning I have worked on and contributed to 22 different apps in the last 12 months, of which 15 are available in the App Store today. That’s a lot of time behind the keyboard.

Business is booming and life is good. So what changed? How is it I can live the ski bum, slacker life and still get a ton of work done? How is it I’m able to work on more apps today compared to a few years ago and still have time for adventure and family? The answer for me was to cut out those things from my life that I enjoy but do not love. (I already cut out those things I hate years ago.)

I stopped writing. I stopped organizing meet ups events. I stopped speaking at conferences. And while I haven’t completely stopped attending conferences and meet up events, I’ve cut way back. In the last 12 months I’ve attended one CocoaHeads event, one conference, and I socialized in San Francisco for only a 3 days during WWDC. This is a big change from just a few years ago when I was writing more words than code, attending and often times speaking at a conference every other month on average, and attending and organizing multiple social gatherings and meet ups each month.

I’ve also made changes to my daily routines. I don’t spend as much time reading news and following the latest happenings on social sites like App.net, Facebook and Twitter. I still make posts to these sites, but I limit the amount of time I spend reading what others have to say. And I’m not as active as I once was in chat rooms and irc. Cutting back on these distractions gives me more time each day to focus on things I love doing.

Some friends and family members have pointed out that I seem happier since moving to Stowe, and they are right. I am happier these days, but it’s not just because I moved to Stowe. It’s because I’m doing more of what I love, and I accomplished this by doing less of what I only enjoy.

By not doing the things I enjoy, I’ve been able to spend more time doing the things I love.

Posted in general, life, work.