Development

The Big Switch

On my latest project, I am trying my hand at a simple app that also has an Apple Watch component, plus a Today Extension. It has been an interesting process, to say the least.

I started off with Cocoapods, since that has worked well for me in the past. I don’t use a huge amount of third-party code, but sometimes it’s really nice to have a souped-up NSDate class, or use SnapKit for some AutoLayout goodness. However, when starting to deal with a combination of Swift, Watch extensions, and Today extensions, plus third party libraries, I had a huge amount of trouble to get Cocoapods to build things in a way that made the App Store submittal process happy. Everything worked just find during development, but getting the Frameworks directory set up just so (delete it, no, fill it, no wait, now the Swift libraries are missing! Argh!) was incredibly frustrating. Frustrating enough that I considered looking into Carthage instead.

I’ve been aware of Carthage, really just as “A dependency manager that isn’t Cocoapods”, but in reading about its simpler approach, I thought it might help avoid the problems I was encountering. And, tl;dr, it did. I feel like my builds are faster, simpler, and more under my control. I think when starting off on a new project, or each time you add a new third party framework, there’s a bit more work, rather than just running “pod install”. And the changes you need to make to your XCode project file are fairly well documented, but not entirely complete when it comes to Watch and Today extensions. But, it ultimately did work, and is more sustainable going forward.

I was lucky that almost all of my CocoaPods were already Carthage-compatible. Only one, Matthew York’s DateTools, wasn’t. DateTools was a bit of fun, since I needed to make it WatchOS and Carthage compatible, plus it’s Objective-C, so I had to make sure its API was available to my apps. All doable, and I’ve got a lovely GitHub fork with the changes if you’re interested (littlepotatosoftware/DateTools), but it was a whole new skill set I needed to learn.

I still haven’t re-introduced the Reveal library to my project. Honestly, haven’t needed it for the past few days while I dealt with built and submission issues. But now I will be using the command line linker arguments to bring it in, instead of using a Pod, so it’s only there for the Debug build. One of my app submission rejections was because I had forgotten to remove it, or at least make it conditional on the debug build, in my Podfile.

I have enjoyed using CocoaPods, and think they do great work, especially they website for Pod discovery. I’ll continue to use it for that, but will stick with Carthage for now. When CocoaPods added their new structure with named targets being required, it felt like any time I made a change to my XCode project file, I risked breaking something in the build of the pod files. And although my pods never change, it always felt like I was spending a fair amount of time every build cycle at least looking through all of the pod sources. Builds feel snappy now.

I tried to document the process as best I could, and may write something up in the future with more detail. The problem with configuration management, and app submission in general, is that you do it just infrequently enough (or at least, I do), that you tend to forget the little details and gotchas. I tried to keep a more accurate log of actions tried this time, to help save myself the cost of relearning it all the next time I have to go through the process.

I also am using fastlane (which I used on Tarrific), and find that it continues to get better and better. It is even happier now that I’ve gotten my framework linking issues taken care of!

Adding color palettes to XCode

I like to put together a color scheme for my apps in Sketch. It’s got a great ability to save the document colors in the color picker window, making it easy to refer to your palette as you design. However, I wanted an easy way to get those colors into XCode.

I’ve come up with a workaround for now. It works at the moment because I have a relatively limited set of colors I want to share, and I’m not planning on changing them too much at this point.

In the standard macOS color picker, you can choose the “Color Palettes” color picker (third from the left, at least on my computer). Most of the time this is set to “Apple” or “Web Safe Colors”. However, you can create your own palette using the gear button, rename it to something relevant, and then add your app’s colors to this palette. I found the easiest way to do this in Sketch is to use the “Show Colors” menu item under the “View” menu. This brings up the floating Apple Color picker. Load up with Sketch color picker, and every time you change the color in the Sketch picker, it will update the color in the Apple picker. You can then use the + button to add the current color, changing the name if you’d like. I did need to restart XCode to make it recognize the new palette, but now all of my app’s colors are in XCode, ready to be applied to UI elements in Interface Builder.

Simple trick, but handy.

Colors_and_Main_storyboard_—_Edited

Pods in Playgrounds

I had a random thought while driving - wouldn’t it be fun to play with some new CocoaPods in Playgrounds? It occurred to me that this wasn’t something I had just stumbled across in my normal blog surfing. It turns out to be fairly easy, but the “obvious” answer from StackOverflow doesn’t work if you have updated to the 1.0 version of CocoaPods.

Check out this github project. You don’t even need to clone the repository, just look at the steps in the Readme:

• Create a new Xcode project
• Close Xcode
• Navigate to project directory
• pod init
• Update Podfile with Alamofire (see example)
• pod install
• Open .xcworkspace
• Add a new playground to the workspace
• Manage schemes -> Check 'Alamofire'
• Build the Alamofire scheme
• Xcode triggers a warning about updating the bundle settings for Alamofire; accept changes
• You should now be able to 'import Alamofire' in the playground


Replace Alamofire with your desired pod, and voila. The trick here seems to be building the scheme associated with the Pod. I tried to add two Pods, and didn’t have any luck - I suspect whatever Xcode is doing when it “fixes” your bundle settings is only valid for the first pod, not both. However, if you want to test out a single pod (Obj-C or Swift), this seems to be a fairly straightforward way of doing it.

