Delivering on what was promised

In October, I purchased a 50″ Vizio TV to go in our freshly remodeled home. It had all the standard TV features, but 2 that interested me were the “apps”, in particular Amazon Prime streaming, as my Apple TV didn’t do that and the WiFi direct remote. the Amazon Prime app turned out to be such a dud that I ended up buying a Roku box primarily for that feature. However, the WiFi direct feature was one that I really wanted so that I didn’t have to aim the remote at the TV. This became even more important due to a poor design decision where Vizio basically put the IR receiver on the bottom left of the TV. Since our TV wasn’t mounted above a fireplace, the IR window wasn’t really visible, so the IR remote didn’t always work.

When we got the TV, the WiFi direct feature was promised in a firmware update. I waited and waited and waited. I contacted Vizio a few times and was told that they were rolling out the update in waves. I read on forums that some people had the newer firmware and some were still waiting. Newer TVs that people bought had the newer firmware.

This past Friday, I finally got real tired of waiting and called Vizio support with the same story. When the rep said that I’d just have to wait, I said that I’d contact the Vizio CEO and attorney general because they advertised a feature that wasn’t available. In addition, I’d file a suite in small claims court. Those would be drastic measures, but after waiting 7 months, I thought it was about time to resolve this. The rep was very nice and said he’d transfer me to executive services. After a few minutes, he came back on the line after talking to upper level support folks and walked me through a firmware update as they flagged my TV as getting it. We tried it a few times to no avail. He talked to another person who said to wait about 20 minutes and the TV will get the update and if it didn’t to call back.

I went about my business and turned on the TV later and almost fell down when I saw that the firmware update with the WiFi direct remote was enabled. Support had told me numerous times that there was nothing that they could do to get the update pushed to a TV which turns out to be a complete lie.

Now my TV has all the features that were advertised. It is interesting to note that Vizio is no longer advertising WiFi direct as a feature for the remote. I guess if companies are pushed hard enough, they’ll do what is right for the customer.

Tweaking a web server with Nginx

A few weeks ago, I started playing with nginx as a replacement for Apache. The exact reasons I decided to do this are a bit unclear, but I think it had something to do with me playing with node.js and MongoDB. The initial setup was pretty smooth and the configuration files are much easier to understand than Apache for my sites. However, I also decided to offload the PHP processing to php-fpm and that’s where the problems began. My VPS is pretty lightweight and doesn’t have a lot of RAM. My blog was running out of memory all the time and php-fpm stopped responding.

After a lot of tweaking to reduce memory usage, I managed to stabilize the system and get much faster response times for my blog; it doesn’t get a lot of traffic, but I think I’ve done a decent job with performance. If I ever get hit with a massive load, I’m sure my server will keel over.

Is there a real reason to use nginx vs Apache? I’m sure some people will say yes, but for me the jury is still out. Things are going smoothly, but was it worth the trouble? I have no idea.

Drones and Privacy

A few months ago, I received a DJI Phantom 2 quadcopter for a present. For most people, a quadcopter is called a drone. Call it whatever you want, it is a fun toy for me (tool for others). I have it outfitted with a GoPro camera and a video transmitter so that I can see what is going on during flight. In a conversation with my in-laws where I was showing my father-in-law how it flies, my mother-in-law indicated that she thought the devices were creepy because they can be used to spy on people. This is the same thing that the media is playing up and catering to the fears of people.

The quadcopters are first off, noisy, you can’t sneak up on people and take a picture; you know they are coming. Second off, the cameras on these copters aren’t all that great for details. The GoPro is a decent camera, but if you want to take a picture of someone in a house, you’re going to have to have the copter right at a window. Third, if you live in a 2 story house, it’s likely that you can already see in your neighbor’s yard. We live on a hill and can easily see into our neighbor’s backyard from our backyard.

In the current state of copters, I find it quite hard to really invade someone’s privacy without them knowing. Also, as I’m just learning to fly, I only fly on my property. When I get more experienced, I’ll goto a park and fly; flying over people’s houses may not be the smartest thing to do.

Time will tell what lawmakers decide to do to this new found hobby of mine.

Thoughts on Storyboards

When Apple came out with Storyboards in Xcode, I thought that they would be quite useful in making it easier to see how an app was laid out. However, after attempting one project with them, I determined that they had limited utility as they wouldn't scale and wouldn't work well for multi person teams. I left storyboards for a year and didn't revisit them.

I started another project about a year after my first experience and decided to give it another go. This project was a small project and I was the only developer, so it was well suited for storyboards. The project grew and grew. Storyboards worked OK, but the layout in Interface Builder was almost too hard to manage. I finally decided to see about splitting up the storyboards into multiple storyboards.

The app was a tab bar based app, so the logical breakdown was one storyboard per tab. It only took about 15 minutes for me to do this and undo a poor initial decision. However, there were still one or two links between storyboards that were easy to fix in code. Some peopl have come up with ways to link storyboards like RBStoryboardLink which looks interesting, but I haven't explored it.

Multiple storyboards seems scary at first, but it is worth doing to keep difference parts of an app more contained and easier to visualize.

I haven't used XIBs in about a year and I'm not sure there is a good reason to use them as storyboards are easy to work with and make it simple to use custom UITableViewCells and UICollectionViewCells.

Lessons in home remodeling

Almost a year ago, we embarked on the journey to transform our house into a home. It has been an interesting journey, to say the least. I’ve learned a lot about myself and a lot about the process. While I love our house and I consider it down, the most important lesson I’ve learned is that I never want to do this again! Why would I say this? Remodeling a house requires you to make hundreds and hundreds of decisions ranging from what faucets to get to what color paint to put on the wall. We had a general contractor who handled all the sub contractors. Dealing with the general contractor was easy and he was quite responsive.

We had an architect do the design and my dad who was in construction inspection his entire career offered to act as the project manager, per se. Man dad was at the house a few times a week and paid attention to all the details along the way helping mitigate problems that arose and guiding us on what we should do. By getting up early every day and working from 5:45 am to 2:30 pm, I was able to goto the house everyday and see what was going on with the house. Inevitably there was some problem I had to deal with or some decision to make.

Just to give you an idea of the decisions we had to make:

  • What faucets to buy
  • What countertop to get in the bathroom
  • What countertop to get in the kitchen
  • What light fixtures to buy throughout the house
  • What outdoor light fixtures to get
  • What floor to get
  • What color paint for all the rooms
  • What color paint for the outside of the house
  • What kinds of toilets to get
  • What towel bars to get
  • What kinds of windows to get (I was very specific on the type of lock I wanted)
  • What sliding glass doors to get
  • What tile to get
  • What fireplace to get
  • What tile to go around the fireplace
  • What color stain for the cabinets
  • What ceiling fans to buy
  • What track lights to get
  • What thermostat to get
  • What furnace to get
  • What garage door to get
  • What garage door opener to get
  • What shelving units to get
  • What closet organizers to get
  • What sinks to get
  • What vanity to get
  • What doors to get
  • What door hardware to get
  • What speakers to get
  • What appliances to get (refrigerator, microwave, washer, dryer, range, dishwasher)

etc.

I tried to keep ahead of the contract and to make things as easy as possible for my wife, I tried to only present a few decisions to her at a time.

On top of the decisions, issues came up with just about every sub contractor. Some issues were easily resolved, some were a bit more complex. One of the most memorable problems was the day we moved in (the house wasn’t done, but enough so that we could move in), I smelled gas in the attic, so I shut off the valve to the furnace. The next morning, I went up again and still smelled gas. The shutoff valve wasn’t properly connected so I had to shutoff the gas to the house. The contractor got the sub contractor out to fix it right away, but that kind of workmanship is pretty unacceptable as it was a safety concern.

This really wore on me and caused me an immense amount of stress. Our house is now really a home and I’m very pleased with the outcome; the process, however, is one that I could have done without.

Another Stab at using OS X Server

I’ve had a few run-ins (as I like to call them) with OS X Server in the course of my career. I’ve been very comfortable with UNIX/Linux machines for a long time (I compiled my own Linux kernels when I was right out of college) and found them to be quite reliable and highly configurable. The lack of a GUI didn’t scare me and I thought it was a plus as there are tons of options for services like Apache and named (DNS) and a there was no way that a GUI could expose all of them.

In one of my contract positions, we were using a Linux box until a new IT person came in and bought an Xserve with OS X Server thinking that since he was comfortable with OS X, the server was the next logical step. While OS X Server runs on UNIX, the friendly GUI hides lots of options, some of which are necessary to running a successful server and some of which are needed when the server does something stupid. So now you have the GUI modifying settings and devs modifying settings via the command line in order to work around deficiencies in the GUI. It was just a recipe for disaster. After awhile, we resigned the Xserve to specific tasks and put the more important services on a Linux box.

My next run in with OS X Server came a few years later when the company I contracted for and then went to work for already had an investment in 4 or so Xserves. They were chosen because the lead IT guy was more comfortable with OS X than with UNIX/Linux (he was more of a desktop support guy and not a server guy). In this setup, we had to use Open Directory and I managed to unify the boxes and spread out the services. Open Directory was a nightmare because sometimes it just returned errors with no way to fix them. Again, the GUI hid things (including ways to fix problems) that would have been simple using a command line. We eventually put a few Linux boxes on the network and ran more core services on those; the Xserves still handled FileMaker Server (that’s another nightmare for another day) and Open Directory. The only saving grace for Open Directory was the GUI for user management as sending LDAP commands to populate it was probably worse than dealing with OS X Server.

I had completely put OS X Server behind me when Apple announced Xcode Server at the last WWDC. It intrigued me, but I ignored it until last week when I went ahead and created a Mavericks virtual machine and put Server on it. It was quite painless and actually looked like it had some useful features. Xcode Server, VPN, and Caching were the primary things that I couldn’t do from OS X out of the box. (I already had FTP, for my scanner, and Apache going on my media center.) After I ran the VM for a day or so, I decided to take a leap of faith and install server right on my media center and not in a VM. I was reassured in this decision after seeing some articles on how to remove it. In the olden days, OS X Server was as a separate install and couldn’t be removed. I’ve been running Mavericks Server for about a week now and it has been great, unlike my previous run-ins with the product. While it is still not perfect (Xcode Server needs some work), it is looking good. I had have to hack on a config file for the web server to do proxying as my security system runs a local service on port 8000 and in order to protect it with SSL, I had to setup SSL on the web server and proxy it, but that was just a matter of adding:

<IfModule mod_proxy_balancer.c>
     ProxyPass / balancer://balancer-group/
     ProxyPassReverse / balancer://balancer-group
     <Proxy "balancer://balancer-group">
          BalancerMember http://localhost:8000
     </Proxy>
</IfModule>

to the config file for the site. The downside is that if I touch the site setup, my changes will get blown away.

While playing around with the Profile Manager today, I think I discovered the biggest problem with OS X Server in the past…Open Directory. In order to do MDM (Mobile Device Management) in Profile Manager, you have to turn on Open Directory. I quickly cancelled out of that and ended that experiment. I mentioned Open Directory to a co-worker who also used to do IT and he had the exact same feeling about Open Directory that I do; I hate it. I know that’s pretty strong, but that service has had many, many problems that I’m unwilling to risk my server to turn that on as I have no use for it. Maybe a company that has a dedicated IT guy has no problem with IT, but if you leave Open Directory out of OS X Server, I think Apple has a fine small business server product.

For developers, OS X Server is now free and if you’re like most geeks, you already have a machine running all the time, so might as well install OS X Server and take advantage of the caching and maybe play around with Xcode Server.

Code Signing Woes on Xcode Server

Following up on my post from yesterday, I’ve discovered that Xcode Server does something very strange in the build process. After the build, it creates a .ipa file that is suitable to install on an iOS device and a .xcarchive file that contains the .dSYM file as well as the .app file which is the .ipa file before it has been packaged up. The packaging process is basically putting the .app file in a Payload directory, zipping it up and changing the .zip extension to .ipa. Sounds simple enough and unzipping the .ipa should yield a file identical to the .app. Unfortunately this is not the case. If you run the following command:

codesign --display --entitlements - AppName.app

on the .app in the xcarchive and on the .app that is extracted from the .ipa file, you will get different results.

From the .ipa, I get:

<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>application-identifier</key>
    <string>123324243AS.com.something.something</string>
    <key>keychain-access-groups</key>
    <array>
        <string>123324243AS.com.something.something</string>
    </array>
</dict>
</plist>

from the .app, I get:

??qq?<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>application-identifier</key>
    <string>123324243AS.com.something.something</string>
    <key>aps-environment</key>
    <string>production</string>
    <key>get-task-allow</key>
    <false/>
    <key>keychain-access-groups</key>
    <array>
        <string>123324243AS.com.something.something</string>
    </array>
</dict>
</plist>

It appears that the code signing entitlement, aps-environment is missing from the .ipa Xcode Server built. I can’t figure out why this is the case, but it does show that I’m not crazy and my setup works. The .ipa I create myself and upload to TestFlight works because my simple packaging script doesn’t re-codesign the .app.

So I have 2 choices when uploading to the app store:
1. Do what I described yesterday and that is resign the app on my desktop machine

  1. Take the .app file out of the xcarchive, zip it up and upload that.

Xcode Server does mangle the product and I’m not sure that is intentional. I should file a bug with Apple to see if they can fix it in the future.

I’d love to be proven wrong on this whole setup. If you have more information, please let me know.

Using Xcode Server for Builds

At last year’s WWDC, Apple introduced Xcode Server for doing continuous integration. Lots of people have tried to use it with mixed results. Recently after dealing with our build server for work (we use Jenkins), I decided to give Xcode server a try for one of my projects.

I was hesitant at first to use OS X Server (which includes Xcode Server) as I’ve had poor results with it in the past. It intrigued me often that I decided to install server and see where it went. OS X server install was a breeze and so was setting up Xcode Server.

I created a “Bot” from Xcode on my development machine and saw that it failed when the server tried to build it. No problem, I searched the Internet and all the results said to add the repository from the server instead of when creating the bot. Perfect, I did that and then the build succeeded. Yeah! I also added my Team to Xcode server so it could pull down provisioning profiles and create a certificate to build.

I checked the log and found 2 problems. First, I have a run script build phase that puts the version number in the Settings.bundle that failed and second, it was being signed using the wrong mobile provisioning profile.

I decided to tackle the second problem first. Through my searches, I found that I needed to put the mobile provisioning profile (an AdHoc one) in /Library/Server/Xcode/Data/ProvisioningProfiles. No problem. Next I also found that I needed to put the certificate and private key for the profile in the System keychain as the Xcode Server runs under _teamserver which doesn’t have its own keychain. I did that as well and found the problem didn’t go away. I started thinking about it and found that sometimes Xcode ignores the Automatic Distribution Code Signing Setting. So, I removed my Team and deleted all the other mobile provisioning profiles. Bingo, now my app was building and being signed correctly.

Next step was to figure out my build phase. After dumping the environment variables, I found that in order to put files in the .app after the build, I had to set my script phase to be:

shortversionnumber=`/usr/libexec/PlistBuddy -c "print CFBundleShortVersionString" ${BUILT_PRODUCTS_DIR}/${INFOPLIST_PATH}`
bundleversionnumber=`/usr/libexec/PlistBuddy -c "print CFBundleVersion" ${BUILT_PRODUCTS_DIR}/${INFOPLIST_PATH}`
shortversionnumber=`echo $shortversionnumber '('$bundleversionnumber')'`

echo ${shortversionnumber}

src_file="${SRCROOT}/Piccee/Resources/Settings.bundle/Root.plist"

dest_file="${BUILT_PRODUCTS_DIR}""/""${UNLOCALIZED_RESOURCES_FOLDER_PATH}""/Settings.bundle/Root.plist"
echo $dest_file

/usr/libexec/PlistBuddy -c "delete :PreferenceSpecifiers" "$dest_file"
/usr/libexec/PlistBuddy -c "add :PreferenceSpecifiers array" "$dest_file"
/usr/libexec/PlistBuddy -c "add :PreferenceSpecifiers:0:Title string About" "$dest_file"
/usr/libexec/PlistBuddy -c "add :PreferenceSpecifiers:0:Type string PSGroupSpecifier" "$dest_file"

/usr/libexec/PlistBuddy -c "add :PreferenceSpecifiers:1:Key string VersionKey" "$dest_file"
/usr/libexec/PlistBuddy -c "add :PreferenceSpecifiers:1:DefaultValue string ${shortversionnumber}" "$dest_file"
/usr/libexec/PlistBuddy -c "add :PreferenceSpecifiers:1:Title string Version" "$dest_file"
/usr/libexec/PlistBuddy -c "add :PreferenceSpecifiers:1:Type string PSTitleValueSpecifier" "$dest_file"

/usr/libexec/PlistBuddy -c "add :PreferenceSpecifiers:2:File string Acknowledgements" "$dest_file"
/usr/libexec/PlistBuddy -c "add :PreferenceSpecifiers:2:Title string Acknowledgements" "$dest_file"
/usr/libexec/PlistBuddy -c "add :PreferenceSpecifiers:2:Type string PSChildPaneSpecifier" "$dest_file"

The key was the ${BUILT_PRODUCTS} variable.

So I was almost done with the build server. I setup 1 bot for the master branch that builds when code changes and another on the build branch that also builds when code changes; however, I only push to build when I’m ready for a build. The build branch also had to upload to TestFlight, so I researched that and came up with very convoluted solutions.

I created a second scheme for the TestFlight upload and set my build branch bot to use that scheme. Then I added a Post Action to the Archive phase that looks like this (make sure you select Provide Build Settings From “Your Target”):

API_TOKEN="API_TOKEN_HERE"
TEAM_TOKEN="TEAM_TOKEN_HERE"
DISTRIBUTION_LISTS="People"
IPA=/tmp/MyApp.ipa
rm -rf ${IPA}
/usr/bin/xcrun -sdk iphoneos PackageApplication -v ${ARCHIVE_PRODUCTS_PATH}${INSTALL_PATH}/${WRAPPER_NAME} -o ${IPA}

RELEASE_NOTES=`cat ${SRCROOT}/CurrentRelease.txt`
echo "*** Uploading ${IPA} to TestFlight ***"
/usr/bin/curl "http://testflightapp.com/api/builds.json" \
-F file=@"${IPA}" \
-F api_token="${API_TOKEN}" \
-F team_token="${TEAM_TOKEN}" \
-F distribution_lists="${DISTRIBUTION_LISTS}" \
-F notify=True \
-F notes="${RELEASE_NOTES}"

echo "TestFlight upload finished!"

I thought I was all done; builds worked and were uploaded to TestFlight. The moment of truth came when it was time to upload to the AppStore. I have push notifications enabled in this app and it is properly provisioning. After the upload, I got email saying that the ape-environment key wasn’t in the entitlements. Very strange, I checked and rechecked the build I got out of Xcode Server and it was correct. I tried a number of things and in the end sort of gave up. I took the archive that the build server created, put it on my main machine, imported into Xcode, exported for AdHoc distribution, resigned it using the same profile it was already signed with and submitted it. For some strange reason, this worked. I can live with that as I don’t submit to the app store all the time.

Things to note

  • You do NOT have to create an AppStore distribution profile. You can submit the AdHoc build to the AppStore without problems. This is key as it lets you test the exact version going to the AppStore without rebuilding or resigning.
  • You have to manually move your mobile provisioning profiles for AdHoc builds to your build server.
  • You have to manually add your private key and certificate to the System Keychain on your build machine.
  • Be careful about your build scripts as the paths are different on Xcode Server.
  • You have to add your repositories from Xcode Server and not from the bot you create.
  • Read the logs carefully when there is a problem.
  • Apple appears to have created Xcode Server for testing and not necessarily for release builds; I hope some of this changes in the future. I’m not a huge fan of unit tests, so I may just be abusing the server by doing what I’m doing.

Overall, I’m pretty plea with having my own continuous integration server. It will catch issues where I have something different from Debug builds to Release builds. In addition, it will upload to TestFlight along with the release notes saving me time. I am a little disappointed about having to resign for the app store, but it isn’t a huge deal. I could probably modify my script to do that during the archive, but I really don’t like having to hard code in the ID of a mobile provisioning profile. I could probably check the profile into source control and reference that, but I’m OK with this solution. As I already want to move the archives to my main machine, the extra signing process isn’t a big deal.

I know that there is a lot here, but hopefully it helps someone else in the future (that person may be me when I forget what I’ve done!).

The downside of parking meters

San Diego is in the process of replacing regular parking meters with ones that are called multi-space meters. These are ones that give you a ticket that you place on your dash. I thought that these were neat as I could just pay with a credit card as I usually don’t have change around. My wife, however, pointed out the problem with these is that the minimum is 1 hour on the meter which costs $1.25. I didn’t think much of it until I had to pick something up today and found a meter with some time left on it; I dropped a quarter in it (I do have some quarters in my car) and got another 12 minutes which was plenty of time for my errand.

It turns out that the pay and display meters do take change and apparently you can put less than $1.25 in them. So the lesson is that I still need to have quarters in my car for times that I think I’ll be at a meter less than an hour; otherwise, paying by credit card is quite convenient. Now if the city could just get with the game and figure out some micropayment strategy with lower transaction fees, maybe they could reduce the minimum amount to go cashless.

Simple fix to “This accessory is not compatible with the iPhone” with mophie cases

I’ve been using mophie battery cases for a few years now when I travel as the iPhone doesn’t seem to last all day when I use it extensively. Granted the iPhone 5 has gotten better, but I typically use GPS to track my run/walk if I’m in San Francisco for WWDC or somewhere else. Every now and again when I’d charge my case, I’d get the message “This accessory is not compatible with the iPhone”. mophie’s FAQ gives some lame answer on how to fix this problem.

Recently I bought the charging dock for my juice pack and was getting this message every time my phone got to 100% charge and then overnight my phone would start to drain. After a bit of searching, I found a reference to charging cables on Apple’s support site. While this wasn’t my problem as the dock has an integrated cable, it got me thinking. My dock was plugged into a USB hub instead of directly into the wall or my Thunderbolt display. I switched the dock to plug into the Thunderbolt display and bingo, the problem went away. This tells me that the current supplied by the hub (it’s an unpowered hub as I don’t want to plug in the power supply) isn’t enough to keep the iPhone/mophie case happy.

Such a simple fix for a problem. Maybe mophie can update their FAQ with this information and save others from returning their products or contacting support.