20 iOS Developer Interview Questions

Link

12 Essential iOS Interview Questions

Link

----------------------------------------

Q: 1 What is the difference between viewDidLoad and viewDidAppear? Which should you use to load data from a remote server to display in the view?

A:

viewDidLoad is called when the view is loaded, whether from a Xib file, storyboard or programmatically created in loadView.

viewDidAppear is called every time the view is presented on the device. Which to use depends on the use case for your data.

If the data is fairly static and not likely to change then it can be loaded in viewDidLoad and cached. However if the data changes regularly then using viewDidAppear to load it is better. In both situations, the data should be loaded asynchronously on a background thread to avoid blocking the UI.

-------------------------------------------

Q: 2 What considerations do you need when writing a UITableViewController which shows images downloaded from a remote server?

A:

This is a very common task in iOS and a good answer here can cover a whole host of knowledge.

  • The important piece of information in the question is that the images are hosted remotely and they may take time to download, therefore when it asks for “considerations”, you should be talking about:

  • Only download the image when the cell is scrolled into view, i.e. when cellForRowAtIndexPath is called.

  • Downloading the image asynchronously on a background thread so as not to block the UI so the user can keep scrolling.

  • When the image has downloaded for a cell we need to check if that cell is still in the view or whether it has been re-used by another piece of data. If it’s been re-used then we should discard the image, otherwise we need to switch back to the main thread to change the image on the cell.

  • Other good answers will go on to talk about offline caching of the images, using placeholder images while the images are being downloaded.

------------------------------------------------

Q: 3 What is a protocol, how do you define your own and when is it used?

A:

  • A protocol is similar to an interface from Java. It defines a list of required and optional methods that a class must/can implement if it adopts the protocol.

  • Any class(for Swift, struct enum may implement protocol) can implement a protocol and other classes can then send messages to that class based on the protocol methods without it knowing the type of the class.

@protocol MyCustomDataSource
- (NSUInteger)numberOfRecords;
- (NSDictionary *)recordAtIndex:(NSUInteger)index;
@optional
- (NSString *)titleForRecordAtIndex:(NSUInteger)index;
@end
// protocol for Class Struct Enum
protocol ProtocolName {
    func hehe()
}

// only for class
@objc protocol ProtocolName {
    func hehe()
} 
protocol ProtocolName: class {
    func hehe()
}

A common use case is providing a DataSource for UITableView or UICollectionView.

------------------------------------------------

Q: 4 What is KVC and KVO? Give an example of using KVC to set a value.

A:

  • KVC stands for Key-Value Coding. It's a mechanism by which an object's properties can be accessed using string's at runtime rather than having to statically know the property names at development time. (provide Key path)

  • KVO stands for Key-Value Observing and allows a controller or class to observe changes to a property value.

  • Swift cannot support KVO solely,need use use objc feature

Let's say there is a property name on a class:

@property (nonatomic, copy) NSString *name;

We can access it using KVC:

NSString *n = [object valueForKey:@"name"]

And we can modify it's value by sending it the message:

[object setValue:@"Mary" forKey:@"name"]

------------------------------------------------

Q: 5 What are blocks and how are they used?

A:

  • Blocks are a method of defining a single task or unit of behavior without having to write an entire Objective-C class.
  • For swift, func/clousure/block is reference passing, is the same

  • Under the covers Blocks are still Objective C objects. They are a language level feature that allow programming techniques like lambdas and closures to be supported in Objective-C. Creating a block is done using the ^ { } syntax:

 myBlock = ^{
    NSLog(@"This is a block");
 }
let myblock: (Int) -> Void = { (res) -> Void in
    print("hehe \(res)")
}

It can be invoked like so:

myBlock();
myblock(20)

It is essentially a function pointer which also has a signature that can be used to enforce type safety at compile and runtime. For example you can pass a block with a specific signature to a method like so:

- (void)callMyBlock:(void (^)(void))callbackBlock;
func hehe(completion: () -> Void) {
    completion()
}

If you wanted the block to be given some data you can change the signature to include them:

- (void)callMyBlock:(void (^)(double, double))block {
    ...
    block(3.0, 2.0);
}
func haha(completion: (double, double) -> Void) {
    completion(3.0, 2.0)
}

--------------------------------------------------

Q: 6 What mechanisms does iOS provide to support multi-threading?

A:

