iOS Development

A UITableViewCell Jeopardy

A unique problem arises when a button is placed in a custom cell and on the button’s tap, the cell has to be modified or some information needs to be saved related to the cell – which necessitates that the table cell needs to be accessed. The worst way of doing this would be to call the buttons’s superview and go up in hierarchy till the cell is reached. This is worst approach because the hierarchy of cells change often as Apple modifies and improves its UITableViewController. The most common and cheapest way of doing it would be to set the button’s tag as the row index, and then on the button’s tap event, get that index from the sender (which is the button itself) and access the cell using

- (UITableViewCell *)cellForRowAtIndexPath:(NSIndexPath *)indexPath

But this is not the best of approaches.Tags are misused heavily and there might always be the risk that the tag of the button may have been set to be something else just for the sake of some other activity. There are multiple better approaches, one of them I am going to describe in this scope. The basic objective of this approach is to connect the button to the table view cell internally. We will create a delegate for the button’s press event and will implement the same in the view controller. This will have the custom cell as a parameter through which we will be able to access the cell.

Steps:

Step1: Create a delegate to handle the button’s tap in your custom cell’s .h file (CustomCell.h):

@class CustomCell;
@protocol CustomCellDelegate < NSObject >
- (void)customCellDidPressMyButton:( CustomCell *)cell;
@end
@interface CustomCell : UITableViewCell

Step 2: Create a property for the delegate, and set it weak

@property (nonatomic,weak) id < CustomCellDelegate > delegate;

Step 3: In your custom cell’s .m file (CustomCell.m) set the target action for the button and implement the selector to call the delegate method


- (void)awakeFromNib
{

[self.customButton addTarget:self
action:@selector(customButtonPressed)
forControlEvents:UIControlEventTouchUpInside];

}
- (void) customButtonPressed
{

[self.delegate customCellDidPressMyButton:self];

}


Now your custom cell is ready with the button’s delegate method to be implemented by the view controller. Here’s how to implement the same in view controller.

Step 4: Implement the delegate method:


@interface MyViewController ()< UITableViewDelegate,UITableViewDataSource, CustomCellDelegate >

- (void)customCellDidPressMyButton:(BAHPropertySearchResultCell *)cell  {

//the cell is in the parameter. Make change to it as required.

}

Step 5: Connect the table view cell with our newly appointed delegate

 
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{

cell.delegate = self;

}

Step 6:  As it is important to assign the delegate, it is also important to remove the delegate when the tableview is done displaying. It can be done in the following method:


- (void)tableView:(UITableView *)tableView didEndDisplayingCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{

cell.delegate = nil;

}

Hope this helps!

Advertisements
iOS Development

Little tricks of Accessibility

When I code, in my mind’s eye I always seem to imagine the user who is looking at or using the feature I am developing. It helps me look at my work from a more consumer driven perspective. A piece of feature, though seems not worth the time and effort, may seem indispensable from that perspective. Such a different perspective becomes of paramount importance when thinking of extending your application’s reach to people who are deprived of experiencing the world the same way as we do.
The importance of providing accessibility for differently abled people to your application can not be emphasised enough. Yes, it is extra hassle. Yes, Apple will still accept your app even if you don’t implement accessibility. And yes! the people who need accessibility are very little compared to the the large user base you are going to cater to. But — it is the right thing to do, it can change someone’s life and for your part: you may be subject to millions of silent tearful thanks and blessings from all over the world for changing so many lives in a better way. If all these do not bother you, close your eyes (imagine you are blind or nearly so) and try to access your computer, you will be bothered.

So, when it is such a great thing to do, why most of the applications don’t offer accessibility support? Why most of the applications downloaded straight from App Store just become unusable in accessibility mode? I believe what discourages people to go this extra mile is the nasty little problems that pop in when you start making your app accessible. Despite such great articles by Matt Gemmell and Mattt Thompson and other readily available examples, there are so many unique problems that arise when implementing accessibility that it really puts off the developer unless she is really a motivated person to implement it. This article ventures to dust away those nasty little problems faced by any iOS accessibility developer as much as possible.

