Best objective-c questions in February 2011

How to draw a color wheel in objective-c

12 votes

I am trying to draw a color wheel for an iPhone, but I can't get the gradient to rotate around a point. I am trying to use gradients but objective-c provides a linear gradient, which draws a gradient in a straight line like this: linear gradient

and a radial gradient, which draws the gradient starting at point and radiating out in all directions like this: radial gradient

I want to draw a linear gradient that rotates around a point like this:

colorwheel

The following draws an HSL color wheel in a UIView subclass. It does this by generating a bitmap by computing, for each pixel, the correct color value. This is not exactly what you're trying to do (looks like it's just hue varies in the circle with a constant luminance/saturation), but you should be able to adapt it for your needs.

Note that this may not have optimal performance, but it should get you started. Also, you can use getColorWheelValue() to handle user input (clicks/touches at a given coordinate).

- (void)drawRect:(CGRect)rect
{
    int dim = self.bounds.size.width; // should always be square.
    bitmapData = CFDataCreateMutable(NULL, 0);
    CFDataSetLength(bitmapData, dim * dim * 4);
    generateColorWheelBitmap(CFDataGetMutableBytePtr(bitmapData), dim, luminance);
    UIImage *image = createUIImageWithRGBAData(bitmapData, self.bounds.size.width, self.bounds.size.height);
    CFRelease(bitmapData);
    [image drawAtPoint:CGPointZero];
    [image release];
}

void generateColorWheelBitmap(UInt8 *bitmap, int widthHeight, float l)
{
    // I think maybe you can do 1/3 of the pie, then do something smart to generate the other two parts, but for now we'll brute force it.
    for (int y = 0; y < widthHeight; y++)
    {
        for (int x = 0; x < widthHeight; x++)
        {
            float h, s, r, g, b, a;
            getColorWheelValue(widthHeight, x, y, &h, &s);
            if (s < 1.0)
            {
                // Antialias the edge of the circle.
                if (s > 0.99) a = (1.0 - s) * 100;
                else a = 1.0;

                HSL2RGB(h, s, l, &r, &g, &b);
            }
            else
            {
                r = g = b = a = 0.0f;
            }

            int i = 4 * (x + y * widthHeight);
            bitmap[i] = r * 0xff;
            bitmap[i+1] = g * 0xff;
            bitmap[i+2] = b * 0xff;
            bitmap[i+3] = a * 0xff;
        }
    }
}

void getColorWheelValue(int widthHeight, int x, int y, float *outH, float *outS)
{
    int c = widthHeight / 2;
    float dx = (float)(x - c) / c;
    float dy = (float)(y - c) / c;
    float d = sqrtf((float)(dx*dx + dy*dy));
    *outS = d;
    *outH = acosf((float)dx / d) / M_PI / 2.0f;
    if (dy < 0) *outH = 1.0 - *outH;
}

UIImage *createUIImageWithRGBAData(CFDataRef data, int width, int height)
{
    CGDataProviderRef dataProvider = CGDataProviderCreateWithCFData(data);
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    CGImageRef imageRef = CGImageCreate(width, height, 8, 32, width * 4, colorSpace, kCGImageAlphaLast, dataProvider, NULL, 0, kCGRenderingIntentDefault);
    UIImage *image = [[UIImage alloc] initWithCGImage:imageRef];
    CGDataProviderRelease(dataProvider);
    CGColorSpaceRelease(colorSpace);
    CGImageRelease(imageRef);
    return image;
}

// Adapted from Apple sample code.  See http://en.wikipedia.org/wiki/HSV_color_space#Comparison_of_HSL_and_HSV
void HSL2RGB(float h, float s, float l, float* outR, float* outG, float* outB)
{
    float temp1, temp2;
    float temp[3];
    int i;

    // Check for saturation. If there isn't any just return the luminance value for each, which results in gray.
    if(s == 0.0)
    {
        *outR = l;
        *outG = l;
        *outB = l;
        return;
    }

    // Test for luminance and compute temporary values based on luminance and saturation 
    if(l < 0.5)
        temp2 = l * (1.0 + s);
    else
        temp2 = l + s - l * s;
    temp1 = 2.0 * l - temp2;

    // Compute intermediate values based on hue
    temp[0] = h + 1.0 / 3.0;
    temp[1] = h;
    temp[2] = h - 1.0 / 3.0;

    for(i = 0; i < 3; ++i)
    {
        // Adjust the range
        if(temp[i] < 0.0)
            temp[i] += 1.0;
        if(temp[i] > 1.0)
            temp[i] -= 1.0;


        if(6.0 * temp[i] < 1.0)
            temp[i] = temp1 + (temp2 - temp1) * 6.0 * temp[i];
        else {
            if(2.0 * temp[i] < 1.0)
                temp[i] = temp2;
            else {
                if(3.0 * temp[i] < 2.0)
                    temp[i] = temp1 + (temp2 - temp1) * ((2.0 / 3.0) - temp[i]) * 6.0;
                else
                    temp[i] = temp1;
            }
        }
    }

    // Assign temporary values to R, G, B
    *outR = temp[0];
    *outG = temp[1];
    *outB = temp[2];
}