I’m hoping this blog post servers as a reminder to myself as well as a help to anyone who is struggling with this in CocoaPods 1.0! I was using Xcode 7.3.1 and CocoaPods 1.0.1.


Introducing... Tarrific!

One of the best things about being an independent app developer is that if you have an idea for an app that would make your life better or easier, there’s nothing stopping you from developing it, and then getting to share it with others. My newest app, Tarrific, falls squarely in that category. I love to cook, and often use a kitchen scale. The tare (or zero) button on the scale is a great way to add new ingredients to a bowl, and weigh them as you go. But, when you forget to zero out a scale first, or the scale decides to time out and turn off while you are working, you’re stuck. How much do the contents weigh? Who knows. Another common situation I found myself in was having my ingredients in a bowl, but wanting to divide them in half, or quarters, etc. Without knowing the exact weight of the contents, or remembering to zero out my scale before I added something and hoping it doesn’t turn off before I’m done, it was really hard to be exact.

Icon-40@3x
From this idea, Tarrific was created. Tarrific lets you store the weights of all of your bowls, measuring cups, dishes — anything you’d like. So, there’s a little bit of setup to do - just grab your most used bowls, weigh them, and save them in the app. Then, when you are in the middle of a big cooking project, just put the bowl and its contents on the scale, and use Tarrific to do something very simple — subtraction! If you pick a saved container, and then enter in the total weight, you’ll be given the weight of the contents. Not so fancy, really, but it can be real lifesaver when you are in the middle of a recipe, and just need to remember how many cups of flour you’ve added to the bowl (it’s about 120g a cup for most flours).

Once you know the weight of the contents, you can do something even more fun — division! Just tell Tarrific how many portions you’d like the contents divided into, and it will tell you what weight you should see on the scale as your remove each part. So, dividing the contents in half is now easy. Pick your container, enter the total weight into Tarrific, and then specify that you want two portions. You’ll then be shown the exact value the scale should display once you have removed half of the contents. I’ve found this invaluable for everything from creating evenly sized mini meatloaves to getting exactly 12 perfectly portioned muffins.

Another fun thing about the development process has been having it tested by my mom. She had been keeping a written list of the weights of her most often used bowls, just so she could subtract the weight out later. She already used an iPod touch for a kitchen timer app, so was able to start using Tarrific as well. This has been the first app of mine that she she had a real reason to use, and it has been a fun process to get her feedback on everything from the icon design to “what does that button do??”.

I’ve learned a lot through this particular app development process, and hope to share some of the new tools and techniques that I tried out on the blog over the next few weeks. For an app that is essentially something very simple (subtraction and division), I really tried to concentration on the design, keeping it simple, streamlined, and useful in the kitchen.

Preview of the tech-y details for the curious: It uses Core Data (my first app trying that out), 100% Swift, fastlane for some of the testing (brand new to me - so cool, but I’m still learning), XCode-based UI animation and unit tests (my first time trying those new tools out), cocoapods (not too many), PaintCode and Sketch for graphics (of course!), and all of the UI done in code, not in IB. That last one was a tricky choice, as an app this simple probably could have been done in IB without too much work. But, I’ve gotten used to SnapKit for Autolayout, and really like the power it gives me to tweak UI values and see all of my constraints in one place. Doing AutoLayout right makes it so much easier to support different size classes and screen sizes, including split screen on new iPads.

If you love to cook, and use a kitchen scale, I hope you’ll give Tarrific a try. It’s free in the App Store. If you really like it and find that you want to add more than four containers, there is a one-time $1 upgrade to unlock unlimited containers. I’d love to hear from you if you try it and want any new features added. Happy cooking!

A Swifty New Year

Do you listen to Under the Radar, the new(ish) podcast from David Smith and Macro Arment? I have been enjoying it, having missed the shorter format of David Smith’s original podcast, Developing Perspective. It directly relates to topics of interest to indie developers, and the shorter format focuses the conversation a bit.

Because of their ergonomics episode, I finally took the plunge and bought a standing desk. I’ll talk more about that in a separate post, but it has been a really positive experience.

I was surprised by their take on Swift, though. Both developers were emphatically in the “no-Swift-for-me” camp for now. This post is my take on moving to Swift, and what I see as the benefits and drawbacks to doing so at this time.

For the new year, give Swift a try. The barrier to entry is low. Every developer has XCode, and its Swift support just keeps getting better. I can understand the reluctance during the Swift 1.0 days. I didn’t play with it then much, either. I found Playgrounds slow, and the compiler crash-prone. Everyone who was talking about Swift seemed to have jumped right into the deep end of complexity with discussions of functional programming and obscure language features.

But, things have improved. Apple has put together a lovely tutorial where they walk you through a nontrivial iOS app using Swift (no temperature converters here!) Start there and just see how you like it. Many of the tutorials on raywenderlich.com have been re-written in Swift. Take one you’ve done before (or a book you’ve purchased in the past), and try it out in Swift.

One approach I haven’t been as successful with is writing some new functionality in an existing Objective-C app in Swift. It can be done, but I find switching between the two to be less efficient. Plus, although the way Swift interacts with the existing Cocoa APIs is improving, it will still feel more clunky than just calling things from Objective-C.

Also, don’t start reading all of the hardcore Swift blogs right away. They bring up cool points, but are too specific and detailed to be useful at first. I found them confusing and overwhelming. However, now four months in to writing Swift almost every day, I have found myself revisiting some of the older posts, and better understanding the concepts they were trying to explore. The WWDC 2015 Swift videos are also nice to watch once you have a bit of practical Swift under your belt.

It will feel frustrating at first - Swift code will take you probably twice as long to write as equivalent Objective-C, and you’ll still be looking things up and fighting compiler errors. Once you have working Swift, it will probably just be Objective-C style, but written in Swift. THIS IS FINE. You spent years building up your Objective-C skills - they are not going to be as easy to discard for a newer, shinier language.

But, when it comes time to create something new, consider Swift. You will end up writing significantly less code overall. As you become comfortable with optionals, value types, and the class/protocol model, you will slowly start to change your style and write more “Swift”-ly. Only then start following Swift blogs. You should also keep an eye on the future of the language that is unfolding on Github. No point in getting attached to a language feature that is destined to disappear (I’m looking at you, c-style for loops…) Give the Xcode migrator less to do by starting to follow future conventions today.

I wrote two apps for AppleTV entirely in Swift. The first went pretty slowly. It felt like I was not only learning a new programming language, but the Cocoa APIs as well. Concepts that seemed so clear when reading the Swift docs seemed more complicated in practice. However, the next Swift app I wrote for AppleTV was essentially written in three days. I now have a hard time bringing myself back to Objective-C. I had written in Objective-C since 1992, and have been surprised by how quickly and completely I want to just stay in Swift.

And then, once you’re ready for it, definitely check out Erica Sadun’s new book, The Swift Developer’s Cookbook. This book is Hard Core, but in a totally amazing way. If you want to start writing code that is not warmed-over Objective-C, and takes advantage of some of the truly cool language features of Swift, this is the book for you. I’m working through it slowly, but find that I am learning something new in every chapter. It is to be savored and digested gradually (ha! because it’s a cookbook! didn’t even to mean to make that pun…).

Here’s to a 2016 is filled with great apps written in Swift!



View Transitions + Some Perspective

Happy New Year!

I’m getting off to a slow start of the work week after a week off with the kids, so I decided to ease into things by stepping through a Ray Wenderlich tutorial. They are always fun to read, relatively short, and I learn something new.

The most recent non-video tutorial was:

Creating Custom UIViewController Transitions

It fulfilled my expectations in terms of better understanding view controller transitions. I still feel like there are just so many moving parts with those transitions (pun only slightly intended), but this was a straightforward enough example to have it make more sense.

But, the coolest thing I learned was just a small tidbit about perspective transforms. The tutorial has you rotate views in and out of view. It turns out that with a simple numeric constant, you can make those rotations look MUCH more realistic.

The trick is referred to here in the Apple Docs: Advanced Animation Tricks

Simply, you sent the layer.sublayerTransform 3DTransform of a parent view to have the m34 field of CATransform3D set to a relatively small negative number (it can be positive too, which appears to change the direction of a rotation). Then, when views contained inside of this container are rotated around the Y axis, they appear to recede into the distance as they spin. This is more realistic than if you didn’t set this field, because then the rotation looks more like a squeeze and expand rather than a true rotation. The value for the m34 field is a bit magical, with the tutorial using -0.002. This represents the inverse of the distance along the Z axis for the viewer, and 0.002 is about 500 pixels. Values in the range 0.001 to 0.004 seem too look fine, with larger values giving a more pronounced size change as the views spin around.

Another interesting fact about the transform is that it is applied to the container view of the views involved in the view controller transition. This container view appears to be created by UIKit to server as a safe place to mess around with transitioning from one view to another. So, each time you perform the transition, you want to reapply the perspective transform to the container view, since it disappears once the presentation/dismissal of the view controller finishes. Interestingly, it sticks around after a new view controller is presented, and only disappears once the presented view controller is dismissed. So, you are applying a transform to a view that already has one, but since this isn’t additive, it is not a problem.

So perspective transforms are neat things to know about it you want to make your y-axis rotations (and presumably x-axis too - I tried to do an x-axis rotation, but the newly presented view kept jumping in from of the existing view before the rotation had completed. But the rotation looked a lot nicer with the perspective enabled).

I may try to take this transitioning to the next level, and see how custom transitions inside of navigation and tab bar controllers can be implemented.

Happy rotating!

So... I Wrote an AppleTV app (and then another)

In what was certainly a record for me, I really did finish and release the app I mentioned in my last post!

tvOS Small Icon Combined
Dolphin Patrol — Get it on the App Store today - it’s free!

I was one of the lucky ones who got an AppleTV developer unit, and for the first time, wanted to be in the App Store on Day One. My development environment consisted of a cheap HDMI monitor that replaced my normal second monitor, hooked up to the AppleTV. I had quickly realized that if I wanted to use the GameController-based APIs, the simulator just wasn’t going to cut it. Overall, I think using the external monitor has worked out well. Only a few times during development did I unplug it from my smaller monitor and hook it up to the family TV. This was worth doing to make sure the game elements were sized appropriately and to be sure I wasn’t letting anything get cut off from the overscan areas, which were different between the TV and monitor.