Define: Accessibility

Accessibility is the degree to which a product, device, service, or environment is available to as many people as possible. Accessibility can be viewed as the “ability to access” and benefit from some system or entity. The concept often focuses on people with disabilities or special needs (such as the Convention on the Rights of Persons with Disabilities) and their right of access, enabling the use of assistive technology.

So what is this all about? If you have never used the iOS devices in accessibility mode it’s of utmost important for you to do it now before we move on to more complicated details:

  • Open the Settings App
  • Go to General –> Accessibility
  • Turn On the Voice Over switch

As you do that, suddenly you will find yourself in a rather inaccessible situation where none of your usual touches and gestures will behave the same way it did normally. Well, don’t fret mon ami, here are the rules of this world to get you started:

  • Tap once to select an item
  • Double-Tap to activate the selected item
  • Swipe with three fingers to scroll

Also, if you do a single finger swipe, the focus of the voice over will shift from one element to another sequentially. When you will be testing accessibility in the device, you will need to quickly switch ON and OFF this mode and there is a shortcut with which you can do that:
In the Settings app —

  • Go to General → Accessibility and
  • Scroll down to the bottom of the screen and tap on the button “Accessibility Shortcut”
  • And check the “Voice Over” option from the next screen
  • Now, triple press the Home button of the iOS device — VoiceOver turns on. At any point of time, you can triple press the Home button to turn it off.

The accessibility can also be tested in iPhone Simulators and the accessibility inspector can be enabled in the “Settings” app in the simulator.

Is it hard to implement?

Despite of the fact that there are several great articles which offer interesting insight into Accessibility on iOS devices, they often seem to oversimplify the hassle of implementing VoiceOver and other accessibility methods, I guess, to liberate you of the fear of  going the extra mile to implement accessibility. Honestly, they are partially true. Here is a quote from Matt Gemmell’s blog which is arguably the best accessibility article existing on the web. he says as below:

The good news is that it’s incredibly easy to add accessibility support to your application (there’s no bad news, incidentally). The reality of adding accessibility support to your app is that:

  1. About 80% of your app is probably accessible already, via the built-in VoiceOver support in UIKit.
  2. You can probably boost that to around 95% simply by spending a few minutes in Interface Builder, without writing a single line of code.
  3. And you can very likely reach 100% accessibility support via implementing some incredibly trivial methods, which will also take you just a few minutes.

Well, not so fast.

For a complex enterprise level application which offers accessibility, making the application compliant to the Disability Discrimination Act and similar ones may become a project in itself. But, no, it is definitely not rocket science. It just demands a little determination, clarity of thought and industry. So, what holds you up? As I told you before, the nasty little problems. What are they?

Problems

Background items are visible.

Accessibility has a bad habit of revealing what’s underneath the curtain. Technically, that means when you add a subview over a view and there are elements that are under your new view, they also get focussed and announced


for (UIView *view in [self.view subviews]){
[view setAccessibilityElementsHidden:YES];
}

There are 2 methods that can be called on a view to render that particular view element inaccessible:

  • isAccessibleElement
  • setAccessibilityElementsHidden

The good thing about the later one is that when it hides one element, it hides the subviews too. This can prove really helpful in the scenario where you have a got a pretty deep view hierarchy.

The single finger swipe is not selecting items on the screen in order

Well, this can prove to be a real nasty one sometimes, because the accessibility switches its focus in the sequence in which the views are laid out in the interface builder and it is not always possible to alter the hierarchy. Apple has suggested a really great and powerful approach. Follow the below steps to dodge the bullet:

  1. Create a subclass of UIView and assign that class to your view in the Interface Builder
  2. In the subclass, over ride the accessibleElements setter
  3. Add the elements of your choice in your preferred order in the array and return it
  4. Implement the UIAccessibilityContainer protocol methods