How to constrain autorotation to a single orientation for some views, while allowing all orientations on others?

9 votes

This question is about iOS device rotation and multiple controlled views in a UINavigationController. Some views should be constrained to portrait orientation, and some should autorotate freely. If you try and create the simplest setup with three views, you'll notice that the autorotation behavior has a few very nasty quirks. The scenario is, however, very simple, so I think I'm either not doing the autorotation implementation correctly, or I'm forgetting something.

I have a very basic demo app that shows the weirdness, and I made a video showing it in action.

The setup is very basic: Three view controllers called FirstViewController, SecondViewController and ThirdViewController all extend an AbstractViewController that shows a label with the class' name and that return YES for shouldAutorotateToInterfaceOrientation: when the device is in portrait orientation. The SecondViewController overrides the this method to allow for all rotations. All three concrete classes add a few colored squares to be able to navigate between the views by pushing and popping the controllers onto/off the UINavigationController. So far a very simple scenario, I would say.

If you hold the device in portrait or landscape orientation, this is the result I would not only like to achieve, but would also expect. In the first image you see that all views are 'upright', and in the second you see that only the second view controller counter-rotates the device's orientation. To be clear, it should be possible to navigate from the second view in landscape mode to the third, but because that third only supports portrait orientation, it should only be shown in portrait orientation. The easiest way to see if the results are alright, is by looking at the position of the carrier bar.

Expected view orientation for the device in portrait mode Expected view orientation for the device in landscape mode

But this question is here because the actual result is completely different. Depending on what view you're at when you rotate the device, and depending on what view you navigate to next, the views will not rotate (to be specific, the didOrientFromInterfaceOrientation: method is never called). If you're in landscape on the second and navigate to the third, it will have the same orientation as the second (=bad). If you navigate from the second back to the first however, the screen will rotate into a 'forced' portrait mode, and the carrier bar will be at the physical top of the device, regardless of how you're holding it. The video shows this in more detail.

Actual view orientation for the device in landscape mode

My question is twofold:

  1. Why does the first view controller rotate back, but not the third?
  2. What needs to be done to get the correct behavior from your views when you only want some views to autorotate, but not others?

Cheers, EP.

EDIT: As a last resort before putting a bounty on it, I completely rewrote this question to be shorter, clearer and hopefully more inviting to give an answer.

The short answer is that you're using UINavigationController, and that won't work like you want it to. From Apple's docs:

Why won't my UIViewController rotate with the device?

All child view controllers in your UITabBarController or UINavigationController do not agree on a common orientation set.

To make sure that all your child view controllers rotate correctly, you must implement shouldAutorotateToInterfaceOrientation for each view controller representing each tab or navigation level. Each must agree on the same orientation for that rotate to occur. That is, they all should return YES for the same orientation positions.

You can read more about view rotation issues here.

You'll have to roll your own view/controller stack management for what you want to do.

Correct and secure manner of storing in-app-purchases

9 votes

What is the best way to store an in-app-purchase on the device, so that the purchases can also be accessed offline but, the security off the purchases are not compromised?

Do not store anything valuable on the device as it cannot be trusted and it can easily be compromised by someone motivated.

Now, all of this depends on the type and value of the item that is being purchased and what happens if its compromised.

If its truly valuable then use a remote secure server for managing secure items. In app purchases include a receipt that can be verified by your remote secure server talking to apple's servers directly through a secure connection. See this link to verifying store receipts.

Point in Tilt Direction - iPhone

9 votes

Hi

In my cocos2d game, I have my player sprite and I want to have him move in the direction I tilt my iPhone. I can deal with that, the hardest bit which I can't work out is:

How do I make my sprite rotate to point in the direction I am tilting? This is represented very well in the 'Tilt to Live' game on the app store. I want controls just like that.

My sprite(for those unfamiliar with cocos2d) does have a rotation value if that helps.

Thanks.

If you don't like the above, here's a simpler way to get a reasonable result!

Hold the iPad in front of you, let LR be the left / right tilt, TA the towards you / away from you tilt. So LR runs from -90 to 90, TA from -90 to 90. (TA negative is leaning towards your belly.)

Display both those numbers on your screen, and move the device around, so you are certain you have that right to begin with. You won't be able to do anything until that is working.

The solutionAngle will be like a clock hand, clockwise, with 12 distant from you.

Go through this decision chain:

If both LR and TA is zero, the machine is flat. Act appropriately.

If LR is flat (0), the answer is either 0 or 180, depending on the sign of TA.

If TA is flat (0), the answer is either 90 or 270, depending on the sign of LR.

Otherwise:

adjustmentAngle = arctan( sin(TA) / sin(LR) )