What Worked

  • Dolphin Patrol was written in 100% Swift 2.0. There was definitely a learning curve associated with this, and more time looking up Swift goodies in the iBooks, Stack Overflow, GitHub, and ericasadun.com. But overall, I believe it ended up saving me time, and I really love writing in Swift. I have been following Swift since it came out, and have written a few sample projects (and a great tutorial from Apple too), but this was the first time committing to it for the entire app. I didn’t use a lot of low-level C APIs, which I think helped.
  • DemoBots. Apple’s sample code was a life saver. I used it to come up with an entirely SpriteKit based solution (at least at first). DemoBots is a beast of a sample app, but it had all of the goodness I needed in there to learn how to use the GameController API. Since from the beginning I knew I wanted to support multiplayer, learning GameController was a requirement.
  • This silly little game controller I had picked up months ago from Meh. My thought at the time was to use it to play iOS games that supported Game Controllers (I never really found one), but it was invaluable for multiplayer and compatibility testing.
  • XCode + Swift was relatively stable. My biggest issue was sometimes a build wouldn’t go across to the AppleTV to run, but just building it again (?) seemed to push it along.
  • Thanks to some enterprising developers on Apple’s developer’s forums, we got a nice little group of testers together to help test each other’s AppleTV apps prior to launch. It wasn’t a lot of time, but it was valuable, particularly since the Apple Developer Forums were just about the only place you could discuss AppleTV development prior to launch.
  • Physics is fun. Some of the most fun I had developing the app involved tweaking the PhysicsWorld constants in the game. Springs can get pretty crazy.
  • Six weeks from start to finish. Completely a new record for me. The motivation of a Day One launch was a huge factor.

What Didn’t

  • Testing a multiplayer game is hard. If you are a solo indie developer, make sure you have some willing family members who will help you test your game. I generally lost to my kids when we played against each other. Playing with a Siri Remote in one hand and a game controller in the other was just about impossible.
  • Entering passwords and email addresses on a newly installed AppleTV is a pain. I wish this process had been easier, particularly since each new beta of tvOS required a clean install.
  • TestFlight was great to have, but came really too late to be a huge help on Day 1.
  • I didn’t end up doing EVERYTHING in SpriteKit. I eventually figured out how to mix and match SpriteKit-based scenes with more traditional UIViewController-based screens. This game me the best of both worlds.
  • Art is hard. The theme of my game was mostly determined by where I could get reasonably priced artwork. I then supplemented with my own meager-but-growing Sketch and Affinity Designer skills. I wish I had spent more time on the icon - the next version will improve that, since the icon is really the only way an App Store user may see your app, during a search.
  • App Store discovery - this has been discussed endlessly already in the developer community, but still, pretty disappointing to be there on Day One and have no way for people to find your app.
  • Charging for the app. I went free after about a week. (I feel like I’m in good company.) Downloads increased accordingly. I didn’t understand how promo codes worked for AppleTV, and initially thought they weren’t supported. However, I now think that you can give them out and redeem them on the iOS app store, and the app will just show up on your AppleTV app store. I have yet to verify this, though. I might have lasted longer as a paid app if I could have given away promo codes - I still would not have made money, but there was at least the chance.

The Future

  • I’m still adding features to Dolphin Patrol. One of the most important is an iOS client app that will act as a bluetooth game controller for multiplayer. I have the bluetooth code up and running, but it will take a bit of work to make the gameplay feel natural. Bluetooth programming is a bit of a pain. I think that apps that are either universal (not currently in my plans) or are at least visible on the iOS app store have a better chance of being discovered.
  • While I was blocked a bit contemplating how to add Game Center Achievements to Dolphin Patrol, I tried my hand at writing another app. I felt like I was on a roll, and my Swift learning curve has ramped up nicely. So, after about 3 days, I have another app sitting in the review queue on iTunesConnect. Not a game, and completely different from my last app, but I really enjoyed writing it and seeing how quickly something could come together. Announcement will be here if it gets approved! Writing AppleTV apps is quite fun, and kind of addictive. I’ve got two more ideas in mind, but also have a set of Mac and iOS apps that have been neglected for far too long. (AlphaBaby, BabyProof, AlphaTalk, and Tapscape, for the curious!)


Shrinking Swift Arrays

I’m really moving ahead with a new project (for tvOS!) and writing it entirely in Swift. On basically the second day of coding, I was really missing some NSArray/NSMutableArray functions from Swift Arrays, and after way more StackOverflow/Google time than it should have taken, here’s a version of removeObject that seems to compile:


Note also that the indexOfObject method on NSArray is replaced by the native indexOf method, so no need really to reimplement that.

Enjoy!

Code Spelunking - DGRunkeeperSwitch

This post is the first of what I hope will be many that takes a piece of software that has been released publicly (usually on github) and looks at the code to learn more about it. I always learn a lot by reading other people’s code, and thought it would be fun to take various controls, apps, etc. and break them apart and point out what I find interesting about them.

The first control I’m choosing is the DGRunkeeperSwitch by Danil Gontovnik. I learned about it from a maniacdev email this morning, and I was immediately drawn in by the smooth animation and clean lines of the control. I use Runkeeper (less regularly than I used to due to the Apple Watch), but hadn’t noticed the control until I went looking for it. It is mainly used on screens other than the “Start” tab, which is where I spend most of my time. But, I don’t love the look of the standard segmented control and switch on iOS, so the more stylish look of this control is appealing.

