Archive

Archive for the ‘cocoa’ Category

Wrapping C++ Final Edition

May 12th, 2012 No comments

I have always strong recommended segregating Objective-C and C++ code with a thin Objective-C++ wrapper. I do not like Objective-C++. It is useful for what it does, but it is a mess of a “language.” It has many downsides, for slower compiles and poor debugging facilities, to confusing code and inefficient ARC code. .mm is a blight on your code. Never let it spread.

That said, Objective-C++ is invaluable for integrating C++ into Objective-C. And while I am not a great lover of C++, it is a very useful language and there is a great deal of excellent code written in it that is well-worth reusing in your Cocoa projects. Many of Apple’s frameworks are implemented in C++.

So my recommendation for those who have existing C++ logic code has always been thus: write your UI in pure Objective-C (.m). Write your “middleware” in pure C++ (.cpp). And have a thin Objective-C++ (.mm) wrapper layer to glue them together. Your ObjC++ API should ideally exactly match your C++ API, just converting types (for instance converting std::string to and from NSString).

(As a side note, I also recommend that OS-related things like file management, network management, and threading all be handled natively. GCD is much better than pthreads. NSURLConnection is much better than writing your own C++ networking layer in BSD sockets. But this is tangental to the main point.)

Saying all that, how do you wrap a C++ object so that Objective-C can read it? This used to be a question that required some significant thought. See Wrapping C++, Take 2 Part 1 and Part 2 for my previous thinking on the subject.

Improvements in Objective-C have made all of the previous hoop-jumping irrelevant. The problem all my previous solutions was trying to solve was that you had to declare ivars in the header. Your ivar was a C++ class (which might be in a namespace or might be a template), and that made it difficult to declare in the header without forcing all the importers to be ObjC++. So to solve this generally you needed opaque types, or at the very least forward declared structs, etc. And it was all a big pain.

But that’s over. You can now declare all your ivars in the implementation file. So everything’s easy. Your wrapper class can have C++ ivars without having any impact on users of the wrapper class.

Consider a simple C++ class (but throwing in the headache of a namespace):

namespace MY {
class Cpp {
  public:
    std::string getName() { return _name; };
    void setName(std::string aName) { _name = aName; };
  private:
    std::string _name;
};
}

The wrapper for this is trivial:

@interface CPPWrapper : NSObject
@property (nonatomic, readwrite, copy) NSString *name;
@end

@interface CPPWrapper ()
@property (nonatomic, readwrite, assign) MY::Cpp *cpp;
@end

@implementation CPPWrapper
@synthesize cpp = _cpp;

- (id)init {
  self = [super init];
  if (self) {
    _cpp = new MY::Cpp();
  }
  return self;
}

- (void)dealloc {
  delete _cpp;
}

- (NSString *)name {
  return [NSString stringWithUTF8String:self.cpp->getName().c_str()];
}

- (void)setName:(NSString *)aName {
  self.cpp->setName([aName UTF8String]);
}
@end

Couldn’t be easier really. The one headache that really remains in my experience is enums inside of a namespace (or more generally enums declared in a C++ header). The best solution is to use #if __cplusplus blocks to strip away the namespace and still declare the enum in pure C. Do this if at all possible. Otherwise you’ll wind up with an C enum that mirrors the C++ enum. This is a maintenance nightmare, since changes to the C++ enum will often be missed in the ObjC enum, and you’ll get very difficult-to-debug errors with enum mismatches.

Just to ask and answer a possible question: why *Cpp and not just Cpp? The reason is that in almost all cases the C++ object will be created outside of your wrappers. So in almost all cases, there’s going to be a method like initWithCpp:(Cpp *)cpp. How does that work? Easy, wrap it in #if __cplusplus:

#if __cplusplus
#include "Cpp.h"
...
- (CppWrapper *)initWithCpp:(Cpp *)cpp;
#endif

Anyway, most of my research into opaque types and generally how to manage C++ wrappers has now become trivial. I’m just giving one more post to let you all know that. (And because Orpheus asked.) Post comments if there are more questions.

Categories: cocoa Tags:

Triangle CocoaHeads (and Building a (Core) Foundation)

March 23rd, 2012 No comments

Last night’s CocoaHeads was a blast. Alondo, you have to come give an intermediate/advanced talk on Storyboards. Thanks a lot to @scottpenrose for his lightning and thunder, and @flightblog for his inspiration (METAR gave me a lot of headaches, too). And of course, thanks especially to Josh for organizing everything. And a new place for NSCoder? You rock.

For those who didn’t scribble notes fast enough, my Core Foundation presentation is attached (including the fix for my memory leak; was it Jay who found that?) I’ll make sure to fix the code in the book for the next edition.

Building a Core Foundation.pdf

Categories: cocoa, iphone Tags: ,

Even Faster Bezier

March 6th, 2012 No comments

When last we looked at Bézier curve calculations, we were able to calculate five million points in about 0.6s (~8.3Mp/s or megapoints-per-second). That’s 1000 points per curve, 100 curves, at 50fps. That was 5x faster than the original -Os optimized function. But we’re just getting warmed up. We haven’t yet gotten half of the performance available.

Read more…

Categories: cocoa, iphone, performance Tags:

Introduction to Fast Bezier (and trying the Accelerate.framework)

February 24th, 2012 No comments

[If you want the answer to last time's homework, skip to the end.]

So you want to hand-calculate Bézier curves. Good for you. It comes up more often then you’d think on iOS, even though UIBezierPath is supposed to do it all for you. The truth is, sometimes you need the numbers yourself. For instance if you want to calculate intersections, or you want to draw text along the curve (like in CurvyText from iOS:PTL chapter 18). Read more…

Categories: cocoa, iphone, performance Tags:

Converting algebra to matrices for Accelerate framework

February 6th, 2012 No comments

Chapter 18 of iOS:PTL includes code for calculating points on a Bézier curve (see CurvyText in the sample code). In the book, I hinted that this operation would likely be well suited to the Accelerate framework. The Accelerate framework provides hardware-accelerated vector operations. Solving Bézier equations seems a perfect fit. I’ll get more into Accelerate in later posts (including some thoughts on when to use it), but first I need to introduce some mathematical groundwork.

In this post, I’m targeting a specific kind of developer; one like myself. My mathematically inclined friends will find this so trivial that it’s hardly worth discussing. For those of you who have never seen a matrix before, this may be a bit dense. But if you’re like me, and once upon a time you actually took linear algebra, but today you wouldn’t know a transpose if it invited you to dinner, this may help. (The last time I computed a dot-product, the Newton hadn’t been released…) My goal isn’t to teach you Guassian elimination or eigenvalues. My goal is to show you by example the specific tools you need to convert the math you find in a book into matrices so you can calculate it faster. (And how to cheat with the incredible new tools available to us.)

Read more…
Categories: cocoa Tags:

Drop-in offline caching for UIWebView (and NSURLProtocol)

January 29th, 2012 36 comments

The most up-to-date source for this is now available at github.

Your programs need to deal gracefully with being offline. Mugunth Kumar has built an excellent toolkit that manages REST connections while offline called MKNetworkKit, and Chapter 17 of our book is devoted to the ins-and-outs of this subject.

But sometimes you just have a simple UIWebView, and you want to cache the last version of the page. You’d think that NSURLCache would handle this for you, but it’s much more complicated than that. NSURLCache doesn’t cache everything you’d think it would. Sometimes this is because of Apple’s decisions in order to save space. Just as often, however, it’s because the HTTP caching rules explicitly prevent caching a particular resource.

What I wanted was a simple mechanism for the following case:

  • You have a UIWebView that points to a website with embedded images
  • When you’re online, you want the normal caching algorithms (nothing fancy)
  • When you’re offline, you want to show the last version of the page

My test case was simple: a webview that loads cnn.com (a nice complicated webpage with lots of images). Run it once. Quit. Turn off the network. Run it again. CNN should display.

Read more…

Categories: cocoa, iphone Tags:

iOS 5 Programming in Adobe E-Book format

December 16th, 2011 3 comments

For those who have asked, the Adobe E-Book version of iOS 5 Programming is available now from Wiley. I’m not certain yet when the Kindle version will be out, but I’m looking into it, along with getting a list of what other formats are planned.

Categories: cocoa, iphone Tags:

A moment in the sun

December 15th, 2011 3 comments

I have no idea what Amazon rankings really mean right around a book launch. Since they weight towards recent sales, I’m sure they spike, so you have to take these things with a grain of salt. But for at least a little while, we have the #1 book in Mobile & Wireless Programming. I promise I won’t keep spamming you all with book updates, but it’s the first time I’ve been at the top of a “best sellers” list.

Amazon's product details 2011-12-14

Categories: cocoa, iphone Tags:

The book is almost here

December 11th, 2011 2 comments

I’ve mentioned that Mugunth Kumar and I have been working on a book, iOS 5 Programming Pushing the Limits. It’s available now for pre-order and should be shipping by 12/20. It will be available in several eBook formats, though I don’t have all the details for that yet. I’m proud of what we’ve been able to put together here. The target audience are developers who have some iOS development under their belts, and are ready to move to the next level. Rather than just focus on the nuts and bolts of getting things done, we cover how to do things well. In the process, we cover a lot of more advanced ground, often of frameworks with “Core” in their names like Core Animation, Core Text, and Core Foundation. We also address practical issues like how to optimize your application for offline work, and how to best handle REST and JSON.

Please send any comments or corrections to me at robnapier@gmail.com. In the meantime, you can take a look at the example code.

Categories: cocoa, iphone Tags:

Properly encrypting with AES with CommonCrypto

August 11th, 2011 57 comments

Update: You can now download the full example code from my book at GitHub. This comes from Chapter 11, “Batten the Hatches with Security Services.”

Update2: The things described here are handled automatically by RNCryptor, which is an easier approach unless you want to write your own solution.

I see a lot of example code out there showing how to use CCCrypt(), and most of it is unfortunately wrong. Since I just got finished writing about 10 pages of explanation for my upcoming book, I thought I’d post a shortened form here and hopefully help clear things up a little. This is going to be a little bit of a whirlwind, focused on the simplest case. If you want the gory details including performance improvements for large amounts of data, well, the book will be out later this year. :D

Read more…

Categories: cocoa, iphone, Security Tags: