Tag Archives: Programming

Dependency Management

With most software projects these days, including open source components is almost a given. There is no reason to reinvent the wheel and some components are so customized that it would take months to mimic the behavior. There are many ways to integrate these components into an application. One of my mantra when working on projects is that I just want to be able to checkout the project from a repository and build it; there shouldn’t be several steps and I shouldn’t have to worry about something outside of my control breaking the build.

Years ago when I worked on a particular project, there was a several step process to just get the source code which integrated open source components. This was extremely fragile as the references to the open source components was for an external repository that could go away at any time. When I became in charge of the project, I changed things so that we only relied on repositories that were under the control of the company (we had shared components).

In iOS development, there are now 2 (or 3) main systems for managing these external dependencies. The first is CocoaPods which is very popular, but relies on the external repositories to always be there and requires modifications to how the project is built. The newer entrant into this arena is called Carthage. Carthage gives me more control on the dependencies. The system makes it easy to store the dependencies in my repo and easily update them. In particular, I use the following command to update

carthage update --platform iOS --no-build

Basically I just let Carthage update the components and I have my project setup to do all the builds. When I checkout the project, it has everything in it and I just build. I think that this setup, at least currently, strikes the best balance to handling dependencies.

The other day I was reminded of this problem when a developer was describing dependencies on one of my projects; the developer basically said that he used a dependency management system that didn’t store the components with the source code. I’ve been writing software for awhile now and while open source makes it easier to get things done, many developers don’t consider the entire build process or risks involved in not having control over all the components.

Native vs Web App for IoT Devices

Recently I was chatting with a friend about a new WiFi router. I hadn’t heard of it and he sent me a link to it. The first thing I noticed about it was that the configuration was done via an iOS or Android app. As an iOS developer, I know that a native app is going to generally provide a better user experience than a web app. However, as a consumer, I shy away from devices that only have a native app interface. If the app stops working, isn’t updated quickly when an OS gets updated, or the company stops supporting the app, I’d be out of luck. In addition, I like being able to configure devices using my desktop machine and most devices don’t have a Mac app for configuration.

The native apps are great, but they have to be secondary to a web interface for any IoT device. I mentioned this to my friend and he understood right away my point. I look at the serial to Ethernet gateway I have that I bought used 3.5 years ago and is likely not made any more and am glad that it has a web interface. Granted it is a very specialized device on my network, but the web interface is the only reason that I’m still able to use it. If it were a device that I wanted to look at more often, like a router that I needed to control various aspects of it, the lack of a web interface makes the device a no go in my opinion.

I wish that more companies would implement web interfaces first for their IoT devices and have native apps as secondary interfaces. I’m not saying that all apps should be web apps; in fact, I believe that native apps provide a better user experience. I am saying that web apps should always be a backup option in case the native app isn’t available or doesn’t work.

When is zip not zip?

Like most experienced iOS developers, I use an automated build system. A colleague of mine and I have spent portions of the last 2 years building up our system so what we do looks like magic to others! As part of this system, we’ve written tools and put together scripts to package our application as an .ipa (iPhone application). An .ipa file is simply a zip file with the extension changed.

Well, it isn’t that simple. It appears that how the zip is created is just as important as the structure of the package. There are various flavors of zip, libraries that do zip, and other tools that zip. In one of our tools, we were using a zip library. It appears that Apple made a change in iOS 9.0.2 or 9.1 that caused applications created by our tool to not install on devices. However, the problem was only present if the app was installed over the air or through iTunes; installed through Xcode’s Devices window succeeded. After an arduous day of debugging trying to determine the failure point (provisioning is usually to blame for failures and they can be super frustrating), I switched our tool to use the command line zip (/usr/bin/zip) and amazingly the problem went away.

It would appear that iTunes, iOS itself, and Xcode use slightly different methods for unzipping and installing applications. Since Apple’s xcrun command for packaging (PackageApplication) uses /usr/bin/zip, I think it is a safe bet. It is invoked using something like:

/usr/bin/xcrun -sdk iphoneos PackageApplication -v MyApp.app -o MyApp.ipa" --sign "iPhone Distribution: Scott Gruby"

On a side note, it also appears that there is an error in the PackageApplication script found at:

/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/PackageApplication

that has:

"--resource-rules=$destApp/ResourceRules.plist");

In Mac OS X 10.10 and higher, this line is no longer valid, so if you use this command, you need to modify the script.

The best, underutilized and poorly implemented accessibility feature

[Update – October 21, 2015: It looks like the issues with News have been fixed with the iOS 9.1 update. Yeah!]

iOS 7 brought a feature called dynamic type which moves away from developers specifying exact point sizes for text and instead uses a number of descriptions for fonts.

From UIFontDescriptor.h:

    // Font text styles, semantic descriptions of the intended use for a font returned by +[UIFont preferredFontForTextStyle:]
    UIKIT_EXTERN NSString *const UIFontTextStyleTitle1 NS_AVAILABLE_IOS(9_0);
    UIKIT_EXTERN NSString *const UIFontTextStyleTitle2 NS_AVAILABLE_IOS(9_0);
    UIKIT_EXTERN NSString *const UIFontTextStyleTitle3 NS_AVAILABLE_IOS(9_0);
    UIKIT_EXTERN NSString *const UIFontTextStyleHeadline NS_AVAILABLE_IOS(7_0);
    UIKIT_EXTERN NSString *const UIFontTextStyleSubheadline NS_AVAILABLE_IOS(7_0);
    UIKIT_EXTERN NSString *const UIFontTextStyleBody NS_AVAILABLE_IOS(7_0);
    UIKIT_EXTERN NSString *const UIFontTextStyleCallout NS_AVAILABLE_IOS(9_0);
    UIKIT_EXTERN NSString *const UIFontTextStyleFootnote NS_AVAILABLE_IOS(7_0);
    UIKIT_EXTERN NSString *const UIFontTextStyleCaption1 NS_AVAILABLE_IOS(7_0);
    UIKIT_EXTERN NSString *const UIFontTextStyleCaption2 NS_AVAILABLE_IOS(7_0);

When developers use these instead of say Helvetica Neue 12, a user can change the font size in Settings->Display & Brightness->Text Size.

Text Size

This is generally thought of as an accessibility feature as it helps people who have trouble seeing. However, for people like me who can see well with glasses, larger type is just more comfortable to read. Implementing this is quite easy, but requires a few extra steps like listening for changes to the fonts and making sure that table rows resize to accommodate the text. These steps aren’t rocket science and don’t take much effort, but many developers are constrained by what their designers give them and many designers are still used to specifying exact fonts as well as spacing. This needs to change as it is hurting those that want to increase the font size and also makes it harder to adapt to different screen sizes.

I’ve implemented dynamic type in a few of the apps I’ve done and it worked out well; the extra effort was worth it in my opinion. Some developers just don’t care and other developers including Apple make an attempt, but fall short.

Here are images from the Apple News app. The first image is the standard text size; the second is the largest text size (largest before going into Accessibility and moving it to super large).

News - Standard Size News - Large Text

(I never knew there were images with the posts because they aren’t seen with the large text.) You can see that the text resizes along with the cells, but the title collides with the first part of the article. That’s pretty sloppy.

The next example is in Calendar. This one is worse than the first because the row is a fixed height and it looks like each row of text is also a fixed height so that when a larger font is used, it looks awful.

Calendar - Regular Font Size Calendar - Large Font Size

For a company that pays so much attention to accessibility, these examples show that individual teams making the apps aren’t doing enough to look at their apps. Maybe all the engineers have great eyes and can see the text, but this does need to get fixed. (Filed as Apple Radar 23196322.)

Outside of Apple, developers need to pay more attention to this; accessibility is hard and I’ll be the first to admit that I don’t do enough on accessibility. Handling dynamic type is an easy first step in making apps more accessible and easier for everyone to use.