First thing to consider when looking at this control is that it is written using Swift 2.0, so fire up the code in the latest XCode beta. It comes with a small sample app, which is a nice touch (and typical for most controls shared on github, I’ve found).

DGRunKeeperSwitch is a subclass of UIControl.

Swift notes
  • Liberal use of tuples for assignment. Increases compactness of the code.
  • Reasonable defaults for configurable aspects of the control, using defaults for variables on the control
  • Uses the deinit method to remove itself as an observer. So nice to have a well-defined place to do this!

General coding notes
  • Changes the underlying layer class of a few views in two different ways. The first, expected, way is by returning a custom class from the class-level layerClass() method. When your own class wants to change its layer, this works. If you want to change the layer class for a standard view, such as UIView, then you can use the Objective-C runtime method object_setClass to change the underlying class object. This new class object updates the cornerRadius of the view based on the height of the bounds. This is done in one list as a Swift didSet on the frame property of the CALayer. (I would almost count that as a clever Swift trick, since something like this is so much simpler to do in Swift than Objective-c). Also, can you really call it the Objective-C runtime when writing in Swift? I suppose just “runtime” is more appropriate now.
  • The clever thing about this control is watching the color of the text labels change as you swipe the selected “bubble” from one item to the other. This is done by having two copies of each label, stacked on top of each other. They are in contrasting colors to their background. There is a background view between these two sets of labels, which contains the selection highlight. A mask is then applied to the view containing the “selected” labels (the top set of labels), such that the selected title views under the current selection background are visible, and the ones outside the bounds of the selection view are masked out.
  • Both tap and pan gestures are supported. UIView dynamics are used for a nice springy animation when switching between choices. Snapping behavior kicks in if you pan only partway.
  • layoutSubviews() handles positioning the selected rectangle above the selected item (essentially either on the right or left side of the control). If the labels are too long to fit in the specified size of the control, the label spills over its background, which doesn’t look great. Truncating the labels to fit would be better than letting them flow over the bounds of the control. This could be done by just pinning the size of each label to the maximum allowed size.
  • The frame of the selection view and the frame of the mask view are tied together using KVO on the frame property of the selection background view. I’m not sure this is worth it, as you could easily set both frames at the same time, instead of decoupling this. Overall, it is less code to just assign the mask in the two places where it changes, although I can understand the desire to tie the two values together with KVO so that you don’t have to worry how many times the selection view is changed - it will always update the mask when its frame changes. Definitely a design choice, and one that I think could go either way.

Side Trip

I was getting an unexpected error message when running the sample app, that was due to the UIViewControllerBasedStatusBarAppearance key being specified in the Info.plist file. This key had been set to NO to allow the view controller to set the color of the text in the status bar explicitly, using the call UIApplication.sharedApplication().statusBarStyle = .LightContent. Without the entry in the plist file, it doesn’t appear that this call actually changes the status bar color. The warning may just be an artifact of a beta release, but it bothered me. The way to fix this was to remove the key from the Info.plist file, and have the root view controller manage its own status bar style. However, the root view controller is actually a UINavigationController, and it does not, by default, defer to its top view controller for its status bar style, even though that would seem to be the obvious way to handle things. You can fix this in an extension to UINavigationController, which either overrides preferredStatusBarStyle() to return the custom status bar style, or in a more general way, override childViewControllerForStatusBarStyle() to return the topViewController, which then implements prefferedStatusBarStyle() itself. This seems like the more general option, and puts the responsibility to set the status bar color in the hands of the view controller that is presenting the rest of the UI, where presumably we are attempting to match an existing UI to the status bar color. One last Swift gush - it is so easy just to add a quick extension to a system class such as UINavigationController.

I didn’t think I would explore the world of status bar style overrides and system class extensions, but you never know what you’ll learn when you dive into a new piece of code!

Possibilities

It would be interesting to see this control support @IBDesignable/@IBInspectable so that it could be configured in IB. It also could be extended to support more than two choices, making it an alternative to UISegmentedControl in addition to UISwitch.

Conclusion

Overall, a lovely little control with clearly written code that takes advantage of some nice Swift language features to implement things in a clean, streamlined way.

Cavewoman Debugging: Episode 5

Episode 5 of Cavewoman Debugging talks about common design patterns in Cocoa development.

Also, I start to find my groove for the podcast. I have been thinking a lot about the audience for the podcast, and listening to this episode of NSBrief helped my thinking. I would like this to be another resource used by people either new to programming, or new to iOS programming. If you are not someone who is seen as the “typical developer”, even better — programming is great fun and I would like to see even more people give it a try!

Show notes.

Listen now.

Leave a review at the iTunes store!

Spread the word about the podcast - I’d love more listeners and feedback (email cavewoman@littlepotatosoftware.com or DM on Twitter @littlepotatosw)

Cavewoman Debugging: Episode 4

Episode 4 of Cavewoman Debugging talks about ways to tackle thorny programming tasks. Quick and dirty throwaway projects are your friend! Plus, I’m still playing SongPop. Challenge me at ne.ribbon!

Show Notes

Listen Now

Cavewoman Debugging: Episode 3

After a longer delay than I intended (thanks spring break and Mother’s Day!), here’s episode 3 of Cavewoman Debugging, where I explore the wonderful world of Xcode plugins.

Listen Now

Cavewoman Debugging: Episode 2