NSThread creates a new low-level thread which can be started by calling the start method.

NSThread* myThread = [[NSThread alloc] initWithTarget:self
                                      selector:@selector(myThreadMainMethod:)
                                      object:nil];
[myThread start];

OperationQueue is the encapsulation of Grand Central Dispatch
NSOperationQueue allows a pool of threads to be created and used to execute NSOperations in parallel. NSOperations can also be run on the main thread by asking NSOperationQueue for the mainQueue.

NSOperationQueue* myQueue = [[NSOperationQueue alloc] init];
[myQueue addOperation:anOperation]; 
[myQueue addOperationWithBlock:^{
 /* Do something. */
}];
let operationQueue = OperationQueue()
operationQueue.addOperation {
    print("hehe")
}

GCD or Grand Central Dispatch is a modern feature of Objective-C that provides a rich set of methods and API's to use in order to support common multi-threading tasks. GCD provides a way to queue tasks for dispatch on either the main thread, a concurrent queue (tasks are run in parallel) or a serial queue (tasks are run in FIFO order).

dispatch_queue_t myQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(myQueue, ^{
  printf("Do some work here.\n");
});
let mySerialQueue = DispatchQueue(label: "mySerialQueue")
let myConcurrentQueue = DispatchQueue(label: "myConcurrentQueue", attributes: .concurrent)

mySerialQueue.async {
    print("do some")
}

------------------------------------------------

Q: 7 What is the Responder Chain?

A:

Event handle chain: from low level to high level, finding first responder

Event response chain: from high level to low level, first responder -> App delegate

When an event happens in a view, for example a touch event, the view will fire the event to a chain of UIResponder objects associated with the UIView. The first UIResponder is the UIView itself, if it does not handle the event then it continues up the chain to until UIResponder handles the event. The chain will include UIViewControllers, parent UIViews and their associated UIViewControllers, if none of those handle the event then the UIWindow is asked if it can handle it and finally if that doesn't handle the event then the UIApplicationDelegate is asked.

If you get the opportunity to draw this one out, it's worth doing to impress the interviewer:

------------------------------------------------

Q: 8 What's the difference between using a delegate and notification?

A:

Both are used for sending values and messages to interested parties.

  • A delegate is for one-to-one communication and is a pattern promoted by Apple. In delegation the class raising events will have a property for the delegate and will typically expect it to implement some protocol. The delegating class can then call the _delegate_s protocol methods.

  • Notification allows a class to broadcast events across the entire application to any interested parties. The broadcasting class doesn't need to know anything about the listeners for this event, therefore notification is very useful in helping to decouple components in an application.

[NSNotificationCenter defaultCenter] 
        postNotificationName:@"TestNotification" 
        object:self];
// core of Notification center
class MyNotificationCenter {
    typealias Observer = (String) -> Void
    //var dict = Dictionary<String, Set<MyClass>>()
    var dict2 = Dictionary<String, Dictionary<MyClass, Observer>>()

    func addObserver(key: String, aClass: MyClass, block: Observer) {
        // dict[key] add aClass
        // dict[key][aClass] add block
    }

    func removeObserver(key: String, aClass: MyClass) {
        // remove dict[key][aClass]
    }

    func post(key: String) {
        // call dict[key][everyClass]
    }
}

-----------------------------------------------

Q: 9 What's your preference when writing UI's? Xib files, Storyboards or programmatic UIView?

A:

There's no right or wrong answer to this, but it's great way of seeing if you understand the benefits and challenges with each approach. Here's the common answers I hear:

  • Storyboard's and Xib's are great for quickly producing UI's that match a design spec. They are also really easy for product managers to visually see how far along a screen is.
  • Storyboard's are also great at representing a flow through an application and allowing a high-level visualization of an entire application.

  • Storyboard's drawbacks are that in a team environment they are difficult to work on collaboratively because they're a single file and merge's become difficult to manage.

  • Storyboards and Xib files can also suffer from duplication and become difficult to update. For example if all button's need to look identical and suddenly need a color change, then it can be a long/difficult process to do this across storyboards and xibs.

  • Programmatically constructing UIView's can be verbose and tedious, but it can allow for greater control and also easier separation and sharing of code. They can also be more easily unit tested.

Most developers will propose a combination of all 3 where it makes sense to share code, then re-usable UIViews or Xib files.

-----------------------------------------------------