So, the code sums up to the following (followed Apple’s documentation)


@implementation MultiFacetedView
- (NSArray *)accessibleElements
{
if ( _accessibleElements != nil )
{
return _accessibleElements;
}
_accessibleElements = [[NSMutableArray alloc] init];

Create an accessibility element to represent the first contained element and initialize it as a component of MultiFacetedView.


UIAccessibilityElement *element1 = [[[UIAccessibilityElement alloc]     initWithAccessibilityContainer:self] autorelease];

/* Set attributes of the first contained element here. */
[_accessibleElements addObject:element1];

/* Perform similar steps for the second contained element. */
UIAccessibilityElement *element2 = [[[UIAccessibilityElement alloc]     initWithAccessibilityContainer:self] autorelease];

/* Set attributes of the second contained element here. */
[_accessibleElements addObject:element2];

return _accessibleElements;
}

The container itself is not accessible, so MultiFacetedView should return NO in isAccessiblityElement


- (BOOL)isAccessibilityElement
{
return NO;
}

The following methods are implementations of UIAccessibilityContainer protocol methods


- (NSInteger)accessibilityElementCount
{
return [[self accessibleElements] count];
}

- (id)accessibilityElementAtIndex:(NSInteger)index
{
return [[self accessibleElements] objectAtIndex:index];
}

- (NSInteger)indexOfAccessibilityElement:(id)element
{
return [[self accessibleElements] indexOfObject:element];
}

@end

Instead of creating the UIAccessibilityElements, the view elements can also be passed into the array which works absolutely fine.

Some Important Notes

  1. When designing the user interface of the application, it is very important to take into account the people who are colour blind. So, to depict the different state of an element with different colours may not be the wisest of choices
  2. For non trivial controls, it is really important to let the user know what it does or how to operate it. For example, if you have created this super cool knob which can be rotated to select different options, it would be really necessary for the voice over to announce that clearly
  3. If you have a hyperlink in the application, which takes the user outside the application, it is of utmost important to make the user aware of the fact in voiceover
  4. As the user taps a control if some change happens to the screen, be it very minimal, the user would love to know about that. So, if because the user entered a great password in the password input textfield whilst creating an account, the “SignUp” button gets enabled, it is important to let the user know that the button got enabled
  5. Ensure that the elements that are hidden are not announced as this will create confusion for the user

Conclusion

I have noted down everything I have experienced while working with accessibility for iOS. I will continue to add to this article any new learnings as and when I encounter it. If you liked this article, let me know by posting a comment. Hope this helped!

iOS Development

Difference between #import and #include

 

The following post is actually a repost from StackOverflow. The answer of the question is scattered in so many places, it’s really hard to get a proper answer. This is my respect to the person who posted the answer (however, was not selected to be the best answer, sadly).

There seems to be a lot of confusion regarding the preprocessor.

What the compiler does when it sees a #include that it replaces that line with the contents of the included files, no questions asked.

So if you have a file a.h with this contents:

typedef int my_number;

and a file b.c with this content:

#include "a.h"
#include "a.h"

the file b.c will be translated by the preprocessor before compilation to

typedef int my_number;
typedef int my_number;

which will result in a compiler error, since the type my_number is defined twice. Even though the definition is the same this is not allowed by the C language.

Since a header often is used in more than one place include guards usually are used in C. This looks like this:

 #ifndef _a_h_included_
 #define _a_h_included_

 typedef int my_number;

 #endif

The file b.c still would have the whole contents of the header in it twice after being preprocessed. But the second instance would be ignored since the macro _a_h_included_ would already have been defined.

This works really well, but has two drawbacks. First of all the include guards have to be written, and the macro name has to be different in every header. And secondly the compiler has still to look for the header file and read it as often as it is included.

Objective-C has the #import preprocessor instruction (it also can be used for C and C++ code with some compilers and options). This does almost the same as #include, but it also notes internally which file has already been included. The #import line is only replaced by the contents of the named file for the first time it is encountered. Every time after that it is just ignored.

 

Source:

http://stackoverflow.com/questions/439662/what-is-the-difference-between-import-and-include-in-objective-c

iOS Development

Creating Singleton…

Singleton classes are unique design patterns which are greatly used for storing data in memory for global use in the application. A Singleton class can have only one instance and that same instance is returned when the initializer is called. Generally the designated intializer (the initializer which makes the [super init] call) is internally called in a class method (initializer) which creates a static instance of the class and returns it. Generally this initializer is prefixed with “Shared” e.g. SharedManager etc.

Steps to Create Singleton

Let’s consider for a moment that we are going to create a singleton class named “MySingleton” and following are the exact steps you will need to follow in a ARC environment.

Step 1. Method and Property Declaration

  1. Declare the required properties in the header file
  2. Declare the initializer class method name

Code:

//MySingleton.h

@interface MySingleton : NSObject {
NSString *someProperty;
}

@property (nonatomic, retain) NSString *someProperty;

+ (id)sharedMySingleton;

@end

Step 2. Method Implementation

Inside the class method sharedMySingleton –

  1. Declare a static variable named sharedMySingleton
  2. Use GCD command “dispatch_once_t” to call the designated initializer method once and assign the same to sharedMySingleton
  3. Return the static variable sharedMySingleton

Implement the designated initializer –

  1. Assign the [super init] to self as is done in designated initializers
  2. Initialize the variables declared in the header file

Code:

+ (id)sharedManager {
static MySingleton *sharedMySingleton = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedMySingleton = [[self alloc] init];
});
return sharedMySingleton;
}

– (id)init {
if (self = [super init]) {
someProperty = [[NSString alloc] initWithString:@”Default Property Value”];
}
return self;
}

This class will return the same instance when ever the “sharedMySingleton’” is called and you have got a Singleton!

Update: Mattt Thompson has put together a nifty little code snippet here for your Xcode to create Singleton classes.

 

iOS Development

NSAutoreleasePool

 

It may be right that the @NSAutoreleasePool has a lot to discuss, but as of now I think the most valuable inputs for me are the following two:

1. When we use the AutoreleasePool?

If you are running a run-loop it should be managing an autorelease pool automatically for you; it should create a pool at the top of the loop and drain it at the end of each pass through the loop.

You only need to cycle one yourself if you have other stuff going on outside of the runloop.

http://stackoverflow.com/questions/3807035/best-way-to-periodically-drain-the-autorelease-pool-on-a-long-running-background

2. When is AutoreleasePool drained?

The Application Kit creates an autorelease pool on the main thread at the beginning of every cycle of the event loop, and drains it at the end, thereby releasing any autoreleased objects generated while processing an event.

http://developer.apple.com/library/ios/#documentation/Cocoa/Reference/Foundation/Classes/
NSAutoreleasePool_Class/Reference/Reference.html

3. Difference between “release” and “drain”?

In a reference-counted environment, releases and pops the receiver; in a garbage-collected environment, triggers garbage collection if the memory allocated since the last collection is greater than the current threshold.

If your system has a garbage Collection, then -drain send message (objc_collect_if_needed) for GC. If you haven’t GC, then drain = release

http://stackoverflow.com/questions/797419/whats-the-difference-between-sending-release-or-drain-to-an-autorelease-pool

Hope this helps!
Anindya

iOS Development

Setters & Getters in Objective C

 

The objective C setters and getters are never used, thanks to the @synthesize keyword bestowed upon us like God’s grace by the good fellows who created the language. Though there is rarely any chance of using it, its good to know how to write it for the apocalypse day when @synthesize is not working (hope it does not come!)

The Getters are easy, simple fellows with minimal code and goes as following:

//MyClass.h file