Episode 2 of my podcast is now available. I discuss third party code and using CocoaPods. Check it out!

Cavewoman Debugging: Episode 1

I have a new feed for my iOS developer podcast, “Cavewoman Debugging”. Check it out!

Pods checkin imminent

I just finished listening to the iPhreaks podcast, episode 97 - “Deconstructing Your Codebase with Michele Titolo”. I enjoyed the entire discussion, and especially hearing a fellow woman developer discussing the nitty gritty of managing your code base. As an independent developer, not all of the conversations were relevant. But, as I find that I work on projects over very long spans of time (approaching years for some of my earlier app releases), it’s practically as if I’m looking at someone else’s code base at times. Most of the time, this comes in the form of “what was I thinking when I wrote this?!?”. :)

However, one point that they touched on was whether or not to check your CocoaPods into revision control. I hadn’t been, but this conversation convinced me that it would be a good idea. Since I’m just running a local git repository, space or checkin times are not really an issue. And, since I’m about to release a new product, having a stable version of ALL code, not just my code, checked in and labeled for the release strikes me as a really good idea. I just recently got burned by an update to CocoaLumberjack that messed up my debugging statements, so I think having my CocoaPods checked in to my own repository will allow me to better monitor what has changed when pods are updated. I solved the CocoaLumberjack with some digging on GitHub, but it was definitely a lesson to be careful about doing random “pod update” calls, especially when you are getting close to a release.

Plus now, when I do a commit in XCode, I won’t see all those annoying ?’s showing up in my commit window. Thank you Michele, for giving me the confidence and push I needed to finally do something about my pods!

Swift By Osmosis

My current project is coming to an end, but has been written in Objective-C. So, I’ve been keeping an eye on Swift, but haven’t really had a chance to jump feet-first into Swift development. I read the original docs when they came out, but haven’t been staying on top the language changes. I’ll probably need to re-read them once I’m ready for a full project in Swift.

If you’re in the same boat, and are looking for some easy ways to learn about Swift on the side, here are few things I’ve come across which I’ve found very helpful:

  • iTunes U - Developing iOS8 Apps With Swift. These Stanford classes are amazing. I enjoyed previous years greatly. Although it starts at a very basic level, it’s great thing to watch while on the treadmill or doing dishes. I always end up picking up a few tips and tricks, either in the API, language, or Xcode by watching these classes. Highly recommended.
  • Swift Cheat Sheet from App Design Vault. I have been signed up for the newsletter from App Design Vault for a while. They have some great free resources, app templates, and tutorials available. A recent newsletter offered this guide to transitioning to Swift. I like that it’s a more manageable size than the hundreds of pages from Apple!
  • You can’t go wrong with anything at raywenderlich.com. I like to pick a tutorial I’ve done before, or a simple one just to see how things I knew how to do before are now done in Swift.
  • Keep an eye out for random small projects/demos that are written in Swift, and follow along. This past week, I’ve been looking at Think & Build’s recreation of the Twitter iOS App UI. I get to learn some cool animation techniques, plus get used to doing it all in Swift.

Have fun learning Swift!

In the beginning...

I’m taking a Swift break today and getting my feet wet with a few sample apps. Even though I’ve read the whole Swift book and watched a fair number of the WWDC Swift videos, playing around with “real” apps is the only way I’ll start to get a handle on what Swift really is like. Plus, when you are feeling frustrated with your current project (I’m looking at you - annoying GameCenter bugs!), trying out a shiny new language is just the ticket.

In my typical dive-way-too-deep approach, I got curious about how Swift apps get started. I found some answers at StackOverflow, but thought I’d summarize my findings here, if only to remind myself of them in the future!

App startup is a bit different between iOS and Mac apps. In both cases, some form of the function UIApplicationMain gets called. In the case of Mac apps, there is still a main.swift file that is created as part of a default Swift project template. Like main.c before it, main.swift appears to exist solely to call NSApplicationMain. NSApplicationMain is responsible for loading up the initial nib file. This nib file is listed in the Info.plist file, under the NSMainNibFile key. The default nib file that is created for you takes care of the rest. There is an object declared in the nib which implements the NSApplicationDelegate protocol. It is also linked to the file owner (NSApplication in this case) so that the main application object’s delegate property points to your AppDelegate object. And so all is good and the your application delegate gets registered with the main application object, and the app proceeds normally.

For an iOS app created with one of the default XCode templates, it is a little bit different. First, there is no main.swift. The Supporting Files folder is a bit empty and lonely with just Info.plist hanging out there. But, there is an automatically created AppDelegate.swift file, just like in an Objective-C project. At first, I missed the magic bit of code which makes this all work. Also, I was thinking that for many simple iOS apps, you wouldn’t even really NEED an application delegate. If you were explaining to a first-time iOS programmer why that class even existed, it would be “well, just ignore it for now”. But, turns out that you can’t just ignore application delegates. The Apple docs state that “Every app must have an app delegate object to respond to app-related messages.” But then again, every single method of the UIApplicationDelegate protocol is optional, so even though it has to exist, it doesn’t need to actually do anything.

The equivalent function to NSApplicationMain on MacOS is UIApplicationMain on iOS. It takes two additional arguments, which are not present on the Mac version - the name of the UIApplication subclass name (if one exists - otherwise it assumes you just want to use UIApplication. It also takes the name of the UIApplication delegate class name. In Objective-C based projects, Xcode would just fill this in with the name of the AppDelegate class it created for you. However, since this file and explicit call to UIApplicationMain are now gone in Swift, how does it find your application delegate?

The secret lies in a special type attribute associated with your application delegate class. Just before the declaration of that class, you will see the @UIApplicationMain attribute specified. If you remove it, then your app fails to compile because it is missing a main entry point. If you remove the class declaration, but leave the attribute, you get a compiler error since the attribute needs to be associated with a class. If you change your delegate class to not conform to the UIApplicationDelegate protocol, you’ll also get an error, telling you that the @UIApplicationMain class must implement that protocol. So, this attribute is special and needs to be associated with an application delegate.

So in the case of Swift apps, the application delegate is also the means by which the initial entry-point into the app is created.

Thank you to this StackOverflow thread, which pointed me in the right direction!

This thread discusses creating your own entry point to NSApplication by creating a main.swift file, removing the @UIApplicationMain attribute and calling UIApplicationMain yourself, passing in a custom subclass of UIApplication. This brings things back closer to the way they used to work in Objective-C. Doing it the new Swift way saves you creating the main.swift file, at least. If you include the main.swift file in your project, even if it doesn’t have any code in it, the compiler will yell at you and make you choose between using main.swift and the @UIApplicationMain attribute. When specifying the name of the delegate class, the example code from SO used “NSStringFromClass(AppDelegate)”. However, you could also pass in “AppName.AppDelegateClassName” instead -- a good reminder that all classes now exist in a namespace based on the app name.

I don’t think this is anything I’ll have to think about in the future, but I like knowing how the flow of the application works (“It just starts up magically” isn’t as satisfying an answer...)

Evolution of Levels

During my extended absence from blogging, I have been hard at work (well, mostly hard at work!) on a new iOS app. It started off as a fun exercise, and has turned into a game. One of the areas of the game I’ve reworked multiple times is the method of providing game level data. The game didn’t even really have levels, but as I played it and tested it, and played other iOS games, adding progressive levels felt like the right way to go. At first, the levels were completely hardcoded into an array of C structures. This worked to get things started. Then, I decided that being completely generated was the way to go. I wrote and entire level generator, although it had rules and parameters so each level wasn’t completely random. It worked nicely, but didn’t seem all that great for challenges between players, or replaying to improve your score. So, jumping onto the JSON train, I next specified the each level format in a JSON-based file, which I loaded at startup. This was a very pleasant format to write (much better than plists)(you can only click on those little tiny + and - icons in Xcode’s plist editor so many times before going crazy), and gave me a certain amount of flexibility. However, it just felt so heavy... all those arrays of strings. I don’t think it was a huge performance problem, but I just felt like it was heavier than I needed. So, back to C structures. But this time, just a small change in how I formatted the default entries in the header file (comments and putting each field on its own line ) made it feel like JSON, but I got back my beloved bitfields and integer-based efficiencies. One area that had pushed me toward JSON was the need to specify some help text per level. Putting ObjC strings into C structures is not really doable, but I came up with a workaround. The strings I needed for each level were written with each structure, but commented out and included an easily grep-able tag. One quick build phase where I ran some grep/sed magic over my header file and generated a .strings file, and I was in business. A great bonus is that some day I could localize the app more easily. Plus, one quick memcpy of the pre-initialized structure into heap-allocated memory meant I could have the best of both worlds -- some values computed at runtime and most values set up ahead of time in a easy-to-read and modify header file. Having things in C also makes it possible to do some debug-only startup validation of the data that would be more difficult to do in a JSON/Dictionary based solution.

Something that seemed like it should be straightforward has certainly taken me a while to figure out. This might not even be the final iteration. But, I’ve coded up the first 10 levels of the game using the new structure (and due to some good factoring in my code, the changes to support an entirely new level format were mostly hidden in one class), and it feels pretty good. One of the reasons I hadn’t finished specifying all of the levels in the game (I’d like to release with 50 levels to start), had been partly due to the cumbersome nature of adding new levels. I’m hoping that the next 40 levels go as easily as the first 10 went.

Good luck designing your own apps! Don’t be afraid to iterate and throw out something that doesn’t feel like it’s working for you. It might have cost me a few hours to rework this code, but if it means I am able to move forward in completing a part of the app that had been annoying me, then it was most definitely time well spent.

Global variables vs method calls

During my rewrite of Mac AlphaBaby, I’ve been trying to do things the “right way”. That has meant a lot of restructuring of code, trying to reuse classes where possible, and general consolidation. I’ve learned a lot since I first started writing Mac AlphaBaby back in 2003 and I want to bring the code base up to more modern standards.

One of the things I’ve often wondered about in Objective-C is the cost for doing things the “right” way. Every time I make 3 method calls (at least!) for something that might have been a single structure access or global variable access in a C program of yesteryear, I cringe a bit. I know that computers have gotten so much faster that it doesn’t really matter how many virtual or dynamic method calls I’m making for something that isn’t in a speed critical path. However, the part of me that learned C and debugged embedded programs in assembly to optimize for speed still didn’t feel great about all that extravagant method calling.

The current case in question is when creating a string whose value needs to be created a runtime, but then is constant after that, is better off being accessed via a global variable or by some kind of method call on a class. Here’s my test class, with all different ways to access a string:

// Globaler.h#import extern NSString *globalString;@interface Globaler : NSObject{ NSString *myInstanceString; NSString *propertyString;}@property (nonatomic, retain) NSString *propertyString;+ (NSString *)staticString;+ (Globaler *)sharedGlobaler;- (NSString *)instanceString;@end
static NSString *myStaticString;NSString *globalString;@implementation Globaler@synthesize propertyString;+ (void)initialize{ myStaticString = [NSString stringWithFormat:@"Hello %@ world", @"static"]; [myStaticString retain]; globalString = [NSString stringWithFormat:@"Hello %@ world", @"global"]; [globalString retain];}+ (NSString *)staticString{ return myStaticString;}+ (Globaler *)sharedGlobaler{ static Globaler *theGlobaler = nil; if (theGlobaler == nil) { theGlobaler = [[Globaler alloc] init]; } return theGlobaler;}- (NSString *)instanceString{ return myInstanceString;}- (id)init{ self = [super init]; if (self != nil) { myInstanceString = [NSString stringWithFormat:@"Hello %@ world", @"instance"]; [myInstanceString retain]; self.propertyString = [NSString stringWithFormat:@"Hello %@ world", @"property"]; } return self;}@end
And here’s the code which accesses the strings in different ways:

NSString *refString = @"reference string";- (void)dealloc{ [super dealloc];}#define NUM_ITERS 100000000- (BOOL)doStuffWithString:(NSString *)str{ if (str == refString) { return YES; } return NO;}- (void)applicationDidFinishLaunching:(NSNotification *)aNotification{ // Insert code here to initialize your application NSString *str; Globaler *g; NSTimeInterval tStart, tEnd; int i; g = [Globaler sharedGlobaler]; tStart = [NSDate timeIntervalSinceReferenceDate]; for (i = 0; i < NUM_ITERS; i++) { str = globalString; if ([self doStuffWithString:str]) { break; } } tEnd = [NSDate timeIntervalSinceReferenceDate]; NSLog(@"global variable time: %f: %f", tEnd - tStart, ((tEnd - tStart) / (NUM_ITERS * 1.0) * 1000.0)); tStart = [NSDate timeIntervalSinceReferenceDate]; for (i = 0; i < NUM_ITERS; i++) { str = [Globaler staticString]; if ([self doStuffWithString:str]) { break; } } tEnd = [NSDate timeIntervalSinceReferenceDate]; NSLog(@"static variable time: %f", tEnd - tStart); tStart = [NSDate timeIntervalSinceReferenceDate]; for (i = 0; i < NUM_ITERS; i++) { str = [g instanceString]; if ([self doStuffWithString:str]) { break; } } tEnd = [NSDate timeIntervalSinceReferenceDate]; NSLog(@"instance variable time: %f", tEnd - tStart); tStart = [NSDate timeIntervalSinceReferenceDate]; for (i = 0; i < NUM_ITERS; i++) { str = g.propertyString; if ([self doStuffWithString:str]) { break; } } tEnd = [NSDate timeIntervalSinceReferenceDate]; NSLog(@"property variable time: %f", tEnd - tStart); tStart = [NSDate timeIntervalSinceReferenceDate]; for (i = 0; i < NUM_ITERS; i++) { str = [Globaler sharedGlobaler].propertyString; if ([self doStuffWithString:str]) { break; } } tEnd = [NSDate timeIntervalSinceReferenceDate]; NSLog(@"shared property variable time: %f", tEnd - tStart);}
What did I find? About what I expected to find. The raw global variable access is the fastest, and it pretty much gets slower as you go on down the line. But, calling a static function which returns a pre-computed static variable came in second. This has some advantages: a relatively small amount of characters to type, you can initialize the static string in the +(void)initialize method, so it only gets created when needed, and it can be put into a more general utility-type class, which lets you group such variables into named collections (named by the class they are in). Here are the timing results:

global variable time: 0.695643static variable time: 1.075534instance variable time: 1.268580property variable time: 1.128956shared property variable time: 1.496929
The most expensive way to call - using a static method to get a global shared object, whose property we then access, is about twice as slow as the raw global variable. But, the static variable is at least a little closer, and seems just as clean. Bottom line, I had to bump up the iteration count pretty high to even get these numbers (measured in seconds), so all of this stuff is just ridiculously fast, and I probably don’t have to worry about it. But, the low-level tech geek person in me just wanted to know, and it will help me make some design choices (and avoid bad ones for the sake of nonexistent performance concerns).

Error debugging on older iPhone

I decided to use my old iPhone 3G to do some debugging today. However, when I tried to download my app to the device, I got the cryptic error:

Error launching remote program: security policy error.

A relaunch of both the device and XCode failed to clear it up. However, a quick Google search revealed the problem. I had expired profiles on the device (along with their unexpired replacements). Apparently just having the expired profiles on the device was enough to confuse XCode and prevent it from launching the app.

I’m documenting this to myself more as a reminder that if I don’t use a device for testing for a while, looking for expired profiles should be my first step if debugging isn’t working.

Now if only I didn’t have references to iOS 4.0 APIs in my code, perhaps I’d be running on my iOS 3.0-based 3G without any problems!
© 2010-2016 Little Potato Software   Follow littlepotatosw on Twitter        Site Map     Privacy Policy     Contact Me