// (NB, that should run from -90 to +90)

if ( LR > 0 ) finalResult = 90 - adjustmentAngle

if ( LR < 0 ), finalResult = 270 + adjustmentAngle

I think that will do it! Hope it helps!

IMO...... be sure to smooth the result over time, for a good feel.

.

setting the angle...

"the only thing I am unsure of currently (concerning your own idea) is how do I apply it to my player? Do I merely make the player rotation value equal to the adjustmentAngle?" .. hi Josh, yes simply set the rotation to the final angle you calculate using the above! Fortunately it's that simple.

If you ever have to convert back/fore between degrees and radians, just paste in these lines of code that everyone uses:

#include <math.h>
static inline float degreestoradians (double degrees) {return degrees * M_PI/180;}
static inline float radianstodegrees (double degrees) {return degrees * 180/M_PI;}

.

where are the axes?...

PS, here's the incredibly handy diagram you may want to bookmark:

http://developer.apple.com/library/ios/#documentation/uikit/reference/UIAcceleration_Class/Reference/UIAcceleration.html

.

converting from accelerometer to angles...

"the accelerometer doesn't provide the raw data in angles. How do get from the raw data"

Quite right, I forgot to mention it sorry. This is an everyday problem...

distanceFactor = square root of (x^2 + y^2 + z^2)
angle X axis = acos ( x / distanceFactor )
angle y axis = acos ( y / distanceFactor )
angle z axis = acos ( z / distanceFactor) )

You must TEST this by writing the three angles on the screen and then moving it around, in other words "physically unit test" that section you write, before you proceed!

here is one of many answers from SO: UIAccelerationValue angle

BTW as you can probably see, you can get a rough result by taking the ratio of simply the raw x by raw y value, rather than the ratio of the two sines, in the 'adjustmentAngle' expression ... but anyway don't worry about that for now.

And finally!

IMPORTANT Readers should note that the amazing new Core Motion system, handles a lot of this for you, depending on your needs. Check it out!!!!!

Hope it helps!

Xcode project management: single engine - different personalized applications

7 votes

The idea is that I have an application template that should be customized for different clients. The main goal is to provide a number of personalized applications with almost the same functionality.

What is the best approach of Xcode project organization (and maybe management) in order to achieve the following points for each client's application:

  1. Always different images set for visual elements (for controls, views, icons etc);
  2. Rarely different XIB files for small UI structure modification;
  3. Visual customizations - code level;
  4. Small functional modifications;
  5. Possibility to switch back to previous personalized versions;
  6. One functional engine (e.g. search functionality);

At the moment, for every personalization request I create in the same project's root directory new project file, and corresponding XIB files, images set and source files (for some functional requests) directories. Each project file has a reference to the main source files directory (engine).

But I suppose that's not the best way to organize this type of projects.

create a project template -- or just a zip file with the template.

first, determine where you can use (something such as) xml defs instead of overriding and other source level changes.

Always different images set for visual elements (for controls, views, icons etc);

add placeholder resources to the project template

Rarely different XIB files for small UI structure modification

add it to the project, referring changes (if it's changed) via vc

Visual customizations - code level;

core libraries, shared across all projects. consider using c or c++ if the library will be large. objc cannot be stripped. this contains implementation stubs, as well as common code, base classes, and interfaces.

Small functional modifications

extend the interface of your core classes so the subclasses may easily implement the frequent alterations. these files are part of the template.

Possibility to switch back to previous personalized versions;

it should be in vc, and the dependency versions should also be tracked.

One functional engine (e.g. search functionality);

an undefined factory function is simple enough:

id<MONSearchEngineProtocol> MONAppCoreCreateSearchEngine();

declare it in the static lib, but define (and implement what is necessary) in one of the project specific sources. you can add this other places - some people would stuff it in the app controller and override it.

if you have a lot of these to manage, consider moving your resources to code (rather than managing a ton of nibs). a nib defines a lot of code -- which is a lot of nearly duplicate code to manage. this will make sense for some resources, and not much sense for others.

Implementing licensing checking library

7 votes

I am working on a small cross platform product for Windows and Mac written in C++/Obj-C. I have been asked to implement a licensing module for the same. This task is part of a very ambitious project to introduce licensing for all our products. At the end of it, we will have a complete licensing scheme where we will be able to sell licenses to our customers which support yearly renewals, license levels, etc. My problem is that I do not know the first thing about implementing license checkers. Can any one point me to some how-to's for the same? Are there any open source licensing modules around that I can study?

I use a system of Partial Key Verification (PKV), and I've implemented this in C# with a PHP generator. Google will come up with various hits, explanations, and implementations; but Brandon Staggs wrote a good overview (albeit in Delphi!), here:

http://www.brandonstaggs.com/2007/07/26/implementing-a-partial-serial-number-verification-system-in-delphi/

PKV works by encoding certain information (license type, serial number product, date, etc) in the key along with a hash of the user name, and hashes of the encoded information. Much of the key actually consists of multiple one char hashes. The idea is that you only check a subset of these hashes. The exact subset that issued can be changed over time for some security and to protect against certain kinds of reverse engineering.

I would also encrypt the key to help obfuscate what each char in the license means. Otherwise someone with multiple keys might determine certain char positions mean certain things ("oh, chars 3-4 are the serial number"). This might be a chink in your armour!

Any license system you develop is going to be imperfect. It will be crackable, and if your products are popular, will be cracked. However there's a strong argument that a license system exists to keep the honest people honest, and produce enough hurdles for the slightly dishonest people - but not so many hurdles that it becomes too much of an inconvenience (eg. I'm generally against hardware locking). Those who do hack your system probably weren't going to pay for it anyway.

