Why Microsoft's Acquisition of HockeyApp Saddens Me

While catching up on the latest tech news last night, I came across a post that said Microsoft had acquired HockeyApp. My first thought was this is a joke. I immediately went to the HockeyApp blog site and, lo and behold, it is not a joke. Microsoft did acquire HockeyApp.

This news left me with mixed feelings. First, I’m happy for the folks at HockeyApp. I’ve been a long time user of HockeyApp, and I feel they have the best solution for beta app distribution and crash reporting. The acquisition is further proof that HockeyApp is an outstanding solution. Yet at the same time it saddens me that HockeyApp is now in the hands of Microsoft.

It’s no secret that I’m not a fan of Microsoft. That wasn’t always the case. I used to love the technology coming out of Redmond, so much so that I worked for nearly 4 years for a consulting company co-owned by Microsoft whose initial purpose was to promote and showcase Microsoft technologies in the enterprise. But around 2005 I started feeling like Microsoft technologies were heading in the wrong direction and, by this time I was working for myself, I stopped recommending Microsoft technologies to clients. I also began transitioning my skill set to other non-Microsoft technologies. By the end of 2008 I was done working in the Microsoft world, a decision that I don’t regret one bit.

In 2010 my dislike for Microsoft became a bit more personal when an accounting mistake caused during the merger of billing systems after a Microsoft acquisition resulted in a collection agency calling me on behalf of Microsoft. I talk in detail about what happened here and here, and thanks to the first post being picked up on Hacker News the matter was eventually resolved. Still, I was left with a stronger dislike of Microsoft.

The combination of my lacking faith in Microsoft technologies and poor customer service experiences1 drove me away from Microsoft world, and in 2010 I made conscious decision to stop giving my money to Microsoft unless there is absolutely no other option2. I’m fully aware that my decision to stop buying Microsoft products and services has zero impact on Microsoft. Also I don’t view Microsoft as an evil empire or a horrible company, and not everything about Microsoft sucks. Heck, they are doing some really neat things these days. But based on my past experiences, Microsoft is not a company I want to do business with today.

It boils downs to a personal preference, much like my preference to shop at Target instead of Wal-mart or to buy from a locally owned store before buying from a national store or online. And this is why Microsoft’s acquisition of HockeyApp saddens me. A product I love is now in the hands of a company I choose to not do business with, and this means I need to think long and hard about whether or not I will continue using HockeyApp when my subscription comes up for renewal in October.

  1. I know there are individuals at Microsoft who really care about and do provide outstanding customer service, and there are consumers and businesses out there that have had nothing but great experiences dealing with Microsoft. But my own personal experiences dealing with Microsoft have been less than ideal.

  2. When writing my books my publisher required I submit my manuscripts in Word documents, so I ended up buying a copy of Microsoft Word. Also I do enjoying playing video games on my Xbox, so Microsoft does get a bit of my money from time to time. But in general I have stopped buying Microsoft products and services.

Posted in general, tech.

iPhone 6 Plus Is Too Big For Me, But I Bought It Anyways

A few weeks back I said I would be buying the iPhone 6, not the 6 Plus. The 6 Plus is simply too large for me. But I have since changed my mind.

There are a few reasons I changed my mind. First and foremost, I could not justify upgrading from the iPhone 5 to iPhone 6. It’s just a hardware upgrade, and I’m very happy with my iPhone 5. Sure, it would be nice having a device with TouchID but that’s not a must have feature for me. And a better camera would also be nice, but again it’s not totally necessary for me.

I actually started the process of ordering the iPhone 6 on two separate occasions this past week, and each time I stopped before completing the order. There simply weren’t any good reasons for me to upgrade my phone other than to keep the end date for my 2-year contract with Verizon in the month of October. But the same is not true for the iPhone 6 Plus.

Different Size Classes

The iPhone 6 Plus has features not available on the 6, features that, as a developer, I need to support in the apps I write. And while I can use the iOS Simulator to test those features, I’m a firm believer that testing on an actual device is far better. Testing on a device gives you a real sense for how your app feels on that device, and that’s why I own a number of iOS devices. The Simulator is great for quick debugging and testings, but nothing beats playing with your app on an actual device.

The iPhone 6 Plus supports different size classes than the iPhone 6 and earlier iPhones. This means, for example, in landscape mode the iPhone 6 Plus can take advantage of displaying a split view controller, which is something the iPhone 6 does not. And again, while I can test this using the Simulator I won’t get a true feel for the differences without using an actual device. But this alone wasn’t the only reason I changed my mind on which device I should buy.

