Interview questions and topics
- ARC and Retain cycles
- Communication patterns
- Viewcontroller lifecycle
- Favorite framework and why
- Classes vs Structs
- Filter, map, reduce in Collections
- Testing
- 3rd party libraries
- Doing an exercise with Gesture Recognizers
- Networking, doing a request
- Debugging, look at code and find bugs.
- Take home projects
ARC and Retain cycles
ARC tracks how many properties, constants, and variables are currently referring to each class instance. ARC will not deallocate an instance as long as at least one active reference to that instance still exists.
Whenever you assign a class instance to a property, constant, or variable, that property, constant, or variable makes a strong reference to the instance. The reference is called a strong reference when it does not allow it to be deallocated for as long as that reference remains.
Notifications
Its a one to many communication pattern.
Observer
Its a one to many communication pattern.
Delegate
Delegation is a simple and powerful pattern in which one object in a program acts on behalf of, or in coordination with, another object. The delegating object keeps a reference to the other object—the delegate—and at the appropriate time sends a message to it. The message informs the delegate (e.g.: UITableViewDelegate) of an event that the delegating object (e.g.: UITableView) is about to handle or has just handled. The delegate may respond to the message by updating the appearance or state of itself or other objects in the application, and in some cases it can return a value that affects how an impending event is handled. The main value of delegation is that it allows you to easily customize the behavior of several objects in one central object.
Its a one to one communication pattern.
Protocol
Its a one to one communication pattern.
ViewController lifecycle
loadView
loadViewIfNeeded
viewDidLoad
loadViewIfNeeded
viewDidLoad
viewWillAppear
viewWillLayoutSubviews
viewdidLayoutSubviews
viewDidAppear
viewWillDisappear
viewDidDisappear
Favorite framework
CoreLocation, MapKit, UIKit, etc
Classes vs Structs
Structures and classes in Swift have many things in common. Both can:
- Define properties to store values
- Define methods to provide functionality
- Define subscripts to provide access to their values using subscript syntax
- Define initializers to set up their initial state
- Be extended to expand their functionality beyond a default implementation
- Conform to protocols to provide standard functionality of a certain kind
Classes have additional capabilities that structures don’t have:
- Inheritance enables one class to inherit the characteristics of another.
- Type casting enables you to check and interpret the type of a class instance at runtime.
- Deinitializers enable an instance of a class to free up any resources it has assigned.
- Reference counting allows more than one reference to a class instance.
A value type is a type whose value is copied when it’s assigned to a variable or constant, or when it’s passed to a function.
In fact, all of the basic types in Swift—integers, floating-point numbers, Booleans, strings, arrays and dictionaries—are value types, and are implemented as structures behind the scenes.
All structures and enumerations are value types in Swift.
Unlike value types, reference types are not copied when they are assigned to a variable or constant, or when they are passed to a function. Rather than a copy, a reference to the same existing instance is used.
Classes are reference types.
Filter, map, reduce in Collections
filter
Returns an array containing, in order, the elements of the sequence that satisfy the given predicate.
let cast = ["Vivien", "Marlon", "Kim", "Karl"]
let shortNames = cast.filter { $0.count < 5 }
print(shortNames)
// Prints "["Kim", "Karl"]"
map
Returns an array containing the results of mapping the given closure over the sequence’s elements.
let cast = ["Vivien", "Marlon", "Kim", "Karl"]
let lowercaseNames = cast.map { $0.lowercased() }
// 'lowercaseNames' == ["vivien", "marlon", "kim", "karl"]
let letterCounts = cast.map { $0.count }
// 'letterCounts' == [6, 6, 3, 4]
flatMap
Returns an array containing the concatenated results of calling the given transformation with each element of this sequence.
let numbers = [1, 2, 3, 4]
let mapped = numbers.map { Array(repeating: $0, count: $0) }
// [[1], [2, 2], [3, 3, 3], [4, 4, 4, 4]]
let flatMapped = numbers.flatMap { Array(repeating: $0, count: $0) }
// [1, 2, 2, 3, 3, 3, 4, 4, 4, 4]
compactMap
Returns an array containing the non-
nil results of calling the given transformation with each element of this sequence.let possibleNumbers = ["1", "2", "three", "///4///", "5"]
let mapped: [Int?] = possibleNumbers.map { str in Int(str) }
// [1, 2, nil, nil, 5]
let compactMapped: [Int] = possibleNumbers.compactMap { str in Int(str) }
// [1, 2, 5]
reduce
Returns the result of combining the elements of the sequence using the given closure.
let numbers = [1, 2, 3, 4]
let numberSum = numbers.reduce(0, { x, y in
x + y
})
// numberSum == 10
Testing
Creating a Unit Test Target- Don't forget to add @testable import <Your Target>
- Use XCTAsset to test models
- Use XCTTestExpectation to test asynchronous operations
// Asynchronous test: success fast, failure slow
func testValidCallToiTunesGetsHTTPStatusCode200() {
// given
let url = URL(string: "https://itunes.apple.com/search?media=music&entity=song&term=abba")
let promise = expectation(description: "Status code: 200")
// when
let dataTask = sessionUnderTest.dataTask(with: url!) { data, response, error in
// then
if let error = error {
XCTFail("Error: \(error.localizedDescription)")
return
} else if let statusCode = (response as? HTTPURLResponse)?.statusCode {
if statusCode == 200 {
promise.fulfill()
} else {
XCTFail("Status code: \(statusCode)")
}
}
}
dataTask.resume()
waitForExpectations(timeout: 5, handler: nil)
}
Code Coverage
3rd party libraries
Cocoapods, Carthage, etc
Doing an exercise with Gesture Recognizers
Moving a view around with a gesture
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let rectView = UIView()
rectView.frame = CGRect(x: 0, y: 0, width: 100, height: 100)
rectView.backgroundColor = UIColor.green
let panGesture = UIPanGestureRecognizer(target: self, action: #selector(handlePan(_:)))
rectView.addGestureRecognizer(panGesture)
let rotationGestureRecognizer = UIRotationGestureRecognizer(target: self, action: #selector(handleRotation(_:)))
rectView.addGestureRecognizer(rotationGestureRecognizer)
let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(handleTap(_:)))
rectView.addGestureRecognizer(tapGestureRecognizer)
view.addSubview(rectView)
}
@objc func handlePan(_ panGesture: UIPanGestureRecognizer) {
let translation = panGesture.translation(in: view)
let rectView = panGesture.view
rectView?.frame = rectView?.frame.offsetBy(dx: translation.x, dy: translation.y) ?? CGRect.zero
panGesture.setTranslation(CGPoint.zero, in: rectView)
}
@objc func handleRotation(_ rotationGesture: UIRotationGestureRecognizer) {
let rotation = rotationGesture.rotation
let rectView = rotationGesture.view
rectView?.transform = CGAffineTransform.identity.rotated(by: rotation)
}
@objc func handleTap(_ tapGesture: UITapGestureRecognizer) {
let rectView = tapGesture.view
UIView.animate(withDuration: 0.5, delay: 0, options: .curveEaseOut, animations: {
rectView?.center.y -= 100 // If you use 'frame' rather than 'center' here if you
// rotate the rect first, if will get crashed
UIView.animate(withDuration: 0.5, delay: 1, options: .curveEaseOut, animations: {
rectView?.center.y += 100
}) { (completed) in
}
}) { (completed) in
}
}
}
zoom
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let rectView = UIView()
rectView.frame = CGRect()
rectView.backgroundColor = UIColor.green
rectView.translatesAutoresizingMaskIntoConstraints = false
let zoomGestureRecognizer = UIPinchGestureRecognizer(target: self, action: #selector(handleZoom(_:)))
rectView.addGestureRecognizer(zoomGestureRecognizer)
view.addSubview(rectView)
NSLayoutConstraint.activate([
rectView.centerXAnchor.constraint(equalTo: view.centerXAnchor, constant: 0),
rectView.centerYAnchor.constraint(equalTo: view.centerYAnchor, constant: 0),
rectView.widthAnchor.constraint(equalToConstant: 100),
rectView.heightAnchor.constraint(equalToConstant: 100)
])
}
@objc func handleZoom(_ zoomGesture: UIPinchGestureRecognizer) {
let scale = zoomGesture.scale
let rectView = zoomGesture.view
rectView?.transform = CGAffineTransform.identity.scaledBy(x: scale, y: scale)
}
}
Networking, doing a request
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// GET
let getUrl = URL(string: "https://www.apple.com/")!
let session = URLSession.shared
let getTask = session.dataTask(with: getUrl) { (data, response, error) in
if let error = error {
print("GET Error: ", error)
return
}
if let httpResponse = response as? HTTPURLResponse {
if httpResponse.statusCode == 200 {
print("GET Success!")
} else {
print("GET Status Code: \(httpResponse.statusCode)")
}
}
}
getTask.resume()
// POST
let postUrl = URL(string: "https://httpbin.org/post")!
let dictionary = ["someParameter": "value"]
let request = NSMutableURLRequest(url: postUrl)
request.httpMethod = "POST"
request.httpBody = try? JSONSerialization.data(withJSONObject: dictionary, options: .prettyPrinted)
let postTask = session.dataTask(with: request as URLRequest) { (data, response, error) in
if let error = error {
print("POST Error: ", error)
return
}
if let httpResponse = response as? HTTPURLResponse {
if httpResponse.statusCode == 200 {
print("POST Success!")
} else {
print("POST Status Code: \(httpResponse.statusCode)")
}
}
}
postTask.resume()
}
}
Debugging, look at code and find bugs
For instance, optional being unwrapped inappropriately, raise conditions in network calls, retain cycles, memory leaks, ui not updated on the main thread.
Take home projects
Networking, tableview, building a ui to a spec pixel perfect, persistance, mapkit, animations, etc. Probably will have to build the UI entirely in code.





No hay comentarios:
Publicar un comentario