Is it always inappropriate to #import more than absolute necessary in Objective-C interfaces?

7 votes

I'm well aware that the general rule of thumb is you should only import what is necessary—base class interfaces, protocol interfaces, etc.—for a class to compile and use @class for everything that can be forward-declared. However, I ran into the following scenario in which I felt like #import was a more appropriate solution:

#import "ClassA.h"      // Previously, @class ClassA;
#import "ClassB.h"      // Previously, @class ClassB;
#import "ClassC.h"      // Unnecessary to forward-declare

@interface ClassD : NSObject

@property (nonatomic, retain) ClassA *  classAObject;
@property (nonatomic, retain) ClassB *  classBObject;
@property (nonatomic, copy)   NSArray * classCObjects;

@end

At first, I simply forward-declared ClassA and ClassB (as the components of classCObjects are of ClassC only by contract). This was my initial instinct.

But after trying to use ClassD elsewhere, I quickly realized that I had to also import ClassA, ClassB, and ClassC along with ClassD everywhere I used it. This seems like something another class shouldn't have to care about when using ClassD. My thinking was that, basically, a user of ClassD should really only care about importing ClassD.h and assume it can work with the entire class without a bunch of other #import statements. Given the above approach, I've basically included everything necessary to work within the domain of ClassD right in its interface.

Is there a strong reason why this approach is not ideal, except for "you've included more than is absolutely necessary for compilation?"

While the strategy you're generally following-- don't import more than necessary--is awesome, classy style and a great thing to aim for in general, don't sweat the tricky cases too much. Just #import what you need.

In practice, on a modern machine, the only effect over-#importing will have is to add a few unobservable microseconds to your compile time. Use the developer time you'll save for making your app awesomer. :)

NSMutableString as retain/copy

7 votes

I have aa number of NSMutableString's in my app (almost 10-11); all defined as ivar/property

@property (nonatomic, retain) NSMutableString *str1;

I read somewhere that it is better to use "copy" for strings. Is that true? If yes, can I just replace retain to copy in my app and remove the release in dealloc ?

Do I need to consider some other things as well ?

Also, is it normal to have 10-11 NSMutableString's in 1 app..I mean from memory usage perspective ? I also have 4-5 NSMutableDictionary's as well in my app. Please let me know if that is fine.

(note: the NSMutableString specific response is a ways down)

I have aa number of NSMutableString's in my app (almost 10-11); all defined as ivar/property

@property (nonatomic, retain) NSMutableString *str1; I read somewhere that it is better to use "copy" for strings. Is that true?

yes, copying NSString (not talking about NSMutableString quite yet) should be the default. the reason (as stated by other posters) is that the implementation of an immutable instance can simply retain itself in its implementation of copyWithZone:. also, copy gives you the expected behavior. in other words, there is not a use for retaining a string if it is in fact immutable. in order to guarantee that you're dealing with an immutable string, you simply copy at creation and set.

If yes, can I just replace retain to copy in my app and remove the release in dealloc?

copy, like retain returns an object which you must explicitly release (e.g., in dealloc) in non-garbage collected environments. immutable strings are still reference-counted. there are exceptions to this, notably:

  • CF/NS-String literals exist for the program's duration

  • you can use CF-APIs to create strings which are never released, or are managed beyond the scope of traditional retain/release mechanisms

  • NS-Type subclasses could implement another scheme (although usual considerations of this are flawed)

Do I need to consider some other things as well?

now we get to the NSMutable-type details. the implementation of property syntax invokes copy. as we know, -[NSMutableString copy] returns an immutable NSString. this is an issue waiting to happen for a naive implementation, since your NSMutableString ivar is now an NSString, using default-synthesized setter implementation.

@property (nonatomic, retain) NSMutableString *str1;`
// or
@property (nonatomic, copy) NSMutableString *str1;`

when declaring:

 @property (nonatomic, retain) NSMutableString *str1;`

you may use the default synthesized-implementation.

but there's a twist when declaring:

 @property (nonatomic, copy) NSMutableString *str1;`

you should not use the default synthesized-implementation. instead, you should write your own:

