Mikey Ward - Big Nerd Ranch Wed, 14 Sep 2022 22:33:24 +0000 en-US hourly 1 https://wordpress.org/?v=6.5.5 Now Available: Swift Programming: The Big Nerd Ranch Guide, Third Edition https://bignerdranch.com/blog/now-available-swift-programming-the-big-nerd-ranch-guide-third-edition/ Tue, 03 Nov 2020 18:30:40 +0000 https://www.bignerdranch.com/?p=4602 The Swift programming language has been evolving at a staggering rate since its original announcement over six years ago. We are proud to announce the 3rd edition of our Swift Programming book, fully updated for Swift 5.3 and Xcode 12!

The post Now Available: Swift Programming: The Big Nerd Ranch Guide, Third Edition appeared first on Big Nerd Ranch.

]]>
The Swift programming language has been evolving at a staggering rate since it was originally introduced over six years ago.

It has been our greatest passion to help developers learn and stay up to date with Swift programming and iOS development through our books and bootcamps. To share our love of Swift and all of the changes it has seen, we are proud and excited to announce the 3rd edition of Swift Programming: The Big Nerd Ranch Guide!

Swift third edition coverSo, What’s New?

While “Updated for Xcode 12 and Swift 5.3” is absolutely true, it doesn’t tell the whole story of this 460-page tome.

We have made a number of other improvements that we think you will love.

Tools for Standing Alone

After you learn Swift, a great next step is to learn about iOS programming and development (I can recommend a great book on the subject).

No matter what your next step is, you have already learned useful skills by the end of this book. With that in mind, we wrote a brand new chapter about writing command line utilities using Swift’s Argument Parser library.

In addition to giving you the tools to build CLI utility apps for your Mac, the new chapter also introduces some important discussion around the filesystem, project organization, and the modularity of Swift, including how to import external libraries using the Swift Package Manager from within Xcode.

Tools for the Future

Developers wanting to eventually learn SwiftUI will be happy to know that we have included coverage of opaque types and property wrappers in this edition, two language features that enable SwiftUI’s elegant syntax.

We have worked hard to expand our discussion around advanced concepts such as memory management and troubleshooting reference cycles, the polymorphism enabled by Swift’s type system, working with closures, generics, and the important differences between value and reference types in your programs.

Lastly, we have included a discussion of the newer language features which have shifted how we think about our programs, such as the generic Result type.

For Dessert: A Taste of SwiftUI

Speaking of SwiftUI, you didn’t think we would leave that out, did you?

The last chapter of the book is a Big Nerd Ranch take on an introduction to building iOS and macOS apps with the SwiftUI framework.

This new chapter, which replaces the old “First Cocoa App” and “First iOS App” chapters with a single multi-platform iOS/macOS app in SwiftUI, takes care to introduce and explain some of the fundamental building blocks of SwiftUI apps. We also take this opportunity to extend our discussion of the filesystem and saving user data.

We think you’ll like where it takes you.

What’s Next?

We will continue to provide world-class training on how to develop apps for iOS, and we are building a SwiftUI Essentials course which we hope to offer in 2021. We look forward to continuing to engage with you and teach you as Apple’s platforms evolve.

But you can rest assured that as we learn more, we will share our passion and love for the latest Swift developments with you.

Keep your eye on this blog and our social media for more. Happy coding!

The post Now Available: Swift Programming: The Big Nerd Ranch Guide, Third Edition appeared first on Big Nerd Ranch.

]]>
New HEVC & HEIF Media Formats: What You Need to Know https://bignerdranch.com/blog/new-hevc-heif-media-formats-what-you-need-to-know/ https://bignerdranch.com/blog/new-hevc-heif-media-formats-what-you-need-to-know/#respond Wed, 07 Jun 2017 10:00:53 +0000 https://nerdranchighq.wpengine.com/blog/new-hevc-heif-media-formats-what-you-need-to-know/ 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.

The post New HEVC & HEIF Media Formats: What You Need to Know appeared first on Big Nerd Ranch.

]]>

Apple has long been very bullish on efficient media technology, almost singlehandedly popularizing H.264 as a web video encoding while leading the charge on the death of Adobe Flash.

Within our apps, Apple settled on PNG as the image format of choice for its powerful compression capabilities that maintain a high fidelity.

So, What’s the News?

Once again, Apple is bringing to the table some new image and video formats to push the platform foward by saving you storage space, bandwidth and computation time. Here’s the short version:

High Efficiency Video Coding (HEVC) is a codec for both images and videos, which requires almost half the storage space (and bandwidth) of H.264 and JPEG. Apple will reuse the existing .mov file extension for HEVC video files. HEVC is also called MPEG-H Part 2 and H.265 by industry standards bodies.

High Efficiency Image Format (HEIF) (pronounced “Heef”) is the file format for HEVC-encoded images, and will use the .heic file extension.

Neither of these formats are bleeding-edge, as both have been ratified by the ISO between 2013 and 2015. This means that many other industry players such as Adobe have already built HEVC/HEIF support into their software.

Yes, But Why Do I Care?

The vast majority of app developers can carry on as usual. Apple’s media frameworks and apps will transparently use HEVC and HEIF for internal encoding and storage, but will automatically transcode HEIF to JPEG or HEVC to H.264 when exporting media when the user sends an iMessage or the developer obtains a UIImagePickerControllerOriginalImage.

Relevant frameworks such as AVFoundation, CoreImage and even UIKit have new APIs in iOS 11 to allow you to request the new-format media if you prefer.

For example, UIImagePickerController’s new mediaExportPreset property defaults to .compatible, which will cause imagePickerController(_:didFinishPickingMediaWithInfo:) to vend a JPEG image, but you can change mediaExportPreset to .current to get a HEIF image instead.

For more on HEVC and HEIF, see WWDC 2017 Session 503: Introducing HEVC and HEIF

But I Stream HLS Video From a Server!

First, there is no requirement that you update your server to stream HEVC video. But you absolutely should, because at a sacrifice of 50% additional server storage (which is cheap), you can lop off half your bandwidth usage (which is not cheap) to supported devices.

Should you really bother doing it now? Isn’t HEVC support limited?

Nope! HEVC playback with software decoding will be available on all Macs running macOS High Sierra and all iOS devices running iOS 11. That means iPhones back to the 5S/SE, iPads back to the Air and Mini 2, and the 6th-gen iPod touch.

Some newer models (6th-gen Intel Core-based Macs and A9-based iOS devices) even have hardware decoding support already built-in for even further improved playback and decoding performance.

But I can support even more devices by using H.264 instead!

Do both! You can have both H.264 and HEVC streams in the same Master playlist. You will need to set the CODECS= attribute on your Media playlists to indicate HEVC support, and then clients will automatically choose the correct stream to meet their requirements.

Given its benefits, it is likely that HEVC will be widely supported across other operating systems (Android, Windows, etc.) in the future. For now, providing both H.264 and HEVC streams is the right choice for optimizing video bandwidth and performance for you iOS user base while not alienating your other target platforms.

Where do I learn more?

HLS content vendors need to:

Learn more about why you should update your apps for iOS 11 before launch day, or download our ebook for a deeper look into how the changes affect your business.

The post New HEVC & HEIF Media Formats: What You Need to Know appeared first on Big Nerd Ranch.

]]>
https://bignerdranch.com/blog/new-hevc-heif-media-formats-what-you-need-to-know/feed/ 0
Illuminating ARCLite https://bignerdranch.com/blog/illuminating-arclite/ https://bignerdranch.com/blog/illuminating-arclite/#respond Tue, 21 May 2013 20:21:37 +0000 https://nerdranchighq.wpengine.com/blog/illuminating-arclite/

Today we’re going to look at using Objective-C’s array and dictionary subscripting syntax with older iOS and OS X versions.

The post Illuminating ARCLite appeared first on Big Nerd Ranch.

]]>

Today we’re going to look at using Objective-C’s array and dictionary subscripting syntax with older iOS and OS X versions.

If you haven’t already, I can’t recommend enough reading Part 1 and Part 2 of Mark Dalrymple’s excellent two-part series about Objective-C’s literal/boxing/subscripting syntax. The code in those posts can be found on GitHub as a Gist.

Recap

When the literal syntax for creating dictionaries and arrays (and numbers) was announced, we as a developer community sang the praises of short, concise code. Then we were introduced to the subscripting syntax for the same, and many of us squealed with joy.

In case you’ve been living under a very large rock, I’m talking about our ability to read a value (and store one) in an NS(Mutable)Array using C-array-like syntax:

    NSMutableArray *cultOfSkaro = [NSMutableArray arrayWithObjects:@"Sec",@"Caan",@"Thay",@"Jast",nil];
    Dalek *leader = cultOfSkaro[0]; // The new hotness
    cultOfScaro[0] = [NSNull null]; // We can also write values!

