May 312014
 

UITextField’s Limitation

UITextField has a property called secureTextEntry that hides the characters as you type them (except for the last one, which is hidden after a brief moment). This is useful for things like a password field.

However, you will notice that the keyboard icon that lets you choose languages is absent. This means that you are limited to using English passwords. It is strange that Apple does not support this (FYI, Android does support it).

Challenges

The only solution I saw was this stackoverflow answer. However, it does not work for all languages. Languages like Korean (Hangul) has a composite character where each letter is composed of multiple symbols. For example, ‘ㅁ’, ‘ㅏ’ and ‘ㄴ’ are all individual characters, but when combined, it becomes ‘만’, which is treated as a single letter.

This means that NSString methods like stringByReplacingCharactersInRange:withString used in the solution in the stackoverflow post does not give the right output.

The Solution

The solution I came up with places a UILabel on top of a UITextField. The UILabel obscures the UITextField, thus hiding the characters being typed in the UITextField. I listen for the UITextFieldTextDidChangeNotification and set UILabel’s text with the appropriate number of “●” (UITextField’s length – 1), except for the last character which is shown. The last character is hidden after a second later if there is no further input.

The cursor is emulated with a ‘|’ character. The blinking is achieved with a NSTimer that toggles the cursor character between a space and a ‘|’.

Demo and Source

You can find the full source along with a sample (the one shown in the video) in my Github repository.

 Posted by at 12:16 am
May 282014
 

Java has a very useful class called the BlockingQueue. With a blocking queue, the dequeue operation will block until there is something to be dequeued. A blocking queue is very handy and can be used to solve the classic producer-consumer problem. I needed a similar class in Objective-C, but I could not find one. The following is a simple implementation.

Queue Implementation

The queue is implemented using NSMutableArray. A queue is a FIFO (First In, First Out) data structure, so enqueue adds an object to the end of the array (simple addObject suffices). Dequeue simply returns the first object in the array, and then removes it from the array (items are effectively shifted up a slot after the deletion).

Locking and Thread Synchronization

NSCondition is used for locking and thread synchronization. If you have two threads sharing a resource (the queue in our case), you will have the following code for the producer and the consumer.

The consumer:

[lock lock];
while (!someValueIsTrue) 
{
    [lock wait];
}
// Do protected work (in our case, dequeue)
[lock unlock]

The producer:

[lock lock];
// Do protected work (in our case, enqueue)
someValueIsTrue = true;
[lock signal];  
[lock unlock];

The Implementation

Here is the implementation of enqueue and dequeue. It is very simple and generally follows the pattern above. Remember, queueing and dequeueing must happen on different threads, so I am using a dispatch queue. If you call NSCondition’s lock in the same thread, you will get a deadlock.

- (void)enqueue:(id)object
{
    [_lock lock];
    [_queue addObject:object];
    [_lock signal];
    [_lock unlock];
}

- (id)dequeue
{
    __block id object;
    dispatch_sync(_dispatchQueue, ^{
        [_lock lock];
        while (_queue.count == 0)
        {
            [_lock wait];
        }
        object = [_queue objectAtIndex:0];
        [_queue removeObjectAtIndex:0];
        [_lock unlock];
    });
    
    return object;
}

Source Code and Sample

I hope this has been helpful to someone.

You can find the complete implementation along with sample code in my Github repository.

 Posted by at 3:49 pm