@interface MyClass: NSObject
{   
    NSString *text;
}

//MyClass.m file

-(NSString*) text
{   
   return text;
}

Setters are however a little tricky:

-(void) setText:(NSString *)textValue
{
    if (textValue != text)
    {
        [textValue retain];
        [text release];
        text = textValue;
    }
}

Quick Facts:

  1. The above method is the setter and is supposed to set the value to the variable which is passed to it
  2. The “if” condition is put there to avoid unnecessary code execution in case the old value and new value are the same
  3. To make sure “textValue” stays with us for a considerable amount and we do not lose it before proper assignment, we pass “retain” message to increate it’s retain count by 1
  4. We liberate “text” of its old value by passing “release” message to it
  5. Finally we assign the new value to text
iOS Development

Logging in Objective C

Logging has always played a very vital role in all kinds of programming platforms and languages. In objective C the most  commonly used method of logging is, as we all are quite well aware of, NSLog(). Though it may seem a little naive for experienced developers to see the usage of NSLog again, but for the new comers I would mention it shortly. However, human beings are curious creatures and never have settled down with anything. So, there are better ways of logging than NSLog. Let us see what these logging mechanisms are:

  • NSLog

    The NSLog, though being memory heavy, is the most commonly used mechanism for logging. The syntax is as follows:

    NSLog(@“message”);
    NSLog(@”%@”, @”message goes here”);
    NSLog(@”The %d iteration of this loop provides data: %@”, iteration, data);

  • Conditional NSLog for Debugging Purpose

    Despite of its simplistic nature, NSLog adds memory overhead and is not at all recommended to be kept in release mode of applications. This is not only because of the associated memory load and leak issues, but also due to the most common error of accidentally leaking proprietary and sensitive data to unauthorized users. But we can not simply live without NSLog (we can, but more on that later). Hence the ideal condition would be to enable NSLog when application is in “debug” mode and switch it off when application is released i.e. in “release” mode. To achieve this the best way is the following:

    Step 1: Add the following code to the Appname_prefix.pch file

    #ifdef DEBUG
    #    define DLog(…) NSLog(__VA_ARGS__)
    #else
    #    define DLog(…) /* */
    #endif
    #define ALog(…) NSLog(__VA_ARGS__)

    Step 2: Go to “Schema” and set the current schema to Debug

    Step 3: In the build configuration “Other C Flags” key add –DDEBUG

    That’s all. Now, when you are building the application and need to log anything which you only want to display in debug mode, use DLog(). When the application will be run in “release” mode, the DLog will print nothing. Also if you need anything to be printed irrespective of the configuration, use ALog in this case. The syntax for DLog and ALog would be exactly as NSLog().

http://www.cimgf.com/2009/01/24/dropping-nslog-in-release-builds/

Pro Tip: An unexplored horizon – Apple System Logs (ASL)

In most of the cases when the application is launched in the App Store and users are using the app, and unfortunately, the application crashes, there is no way to receive this kind of information without a lot of effort. A few days back, it was impossibly difficult to get access to the crash logs, warning logs etc. However, recently Apple has enabled the “Apple System Log” (ASL) which was there in OS X, in iOS also. Accessing the ASL, now we can get all 7 levels of logs and can easily post them to any server and set up a automatic logger system like Crittercism (however, Crittercism does it too elegantly).

ASL is a low level C API used to access the Apple Server Logs and use them in applications. Here is a quote from the manual page:

 The new API allows client applications to create flexible, structured messages and send them to the syslogd server, where they may undergo additional processing. Messages received by the server are saved in a data store (subject to     input filtering constraints).  This API permits clients to create queries and search the message data store for matching messages.

More details on ASL can be found in the following links:

Information Source Blogs:

http://www.cocoanetics.com/2011/03/accessing-the-ios-system-log/

https://developer.apple.com/library/ios/#documentation/System/Conceptual/ManPages_iPhoneOS/man3/asl.3.html