Best objective-c questions in October 2010

Check iOS version at runtime?

9 votes

This is sort of a follow on from my last question. I am using beginAnimations:context: to setup an animation block to animate some UITextLabels. However I noticed in the docs that is says: "Use of this method is discouraged in iOS 4.0 and later. You should use the block-based animation methods instead."

My question is I would love to use animateWithDuration:animations: (available in iOS 4.0 and later) but do not want to exclude folks using iOS 3.0. Is there a way to check to iOS version of a device at runtime so that I can make a decision as to which statement to use?

You must not check iOS version, instead of that you must check in runtime if a particular method is present or not. In your case you can do the following:

if ([[UIView class] respondsToSelector:@selector(animateWithDuration:animations:)]){
// animate using blocks
}
else {
// animate the "old way"
}

How do I flag a method as deprecated in Objective-C 2.0?

9 votes

I'm part of a team developing a fairly large iPad app and there are many different classes we've created as a result. The trouble is some of the methods are now pretty much obsolete and I don't want simply remove them yet as I know some parts of the overall system use the methods... but there are better (newer) variants available which should be used instead (some of the old ones actually call the new ones, but the overall class interface is getting messy).

Is there a way in which I can mark certain methods as depreciated (like @deprecated in Java and [Obsolete] in .NET).

I see that Apple use Availability.h and have tags such as

__OSX_AVAILABLE_BUT_DEPRECATED(__MAC_NA,__MAC_NA,__IPHONE_2_0,__IPHONE_3_0);

... is this the only way to do it (+ is it App Store safe to do this?) or are there alternatives which will flag a warning in XCode?

Source

Deprecation Syntax

Syntax is provided to mark methods as deprecated:

@interface SomeClass
-method __attribute__((deprecated));
@end

or:

#include <AvailabilityMacros.h>
@interface SomeClass
-method DEPRECATED_ATTRIBUTE;  // or some other deployment-target-specific macro
@end

TTPickerTextField example

9 votes

I've been trying all day and just can't make the the TTPickerTextField work. It displays, I set its dataSource to the example code's MockDataSource and type in a name from the mock and it doesn't work. There doesn't seem to be any documentation or any examples anywhere on the internet, something that I find surprising.

So: does anyone have (or can anyone throw together) a really simple example of how the TTPickerTextField works? All I want to do is have someone type something in and put it in a bubble, like in the iPhone Mail app.

Have you seen this example?

https://github.com/shayne/TTPickerTextFieldDemo

Erlang as an embedded system within an application?

9 votes

I have quite a lot of code written in Erlang, which I want to include in applications written in Objective-C, eg on the iPad. Ideally I would want to have an object that encapsulates the Erlang run-time; this could then be accessed like the standard Erlang shell, something along the lines of:

ErlangRT *runtime = [[ErlangRT alloc] init];
ErlangValue *retval = [runtime execute:@"io:format(\"hello world~n\")"];

I don't care too much about performance etc; I can see how it could work, but as I don't know too much about the way the Erlang VM is implemented I have no idea how easy or difficult it is to do, or if anybody has already done something similar. I know there are other ways of interfacing between Objective-C and Erlang, but they seem to assume an independently installed Erlang system on the target machine. I would prefer it to be like a library that you simply link in with the application.

So my question is: is this comparatively easy to do, and/or has somebody already worked on this?

We've got Erlang working on the iPhone (and approved for the App Store) as part of our package of Apache CouchDB for iOS. The Github project is here: https://github.com/couchbaselabs/iOS-Couchbase

The Erlang we use is here: https://github.com/couchbaselabs/iErl14

More info on Mobile Couchbase: http://www.couchbase.com/products-and-services/mobile-couchbase

Enjoy!

Chris

Differences Between Cocoa and iPhone development

8 votes