And don’t forget dictionaries!

    NSMutableDictionary *theGuide = [NSMutableDictionary dictionary];
    theGuide[@"Earth"] = @"Mostly harmless."; // ...mostly.

This “new” subscripting syntax is super-duper wonderful for sparing us lots of typing.

The problem, of course, is that it’s still new. Subscripting is only supported at runtime in iOS 6 and OS X 10.8, and while we can dream, most clients are not yet ready to drop support for iOS 5 and OS X 10.7.

What makes this feature not backward-compatible? Consider that:

    cultOfScaro[0]

doesn’t equate to:

    [cultOfScaro objectAtIndex:0]

as we’d expect. It instead equates to:

    [cultOfScaro objectAtIndexedSubscript:0]

and that method doesn’t exist on NSArray in iOS 5 or OS X 10.7. We get the same raw deal with dictionaries, where

    theGuide[@"Earth"] = @"Mostly harmless.";

is short for:

    [theGuide setObject:@"Mostly harmless." forKeyedSubscript:@"Earth"];

So what do I do about it?

If you want to be able to use array and dictionary subscripting syntax with older versions of iOS and OS X, you’re in luck!

If you’re already familiar with Objective-C categories, you can just add the subscript-related methods to NS(Mutable)Array and NS(Mutable)Dictionary yourself!

For example, you could implement a cheap -objectAtIndexedSubscript: in a category on NSArray, like so:

    - (id)objectAtIndexedSubscript:(NSInteger)index
    {
        NSAssert(index >= 0, @"If you want negative indices, see Mark's posts linked above.");
        return [self objectAtIndex:index];
    }

And there you have it. This implementation isn’t particularly robust, but it would get you back to level ground for being allowed to use subscripting syntax for reading values.

But wait, there’s more!

Unfortunately, there are two problems with this approach. One is more technical and one more practical.

The technical problem is that when a category is loaded, its methods are installed onto their appropriate classes, which is a good thing. If you implement a method in a category that was already present on the class, however, you replace that method. It’s generally poor form to replace a method whose implementation you didn’t write (or don’t fully understand). On devices running iOS 5, we’d be adding the method, but under iOS 6, we’d be replacing it. Harrumph.

The practical problem is that we’d be wasting our time to begin with! Apple has already provided us with a mechanism for utilizing subscripting syntax with older deployment targets.