Q: 10 How would you securely store private user data offline on a device? What other security best practices should be taken?

A:

Again there is no right answer to this, but it's a great way to see how much a person has dug into iOS security. If you're interviewing with a bank I'd almost definitely expect someone to know something about it, but all companies need to take security seriously, so here's the ideal list of topics I'd expect to hear in an answer:

  • If the data is extremely sensitive then it should never be stored offline on the device because all devices are crackable.
  • The keychain is one option for storing data securely. However it's encryption is based on the pin code of the device. User's are not forced to set a pin, so in some situations the data may not even be encrypted. In addition the users pin code may be easily hacked.
  • A better solution is to use something like SQLCipher which is a fully encrypted SQLite database. The encryption key can be enforced by the application and separate from the user's pin code.

Other security best practices are:

  • Only communicate with remote servers over SSL/HTTPS.
  • If possible implement certificate pinning in the application to prevent man-in-the-middle attacks on public WiFi.
  • Clear sensitive data out of memory by overwriting it.
  • Ensure all validation of data being submitted is also run on the server side.

-----------------------------------------------------

Q: 11 What is MVC? How is it implemented in iOS? What are some pitfalls you've experienced with it? Are there any alternatives to MVC?

A:

MVC stands for Model, View, Controller. It is a design pattern that defines how to separate out logic when implementing user interfaces.

In iOS, Apple provides UIView as a base class for all Views, UIViewController is provided to support the Controller which can listen to events in a View and update the View when data changes. The Model represents data in an application and can be implemented using any NSObject, including data collections like NSArray and NSDictionary.

Some of the pitfalls that people hit are bloated UIViewController and not separating out code into classes beyond the MVC format. I'd highly recommend reading up on some solutions to this:

https://www.objc.io/issues/1-view-controllers/lighter-view-controllers/
https://speakerdeck.com/trianglecocoa/unburdened-viewcontrollers-by-jay-thrash
https://programmers.stackexchange.com/questions/177668/how-to-avoid-big-and-clumsy-uitableviewcontroller-on-ios

In terms of alternatives, this is pretty open ended. The most common alternative is MVVM using ReactiveCocoa, but others include VIPER and using Functional Reactive code.

MVVM

Model - View - ViewModel, viewModel saved the data directly can show in the view and worked for fetch data

VIPER

View - Interactor - Presenter - Entiry - Router

View - View + ViewController

Interactor - data manager

Presenter - control View to show something

Entity - raw model

Router - view switching and hierarchy

------------------------------------------------------

Q: 12 What’s the difference between an “app ID” and a “bundle ID” and what is each used for?

A:

  • An App ID is a two-part string used to identify one or more apps from a single development team. The string consists of a Team ID and bundle ID search string, with a period (.) separating the two parts.
  • The TeamID is supplied by Apple and is unique to a specific development team,
  • while the bundle ID search string is supplied by the developer to match either the bundle ID of a single app or a set of bundle IDs for a group of apps.

Because most people think of the App ID as a string, they think it is interchangeable with Bundle ID. It appears this way because once the App ID is created in the Member Center, you only ever use the App ID prefix which matches the Bundle ID of the Application Bundle.

  • The bundle ID uniquely defines each App. It is specified in Xcode. Single Xcode project can have multiple Targets and therefore output multiple apps. A common use case for this is an app that has both lite/free and pro/full versions or is branded multiple ways.

-----------------------------------------

Q: 13 A product manager in your company reports that the application is carshed. What do you do?

A:

THis a great question in any programming language and is really designed to see how you problem solve. Your are not given much information, but some interviews will slip you more details of the issue as you go along. Start simple:

  • get the act setps to reproduce it -- reproduce
  • find out the device, iOS version -- collect device/OS version/software version info
  • do they have the latest version?
  • get device logs if possible. -- find logs or moniter data

Once you can reproduct it or have more information then start using tooling. Let's say it crashes because of a mempry leak, I would expect to see someone suggest using Instruments leak tool. A really impressive candidate would start talking about writing a unit test that reproduces the issue and debugging through it.

Other variations of this question include slow UI or the application freezing. Again the idea is to see how you problem solve, what tools do you know about that would help and do you know how to use them correctly.

----------------------------------

Q: 14 What is AutoLayout? What does it mean when a constriant is "broken" by iOS?

A:

AutoLayout is way of laying out UIViews using a set of constraints that specify the location and size based relative to other views or based on explicit values. AutoLayout makes it easier to design screens that resize and layout out their compinents better based on the size and orientation of a screen.

The constraint includes:

  • setting the horizontal/ vertical distance between 2 Views
  • setting the height/width to be a ratio relative to a different view
  • a width/height/spacing can be an explicit static value
  • provide priority to resovle conflict, larger priority is more priority

Sometimes constraints conflict with each other. For example imageine a UIView which has 2 height constraints: one says make the UIView 200px height, and the second says that makes the height twice the height of a button.If the iOS runtime cannot satify both of these constraints then it has to pick only one. THe other is then reported as being "borken" by iOS

---------------------------------------------

Q: 15 What are “strong” and “weak” references? Why are they important and how can they be used to help control memory management and avoid memory leaks?

A:

By default, any variable that points to another object that is the "strong" reference. Retain cycle occurs when two or more objects have strong references to each other. Any such objects will never be destroyed by ARC(Automatic Reference Counting). Even if every other object in the app releases ownership of these objects, these objects will continue to exist by those strong references. This therefore results in a memory leak.

  • Reciprocal strong references(strong reference to each other) should therefore be avoid to the extent possible. However, we can use weak references to avoid this type of memory leak. Declaring one of the two references as weak will break the retain cycle and thereby avoid the memory leak.

  • To decide which of the two references should be weak, think of the objects in the retain cycle as being in a parent-child relationship. In this relationship, the parent should maintain a string reference(such as ownership of) its child, but the child should not maintain a strong reference(such as ownership of) its parent.

For example, if you have Employer and Emplyee objects, which reference one another, you would most likely want to maintain a strong reference from the Employer to the Employee object, but have a weak reference form the Employee to the Employer.

---------------------------------------------

Q: 16 Describe managed object context and the functionality that it provides

A:

You can think of a managed object context as an intelligent scratch pad. When you fetch objects from a persistent store, you bring temporary copies onto the scratch pad where they form an object graph (or a collection of object graphs). You can then modify those objects however you like. Unless you actually save those changes, though, the persistent store remains unchanged.

----------------------------------------------

Q: 17 Compare and contrast the different ways of achieving concurrency in OS X and iOS.

A:

There are basically three ways of achieving concurrency in iOS:

threads
dispatch queues  
operation queues

The disadvantage of threads is that they relegate the burden of creating a scalable solution to the developer. You have to decide how many threads to create and adjust that number dynamically as conditions change. Also, the application assumes most of the costs associated with creating and maintaining the threads it uses.

OS X and iOS therefore prefer to take an asynchronous design approach to solving the concurrency problem rather than relying on threads.

  • One of the technologies for starting tasks asynchronously is Grand Central Dispatch (GCD) that relegates thread management down to the system level. All the developer has to do is define the tasks to be executed and add them to the appropriate dispatch queue. GCD takes care of creating the needed threads and scheduling tasks to run on those threads.

All dispatch queues are first-in, first-out (FIFO) data structures, so tasks are always started in the same order that they are added.

An operation queue is the Cocoa equivalent of a concurrent dispatch queue and is implemented by the NSOperationQueue class. Unlike dispatch queues, operation queues are not limited to executing tasks in FIFO order and support the creation of complex execution-order graphs for your tasks.

--------------------------------------------

Q: 18 List and explain the different types of iOS Application States.

A:

Not running state: The app has not been launched or was running but was terminated by the system.

Inactive state: The app is running in the foreground but is currently not receiving events. (It may be executing other code though.) An app usually stays in this state only briefly as it transitions to a different state. The only time it stays inactive for any period of time is when the user locks the screen or the system prompts the user to respond to some event (such as an incoming phone call or SMS message).

Active state: The app is running in the foreground and is receiving events. This is the normal mode for foreground apps.

Background state: The app is in the background and executing code. Most apps enter this state briefly/shortly on their way to being suspended. However, an app that requests extra execution time may remain in this state for a period of time. However, an app being launched directly into the background will enter this state instead of the inactive state.

Suspended state: While suspended, an app remains in memory but does not execute any code. When a low-memory condition occurs, the system may clean suspended apps without notice to make more space for the foreground app.

The app is in the background but is not executing code. The system moves apps to this state automatically and does not notify them before doing this.

--------------------------------------------

results matching ""

    No results matching ""