I'm currently reading Aaron Hillegass' book "Cocoa Programming for Mac OS X" as it is highly recommended throughout the community. I'm wondering if there's an extreme difference between "Cocoa Programming" and iPhone development. I'm more interested in iPhone development, but I figured iPhone development would be easier to pick up if I was comfortable with Cocoa before moving on.

iPhone programming is a form of Cocoa (technically "Cocoa Touch"). It shares almost all the same programming idioms, and there's a huge overlap in the frameworks.

Hillegass' book is a great starting point for either. After about chapter 7 in Hillegass, you'll start getting into more "Mac" topics like document window management etc. None of this is bad to understand, but that's where it begins to differ in the details, and you'll find that it won't translate quite so directly.

The patterns he teaches you to think in will be useful in all cases. But the actual classes and objects you use for the Mac stuff don't all have equivalences in the iPhone world. On iOS, the view management (UIView) is quite different from Mac's NSView stuff. It's actually simpler and easier to understand on the iPhone, I found.

Hillegass has a new iPhone-specific book out. I haven't browsed through it yet.

Smalltalk blocks in Objective-c?

8 votes

Does Objective-C support blocks "a la Smalltalk"?

In Smalltalk, blocks are similar to "closures" or "lambda-expressions" or "nameless functions" found in other languages.

Yes: http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/Blocks/Articles/00_Introduction.html

Out of the box, they're only supported in the version of Objective-C 2.0 that comes with XCode 3.2. This means you'll need Snow Leopard if you want to use the official build tools. A potential work-around for 10.5 is described here: http://thirdcog.eu/pwcblocks/#leoiphone

Blocks instead of performSelector:withObject:afterDelay:

8 votes

I often want to execute some code a few microseconds in the future. Right now, I solve it like this:

- (void)someMethod
{
    // some code
}

And this:

[self performSelector:@selector(someMethod) withObject:nil afterDelay:0.1];

It works, but I have to create a new method every time. Is it possible to use blocks instead of this? Basically I'm looking for a method like:

[self performBlock:^{
    // some code
} afterDelay:0.1];

That would be really useful to me.

There's no built-in way to do that, but it's not too bad to add via a category:

@implementation NSObject (PerformBlockAfterDelay)

- (void)performBlock:(void (^)(void))block 
          afterDelay:(NSTimeInterval)delay 
{
    block = [[block copy] autorelease];
    [self performSelector:@selector(fireBlockAfterDelay:) 
               withObject:block 
               afterDelay:delay];
}

- (void)fireBlockAfterDelay:(void (^)(void))block {
    block();
}

@end

Credit to Mike Ash for the basic implementation.

Is array of Object possible in Objective C?

7 votes

I'm quite new to objective-c. I have problems when creating array of objects. In java it is possible to make array of object and can access individual instances directly.

For example,

SomeClass[] instance = new SomeClass[10];
instance[i].var=10;

Is there any way to do like this in objetive-c? Can I access the instance variable in array of object directly using index? An example would be of more help. Thanks in advance

