Passwords are the worst way to authenticate users, except for all the other ways we’ve tried. In their 2018 software updates, Apple embraces the status quo by providing their users with new defaults aimed at safety and convenience.
Passwords are the worst way to authenticate users, except for all the other ways we’ve tried. In their 2018 software updates, Apple embraces the status quo by providing their users with new defaults aimed at safety and convenience.
The eyes of the world are on San Jose as thousands of developers, including half a dozen nerds, gathered for Apple’s annual World Wide Developer Conference. This year’s announcements did not feature any hardware updates but there were several software updates that you will want to keep your eye on. Let’s take a quick look at a few updates your engineering team will want to be aware of in the months ahead for Siri, CoreML, ARKit, and Swift. Finally, let’s also take a glance at a major opportunity in 2019 for bringing your iOS App to macOS with a few musings from yours truly.
At WWDC 2018, Apple continued to push the envelope with ARKit by releasing ARKit 2. Late in 2017, Apple released ARKit 1, which allowed users to place 3D objects in the real world. This technology was showcased by companies like Ikea who allowed users to try out furniture in their homes. A few months later, Apple released ARKit 1.5. This release gave users the ability to detect not only horizontal planes like the floor of their homes, but also their walls. In addition to vertical plane detection, Apple added Image Recognition, which allowed users to detect images and paintings just by pointing their phones at them. At WWDC 2018, Apple introduced enhancements to face tracking, as well as the following new features: saving and loading maps, environmental texturing, image tracking, and object detection.
WWDC 2018 began this week in San José, CA, with the usual excitement of thousands of developers from all over the world that could not wait to learn what new shiny objects Apple would unveil for them. The expectant developer community was not disappointed. Even though the announcements were largely evolutionary and no new hardware of any kind was unveiled, the enhancements to all four platforms (iOS, macOS, watchOS, tvOS) and the development tools were many, and hint at big things to come.
Core Graphics, also known by its marketing name “Quartz,” is one of the oldest graphics-related APIs on the platforms. Quartz forms the foundation of most things 2-D. Want to draw shapes, fill them with gradients and give them shadows? That’s Core Graphics. Compositing images on the screen? Those go through Core Graphics. Creating a PDF? Core Graphics again.
Learn how to be more proficient with Swift by using the Compiler. Big Nerd Ranch shares lessons learned from nerdcamp.
Take a deep dive into the internals of iOS frameworks and learn how to best use (and not use) frameworks for cleaner, faster code and debugging.
Big Nerd Ranch’s newest offering is officially live. The Frontier is a screencast series built to advance your iOS or Android skills with expert instructors, on your time and at your pace. I’ll share a little bit more on why we created The Frontier.
One thing that sets Big Nerd Ranch instructors apart is we consider ourselves students first. That’s definitely the case with Kristin Marsicano, whose passion for learning and asking questions has solidified her as an Android expert in a few short years. Her advice to all her fellow programmers out there might surprise you.
Big Nerd Ranch was founded on the idea that developers learn best when immersed in a distraction-free environment. Today I want to talk to you about a new path to advance your skills; one that doesn’t look like anything we’ve offered before.
Siri is Apple’s intelligent personal assistant. Siri allows you to use your voice to interact with your iOS, watchOS, tvOS, and macOS devices. This series explores SiriKit and how you can use it to expose your app’s functionality through Siri. Part 4 shows how to enhance and brand your app’s Siri experience by adding a custom UI.
Siri is Apple’s intelligent personal assistant. Siri allows you to use your voice to interact with your iOS, watchOS, tvOS and macOS devices. This series explores SiriKit and how you can use it to expose your app’s functionality through Siri. Part 3 continues the exploration, focusing on those final details needed to ship your Siri-enabled iOS app.
On iOS projects, we often find ourselves using command-line tools for testing and distributing our apps. More often than not, these tools were written in Ruby. In this post, we will give you a solid understanding of each step in the Ruby toolchain so you can confidently set up a consistent environment for your development team.
Siri is Apple’s intelligent personal assistant. Siri allows you to use your voice to interact with your iOS, watchOS, tvOS and macOS devices. This series explores SiriKit and how you can use it to expose your app’s functionality through Siri. Part 2 explains the heart of SiriKit: Resolve, Confirm and Handle.
Siri is Apple’s intelligent personal assistant. Siri allows you to use your voice to interact with your iOS, watchOS, tvOS, and macOS devices. This series explores SiriKit and how you can use it to expose your app’s functionality through Siri. Part 1 explains the basics of SiriKit and how to add it to your iOS app.
The unveiling of the iPhone X has confirmed the existence of the top “notch” or sensor housing. While this seems purely aesthetic, there are a few things to consider when designing around this sensor housing in both portrait and left/right landscape orientations.
One of Apple’s showcase features is the new Files app, which allows users to manage files stored locally and in iCloud. In this post, we learn how your app can take advantage of this cool new feature.
Apple’s new iPhone X changes the landscape (pun intended) for iOS developers. There are things you need to do to ensure your app continues to look stunning on iPhone X display. Discover what you need to do to get your app updated.
Develop more intuitive and creative tvOS apps by adding animation and custom focus behaviors. This tutorial walks you through controlling focus between a split view controller and animating the custom collection view layout from part 1.
Swift protocols can have associated types, which makes them more powerful than Objective-C protocols. It also makes them more complicated. In this post, learn how Swift protocols balance power and complexity. See an example of code that uses a protocol with associated type, then understand why it has to be generic.
WWDC 2017’s Design for Everyone challenges developers to work for all our users. This post will teach you to rise to the challenge through concrete examples of accessible design. The examples I list are iOS-specific, but the ideas aren’t—developers across all platforms should keep accessibility in mind.
Year after year, Apple rolls out platform features that greatly improve usability when they’re used correctly. Unfortunately, many apps that have been around for awhile still don’t take advantage of these features. With the release of iOS 11 on the horizon, now is the perfect time to start incorporating them. To help you along, I’ve listed out some under-used features and reasons why your users will thank you for using them in your app.
In Part 4 of our series on tvOS game development, we add the important stuff: Bullets! Explosions! Death! Carnage! We’ll discover how to create a bullet and then detect when it hits something.
At Big Nerd Ranch, our iOS team has created a library called Deferred to help you work with values that have not yet been determined. Here’s how to use it to your advantage and incorporate it into your apps.
Last time, we talked about 10 Tips for Mastering the Focus Engine on tvOS, and this time we’re diving into a new API that comes with tvOS 11. Included in the tvOS 11 changes is a new property on UIImageView that we can use to extend the motion effect to more than just the image itself.
The tvOS focus engine and collection views can bring a robust and interactive control to the television screen, but to design any layout that is non-linear, you will need to create a custom layout. In this post, we’ll create a custom control for a tvOS app to show how to create a custom layout in the shape of a circle.
With iOS 11 and Android O launching later this year, you may be curious as to whether or not you should spend the money updating your apps. The answer is a resounding yes. Here’s why.
In Part 3 of our series on tvOS game development, we add some animations to our sprites. Learn how to customize your own characters by using Aseprite and then make them move.
Recent versions of iOS have reimagined the design for several of Apple’s platform apps, with big titles, rounded card-like UI and filled buttons. Apple pushes these changes even further in iOS 11 by making them the norm for the platform, which means that it is time to reevaluate your apps to ensure that they conform with the new design language.
Core ML is an exciting new framework that makes running various machine learning and statistical models on macOS and iOS feel natively supported. In this tutorial, learn to create a linear regression model in Python and convert it to a format that Core ML understands.
mobbed.io recently chose Big Nerd Ranch as a top company on its “20 Best iOS Development Companies in the World” list.
Once again, Apple is bringing to the table some new image and video formats to push the platform forward by saving you storage space, bandwidth and computation time. Here’s the short version.
One of the objections to the iPad becoming a mainstream productivity device is the lack of seamless interplay between apps. With the addition of drag and drop, Apple has once again pushed the iPad forward as a strong contender in the productivity space.
iOS 11 added a property to
UINavigationItem that can enable a large out-of-line title in the navigation bar. Here’s how to take advantage of it.
At this year’s Worldwide Developers Conference (WWDC), we saw the continued evolution of Apple’s offerings. Pundits may say these changes aren’t revolutionary enough, but we’re excited about a number of refinements.
The correct answer to “throws or Result?” is a loud BOTH! Learn to make the best of these tools to write clear, maintainable a/sync code through a worked example.
In Part 2 of our series on tvOS game development, we begin laying out our game. In this instance, we’ve created a clone of the 1981 Willams arcade classic Robotron: 2084.
If you want to write a game for tvOS, it starts with understanding what the controllers can do for you. In the first of a five-part series, Steve Sparks takes you through the Game Controller framework.
Making your apps accessibile is hard work, especially when dealing with Accessibility Traits. Discover a straightforward way of handling it, and then another more creative solution to make it more Swifty.
Technology should be accessible to everyone. Apple has worked hard to make it easier to support Accessibility. Here’s some tips on how to support it.
Applications that run on the Apple TV present an entirely new method of interaction compared to mobile and desktop applications. Instead of directly interacting with the device, a user uses the remote to indirectly control it.
In my last post, you learned how the compiler compiles the source files. This time around, you’ll see how everything is pulled together.
Manual Swift: Understanding the Swift/Objective-C Build Pipeline walked you through the high-level view of how Objective-C gets access to Swift code. Today, we’re going to see what that looks like in practice by examining Xcode build logs.
In Core Graphics, a path is a step-by-step description of some kind of shape. It could be a circle, a square, a valentine heart, a word frequency histogram or maybe a happy face.
If current trends continue, most babies born today will never own a laptop or a desktop computer. They will carry a smart phone, and at home they will have a streaming device connected to their TV. That streaming device will run apps. And that leads us to why your company needs a tvOS app.
The first point of the Swift API Design Guidelines is that “clarity at the point of use is your most important goal.” What does it look like to put that goal into practice? I found an answer recently while writing some integration tests. My test code started out difficult to follow, but by working on its clarity one step at a time, I ended up with an API I love. Let’s take a look at the process I went through to see what it looks like to improve the clarity of your code.
It’s hard monetizing your apps, and as much as Apple has done to make in-app purchasing (aka IAP) easy, it’s still not easy. The code is the easy part. There are a bunch of things to get straight before we even get to the code. Today we’re going to walk through the process from start to finish.
As a fan of strongly typed programming languages, I love relying on the type system to catch common mistakes and typos early. Occasionally though we want to relax the strict rules to gain the payoff of flexibility over safety. Just like you use a rubber eraser to remove written material, we can use a concept known as Type Erasure to remove type information from our programs.
Swift on the server is an exciting application of the language. In this post, we’ll take a look at a popular framework to get a flavor for Swift web development.
Every build pipeline is an opportunity for leaks and stoppages. Understanding how all the bits come together to make a functioning app helps you to plumb your way through these problems. So… How exactly does Swift and Obj-C all turn into one app?
Is it possible to ask a question that leads you directly to fixing a bug? If so, how do you find those questions to ask them?
Swift style encourages developers to use the compiler to their advantage, and one of the ways to accomplish this is to leverage the type system. In many cases, doing so can feel fairly obvious, but working with
UIKit can be challenging since it often hands you
String instances to identify view controllers, storyboards and so on. We have received some guidance on this issue in the form of a WWDC session in 2015, but it’s a good idea to revisit the problem to continue our practice of thinking Swiftly.
I took a week-long hacking vacation (“hackcation”?) to start an iOS app side project. I learned testing in Ruby, which is known for the maturity of its testing tools and practices, and I was interested to see how they applied in the context of Swift. After a week, here are some of my impressions.
Chris Hepworth is an alumnus of the iOS Essentials with Swift bootcamp here at Big Nerd Ranch who recently released his second app in the App Store. Since we love to showcase alumni success, we interviewed him about his career path, his experience at Big Nerd Ranch, and his two complete apps.
ConstraintLayout and Auto Layout use the same underlying algorithm. How do they differ?
Swift allows for chaining methods together to perform powerful operations in a single line of code. If you aren’t careful, however, this can lead to code that is difficult to read and maintain. In this video, I’ll show you some approaches to make this more clean and manageable.
Swift’s destructuring case statements are cool. But when you don’t care about the associated data at all, go with
case .tag: rather than
case .tag(_, _):. Here’s why.
If you’re writing Swift apps and not Swift frameworks, do Swift’s access modifiers even matter, or are they just a big distraction?
Should you use BNNS or TensorFlow to add artificial intelligence to your iOS or Mac app? The answer is… both.
Imagine that one day you’re feeding some innocuous looking code to a Swift compiler, and then you get a smackdown of an error. Where’d it go? It got renamed.
It’s been possible to write cross-platform SpriteKit code, but you had to build all the boilerplate yourself. The new Xcode 8 Beta 3 includes a new project template for cross-platform games, saving many hours of repetitive setup. In this video, Steve Sparks walks through the structure of the template and shows you how to start creating your own.
Designing meaningful products for Apple TV requires taking into account many more additional factors than when designing for a mobile device. To prepare for this, here are some considerations when designing your app for tvOS.
selector is key to Objective-C’s dynamic runtime nature. It’s just a name that’s used, at runtime, as a key into a dictionary of function pointers. Whenever you send a message to an Objective-C object, you’re actually using a selector to look up a function to call. Sometimes selectors bubble up in Cocoa/CocoaTouch API, and you will need to deal with them in Swift.
Apple has been using machine learning in their products for a long time—Siri answers our questions and entertains us, iPhoto recognizes faces in our photos, Mail app detects spam messages.
As app developers, we have access to some capabilities exposed by Apple’s APIs such as face detection, and starting with iOS 10, we’ll gain a high-level API for speech recognition and SiriKit.
It’s been a bit over a year since we got the Apple Watch, and
right at a year since we got watchOS 2. Back then, we were
excited to be given a way to interact with the digital crown. You created a
WKInterfacePicker in IB, filled it with picker items, and
it would react to the crown for you. It was usable, but limited. It required
you to give up screen space, even though you could make it invisible.
Swift 3.0 changes the semantics of
ImplicitlyUnwrappedOptional, and is even safer than its previous incarnations. What has changed in Swift 3.0 for this type that improves the language’s safety? The answer has to do with improvements in how the compiler infers type information for
WWDC 2016. New Notification Center features? Eh. Bouncy sticker graphics giant emoji in Messages? Blah. New file system? OMG. Apple File System. APFS. NEW FILE SYSTEM!. That wasn’t on any Rumor Radar that I had seen.
With the advent of WWDC comes a lot of new information. Don’t want to wait for the WWDC 2016 videos? Start with our list of recommended reading.
As I type, Apple’s yearly developer conference, WWDC 2016, is in full swing. The keynote can be watched via Apple TV and their website, or you can catch summaries and highlights on every site that covers Apple’s doings.
Apple’s bundled test framework XCTest provides a very limited, general collection of assertions. These get the job done much of the time, but sometimes they’re not the right tool to communicate what you’re actually checking. That’s when it’s useful to know how to write custom assertions that clearly express what you are truly checking for without getting lost in a maze of little this-that-and-that assertions.
Protocol-oriented programming leverages Swift’s features in a powerful way, but there are practical concerns, like whether you want both value types and reference types to be able to conform, limiting the application and usability of a given protocol. This post provides an example where the developer may want to make this limiting choice, elucidates the tensions in making the decision, and discusses some strategies in moving forward.
Welcome to Part 4 of the “Let’s Build an iOS App in Rust” series. We’ll continue to build on the tools and techniques we explored in the first three parts, creating a basic view model in Rust.
Parsing JSON can be tricky, but it shouldn’t be. We think parsing JSON should feel like writing regular Swift code, so we’ve introduced Freddy, a new open-source framework for parsing JSON in Swift.
As app developers, we don’t have the luxury of shipping our software exclusively on the latest-and-greatest OS version. We want to use the new shiny toys, but we also need to be able to work on older versions of the OS that don’t have these features. Swift 2.0 introduced a new language construct,
#available, that helps solve the problems that crop up when your app needs to support multiple versions of iOS or OS X.
In Part 3 of our “Building an iOS App in Rust” series, we’ll cover how to pass much more complex data than strings, and how to correctly and safely manage the ownership of that data.
In previous posts, MarkD delved into many of the diagnostic tools available to us in Instruments, such as the Time Profiler and the Energy Diagnostics template. In that same vein, I’ll provide an overview of the Cocoa Layout Instrument.
When we at the Ranch use Core Data, we inevitably end up using it in a multi-threaded environment. The Right Way™ to use Core Data across multiple threads is a topic of fierce debate, one that we had ourselves when we set out to create a shared Core Data stack.
UI testing is testing via the user interface. This is nothing new; we do it all the time, manually, by running an app and tap-tapping through its UI. But manually testing for regressions is dull. This is why we have computers, right?
Last time, we built a simple “Hello, World!” library in Rust and successfully linked it into an iOS app. This time, we’re going to explore more of Rust’s FFI, or foreign function interface, layer. The Rust book has an excellent chapter on Rust’s FFI facilities; however, it is almost exclusively about how to call C libraries from Rust, whereas we want to go the other direction and call Rust from Swift.
As my fellow Nerd Juan Pablo Claude pointed out in his post on Error Handling in Swift 2.0, the latest iteration of Swift introduces many features, and a new native error handling model is notable among these. While Juan Pablo’s post offered a bit of history and differences between Objective-C and Swift error handling, today I’d like to dive into the differences in error handling between Swift 1.2 and Swift 2.0.
There are a lot of nerds with a soft spot for horology. I tend towards chronographs; I love the extra functions for stopwatches, secondary time zones and time-to-speed conversions. All of those additional displays are called complications. Now Apple has done a pretty great job of enabling custom complications with watchOS 2.
One of Xcode 7’s new features is in-line display of code coverage metrics. Yay? That’s a pretty dull way of describing a nice feature. Code coverage figures out which lines of code have been executed while running unit tests, and now Xcode shows you information about this coverage in the UI.
When Apple announced Swift 2.0 at this year’s WWDC, Swift’s main architect, Chris Lattner, indicated that the 2.0 update to the language focused on three main areas: fundamentals, safety and beautiful code. Out of the list of new features, improvements, polishes and beautifications, one that may impact your Swift 1.x code the most is error handling.
When Apple announced WatchKit 2, I shot over to the developer website and immediately began consuming whatever documentation I could find. There was something I didn’t really expect, but was happy to see: Core Motion. You see, I love Core Motion. I love sensors. I love hardware.
When I put up the draft of my Digital Crown blog post for internal review, my friends MarkD and Step both saw the little one-liner I’d thrown in about making the Taptic Engine click as you scroll the Digital Crown. They wanted to hear more, but to their disappointment, I declined, saying it was a post for another day. Well, today is that day.
One of the most exciting announcements from WWDC this year was that native multitasking is coming to iPad. The ability to run two apps side by side is something that many iPad owners have wanted for some time to increase productivity. What do you have to do to get this working in your app? The wonderful answer is that you don’t have to do anything whatsoever! That is, if you’ve been following Apple’s recommendations over the past few years, then you don’t have to do much of anything.
WatchKit 2 allows code to run on the watch itself, rather than in the extension space on the phone. Running on the watch increases the difficulty of some things like communication with your containing app, as well as opening us up to power consumption issues, but it unlocks so much potential that it’s worth it. Most of that potential is in the hardware. The first and easiest piece to chew off is the Digital Crown.
The theme of this year’s WWDC announcements was one of incremental refinement. The landscape of iOS and OS X aren’t changing dramatically; rather everything is getting a bit better. If you feel like your investments in yesterday’s new technologies like Auto Layout, Storyboards or WatchKit weren’t paying off, now is when that investment will bear fruit. If you aren’t familiar with these technologies yet, be sure to check them out before the end of the year. In the meantime, let’s get into the changes in more detail.
If you’re developing an app on multiple platforms, you’ll often face duplicate work. C++ is the reigning king of the hill for portable, native library development, but there’s a new challenger in Rust.
Consider the humble line—just a straight sequence of pixels connecting two points. There are well-known algorithms you can use to do your own drawing, but these days, we have toolkits to do the hard work.
What do designers, who may have little to no experience with mobile design, want and expect out of courses? Do web designers or graphic designers see the value of an extended, in-depth course like we offer at Big Nerd Ranch?
Get ready to tap into your creativity alongside the Nerds. Designers, developers and project managers: join us for our new Android Mobile Design and iOS Mobile Design bootcamps. In two days, these classes will teach you to design intuitive interfaces employing platform-specific conventions and innovative trends. You will learn vocabulary, current trends and how to work alongside developers to create a pixel-perfect app for mobile devices.
Learn ALL the things! That’s basically the motto at Big Nerd Ranch. And in my last post, I wrote about how my team, The Artists Formally Known As (╯°□°)╯︵ ɥsɐןɔ, learned a lot of new things when we tackled hardware hacking with Arduino, NeoPixels and Artoo.
I took Big Nerd Ranch’s Beginning iOS with Swift course and I have to admit, I left the bootcamp impressed—and with a whole lot of newfound knowledge.
We recently had our annual app-building competition, Clash of the Coders. It’s a fantastic opportunity for us nerds to experiment with unfamiliar technologies, stretching ourselves and our tools. It’s all about learning, a fundamental value of Big Nerd Ranch. After an intense 72-hour coding marathon, our team (The Artists Formally Known As (╯°□°)╯︵ ɥsɐןɔ, yep) came out with an online, multiplayer game equipped with clients crossing four platforms: iOS, Android, Web… and Arduino!
Continuous integration has become an important topic and a significant part of a developer’s workflow. Finding bugs and ensuring a stable codebase are among the most important benefits of using continuous integration. While these benefits are huge on their own, we can extend our continuous integration setup to actually deploy new builds of our application to our testers. We call this extended setup continuous deployment.
Fumbling with a bunch of credit cards and a wallet is a hassle. Whether you love or hate Apple, you will not find a more secure form of credit card payment than Apple Pay. Period.
The release date for the long-awaited Apple Watch has not yet been announced, but the nerd herd here is hard at work learning how to program with WatchKit. We believe that the 4th beta of Xcode 6.2 is a rather stable version of what we should expect for the public release of iOS 8.2 and WatchKit early this year.
Learn more about showing numbers correctly in iOS and OS X using Xcode 6 and Playgrounds.
For a designer, the word “port” can be cringe-inducing. By definition, a port is an application adapted from one environment to another. However, what sounds like a short re-skinning project is actually a challenging process involving design, development and stakeholder communication.
Swift access control enables you to hide the implementation details of your code and to specify a preferred interface through which that code can be accessed and used. It also allows the developer to control the context their types, methods, and other names can be used from.
You need to interact with the current Core Graphics context in some manner to actually draw stuff, so it’s good to get comfortable with it, what it does, and why it’s there.
iOS 8 and Xcode 6 have brought about the ability to use vector assets in your applications. Unfortunately, Xcode 6 doesn’t fully support vector assets in iOS just yet. Let’s look at how you can create and use vector graphics that are non-destructive and editable in the future.
Are you in Chicago or Austin? Do you want to get up to speed with Swift and iOS 8? We can give you a huge boost up the learning curve.
Using Core Data in a multi-threaded environment has always required a deep understanding of the framework and a healthy dose of patience. Asynchronous fetching is not necessarily a feature of a multi-threaded Core Data environment. However, its ability to alleviate a common performance issue could potentially free you up from the added complexity of a multi-threaded CoreData stack.
With the addition of two new iPhone sizes, designers and developers will have to be more flexible in their layouts. In this demo, I give a quick overview of Universal Storyboards and Adaptive UI in iOS 8, and how they impact design and development.
In 2013, Apple shipped a revamped testing framework in Xcode called XCTest, and this year, they’ve shipped a few features with Xcode 6 that were missing from last year’s update. In this video, Sean McCune gives a quick demo of those features.
Designers need to be aware of many new features when it comes to designing for iOS 8 apps. Extensions, device sizes and frameworks like HealthKit and HomeKit all have an impact. In this demo, I talk about the ways that iOS 8 changes app design.
In this demo, I cover Interactive Playgrounds and Functional Programming.
While the visual design of iOS 8 remains similar to its predecessor, it is packed with features that require special design attention.
In this tutorial, I talk about about Core Data and what’s new in iOS 8. I focus on two new APIs, both centered around performance: batch updating and asynchronous fetching.
CloudKit gives you record-based, auto-replicating storage across all of your iOS and Mac devices. In this demo, I cover creating records, the push notification subsystem and CloudKit’s capacities.
Apps often need to store their data model objects in the cloud, and Apple has released CloudKit to address this need. I decided to put together a chat application to learn more. Here's how to simply create objects in the public database.
WWDC 2014 was full of surprises and exciting technology to explore, and the new
Playground was high on that list.
Playgrounds provide a convenient environment for rapidly developing and trying out code. Apple’s
Balloons.playground demonstrates much of the power of the
Playground: it can serve as both a document and as a REPL. The combination of the two means that a
Playground is a fully interactive document.
Can’t get enough info about iOS 8? Join us for our one-day iOS 8 bootcamps in cities across the U.S.
In 2013, Apple shipped a revamped testing framework in Xcode called XCTest, and there was much rejoicing. The old framework hadn’t been updated in years, and a number of third-party testing tools and frameworks had sprung up to provide new features and capabilities. It was good to see the built-in tools getting some love again, and this year, Apple is shipping a few features with Xcode 6 that were missing from last year’s update. One I’m particularly glad to see is support for asynchronous testing.
Yesterday, we at the Ranch we were gathered around the campfire for Apple’s latest announcements. It may not have been the wearable or maybe even the inflatable you were expecting (I might have misheard the rumors), but Apple’s fall event, usually dedicated to the iPod and iPhone, has come and gone once again. There is tons of news to unpack for you, your apps and your users. Let’s get going.
Last year, Apple gave us an iOS update that was all about the appearances. The update for iOS 8 takes a deeper look at the workings underneath. Before we head into Apple’s 2014 announcements, let’s take a last look at some of the rumors.
Why would an experienced iOS developer want to take our Ruby on the Server bootcamp? Nerd Steve Sparks on learning new tricks and why you need a guide.
Our first roadshow is bringing one-day classes in Swift and iOS 8 to a city near you.
Microsoft Azure, a cloud storage and computing platform, is a one-stop shop for virtual machine hosting, web hosting, machine learning analysis, web-enabled databases, content delivery and more. Here's how to get started.
At Big Nerd Ranch, we love certain things. We love coffee, we love fitness and we really love technology. When Apple announced Swift, I found it really hard to resist cracking open the free books and seeing what it’s all about.
Swift helps you write code with fewer bugs. But even more intriguing are the possibilities to change “things I have to worry about” in Objective-C into “things I can let the compiler worry about” in Swift.
…and upon looking into the face of indescribable horror, a bug so unfathomably odd that it shook the foundations of all meager human beings, I was overcome by an indistinct feeling of dread and approximate horror previously unfamiliar to me.
Want to use UIDynamics in Swift? Turns out, UIDynamics in Swift is pretty much just like using it in Objective-C. We just need to drape it in the Swifty Goodness™ and it will work just like it is expected to.
Sometimes you stumble across a file. It might be something random in your Documents folder. It might be something a parent or a client sent you. Unfortunately, you have no idea what it might be. Files don’t have to have extensions on the Mac, so there’s not much hint what “Flongnozzle-2012” might contain. But if you’re comfortable in the Terminal, you have some built-in tools to help you identify files.
Wearables are becoming ubiquitous. Every day, it feels like there’s some new fitness tracker with a slightly different set of sensors and an entirely new app/API/website/life-changing-experience/yet-another-account-to-set-up. And fitness trackers are only the most popular bastion of wearable computing. Once you start counting the many devices that used to be released as a USB peripheral and are now being updated to use Bluetooth Low Energy and a rechargeable battery, the list of wearables becomes even larger than the number of Android devices available.
After WWDC, there are new SDKs (Software Development Kits), APIs (Application Programming Interfaces) and new languages to play around with, along with the usual extensions to existing interfaces. Getting up to speed quickly with a new SDK, especially a pre-release SDK, can mean the difference between having a good time with new software toys or becoming angry and making those around you miserable.
When Apple announced Swift, I heard a few people say “Hurray! Now I can be an iOS developer without learning Objective-C!” I have three messages for these people:
In last week’s WWDC, Apple introduced an entirely new language for Mac and iOS development called Swift. Swift is a modern language that is less verbose but is just as expressive as Objective-C. Furthermore, Swift offers a number of features not available in Objective-C. We at the Big Nerd Ranch are incredibly excited about it.
In their opening keynote on Monday, Apple stated that iOS 8 is their biggest update to iOS since its initial developer release with iPhoneOS 2.0. It sounds hyperbolic, but it isn’t—this year is huge, both for users and developers.
Miss Aaron Hillegass’ talk at AltConf? We’ve got you covered.
Editor’s note: We have since published the first edition of our Swift programming guide, currently an Amazon best seller. Our iOS and Cocoa bootcamps have also been updated to include Swift programming.
You can find Part 1 of this series here.
You can find Part 2 of this series here.
Dependency injection refers to the design principle of telling a class which other objects its instances should work with, improving the flexibility with which the class can be used in different contexts. There are no special tools or libraries needed, and it's easy to adopt dependency injection in legacy code to enable testability.
Big Nerd Ranch fan Dave McKinney recently gave himself one month to learn some basic programming skills and build an iOS app from scratch. Starting with zero code experience, would he be able to learn enough to make a simple app and submit it to the App Store?
Although the iOS 7 adoption rate is now at 85 percent, many developers still need to support iOS 6. I've seen people struggle with designing their interfaces so that they look at home on both versions of the operating system. This blog post will show you the best practices for achieving this goal.
In our Advanced iOS bootcamp, there’s always something new for us instructors to learn from the students. But last week, my class has an extra surprise for me: mutiny!
Mock objects are used by many developers when they're using test-driven development to design their systems, but what is it? And what are all these subtypes like partial mocks and nice mocks? Are mock objects usually nasty but impartial? Let's take a look, using examples from the OCMock framework for Objective-C testing.
Using iOS 7’s Dynamic Type adds polish to an app. Unfortunately, it can feel cumbersome to use. BNRDynamicTypeManager is an open-source library that makes it less painful.
Jamie Daniel has attended not one, but three Big Nerd Ranch bootcamps. And he’s putting his knowledge to good use: Jamie is collaborating with a medical team at Duke University to develop a tool that helps doctors and healthcare providers improve care for patients with diabetes.
Last week I walked through finding and fixing My Favorite Bug. Observant readers may have noticed a multi-step process outlined by some <H3> tags. Get the Attitude, Do Corrective Maintenance, and so on. What was that?
I love stories. I love telling stories, and I love listening to stories. I learn from stories. I believe that we, as a programming community, don’t tell enough personal stories around the campfire.
I’m a big fan of caveman debugging. That is, using log statements to gather information and visualize a program’s control flow. But I only use it very tactically: I need this one piece of information. Add a log or two and see what I get. Once I solve the problem I take out the logs before sending the code out for review and checking it in. I consider caveman debugging different from the logging an app does to report its activity or health. This should be designed like any other feature, and not be dependent upon developers randomly scattering log statements around the code base.
I’ve talked about stochastic profiling in the past, such as the fairly recent Rock Heads. It’s something I mention when I talk about debugging or performance tuning at various conferences. Interestingly enough, I had a need for it last night because I had stumbled into an often-reported, difficult-to-reproduce problem and wasn’t in a situation to hook up Instruments.
iPhone 5s. iPad Air. The 64-bit era has moved from the desktop and into our hands. Mike Ash has an excellent article covering what 64-bit ARM is. I’m here to explore some of the day-to-day implications of this 64-bit thing.
Every great developer should know how to use a debugger. Xcode has an excellent debugger UI that wraps LLDB (or, if you’re living in the past, GDB), giving you access to all the standard tricks like breakpoints, stepping in and out and around your code, and stack frame details.
One of the wonderful(?) things about Objective-C is that it’s based on C. Part of the power of C is bit-bashing, where you can manipulate individual bits inside of a piece of memory. Have a bunch of boolean values but don’t feel like wasting a byte or two for each one? Represent them as individual bits! Luckily we tend not have to do this a lot of these days given the massive amounts of memory that we have to play with, even on iOS devices. That being said, there are times where bitwise operations appear in the Cocoa APIs, so it’s good to be comfortable with a couple of basic operations.
One of our interns recently asked what seemed like a fairly innocuous question: “What are the scenarios where the use of instance variables would be more preferred than using properties?” At Big Nerd Ranch, we strongly prefer using properties to direct ivar access, but take a sampling of the Objective-C community and you’ll find almost as many answers as there are developers:
Part of the fun of teaching a live class is fielding questions and thinking on your feet. Once I was showing some code that used @properties extensively in the interface, and one of the students asked “What are all the little fiddly bits that go after the
@property? I’ve used retain and assign and nonatomic, but don’t really know what they really do.” (There’s a TL;DR at the end of all the
@property attributes if you just want a quick cheat-sheet.)
UIKit Dynamics is one of the more fun parts of iOS 7, giving us user interface elements that mimic real physical objects. They can bump into each other, move and spin, fall with gravity and bounce around on invisible springs and strings. I decided to build an app that plays Pong using only UIKit in order to see how it all worked.
iOS 7 feels fresh and new, thanks in large part to its zooming, swooping, sliding interface. To me, it feels alive and fresh after several years of everything sliding in from the right. You want to add this yummy goodness to your app, right? Let’s get to it.
Lots of people have been calling Apple’s new iOS 7 design “flat,” but to me, that’s oversimplifying Apple’s intent.
Even though Apple is known for limiting what you can do on iOS compared to Mac OS X, they actually provide you with some information about the OS and hardware environment you’re running in, assuming you know where to look. Here I’ll be looking at three different places to accumulate this info: the
NSProcessInfo, the application bundle, and a Unix system call.
I sometimes see the question “How do I cast a method into a function pointer?” come up during classes or on some form of social media. One problem programmers have, which asking questions, is phrasing the question too specifically. In this case, the real question is “How do I use an Objective-C method as a callback for a C library?” Casting a method to a function pointer is one possible way of solving the problem. Is it the right way?
] At this year’s annual Clash of the Coders, I teamed up with Steve Sparks and Mark D to create Krëndler, a framework that can be added to any iOS application to record and play back a user’s touch events. Steve and Mark took care of the iOS aspect, while I created an API for them to use to store the touch event data they collected.
Want to learn more about what’s really happening inside those square brackets? Read the entire Inside the Bracket series.
Want to learn more about what’s really happening inside those square brackets? Read the entire Inside the Bracket series.
Want to learn more about what’s really happening inside those square brackets? Read the entire Inside the Bracket series.
We’re settling into our usual routines after returning from a great week in San Francisco and WWDC. We wrote about the WWDC keynote, both its focus on users and on its attention to the details. Aaron spoke at AltWWDC and at the Union Square Apple store. We ate delicious food and managed to sneak in visits to a few sights.
I was one of five lucky Nerds who got to attend Apple’s WWDC this year, and it has been a blast so far. The keynote was probably the most exciting in terms of the big-picture changes coming from Apple. Interestingly enough, the big picture means focusing on the little things.
Depending upon your perspective as a developer, you may have been disappointed by the relative lack of developer-focused information in the WWDC 2013 keynote. I was not.
So. That Clash of the Coders Thing. Kind of nice being able to flex mental muscles over a 72-hour sleep-deprived Dr Pepper-infused period of time, performing acts of violence upon the Objective-C runtime,
UIApplication, and the layer stack. It was a blast being able to use all my platform knowledge with the express purpose of subverting it.
I was hanging out on the #macdev IRC channel on Freenode the other day when someone asked a question: “
static has different meanings based on the context it is placed in, right?”. Indeed, it has different meaning. And yet it’s the same. Static is a C Koan.
Instruments is a cool tool. There is a lot it can do beyond “simple” things like profiling your application’s execution time or finding your memory leaks. It can also give you holistic views of the activity on a device, such as power consumption.
You can find all sorts of interesting and useful stuff in Apple’s header files. Don’t be afraid to explore them. I usually troll through the headers when a new major SDK version comes out (like IOS 7 probably will be this year) to see what’s new. I also use them for API exploration. As always, when in doubt be sure to read the official documentation. Apple’s documentation is good. It’s also voluminous. But once you’ve marinated in a framework for awhile, you know how things work and might only need a refresher or a nudge in the right direction. These days I usually spelunk in the headers, and then hit the docs if I’m not sure what the headers are trying to tell me.
Just got back from the DC area, where some fellow Ranchers and I went to CocoaConf. If you’re not familiar with CocoaConf, it’s a traveling technical conference for Mac and iOS developers. I like to call it a peripatetic conference, where Dave Klein (who runs the conference) travels around with his family to different cities and puts on a great conference. There are conferences coming up in Dallas April 4, and in San Jose April 18.
Simple questions can be fun. A friend in the Pittsburgh CocoaHeads said “Hey MarkD. We’re having a discussion at work on the right way to iterate through an NSArray. One dude said to just use the
for...in syntax, and the other said that we should always use the block based iteration form. What do you think?”
I lied. Sorry. I thought this dive into DTrace would be a three-parter, but here’s a part 4, on static probes, suggested in a comment by Chris last month.
As you’ve seen before, DTrace can give you a huge amount of visibility into the guts of your computer. You saw the
syscall provider which lets you attach probes to system calls, those functions that let you take advantage of services from the kernel. You also saw the
pid provider which lets you look inside individual processes and trace the function activity inside of there.
The other day I was chatting with one of my colleagues at the Ranch and he asked me where I get my blog ideas. One fertile idea-ground is what sometimes happens during day-to-day work, solving a potentially hard problem in a way that’s actually pretty easy. And then I discover there’s a fair amount of ground work needed to understand it. Hence these multi-part War and Peace epics.
Sometimes things aren’t as simple as they appear. One of my former students was asking what
id * meant. This seemed straightforward enough, but as I started exploring the question in more detail, things were becoming curiouser and curiouser.
Last fall I took a week off to escape from the world. I assigned myself three tasks for that time: disappear and recover from a number of stressful deadlines, clean up my office area (affectionately known as “my cage”), and learn about CocoaTouch gesture recognizers. I ended writing a little tool for playing around with gesture recognizers that I called GestureLab.
Grand Central Dispatch, a.k.a libdispatch and usually referred to as GCD, is a low-level API known for performing asynchronous background work.
dispatch_async is its poster child: “Throw this block on a background thread to do some work, and inside of that block toss another block on the main thread to update the UI.”
Did you know that Microsoft sold more than 40 million Windows 8 licenses in just one month? Now that’s a big market in need of well-designed apps, and we pride ourselves on being at the intersection of useful and Nerdy know how.
Update: In the time since this blog post was published, the compiler behavior demonstrated has been remedied in the version of clang accompanying Xcode 4.6. For a BOOL generateMipmaps, @(generateMipmaps) now evaluates to kCFBooleanTrue or kCFBooleanFalse.
Geometry is everywhere in modern programming. We have to know how to deal with points, sizes, and rectangles. Back in the old days we’d use
NSRect. These types were bitwise-identical with their Core Graphics counterparts (
CGRect), but weren’t type miscible, so you had to play games to use use one where another was wanted. With modern flavors of Cocoa, we can use them interchangeably. If you’re looking at a codebase that has both NSBlah and CGBlah for basic geometrical types, rest assured they’re the same at the bit-level.
Fast Enumeration, part 1 covered what fast enumeration is. Part 2 covered the method
countByEnumeratingState, which is the centerpiece of fast enumeration. This time around there’s actual code which implements a collection that can be fast enumerated, without cheating and falling back on one of Apple’s collections.
Fast Enumeration, part 1 covered what fast enumeration is,
NSEnumeration a bit, and introduced adopting fast enumeration in your own classes by doing a simple pass-through to Apple’s collections. This time around it’s time to look deeper at the central Fast Enumeration call, which I’ll refer to as
Fast Enumeration was introduced into Objective-C back in the 10.5 days. It’s the feature that lets you succinctly iterate through a collection:
This question came up in an IRC channel the other day: “What’s the best way to set up a property that’s read-only externally, but modifiable inside of the class, so I can use properties or KVC to change it?”
__unsafe_unretained. That sounds pretty scary. It’s a new symbol added by ARC that’s used to decorate pointers. It pops up in Xcode’s autocomplete occasionally, and sometimes you see it in code you find on the net. What is it? When would you want to use it?
I usually encounter two classes of bugs on a regular basis. The first is of the form “I think I know where this is” which won’t take long to find. The steps are pretty easy: Figure out how to reproduce it. Set a couple of breakpoints. Add some caveman debugging. Find the problem and fix it. These are my favorite kind of bugs because they’re over and done with quickly, I can get a quick hit of that “you done did good” glow from making a software system better, and then move on to some more interesting problem.
When I’m developing new code, my usual habit is to do a lot of small iterations. That gives me a little bit of success fairly often. I’m not as happy if I have to work for a long time until I can see something appearing on the screen.
You know that sinking feeling in your stomach. That horrible emotion that you know that something has gone wrong, seriously wrong, and you’re going to be facing a mountain of pain. That terror that’s even worse than your significant other sitting you down saying “we need to talk”. It’s this:
Today is Labor Day over here in the states, with many Nerds are taking a well-deserved break to go out into the Big Room and enjoy the company of friends.
CocoaHeads Boise on twitter asked for an elaboration on big vs little endian. In the query was a very interesting statement: “surprised not mentioned in my C books.” I had never thought about endianness issues being covered in introductory materials .
As happens occasionally, an interesting technical discussion ensues in an IRC channel. Earlier this week, this question came up why does Apple do this to most of their
enums in the Cocoa headers:
Cocoa has a number of classes that can hold arbitrary amounts of Stuff. Things like arrays, dictionaries, sets, index sets, character sets, strings, data, strings, and so on. These classes come in two flavors, mutable and immutable.
I like warnings. I really do. It reminds me that the compiler loves me and is looking out for me. (OK, the compiler at least tolerates me.)
You know that feeling. You’re on a deadline. It’s 9:00 at night. You have a demo the next morning. Suddenly Xcode freaks out. Apps running half the time. Rebooting your phone. Rebooting your computer. Finally the phone decides to run your App for awhile.
Last time you saw how to register for notifications. Now time to handle them!
Notifications on the brain. Last time was a bug report about something I stumbled across when debugging some notification-related stuff. Before pursuing that much farther, I figured I’d talk about notifications.
Ever be coding along, giddily hooking objects together and doing that voodoo that you do so well, and all the sudden you hit a wall. Things stop working. You’ve hit, what could be, A Bug. “Can this really be broken? What’s going wrong?” And then you’re stuck in a gumption trap , shaving yaks until you can get back to your important work.
Just got back from a weekend at CocoaConf down in Herndon VA. A lot of great sessions from Ranch folks, and from everyone else as well. One of my favorites was the session Chad Sellers from Useful Fruit had on Text, covering the text system from
NSString up through
NSTextView and back down to Core Text. I learned stuff.
I’m a fan of Caveman Debugging, where you use print statements to trace program flow and display specific program information. I was kind of surprised when reading Coders at Work how many industry luminaries do the same thing. It’s just another tool in the debugging arsenal, along with unit tests, debuggers, Instruments, and the plethora of other software investigation toys.
Today’s topic was suggested by Paul Bruneau - thanks!
Apple’s WWDC is next week! Woot! But I know a lot of folks can’t make it to WWDC. There are a number of conferences happening over the summer for folks to get their technical info fix.
I got a question from a friend of mine the other day:
Saving data to the file system and reading it back is a pretty common operation. One of the first ways many Cocoa and iOS programmers learn to read and write are by using the convenience functions provided by
NSData, and friends.
writeToURL:atomically: for writing and
dictionaryWithContentsOfURL: for reading.
Instruments is a very cool profiling application, but it’s one of those things that’s kind of hard to write about. You can outline the features it has, create some contrived debugging situations (“oh look, I’ve introduced a memory leak where no sane person could have accidentally created one.”), and make some pretty screen shots.
Update October 2013 - On 64-bit iOS (device and simulator)
BOOL is now actually
bool, so the sharp corners have thankfully gone away for that platform. For everything else, though…
If you’re an iOS programmer who only programs CocoaTouch, I want to encourage you to give desktop Cocoa a try. I’ve primarily been shipping iOS software for the last two years, but I’ve also been doing a fair amount of Cocoa programming on the desktop during that time, either writing helper tools or implementing parts of the iOS app on the desktop.
Every now and then I get a question about an idiom I use for looping through a collection of literal structures. This is handy for little lookup tables, or using pre-defined data to populate another data structure.
An idiom used by some Objective-C programmers is prefixing instance variable names with underscores. You do see this with explicitly declared instance variables:
The Beltline Bikeshop App, Bike Spot, is LIVE and available to install on your iOS device!
One of the directions Apple is taking in Objective C that I’ve come to really like is the migration of stuff out of header files. I’m a firm believer that header files should only contain the public programming interface, along with any bookkeeping the compiler absolutely has to have And nothing else. Anything that doesn’t contribute to a person’s understanding of how to use your class shouldn’t be in there.
Last time we talked about protocols and why you’d want to use one. So, when would you want to make your own protocol? You make protocols when you’re defining some kind of mechanism for your object to use other objects to do its work. One use of protocols is defining the set of methods used for plugins. AMOSXP(3) has a section that builds plugins in Cocoa, using a protocol to spec out how the plugin and the host application interact with each other.
The last post about isEqual: vs isEqualToString: included some timings I made to test the performance of those two calls, along with
compare:. That posting mentioned going down a rabbit hole, verifying commonly held beliefs of about
isEqualToString:. The other rabbit hole I went down related to the performance tuning. A couple of commenters on the post asked some good questions relating to the timings, especially about literal strings.
_TL;DR: When to use
isEqualToString:? There’s no meaningful performance difference between the two. For convenience use
isEqual:. For a modicum of type safety use
isEqualToString:, but it’s not as safe as you might believe. If you have unicode strings with different normalizations, use
compare:. Be careful if
nils are involved.
We have a lot of very convenient, very powerful methods at our disposal such as
[NSData dataWithContentsOfFile:]. This method goes to the file system, opens the file, reads in all the bytes, closes the file, packs the bytes into an
NSData, and returns it back to us. It replaces a loop and several other lines of code into one convenient package. If it can’t do the work, it returns
nil. That’s pretty simple.
You might want to check out Part 1 if you haven’t already seen the new
NSDictionary literal syntax, and using square brackets to dig into collections.
Update : Official Documentation now
Timing how long a block of code takes is a useful tool. Maybe you’re choosing between two different calls that do similar things and you’re wondering which one is faster. If one is faster, is it faster-enough to make any difference? The usual techniques involve using a profiler like Instruments, or calling a time function like
gettimeofday() before and after your code and calculating the delta. Those of us on mach-based systems like iOS and OS X can use
mach_absolute_time(), which is the finest-grained timepiece available on the system.
My fellow Advanced Mac OS X Instructor, and general all-around super-nerd Jeremy W. Sherman digs into the tantalizing possibility of @import syntax.
Objective-C categories are cool. They allow you do something that you can’t do in most compiled languages: add new methods to existing classes. You can even add methods to classes that you didn’t write.
One of our engineers was working on a project and wrote some code that crashed when running on a device:
Voices that Matter is going to let me do the keynote on the first morning of their iOS conference this spring. The conference is April 9 and 10 in Seattle. You should come – it is a well-run and informative gathering. (Early-bird pricing ends on Feb 25, so sign up now.)
Making a .epub or .mobi version of a book is not as easy as it looks. Until recently, if you bought the Kindle version of our iPhone book you were buying something that was generated from our PDF. In particular, all the code blocks were just images from the PDF.
Update: It appears Apple has done a lot of these things, so thanks!
Let’s face it. We all have questions. Why is the sky blue? What shirt will I wear today? Why does mommy spend so much time on the phone with “the handyman?” Thanks to the Big Nerd Ranch, there is now a place to ask these questions, and more.
I just open sourced a simple persistence layer for Cocoa and iPhone that uses Tokyo Cabinet. If you are frustrated with Core Data, you might find it useful. Check it out on GitHub.
When you write a Core Animation heavy application, you spend a lot of time implementing code that executes when an animation finishes. Typically, the view controller whose view contains the animating layers implements animationDidStop:finished: and does a series of checks to see which animation finished. This method becomes difficult to manage as the number of animations it handles increases. You must also set the delegate of each animation object and tell them not to remove themselves when finished. You end up writing a lot of code over and over again.
(Disclaimer: These are my (Joe Conway) opinions. Not Aaron Hillegass’ or any of the rest of the Big Nerd Ranch staff.)
This one is not really crap; it is just a sad omission in the Objective-C 2 language.
Before I go into another shortcoming of UIKit, I’d like to make it plain that I genuinely like most of UIKit. In many ways it is much better than AppKit. I love UIControl, and I think that UITableViewCell being a subclass of UIView is a huge step forward. But, the weaknesses are the parts that demand difficult design decisions, so I’m delving upon them in this series.
Last week, my colleague Joe Conway wrote a posting suggesting that dot-notation was not a great addition to the Objective-C language and that he felt that programmers should not use it. Â There was outrage. I, myself, was shocked that people cared at all. Â After all, there are some examples of truly stupid stuff that Apple has done that are being misused in genuinely dangerous ways by the iPhone developer community. Â These are worthy of discussion. Â So, I’m doing a multi-part feature that I will call “Real iPhone Crap,” and this is the first installment.
When I teach, I always make sure to mention the dot-notation addition to Objective-C 2.0. Then, I make sure to tell the students never to use it ever, ever, ever again. But why? Why this seemingly irrational hatred of dot-notation? Is this a style choice and us “bracketeers” are being hard-headed? The answer is no, we are not being hard-headed, we are keeping our code consistent and maintaining readability.
As you probably already know, this week marks Apple’s WWDC 2009 Conference in sunny San Francisco, California.
The iPhone SDK has now been around long enough where we can start to pick out good practices in using some of the more “fuzzy” areas. There are two small, but important, practices that can make your life much easier.