- (void)setStr1:(NSMutableString *)arg
{
    /* locking/observing/undo/etc omitted */
    NSMutableString * copy = [arg mutableCopy];
    NSMutableString * prev = str1;
    str1 = copy;
    [prev release];
}

- (NSMutableString *)str1
{
  /* locking/observing/etc omitted */
  /* don't return something the clients thinks they may
     possibly modify, and don't return something you may
     modify behind their back
  */
    return [[str1 mutableCopy] autorelease];
  // -- or???
    return [[str1 retain] autorelease];
}

hmm... that's not very clear, and not very considerate for clients. it also implies a lot of unnecessary things, and introduces additional copy-overhead. let's re-evaluate this.

additional considerations/problems at this point:

  • the default-setter requires that the client makes a mutableCopy of the string, if they only hold an immutable string. that is immediately turned into a unique copy by you, in the setter, since you can't expect the client to create a unique mutableCopy just for you -- besides, that's the duty of class's implementation. so NSMutableString is a bad argument for the setter. NSString is the appropriate setter, unless you're retaining the string.

  • NSMutableString is also an ambiguous getter -- see the implementation. does it copy+autorelease or retain+autorelease? there isn't a standard expectation for the general form. also, clients may depend on one specific behavior. this really is an implementation detail of the class, unless you're dealing with tightly coupled objects. tightly coupled objects are those which are basically co-dependent, and not generally reusable in other contexts. that concept's fine, you may just be using a private class for several reasons. in either case, copy/write semantics to external clients and subclasses is not (implicitly) clear, and the implementation is dangerous.

  • sharing an NSMutableString is generally a bad design. NSMutableString is not thread-safe. it makes no sense for clients to access and mutate the string - it's dangerous. any design which shared objects which are not thread safe should be considered with care. sharing in this case also extends to subclass usage (so make it @private, wherever possible)

  • retain is also generally a bad design -- the clients are not going to know when the string's been (or is being) modified externally, unless you add equivalent external code to support that.

  • depending on how the interface is used, this can also introduce a lot of unnecessary copying. boo.

ok - now we're pretty convinced our 'improvement' is still a bad idea in most cases =) how can we improve the design?

you should, apart from exceptional cases of tightly coupled objects, declare/implement your property as follows:

@interface MONThing : NSObject
{
@private
    NSMutableString * str1;
}

/* note: passes/returns NSString */
@property (nonatomic, copy) NSString * str1;

@end

@implementation MONThing

// no need for clients to create a mutableCopy
- (void)setStr1:(NSString *)arg
{
  /* locking/observing/undo/etc omitted */
    NSMutableString * copy = [arg mutableCopy];
    NSMutableString * prev = str1;
    str1 = copy;
    [prev release];
}

// the result is clearly defined. return a copy for
// thread-safety, expected behavior, and to minimize
// further copies when handling the result.
- (NSString *)str1
{
  /* locking/observing/etc omitted */
  /* don't return something the clients thinks they
     may possibly modify, and don't return something
     you may modify behind their back
  */
    return [[str1 copy] autorelease];
}

@end

your interface is now improved, more correct, requires less documentation and performs better.

you can also remove publicly visible accessors if you don't need them.

we can live with that interface, where it is required.

but there's more! as it turns out, the interface is necessary less often than many people think. we can avoid many of the issues altogether in most cases by simply avoiding use of NSMutableString as an ivar where possible.

as mentioned earlier, NSMutableString is not thread-safe, it's easier and more efficient in many cases to use a (copied) NSString ivar when your string is small, or does not change frequently. by adding the mutable string to the interface (as above), you'll have to guarantee thread-safety manually. in many cases, it is optimal to do something along these lines:

@interface MONThing : NSObject
{
    NSString * str1;
}

@property (nonatomic, copy) NSString * str1;

@end

@implementation MONThing

@synthesize str1;

- (void)updateTimeElapsed:(NSTimeInterval)seconds
{
    NSMutableString * s = [NSMutableString stringWithFormat:@"%f seconds", seconds];
    /* ...some mutations... */
    self.str1 = s;
}

@end

of course, there will be a few exceptions to this -- where you will need a mutable ivar, but it's best to use immutable ivars where possible, and where in doubt, rather than introducing a ton of threading complexities. in most cases, you can remove the use of mutable strings from interfaces, and build the strings when necessary (as demonstrated above).

collections (NSMutableArray, NSMutableDictionary, NSMutableSet, etc), on the other hand, are required more often in implementations, and are more complex in general.

good luck!

How do I upload files using http/ftp to iphone/ipad? (Eg. ifile, goodreader)

7 votes

Is there any good advice on uploading files to the device? I've seen many apps create a http server on 80 or 8080 to upload files. Does that mean I have to implement a server too?

Are there any 3rd-party libraries? (Preferably open-source and non-GPL)