The Pocket Test

Over the weekend, while attending Çingleton, I did a number of pocket tests using various iPhone 6 Plus devices. Some had cases, others did not. What I found was that while I notice the iPhone 6 Plus in my pocket, it wasn’t as uncomfortable as I thought it would be. Does it feel as nice in my pocket as the iPhone 5 or even the 4s? Certainly not. And there will still be times when I’m annoyed at the size of the 6 Plus when carrying it in my pocket, such as when I’m snowboarding. In fact, I’ll likely have to carry the 6 Plus in my jacket pocket when snowboarding instead of my front pants pocket. And I’m not thrilled about carrying the larger device in a cargo pocket when I’m hiking as it will be banging against my leg as I walk.

But as I thought about it more I realized that I don’t keep my iPhone 5 in my pocket all that much. I work from home and the majority of the time my iPhone is sitting on my desk. I do put it in my pocket when I leave the house, but typically I’m at home more than not.

Still, after a weekend of various pocket tests I wasn’t completely sold on the iPhone 6 Plus. I certainly was leaning towards buying it, but I was still on the fence. That was until I learned about the zoom view.

Zoom View

With the zoom view an iPhone 6 Plus behaves like an iPhone 6. For instance, when the zoom view is enabled the home screen does not rotate when the iPhone 6 Plus is in landscape mode. In fact, it appears that the size classes used on the iPhone 6 Plus are the same as the iPhone 6 when using zoom mode. This means that the iPhone 6 Plus can be used to test the behavior of your app as if it were running on an iPhone 6. And that sealed the deal for me.

Using the iPhone 6 Plus to test my apps is like having two devices in one. I can test my apps to make sure the user experience is perfect for iPhone 6 Plus users and, thanks to the zoom view, iPhone 6 users. At this point the decision to buy an iPhone 6 Plus became a no brainer for me.

Not a Developer

Would I buy an iPhone 6 Plus if I weren’t a developer? Nope, I would not. In fact I would not buy the iPhone 6 either, at least not right now. My iPhone 5 suits me well, and I would have no good reason to upgrade if I weren’t a developer.

What I Really Want

What I really want isn’t the iPhone 6 Plus, but what I want does not exists, at least not yet.

As a developer what I really want is an iPod touch Plus. If Apple were selling an iPod touch Plus that is the same as the iPhone 6 Plus minus the phone, then I would buy it in an instant. That way I could continue using my iPhone 5 as my primary phone device and the iPod touch Plus as a test device. And my son would be happy too because in his mind the iPod touch Plus would be his even though I would use it for testing purposes. But sadly there is no such thing as an iPod touch Plus right now.

Change My Mind Again

So there you have it…the reasons I changed my mind.

  1. Different size classes and UI behaviors.
  2. Not as uncomfortable in my pocket as I thought it would be.
  3. Able to test iPhone 6 and 6 Plus user experience from the same device.
  4. No iPod touch Plus.

There’s actually one more reason that led to me changing my mind, Apple’s return policy. If after the first week of owning an iPhone 6 Plus I find that carrying it around in my pocket too annoying then I can return the device. I doubt I will return it especially after talking with many iPhone 6 Plus owners at Çingleton this past weekend, but still, there is always a chance I will change my mind again.

Posted in general, ios, programming, tech.

Microblogging, the Open Web, and Cross Post

Recently Manton Reece has been talking a lot about microblogging in an open web world using RSS. He has touched on points that are important to me, specifically content ownership. Like many people I post regularly to App.net, Facebook, Twitter, and other social networks, but I’ve always had one big problem with these networks. My micro-posts do not appear on my web site, and if these networks were to disappear in the future, then my content disappears too.

A Bit of History

I started thecave.com back in 1997. It was called “The Programmer’s Hideout” and I published various programming how-to articles for SQL Server, Delphi, and other tech that was interesting to me at the time. What I didn’t know at the time was that I was blogging. It wasn’t called blogging in 1997, but that’s exactly what I was doing. It wasn’t until March 2002 that thecave.com became what is typically known today as a blog site.