You’re welcome to try it yourself. Take a new command line project, set its deployment target to OS X 10.7, and give it a basic test:

    #import <Foundation/Foundation.h>

    int main(int argc, const char * argv[])
    {
        @autoreleasepool {
            NSArray *strings = @[@"E",@"G",@"B",@"D",@"F"];
            NSString *eString = strings[0];
            NSLog(@"%@",eString);
        }
        return 0;

You’ll find that this (tiny) app will build and run just fine, even on a Mac running OS X 10.7. It just works! Magic!

Welp, that was a short blog post. Cheers!

Not so fast, Bub.

Nerds tend not to like magic. Oh, we love to see a good trick. But things that we can’t explain really tend to get under our skin.

“Now, Mikey,” you might ask, “what in tarnation is going on that makes this work?”

First, I’d laugh at you for using a word like “tarnation”. Then, I’d tell you a short story about a small library called ARCLite.

When ARC was first introduced, our minds were blown. We could feel years being added to our lives at the thought of not having to write -retain and -release calls anymore. Even better, it turned out that ARC was backward-compatible! But how?

Apple had provided a build shim in the form of a static library called libarclite. Xcode 4.2 and later knew to link against this library anytime you built a project with a deployment target of iOS 4 or Mac OS X 10.6 with ARC enabled. This library provides ARC support for older systems.

It turns out that the-little-lib-that-could has also taken up the torch of providing older systems with support for container subscripting, while also solving our technical problem above: libarclite provides implementations of -objectAtIndexedSubscript: and friends to the container classes on iOS 5 without replacing the implementations provided by iOS 6.

libarclite does this by waiting until runtime to decide whether or not to add the method, by first finding out whether the method already exists.

Waiting until whattime?

If you’ve ever swizzled a method, go ahead and move on. If you haven’t, you’ll want to be seated for this bit. We’re going to talk about the Objective-C runtime library, and use it to understand a bit about how Apple’s pulling off the feat of only adding a category method when it doesn’t already exist.

The Objective-C runtime is the beating heart of a Cocoa application. It’s the low-level bit that puts the “Objective” in Objective-C by teaching C how to be object-oriented. The runtime library is also almost completely open source! We’re interested in one particular and integral header, however: runtime.h.

If you take a moment to browse this file, your imagination will start to run wild with possibilities. With these functions, you can define an entire class after your program has started running! There’s not really much practical use for such a thing (in our position), but when has that ever stopped us from trying? In fact, runtime class definition is how KVO works! But that could be a totally separate post.

There’s a specific function of interest to us in runtime.h:

    OBJC_EXPORT BOOL class_addMethod(Class cls, SEL name, IMP imp, const char *types)

This function allows you to attach to a class an entirely new method that didn’t appear in the class’ header or implementation file. Of course, the method must be defined somewhere in your code, but this function allows you to attach it to a class that didn’t have it before.

The class_addMethod() function takes four parameters:

  • a Class to which the method should be added, such as that returned by [NSString class]. Just as @"Hello" is an instance of type NSString*, NSString itself is of type Class.

  • a selector that names the method—yes, the same sort of selector that you use with NSTimer

  • a function pointer to the actual implementation of the method you wish to add, and

  • a C character array describing the types of arguments the method accepts

The function returns a BOOL indicating the success or failure of the method addition. The function will fail and return NO if the target Class already has a method with the specified selector.

So what now?

How can we use class_addMethod() for ultimate science?

Let’s do it. Step zero? Import runtime.h so that we can use the functions declared there:

First, we’ll go ahead and create our NSArray+Subscripting category, as we discussed at the beginning of the post:

    @implementation NSArray (Subscripting)
    - (void)bnr_objectAtIndexedSubscript:(NSInteger)index
    {
        return [self objectAtIndex:index];
    }

You’ll notice immediately that I’ve changed the name of the subscripting method. Remember that if I’d named it:

    - (void)objectAtIndexedSubscript:(NSInteger)index

then this method would be installed on NSArray as is, regardless of the OS version. We don’t want that, so we define the method using a fake/temporary name.

For this same reason, we should always namespace our category methods like this (prefixing the method name with an identifier of some sort, such as bnr_ above) so that we don’t accidentally replace methods that we didn’t even know existed.

The second step is to find a place to put our call to class_addMethod(). We want to implement or override a method that we know will execute very early in an application run.

When an application launches, one of the very first things that happens (even before main() is called!) is that each class that the application will use is loaded into the runtime. Each class is sent the +load message (and, because it’s special and doesn’t play by the usual rules, to each category on each class). This is a dangerous place for most types of activity, but it’s the perfect place to make changes to the runtime. That’s not to say that making runtime changes is always safe, mind you.

So, here’s our NSArray+Subscripting.m:

    #import "NSArray+Subscripting.h"
    #import <objc/runtime.h>

    @implementation NSArray (Subscripting)
    + (void)load
    {
        class_addMethod([NSArray class],
                    @selector(objectAtIndexedSubscript:),
                    method_getImplementation(bnr_objectAtIndexedSubscript:),
                    method_getTypeEncoding(bnr_objectAtIndexedSubscript:)
                    );
    }
    - (void)bnr_objectAtIndexedSubscript:(NSInteger)index
    {
        return [self objectAtIndex:index];
    }

There are some fantastic bits at work here. First, class_addMethod() will fail if a method already exists with the passed-in selector. Second, arguments that initially looked incredibly daunting when we saw this function’s declaration (what on earth is an IMP or a type encoding?) are satisfied by calling other runtime functions from runtime.h! It feels like cheating!

I challenge you now to spend some time looking through the documentation for the various functions in runtime.h, and experimenting on your own.

Excellent, so this is all I need to get subscripting in iOS 5?

Not so fast. Remember, Apple is already doing this (or something like it) for you with libarclite! We’ve meandered down the runtime’s rabbit-hole as an exercise in pulling away the magic curtains, as it were.

There are certainly plenty of runtime hacks at varying levels of evil and danger that you may find useful in your own application, but this one’s already been done for you.

If you’re interested in learning more about the Objective-C runtime and its dark secrets, sound off in the comments.

Also, check out these excellent resources: *

The post Illuminating ARCLite appeared first on Big Nerd Ranch.

]]>
https://bignerdranch.com/blog/illuminating-arclite/feed/ 0