EDIT: I am going to upgrade files in the app for specific devices in a corporate environment, so the ipad pulling files from a central server is also an alternative. But I would have to send messages to these ipads to tell them to fetch those files.

I assume what you want is a kind of automatic update. An app do something by order from server without user's manual operation.

I don't know enterprise-license specific feature of iOS. But I believe there's no such enterprise-specific APIs. And as I know, automatic update is almost impossible. Because,

  1. There is no system-level support for automatic update. (yet?)
  2. So messaging and fetching feature should be implemented in app.
  3. But no app is guaranteed to run in background for long time.
  4. And also user can turn off any app at any time.
  5. There is no way to send message to an app which is not running.
  6. Even you can send, there is no way to address each client form the server.

If your app is running, sending message or commanding them to fetch or do anything is just a simple work. The problem is there is no regular way to force them always keep alive. Even under situations like OS reboot or abnormal termination.

However there is an alternative. Just registering app as VOIP app like Skype. OS does not keep the app running too, but will monitor specific socket port, and will wake your app when the socket receives some message. For more details, see here: http://developer.apple.com/library/ios/documentation/iphone/conceptual/iphoneosprogrammingguide/BackgroundExecution/BackgroundExecution.html#//apple_ref/doc/uid/TP40007072-CH5-SW15

In AppStore, an app using VOIP for other purpose like automatic update will not be passed, but you have no need to concern about it.

And other way to send message to device without running app is push notification. This is a feature supported in system-level. But this is not designed to commanding app. This is designed to send textual message. So If your app is not running, the message will be displayed to user. However, you can guide the user to start the app by sending push notification.

As a final option, you can request some feature to Apple for enterprise environment. If your company is big enough to get an enterprise license, Apple will consider your feature request seriously.


If you decided to use VOIP method, I'm sorry I can't help you any more. I have no experience of implementing this kind of app. But it should not so hard.

However hard part is server. It definitely require custom server program which keeps TCP/IP connection. Regular HTTP server cannot be used. Because HTTP itself is designed as not to keep TCP/IP connection. You have to build this kind of server yourself from scratch. You'll have to handle lower level TCP/IP transmissions.

There are a few solutions(both of free/commercial) for this kind of server, but none of are popular because this kind of server regularly needs full customization. So there's nothing to re-use or share.

However I believe this is most suitable implementation for your app.


If you can satisfy automatic update only when the app is running, you can archive it by polling server status from the client periodically.

This is easy to implement because you can use regular HTTP servers for this. Client connect and download recent updates from central server periodically. If there is a new update, just fetch and do what you want. And the app is launched, just check the update at first. Prevent all operation until update applied.

This is regular way. Most of applications are built with this method. In this case, you have no need to implement server or hard thing.

However applying speed of update is depend on polling period.


(Edit)

I couldn't care about private APIs. Because your app is not for AppStore, so you can use private API's freely. (This is different thing with jail-breaking. There are so many hidden features by excluded from documentation) I don't know about private APIs, but it's possible there is some API which enable the support for keep-alive of the app. However, this reverse engineering work is so painful unless you're born to hack.

Problem with saving NSDate to the CoreData context

7 votes

Hi,

I'm trying to save managed object with one of the attribute's type Date to the managedObjectContext.

Code is like:

reminder.eventDate = selectedDate;
NSLog(@"Date: %@", selectedDate);
NSError *error = nil;
if (![reminder.managedObjectContext save:&error]) {
    NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
    abort();
}

during context saving program crashes with SIGABRT. Here is a console log:

2011-02-28 00:50:18.817 MyApp[9021:207] *** Terminating app due to uncaught 
exception 'NSInvalidArgumentException', reason: '-[__NSDate isEqualToString:]: 
unrecognized selector sent to instance 0x4e73490'
*** Call stack at first throw:
(
    0   CoreFoundation                      0x01057be9 __exceptionPreprocess + 185
    1   libobjc.A.dylib                     0x011ac5c2 objc_exception_throw + 47
    2   CoreFoundation                      0x010596fb -[NSObject(NSObject) doesNotRecognizeSelector:] + 187
    3   CoreFoundation                      0x00fc9366 ___forwarding___ + 966
    4   CoreFoundation                      0x00fc8f22 _CF_forwarding_prep_0 + 50

Does anyone knows why I have that? Second question is why when I check in debugger mode selectedDate isn't NSDate type but __NSDate (double underscore in front).

Thanks!

UPDATE:

I did some changes to easier catch the bug. so code now is like:

reminder.eventDate = [NSDate date];
NSLog(@"Date: %@", selectedDate);
NSError *error = nil;
if (![reminder.managedObjectContext save:&error]) {
    NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
    abort();
}

so, here we save definitely NSDate. reminder.eventDate is NSDate too. But I still have this error. If I comment reminder.eventDate = [NSDate date]; saving throws another error (date is mandatory field in NSData, so save: returns error "The operation couldn’t be completed." with eventDate = nil;. CoreData structure is checked multiple times - eventDate has Date type.

UPDATE (Problem solved): Finally I found the problem. eventDate was set as key for the detailTextLabel.text in my tableview cells (I used KVO for that). So if was no direct call and I wasn't able to find any method invokation for the eventDate. Strange thing is that crash was on the save method, not later. And in the call stack there is no tableView:cellForRowAtIndexPath: method at all...

Just to add to what has already been said:

It doesn't have to be a problem with the model or the NSManagedObject subclass. It could just be a piece of code almost anywhere that calls isEqualToString:. Somewhere you've got an object that the code assumes should be a NSString but is instead a NSDate object. I would look at any code that might convert dates to strings.

However, since it happens upon save I would look at any customizations you might have done to the subclass.

The place to start is by searching the project for isEqualToString:.

Update:

Since isEqualToString is a testing method it can be activated anytime you do a compare for a string such as in a sort. I couldn't reproduce your exact error but the following code does something similar:

id idDate=[NSDate date];
NSString *bob=[NSString stringWithString:@"bob"];
NSString *steve=@"test this";
steve=idDate;
NSLog(@"test=%@",([steve compare:bob]) ?@"YES":@"NO");

... complies but throws an exception:

-[NSCFString timeIntervalSinceReferenceDate]: unrecognized selector sent to instance 0x4040

So, you can see how these types of errors can slip in. It's also a demonstration for why you should be careful with the use of id.

Objective-C: Assertion vs. Exception vs. Error

6 votes

In Cocoa, when should I use NSAssert, NSException, NSError?

Here's what I've been thinking:

NSAssert - When creating any client program used for the programmers own benefit to double check rules, conventions, assumptions, or pre-conditions and post-conditions?

NSException - When creating a third-party library for the benefit of other programmers that use the library, so that they immediately know when an input is invalid?

NSError - When interfacing with an external system to get data like a file, database, or web service that isn't guaranteed to give me a result?

P.S. If this is a duplicate my apologies, I've only seen this topic in context of Java and C#.

An NSAssert will throw an exception when it fails. So NSAssert is there to be short and easy way to write and to check any assumptions you have made in your code. It is not (in my opinion) an alternative to exceptions, just a shortcut. If an assertion fails then something has gone terribly wrong in your code and the program should not continue.

One thing to note is that NSAssert will not be compiled into your code in a release build, so this is typically used for sanity checking during development. I actually tend to use a custom assert macro that is always active.

The times you would @throw your own NSException are when you definitely want it in a release build, and in things like public libraries/interface when some arguments are invalid or you have been called incorrectly. Note that it isn't really standard practice to @catch an exception and continue running your application. If you try this with some of Apple's standard libraries (for example Core Data) bad things can happen. Similar to an assert, if an exception is thrown the app should generally terminate fairly quickly because it means there is a programming error somewhere.

NSErrors should be used in your libraries/interfaces for errors that are not programming errors, and that can be recovered from. You can provide information/error codes to the caller and they can handle the error cleanly, alert the user if appropriate, and continue execution. This would typically be for things like a File-not-found error or some other non-fatal error.

What is the reasoning behind Singleton accessor names?

6 votes

Over the course of a few projects, I have written a decent amount of class factory methods for accessing a Singleton instance of a class. I have always used some variation on the + (id)sharedSomething; naming convention.

Apple, on the other hand, has a variety of naming conventions. For example:

// NSNotificationCenter
+ (id)defaultCenter;

// NSUserDefaults
+ (NSUserDefaults *)standardUserDefaults;

// UIApplication
+ (UIApplication *)sharedApplication;

Is there any rhyme or reason to the adjective placed before the noun in those names that I should be aware of when naming my own methods? I originally thought it might have something to do with "flexible" vs "strict" singleton designs, but NSFileManager and NSNotificationCenter both follow the + (id)defaultSomething convention, yet NSFileManager supports the allocation of other instances while NSNotificationCenter does not. I'm stumped.

EDIT: I was wrong in thinking NSNotificationCenter does not support the instantiation of new centers. It's just not terribly common, so the original hypothesis is not necessarily invalidated.

In general, the shared… methods are for true singletons (NSApplication, NSWorkspace, etc.) while default… or standard… denotes a class that can be usefully instantiated, but where most clients will be happy just working with a single global instance. But there isn't any public written standard, and it seems primarily to have been a decision made whenever such a class was written.

Find locale currency for iphone programmatically

6 votes

I want to find out the currency locale on user's iphone programmatically. That means, if user is in US Store, the currency locale should be USD, for Australia, it should be AUD. My purpose of this task is to try to convert the item price listed on our app to be nearly match with the price that AppStore ask.

For example, if we sell a video 3 usd, and an Australian wants to buy it, then I should show 2.8 AUD in my app screen. It will reduce the calculation in the user over the real price in his country. Does anybody know how to do it?

Hi all, thanks for your answer. I finally figured out that I can retrieve the price and the currency code directly from Apple:

- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response {    
    NSArray *products = response.products;
    if (products && products.count != 0) {
        product = [products objectAtIndex:0];
        [[NSNotificationCenter defaultCenter] postNotificationName:PRICE_UPDATED object:product.LocalizedPrice];    
    } 

    // finally release the reqest we alloc/init’ed in requestProUpgradeProductData
    [productsRequest release];
}



@implementation SKProduct (LocalizedPrice)

- (NSString *)LocalizedPrice
{
    NSNumberFormatter *numberFormatter = [[NSNumberFormatter alloc] init];
    [numberFormatter setFormatterBehavior:NSNumberFormatterBehavior10_4];
    [numberFormatter setNumberStyle:NSNumberFormatterCurrencyStyle];
    [numberFormatter setLocale:self.priceLocale];
    NSString *formattedString = [numberFormatter stringFromNumber:self.price];
    [numberFormatter release];
    return formattedString;
}

@end

Test Driven Development (TDD): Writing unit tests in Xcode 4

6 votes

I am keen to write a library project with tests, even if I then include the code in other projects (as opposed to linking to the lib.) for inclusion on ios projects.

It seems checking the 'Include unit tests' isn't enough for xcode 4 to properly initialise a project with tests, and after looking through the Apple documentation I can't find anything relevant.

Does anybody know of any resources or tutorials for getting this working?

Even with the default Cocoa Touch Static Library project, upon choosing "Test" from the "Product" menu, it fails (when linking) with this error (the project is called test1):

library not found for -ltest1
Command /Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/llvm-gcc-4.2 failed with exit code 1

Any help would be much appreciated.

OK I finally got this working.

The trick was to create the library without checking the 'Include unit tests' option in XCode 4. Then I created a new target myself.

(in xcode 4)

  1. Create a new Cocoa Touch Static Library project and DON'T check "Include Unit Tests"
  2. Select the project in the navigator
  3. Go into the "Build Phases" tab
  4. Click 'Add Target' and choose 'Cocoa Touch Unit Testing Bundle'
  5. Go through the wizard until the target is created
  6. Then go in the "Product" menu and choose "Edit Scheme..."
  7. Make sure your project (not the test target) is selected and, select "Test"
  8. Click + to add a new target
  9. Choose your test project and click Add
  10. Now press Cmd+U (this is the shortcut for "Product > Test" menu item) and you'll notice the default test fails.

I hope this helps.

UINavigationController: Hiding Back Button on One View Hides it For All Views

6 votes

I have a UINavigationController that contains 3 UIViewControllers on the stack.

View A - is the root
View B - is pushed by View A and has `self.navigationItem.hidesBackButton = YES;`
View C - is pushed by View B and has `self.navigationItem.hidesBackButton = NO;`

View C does not show the back button, even though I have hidesBackButton set to NO. How can I resolve this?

Hi Sheehan,

Update
A possible bug in 4.2 as it works till 4.1 sdks

I have tried this and mine is working perfectly. I am just posting the implementation of B view controller (BVC) and C view controller (CVC). My initial guess is that you are not setting the title of BVC in viewDidLoad.

@implementation BVC


// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
    [super viewDidLoad];
    self.navigationItem.title = @"I am B";
}


- (void) viewWillAppear:(BOOL)animated{
    self.navigationItem.hidesBackButton = YES;
}

- (IBAction)pushB:(UIButton *)sender{
    CVC *cvc = [[CVC alloc] initWithNibName:@"CVC" bundle:nil];
    [self.navigationController pushViewController:cvc animated:YES];
    [cvc release];
}
@end

@implementation CVC

- (void) viewWillAppear:(BOOL)animated{
    self.navigationItem.hidesBackButton = NO;
}
@end

Regular Expression to replace " {" with "(newline){" in xcode

4 votes

I need to change my coding style of putting opening braces in same line to new line. I need to find and replace the (space){ with (newline){. I heard using regular expression find and replace, its pretty simple.

Could anyone help me on this?

You could try the following:

  • In the Find box, type space \ { $
  • In the Replace box, type control+q return {

control+q is needed to quote the return key. There’s no visual feedback for typing control+q return, so the only visible character in the replace box is the opening curly brace:

Screenshot Find & Replace

Although this answers your question, there’s (at least!) one problem: it won’t indent the opening curly brace, so something like

- (void)method {
    for (obj in collection) {
        NSLog(@"%@", obj);
    }
}

is converted to

- (void)method
{
    for (obj in collection)
{
        NSLog(@"%@", obj);
    }
}

The menu item Edit > Format > Re-Indent will place the opening curly braces in the correct indentation tab but there might be non-desired side effects to your code style.


Edit: as commented in the other answer, you might want a regular expression that matches an arbitrary number of whitespaces surrounding the curly brace, e.g. \s*{\s*$