thecave.com has changed a lot under the hood. In the beginning I used a blogging engine that I wrote. I later switched to a hybrid engine using blogger.com as my editor. Blogger would upload an XML version of the post to my server that my blogging engine would consume and publish the website. As time went on I would used other blogging engines including Wordpress for thecave.com. Today thecave.com is a static HTML website generated by Jekyll. Despite all the changes under the hood, every post I have made to thecave.com since March 2002 is still available today1. I own and control the content, and it is not going away.

This isn’t true for my Facebook or Twitter posts. They control the content, content that could disappear in the future. That is why Manton’s thoughts on microblogging in an open web environment has piqued my interest. I want to take back control of my content including my micro-posts, but how do I do this? As luck would have it, Manton suggested a possible solution for me that fits in nicely with Cross Post, the app I’m currently working, and his suggestion is changing the way I think of Cross Post2.

The Suggestion

Cross Post is designed to make it easy to share your status and photos across multiple social networks. In other words, Cross Post is a microblog app that lets you post to one or more social networks. Manton’s suggested to me that I add RSS support to Cross Post. It took a while for his suggestion to sink in, but when it did turn on I was like “Oh shit! I want that!”

Cross Post lets me post updates to App.net, Facebook, and Twitter so friends and family can read about me drinking beer, snowboarding, and doing other boring things. But more importantly it can be updated to give me the option to store my content in a location that I have complete control of. Cross Post then becomes an app for microblogging that not only publishes content to multiple networks, it stores your post in a place that you have complete control over and ownership of. And RSS is the perfect solution for this.

When I first heard Manton’s suggestion of adding RSS support to Cross Post, my thinking was that Cross Post would host the RSS feed on its own server. But this is not as simple as it sounds. This requires me to implement some type of user management system. Also since the Cross Post server would be hosting the content, I would have to implement features to allow a person to edit and remove posts. And then there is the hosting cost for hosting all the photos that a person can include with each post. But beyond that, you as the user of Cross Post would not have complete control over the content. It would be hosted on the Cross Post server, and if Cross Post were to ever disappear, then so would your content. In other words letting Cross Post host your content is no better than using App.net or Twitter. But I didn’t give up on the idea of using RSS in Cross Post.

Content ownership is what is important to me, and I knew there had to be a way to make this work. So my next thought was to have Cross Post support different blogging engines. Instead of just posting to social networks, Cross Post could upload your post to your web site directly. But that’s no easy task. What you are talking here is a microblogging version of MarsEdit, which is not something I care to write. Besides, a microblogging MarsEdit wouldn’t help me get my post into thecave.com because only static HTML is hosted. What Cross Post needs to do is post the content somewhere available on the Internet, but it has to be a location that the person has complete control. That’s when it hit me. Dropbox.

Host on Dropbox

Cross Post can post the content to your Dropbox (or similar service), and with syncing you will have a copy of your content for as long as you like. Even if Facebook or Twitter disappears, you would still have a copy of your post. And using RSS to store the content lets you do all sorts of things, from syndicating the post to other services to displaying the content in your own website to letting family and friends read you micro-post via an RSS reader.

But How

Here’s my current thinking of how it would work:

Using Cross Post, the person grants the app access to Dropbox (Google Drive, SFTP, whatever). When the person makes a post, Cross Post will append it to two feed files, full.rss and recent.rss. Full would contain all micro-posts ever made through the app. Recent would be the last n number of posts where “n” is set by the person (i.e., 5, 10, 20, etc). And if the post includes a photo, then the photo is uploaded to a subdirectory and the appropriate link is added to the entry in the feed file. If the person wishes to publish the feed to a service or let others consume the feed, then the Dropbox public link to the RSS feed file can be used.

The beauty of this approach is that the person has full control over the microblog content and that content is synced to their computer. Even if Cross Post disappears, the content does not. And for oddballs like me, I can integrated the microblog content into my static HTML site just by adding a plugin to Jekyll that consumes the RSS feed and generates a markdown file for each new post before generating the complete site. Heck, I can automate this to have my website updated in near-real time each time I make a new post via Cross Post.

So that’s my thinking, at a high level, for adding RSS support to Cross Post. This feature will not be in the first release of Cross Post. My first goal is to stabilize and ship the current version of the app. Once that happens I’ll focus on adding RSS support.

Whadda think? Is RSS support something that interest you? Let me know on App.net or Twitter.

  1. I still have the content from thecave.com pre-March 2002, but it’s not published on the Internet anymore.

  2. That Manton is a smart guy.

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.