Determination or insanity?

For the last week I’ve been tracking down a bug in my current project. I’ve spent just about every spare minute including the weekend trying to figure out why my code works in a test app, but not the main app. I rewrote a huge piece of some communications code to no avail. I tried threading the communications, putting in proper locks, changed how I processed the bytes, etc. Basically when I was receiving large amounts of data from a Bluetooth device, some data was lost in the transmission and the checksum was incorrect; for small amounts of data, this problem didn’t show up. At this moment in time, I believe I’m the only person in the world working with this combination of hardware and software which made using Stackoverflow useless.

A co-worker of mine kept sending me ideas to try as I was completely out of ideas. His latest idea was to put the files from my test app into the main app to make sure the project settings weren’t the problem. That didn’t solve the problem, so I started ripping out pieces of the code and came across some code we had put in for a demo.

All of the communications code that I was working on was using the External Accessory protocol over Bluetooth. The demo code we had in there was using Multipeer Connectivity which uses WiFi and Bluetooth to discover peers. Once I removed that code, all of my communication issues went away! Now I should file a Radar issue with Apple on issue, but I can’t reproduce it outside of the particular hardware I’m using, networking library I’ve written, and a few other pieces so a bug report would be quite lacking.

I must have spent 40+ hours on this one issue which has caused me to lose sleep and be a bit on edge all week. As failure was not an option and I had no place to turn, I had to solve this. I’m sure that others would have given up as 40+ hours is far too long to spend on a bug. For me, however, I actually spent 4 months full time chasing down a bug in a network router for a cellular base station; like this one, I did eventually discover the fix.

Lesson learned…be careful of using different communication libraries in an app.

Swift Lessons

As I wrote in my last post, I’ve been learning Swift. This has been interesting. Chris Lattner and his team have been working on Swift for years and have done something that is amazing. Not only have I learned a bit about programming in Swift, I’ve learned a few things about using Swift.

  • Swift isn’t ready for prime time. I’ve seen references to this from Apple.
  • There are lots of bugs in the compiler; SourceKit crashes all the time and auto complete dies.
  • The syntax, while flexible, is a bit confusing at times. For instance, I have a framework in my app called Vera. In some places I access classes of that framework using the Vera namespace, i.e. Vera.Device.Category.Audio to get an enum value and in other places, I use an array of Device. This is confusing and inconsistent.
  • In some places, parameters have names and others they don’t. While you can specifically require the parameter names, sometimes you don’t have to do that and sometimes they’re required.
  • While Swift is extremely flexible, it is confusing as anything once you start getting into wacky things go haywire. Take a look at this code with AnyObject and Unmanaged.
  • There are bugs in the optimization such that turning on optimizations breaks certain code (like the one referenced in the last bullet). I can’t remember the last time that turning on optimizations broke code that I didn’t discover until I tried to deploy an app.

I’m sure that things will get better, but at the moment more work needs to be done. I’ll keep poking with Swift and enhancing my app.

Learning Swift

When Apple announced Swift at WWDC, I knew that if I was going to keep up with the youngsters, I had to learn Swift. Unfortunately it has been a long time since I learned a new language; I learned Objective-C in 2000, I think. While I am capable of learning, finding the time to learn it and use it are getting harder and harder. However, I know that I didn’t have a choice.

I started reading Apple’s books on Swift and made it part way through when I got distracted. I’ve restarted a few times, but still haven’t finished. So I decided to take my automation app and completely rewrite it in Swift. While I could have re-used my existing code, I decided to do my implementation completely in Swift using a few open source libraries (there may have been better libraries to use, but the ones I picked seemed reasonable for now). While I’m still learning Swift, I thought it was a decent attempt to learn it. I’ve put my rewrite on GitHub for all to mock.

I’m going to keep learning and I think that reading the books will make a lot more sense now that I have a project under my belt.