Using the Foundation Framework (which you almost certainly will be if you're using Objective-C):

NSString *object1 = @"an object";
NSString *object2 = @"another object";
NSArray *myArray = [NSArray arrayWithObjects:object1, object2, nil];

NSString *str = [myArray objectAtIndex:1];

Here, str will be a reference to object 2 (which contains another object). Note that the nil 'terminates' the list of objects in the array, and is required. If you want a mutable (modifiable) array:

NSString *object1 = @"an object";
NSString *object2 = @"another object";
NSMutableArray *myMutableArray = [NSMutableArray array];

[myMutableArray addObject:object1];
[myMutableArray addObject:object2];

What is the point in a retain immediately followed by an autorelease?

7 votes

I'm looking at some open source code and trying to understand why the author has done something in a particular way.

The class is a wrapper around NSArray to create a stack data structure with push, pop, etc.

One method is topObject which returns the topmost object on the stack and its implementation is:

- (id)top {
    return [[[stack lastObject] retain] autorelease]; // stack is an instance of NSMutableArray
}

What's with the retain followed by an immediate autorelease?

My initial reaction was that this would prevent an analyser warning about a memory leak, but I analysed without the retain/autorelease and there was still no warning.

Looking at the lifecycle, an object would be created, pushed to the stack and released, so the stack owns the object (the underlying array will retain it upon adding).

So I don't understand the use of the retain/autorelease here...

Let's assume top would look like this:

- (id) top {
    return [stack lastObject];
}

Then imagine this:

foo = [bar top];
[bar removeAllObjects];
// Do something with foo

The following would happen: The second line would make the retain count drop to 0, and by the third line foo would point to deallocated memory. But with the retain and autorelease the retain count is 1, until the pool is emptied thus on the third line foo would still point to a valid object.

Good Learning Method for Objective-C?

6 votes

I know this must be asked a millions times and can't be easy to answer as there is o definitive method, but any help would be appreciated, thanks.

I have been playing around with all sorts of things in Xcode and with Objective-C, however I can't seem to find a good way of learning things in an efficient way.

I have bought the book 'Programming in Objective-C 2.0' and its great but just lays down the basics it seems.

I want to learn in the 2D game development direction, then of course 3D after nailing that, if thats the right thing to do?

I am 17 currently in year 13, last year of school/A Levels and am almost definitely taking a gap year. Any good, well known reputable courses online or offline (real world)? This is my first programming language, and I am absolutely serious about learning this.

One last question, is when learning things online, I have in the past started building a feature and learning a certain aspect in programming only to find out after adding more its slows down the app or its to inefficient. Is the key to use a certain method in a certain situation (being os many ways to do the same thing) or use any of those methods and refine it in your app to make it run smoothly? Sorry, its hard for me to know when I have little experience, thus far.

Sorry for rambling on! I would appreciate any help, thank you!

Cocoa and Objective-C Resources helped me a lot. It focuses more on mac programming than iOS.

How-to articles for iPhone development, Objective-C covers the iOS side very well.

How to create a Static NSMutableArray in a class in Objective c?

6 votes

I have Class A which is super class for both class B and class C. I need to store the objects of Class A in 'static' NSMutablearray defined in Class A. Is it possible to modify data stored in MSMutableArray using methods in Class B and Class C? How to create and initialize Static array? An example would be of more help. thanks in advance.

Here is one way to do it.

@interface ClassA : NSObject
{
}

-(NSMutableArray*) myStaticArray;

@end

@implementation ClassA

-(NSMutableArray*) myStaticArray
{
    static NSMutableArray* theArray = nil;
    if (theArray == nil)
    {
        theArray = [[NSMutableArray alloc] init];
    }
    return theArray;
}

@end

That is a pattern I use quite a lot instead of true singletons. Objects of ClassA and its subclasses can use it like this:

[[self myStaticArray] addObject: foo];

There are variations you can consider e.g. you can make the method a class method. You might also want to make the method thread safe in a multithreaded environment. e.g.

-(NSMutableArray*) myStaticArray
{
    static NSMutableArray* theArray = nil;
    @synchronized([ClassA class])
    {
        if (theArray == nil)
        {
            theArray = [[NSMutableArray alloc] init];
        }
    }
    return theArray;
}

Getting current device language in iOS?

6 votes

I'd like to show the current language that the device UI is using. What code would I use?

I want this as an NSString in fully spelled out format. (Not @"en_US")

This will probably give you what you want:

NSLocale *locale = [NSLocale currentLocale];

NSString *language = [locale displayNameForKey:NSLocaleIdentifier 
                                         value:[locale localeIdentifier]];

It will show the name of the language, in the language itself. For example:

Français (France)
English (United States)

How safe is information contained within iPhone app compiled code?

6 votes

I was discussing this with some friends and we began to wonder about this. Could someone gain access to URLs or other values that are contained in the actual objective-c code after they purchase your app?

Our initial feeling was no, but I wondered if anyone out there had definitive knowledge one way or the other?

I do know that .plist files are readily available.

Examples could be things like:

-URL values kept in a string

-API key and secret values

Yes, strings and information are easily extractable from compiled applications using the strings tool (see here), and it's actually even pretty easy to extract class information using class-dump-x (check here).

Just some food for thought.

Edit: one easy, albeit insecure, way of keeping your secret information hidden is obfuscating it, or cutting it up into small pieces.

The following code:

NSString *string = @"Hello, World!";

will produce "Hello, World!" using the strings tool. Writing your code like this:

NSString *string = @"H";
string = [stringByAppendingString:@"el"];
string = [stringByAppendingString:@"lo"];
...

will show the characters typed, but not necessarily in order.

Again: easy to do, but not very secure.

MPMoviePlayer load and play movie saved in app documents

6 votes

I am writing an application that stores the movies in the photo roll into the local documents folder for the app. I can play remote movies using the MPMoviePlayer, however trying to play a movie stored in the documents folder for the app always returns MPMovieLoadStateUnknown.

The notifications are all getting sent and received from the default notification center (MPMoviePlayerLoadStateDidChangeNotification, MPMoviePlayerPlaybackDidFinishNotification). An alert box shows up shortly after getting the loadStateUnknown message in the console, saying that the movie could not be played and the app then receives the movie playback completed notification.

I think that it may be a case that the filename (MPMoviePlayer can only take a URL as the asset location) cannot be found. Has anyone dealt with this issue or similar?

Given that none of the other answers seem to resolve the problem, I'm inclined to think that the problem might be with the Documents file path you are producing.

You should be using the following method to generate the path to the application's documents folder:

NSString *userDocumentsPath = nil;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
if ([paths count] > 0) 
{
     userDocumentsPath = [paths objectAtIndex:0];
}

I want to learn Objective-c, but...

6 votes

...I am not sure which book to go with.

I came to conclusion and it's between those two: [Programming in Objective-C 2.0] vs. [Learn Objective-C on the Mac].

My programming experience/skill is fairly strict, as I just know a little C. I know some loops (if, if-else, while, for, do, case) and how algorithm work. That's pretty much it, I have no experience in pointers, I/O or more advanced stuff. I read nearly half of the book [Learn C on the Mac], until Chapter 7: Pointers and Parameters. I liked the book, it gave me a push inside the World of Programming and learned me the basics and thought that was enough to go on with Objective-C.

But I am not sure what to do from here: which book to continue reading in. I have started reading a little in [Programming in Objective-C 2.0] until chapter 4, but I have had a hard time follow him. I am not sure if I get the syntax correctly and if I understand the different class, objects, methods and instances properly. But that's not the question for now, sorry for off-topic :P

What would you recommend for me to read, based on the knowledge I have in programming (with only a procedural language like C)? Would you even recommend me to read a back or start somewhere else? I read that Kochan's book is the single best, but I am not sure if it's too advanced stuff for me. What is your impression on the book?

Thank you all so very much in advance!

  • P.S. My native language is Danish, so sorry for typos and grammar mistakes
  • P.P.S. This is my first post to this board, I just signed up. Please correct me if I did something wrong. Thank you.

Cocoa Programming for Mac OS X, by Aaron Hillegas.

Brown noise on cocoa

6 votes

How can I create a brown noise generator using Cocoa?

BTW Brown noise is similar to pink and white noise and has nothing to do with "The brown note" or anything silly. See http://www.mediacollege.com/audio/noise/brown-noise.html

I thought I saw some open source white noise Core Audio audio units around the web but I can't find them. In any case I'd start there since the basics are the same. I think Brown noise is just a few differently set parameters / ranges.

MusicKit might certainly work but Core Audio is part of the OS and likely a lot more CPU-friendly because of that.