Miscellaneous2 Flashcards
How is your app notified during a touch interaction when a call comes through?
UIKit notifies the app via touchesCancelled(_:with:)
Explain how UITouch class in UIKit works when a user adds one finger then another?
A UITouch object is created for the first finger and delivered to the app via a UIEvent object to the UIView’s touchesBegan, touchesMoved, touchesEnded method calls.
That is repeated for each subsequent touch interaction with a new finger, with multiple touches delivered together inside the UIEvent object.
Can you override functions from a Swift extension?
No, not permitted. Only permitted to override from a class that inherits from the class you are extending.
What is the importance of the final keyword for classes and methods?
A final class cannot be extended. Final methods cannot be overridden in subclasses.
How can you keep track of multi-finger touches?
Override touchesBegan, touchesMoved, touchesEnded, touchesCancelled in the UIView or UIViewController class while tracking the touches in an array of 5 UITouch objects, each indexed by finger.
https://stackoverflow.com/questions/39823914/how-to-track-multiple-touches
var fingers = UITouch?
// SETUP ARRAY IF FINGER NIL override func touchesBegan(_ touches: Set, with event: UIEvent?) { super.touchesBegan(touches, with: event) for touch in touches{ let point = touch.location(in: self.view) for (index,finger) in fingers.enumerated() { if finger == nil { fingers[index] = touch print("finger \(index+1): x=\(point.x) , y=\(point.y)") break } } } }
//TRACK MOVEMENT BY FINGER MATCHING TOUCH ID override func touchesMoved(_ touches: Set, with event: UIEvent?) { super.touchesMoved(touches, with: event) for touch in touches { let point = touch.location(in: self.view) for (index,finger) in fingers.enumerated() { if let finger = finger, finger == touch { print("finger \(index+1): x=\(point.x) , y=\(point.y)") break } } } }
Can touchesBegan, touchesMoved, touchesEnded, touchesCancelled be overridden on UIViews and ViewControllers?
Yes
What are some ways of restricting touches on a UIView/ViewController?
Universally: UIApplication’s beginIgnoringInteractionEvents (bookended by endIgnoringInteractionEvents)
isUserInteractionEnabled
alpha = 0.0 (touches fall thru)
isHidden
isMultipleTouchEnabled
How do you convert a point from one coordinate space to another’s?
func convert(_ point: CGPoint, to view: UIView?) -> CGPoint
Where point is in the receiver’s coordinate space and view is the view to translate it into
What are the four methods that intercept touches on UIView and descendants?
touchesBegan, touchesMoved, touchesEnded, touchesCancelled
What is some of the information you can get out of a UITouch?
location(in:): gets the location as translated into the coordinate system of the in parameter element.
previousLocation(in:): same as above, but the the position of the element previously in the coordinate system of the in parameter element
preciseLocation/previousPreciseLocation
timeStamp: TimeInterval can kept as a class variable and used to subtract to get time difference between touches.
force: where 1.0 is average touch
tapCount: number of times the finger was tapped for a given touch.
view: the view to which touches are being delivered, if any
// CODE BELOW: GET PREVIOUS LOCATION, CURRENT LOCATION IN SUPERVIEW AND RECALCULATE THE CENTER BASED ON THE CHANGE IN X/Y override func touchesMoved(_ touches: Set, with event: UIEvent?) {
let t = touches.first let point = self.convert(self.center, to: superview)
if let location = t?.location(in: self.superview), let oldLocation = t?.previousLocation(in: self.superview){
let deltaX = location.x - oldLocation.x let deltaY = location.y - oldLocation.y
self. center.x += deltaX self. center.y += deltaY } }
What class member of UIView can be set to false to stop more than one finger touches?
isMultipleTouchEnabled
Are Gesture Recognizers part of the UIResponder chain?
No, does not participate in responder chain. Touches are delivered to a view and if there are Gesture Recognizers it gets delivered there as well, and to the superview’s Gesture Recognizers, etc. up the chain.
At a high-level how does Gesture Recognizer determine a gesture?
It maintains its own sate as touch events arrive, building up evidence as to what gesture it is, until it decides it has its gesture, where it then sends a single message(e.g., tap) or series of messages(e.g., movement)
What are key methods of UIGestureRecognizer?
location(ofTouch:in) - in, is the view whose coordinate system you want to use
isEnabled: turn on/off
state: progression of modes the GR goes through as it starts, recognizes the gesture, updates changes, and ends. (.possible, .failed, .ended, .began, .changed)
view: view where the GR is attached
List the set of UIGestureRecognizers
UITapGestureRecognizer UIPinchGestureRecognizer UIRotationGestureRecognizer UISwipeGestureRecognizer UIPanGestureRecognizer UIScreenEdgePanGestureRecognizer UILongPressGestureRecognizer
List the states of a UIGestureRecognizer
.possible .failed .ended .began .changed
What do the states of a UIGestureRecognizer mean and at a high-level list out what they do?
UIGestureRecognizers stay in a particular state until a decision is made. State becomes .possible -> .began -> .changed -> .ended for a drag where .changed is called repeatedly. A tap might go .possible->.ended where the gesture is recognized or .possible->.failed where its the wrong gesture.
Action messages are sent to selectors once for .began, as many times as necessary for .changed, and once for .cancelled/.ended.
What methodology do you use to prevent conflicts between UIGestureRecognizers?
require(toFail:UIGestureRecognizer)
Make the UIGestureRecognizers dependent on each other using require to have one fail before the other.
What kind of conflicts can arise between UIGestureRecognizers?
A double tap and a single tap on the same UIView
UIControl in a superclass view (think root window view with UIButton in it and a GR on the view to detect background taps) - If the user taps button the GR will also fire.
Solve this issue with require(toFail:) on the GR
Solve this issue by subclassing UIView and overriding gestureReognizerShouldBegin - this can then return false so the UIView(or Button, or other control) for the type of gesture recognizer, like a SingleTapGR vs others which could return true.
If you subclassed UIView and implemented touchesBegan, touchesMoved, touchesEnded, etc (where touches moved repositions the UIView)
Then, also put a UIPanGestureRecognizer on the UIView inside the UIViewController it’s instantiated in, that only prints to output.
What happens?
UIGestureRecognizers supplant overriding touchesBegan, touchesMoved, etc. but not until the Gesture is recognized.
SO.
Initially, touchesMoved is called until the Gesture is recognized as a Pan by the GR which then takes over. So, the dragging would work until the PanGR takes over, in which case the movement stops and only prints to output.
Difference between isKind(of aClass: AnyClass) and isMember(of aClass: AnyClass)
isKind will return true if the caller is an instance or a subclass of that parameter class. isMember returns true if it is an instance NOT a subclass.
Describe the sequence of events when hitTest method is called by UIView?
hitTest(_ point:CGPoint? with UIEvent?) takes a point in and first calls the same method on its own subviews. The subviews are queried front-to-back order so the one in front reports the hit first.
If a subview returns a view, hitTest immediately returns that view.
If no subviews or all return nil (meaning neither they nor their subview have been hit) then the UIView calls point(inside:with) on itself. If hit was inside itself, the UIView returns self, otherwise nil
If you have two UIViews on superview but want to monitor hit testing at the superview level. You place a UITapGestureRecognizer on the superview and make the UIViews subviews by adding them.
What do you do to distinguish which UIView was tapped?
In the action method of the UITapGestureRecognizer, perform a hit test to return the touched view. Then test if that view is an instance of one or the other UIViews.
let p = tapgr.location(ofTouch:0, in tapgr.view) let v = tapgr.view.hitTest(p, with: nil)
// now we've got the view that was touched, test which one if let v = v as UIView && v === self.myTargetedView{ .... }
What method can you call on a GestureRecognizer that will give you the Point of the touch that occurred?
location(ofTouch:, in UIView)
ofTouch is the Index of the touch event
Can you call hitTest on CALayers?
Normally CALayer do not receive touches. Yet you can still detect touches by calling hitTest on the layer with a point in the super layer coordinates.
Describe what UIViewControllers are responsible for and their purpose?
Logic of what views are shown, what data those views display, response to user gestures, View and Controller in the MVC design pattern,
Manages the interface and presents UIViews
Animation of the interface
Save and restore state
Root View: the UIVC that sits on top of the UIView hierarchy
What retains the root UIViewController?
UIWindow
What retains an embedded UIViewController?
Parent UIViewController
Is it safe to perform dimension dependant calculations from the viewDidLoad method?
No, self.view dimensions may not have been set from this function.
What is the UIViewController’s loadView method for?
Loading the initial view of that UIViewController! (self.view). If you don’t override it, a generic view is assigned to self.view by the default implementation of loadView
How do you use a nib file to load a UIViewController?
Create the nib (file->new file->iOS->user interface -> view. Then instantiate the VC with the name of that nib file:
let theVC = MyRootViewController.init(nibName:"mynib", bundle: nil) self.window.rootViewController = theVC
What are some of the methods that are called when a UIViewController receives events that the main view is being resized?
viewWillTransition(to:with:TransitionCoordinator): sent when main view’s size will change (rotation, user widens window on iPad)
willTransition(to:with:TransitionCoordinator): sent when trait Collection is about to change (could be rotation or other things like dynamic text size change)
traitCollectionDidChange(_:): sent after trait collection changes, when trait collection is set for the first time.
What is the TransitionCoordinator parameter of viewWillTransition/willTransition?
Use the coordinator to hook into the transition animation and perform setup/teardown and add a completion. I.e., change constraints for rotation change.
coordinator.animate(alongsideTransition: { _ in
}) { [unowned self] _ in self.postsCollectionView.reloadData() self.postsCollectionView.collectionViewLayout.invalidateLayout() DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(500)) { // Trigger layoutSubViews call when orientation changes UIView.animate(withDuration: 0.5) { self.postsCollectionView.alpha = 1.0 } } }
What’s the most reliable way to detect size changes (e.g., rotation)?
viewWillLayoutSubviews/viewDidLayoutSubviews: there are some situations where view can be resized without a size change being notified but you’ll ALWAYS get layout events, the viewWillLayoutSubviews and viewDidLayoutSubviews methods.
What’s the updateViewConstraints method?
UIViewController method (that can be overridden) that the view receives when it’s told to update its constraints.
On size change like rotation what are the order of methods related to the change that is called?
willTransition(to:with) //the trait collection viewWillTransition(to:with) //the size updateViewConstraints traitCollectionDidChange(_:) viewWillLayoutSubviews viewDidLayoutSubviews
It’s possible that some of these events are sent more than once so take care to do nothing if nothing is changed.
How do you check the orientation of the device?
UIApplication.shared.statusBarOrientation
OR
UIApplication.shared.windows.first?.windowScene!.interfaceOrientation if > iOS 13
check landscapeLeft/landscapeRight/portrait/portraitUpsideDown of the orientation object
if #available(iOS 13, *) {
orientation = (UIApplication.shared.windows.first?.windowScene!.interfaceOrientation)!
} else {
orientation = UIApplication.shared.statusBarOrientation;
}
if orientation == UIInterfaceOrientation.portraitUpsideDown || orientation == UIInterfaceOrientation.portrait{
}else if orientation == UIInterfaceOrientation.landscapeLeft || orientation == UIInterfaceOrientation.landscapeRight {
How can you test for the iOS version?
if #available(iOS 13, *){ ….}
What are three ways to lock an application into a particular orientation?
In the info.plist: UISupportedInterfaceOrientations
AppDelegate: implement the application(_:supportedInterfaceOrientationsFor:), returning a bit mask indicating the permitted orientations. This overrides info.plist.
Top-level VC may override the supportedInterfaceOrientations property returning a bit mask listing the set of allowed orientations
Be careful: mixing these, using info.plist then overriding in root VC will result in strange behavior.
The bit mask values are: .landscapeLeft .landscapeRight .portrait .portraitUpsideDown .all .allButUpsideDown
Should you create a UIView inside viewWillLayoutSubviews?
No, viewWillLayoutSubviews is fine for positioning items, adding or taking away constraints, but not for creating because it gets called repeatedly throughout the lifetime of an app.
Create a UITabBarController manually with two child UIViewControllers, one red, one green background.
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
self.window = self.window ?? UIWindow() let tabBarController = UITabBarController.init() let vc1 = UIViewController.init() let vc2 = UIViewController.init()
vc1.view.backgroundColor = UIColor.green vc2.view.backgroundColor = UIColor.red vc1.title = "Green" vc2.title = "Red" tabBarController.viewControllers = [vc1,vc2] self. window?.rootViewController = tabBarController self. window?.makeKeyAndVisible() return true }
What are the two key methods to show and hide a ViewController?
present(_:animated:completion)
dismiss(animated:completion)
What are the steps of Test Driven Development Cycle?
Focus on writing only code necessary to pass tests.
1) Add a test
2) Run the tests and make sure it fails
3) Write the code that makes the test pass
4) Run tests
5) Refactor code
6) Repeat
What does the test creation step entail in TDD?
- Each new feature begins with a test.
- Write a test that defines the function, it should be very succinct.
- To write the test the developer must clearly understand the feature’s spec and requirements.
- use cases and user stories can cover the requirements)
What are the advantages of writing tests first?
- Helps ensure the app is written for testability. Developers think about testing from the beginning rather than retrofitting it into a design.
- Writing tests first helps understand the requirements.
- Ensures effectiveness of test code.
- Maintains continual focus on software quality.
What does “red, green, refactor” mean?
First tests fail(red), then pass (green), then refactoring to eliminate redundancies and duplication.
List some important HTTP codes
200 OK — This is most commonly used HTTP code to show that the operation performed is successful.
201 CREATED — This can be used when you use POST method to create a new resource.
202 ACCEPTED — This can be used to acknowledge the request sent to the server.
400 BAD REQUEST — This can be used when client side input validation fails.
401 UNAUTHORIZED / 403 FORBIDDEN— This can be used if the user or the system is not authorised to perform certain operation.
404 NOT FOUND— This can be used if you are looking for certain resource and it is not available in the system.
500 INTERNAL SERVER ERROR — This should never be thrown explicitly but might occur if the system fails.
502 BAD GATEWAY — This can be used if server received an invalid response from the upstream server.
What is the unauthorized HTTP code
401
What is the Created HTTP code
201
What is the accepted HTTP code
202
What is the bad request HTTP Code
400
what is the Forbidden HTTP code
403
What is the Not Found HTTP code
404
What is the internal server error code
500
What is the bad gateway code
502
What are some design guidelines for creating REST APIs?
Simplicity and ease of use
- focus on URIs and payloads (internal domain model is not as important0
- Explorable on standard web browser
Consistency
Flexibility
What are the four HTTP methods?
GET — To get a resource or collection of resources.
POST — To create a resource or collection of resources.(can be used and not create a resource)
PUT/PATCH — To update the existing resource or collection of resources.(either creates or replaces an existing resource)
DELETE — To delete the existing resource or the collection of resources.
What’s the GET HTTP Method?
Returns (GETs) a resource or collection of resources
What’s the POST HTTP method?
Creates a resource or collection of resources. (can be used and not create a resource)
What’s the PUT HTTP method?
Updates existing resource or collection of resources (either creates or replaces an existing resource)
What’s the DELETE HTTP method?
Deletes an existing resource or collection of resources.
When designing an API what’s the primary decision that needs to be made?
Separate API into logical resources (nouns: sounds, cars, payments, articles, etc)
Figure out the data set: what set of data / which concepts do you want to expose/manipulate through the API?
What should be used as resource names for an API?
USE NOUNS
Good examples /employees /cars /payments /bills
Bad examples: /addEmployee /buyCar /sendPayment /createBill
Elaborate on what the difference is between POST and GET?
The GET request response body contains a representation of the fetched resource.
The POST request body contains a representation of the resource to create.
Where is the JSON type set in a header of a POST request?
Content-Type: application/json; charset=utf-8
Show what a POST request to update an existing resource would look like?
POST https://adventure-works.com/orders HTTP/1.1
Content-Type: application/json; charset=utf-8
Content-Length: 57
{“Id”:1,”Name”:”Gizmo”,”Category”:”Widgets”,”Price”:1.99}
How should a GET request be configured in order to receive JSON?
Accept Header should be set to application/json
GET https://adventure-works.com/orders/2 HTTP/1.1
Accept: application/json
If a POST method creates a new resource successfully what HTTP status code is returned?
201 (Created)
Whats a PATCH HTTP request
Updates a resource partially. The sent JSON has a subset of fields to change. E.g.
Original resource: { "name":"gizmo", "category":"widgets", "color":"blue", "price":10 }
PATCH Merge patch (subset of original): { "price":12, "color":null, "size":"small" }
If a POST, PUT, PATCH or DELETE is long running what should the server return to the client?
202 (Accepted) to indicate the request is processing but not complete.
How to support versioning in API design?
add version in URL: /v1/tickets
What is resource nesting when designing a REST API?
The URI will demonstrate the hierarchy between resource objects.
/users
How to handle Errors when designing an API
Use the Standard HTTP error codes and change the message parameter in the response body JSON.
{
“status”: 400,
“message”: “No to number is specified”,
“code”: 21201,
“more-info”: “http://www.twilio.com/docs/errors”
}
What are three important functions a REST API can perform?
Filtering, Sorting Paging
Give an example of filtering a REST API
Filtering:
GET /users?country=USA
GET /users?creation_date=2019-11-11
Give an example of sorting a REST API
GET /users?sort=birthdate_date:asc
GET /users?sort=birthdate_date:desc
Give an example of Paging an REST API
GET /users?limit=100
GET /users?offset=2
What are some important parts of API Documentation?
- provide information about the available endpoints and methods
- request/response examples
- possible response codes
- information about the authorization
- available limits or throttling.
Publishing the documentation in the form of a browsable web page with interactive options, curl examples, maybe even a playground is a good idea.
Swagger: can define Open API Specification throughSwaggerHUB. What are key objects in the YAML of OAS?
Info (license, contact, terms, description)
Servers: url, description
Paths: define the REST URLs…..HTTP method, define parameters (type, min/max values, etc), responses(for each HTTP code), description, content, define return JSON(array, properties, etc)
What are CodingKeys used for in the Codable protocol?
CodingKey is a protocol used in an enumeration of the string values of keys in the JSON to parse. The string used is the key name used during encoding and decoding.
struct Landmark: Codable { var name: String var foundingYear: Int var location: Coordinate var vantagePoints: [Coordinate]
enum CodingKeys: String, CodingKey { case name = "title" case foundingYear = "founding_date" case location case vantagePoints } }
If you dont need bidirectional encoding/decoding support what should you do?
Conform the class to either Encodable or Decodable INSTEAD of Codable.
Describe the steps to give default values to incoming JSON
1) Construct a struct representing the JSON
2) Conform to the Codable (or just Encodable/Decodable)
3) Apply Coding keys as an enum to assign keys for each value (recursive if required)
4) implement the init(from decoder:Decoder) throws initializer.
struct VideoId:Codable{
var kind:String
var videoId:String
var channelId:String
enum CodingKeys: String, CodingKey{ case kind = "kind" case videoId = "videoId" case channelId = "channelId" }
init(from decoder: Decoder) throws { let decoded_video = try decoder.container(keyedBy: CodingKeys.self)
kind = try decoded_video.decodeIfPresent(String.self, forKey: .kind) ?? "None" videoId = try decoded_video.decodeIfPresent(String.self, forKey: .videoId) ?? "None" channelId = try decoded_video.decodeIfPresent(String.self, forKey: .channelId) ?? "None" } }
Make a basic HTTP request to a url to download a file
let s = "https://url" let url = URL(string:s)! let session = URLSession.shared let task = session.downloadTask(with:url){fileURL, resp, err in
if let url = fileURL, let d = try? Data(contentsOf:url){ let im = UIImage(data:d) DispatchQueue.main.async{ self.iv.image = im } } }
task.resume()
When adding embedded ViewControllers what are the methods that always need to be called?
willMove and didMove
Add a Child to a ViewController:
- addChild(childVC) with the child as argument (child is added to children array and retained)
- self.view.addSubview()
- didMove(toParent:self) to child ViewController
willMove is sent by addChild automatically
When removing embedded ViewControllers what are the methods that need to be sent?
willMove and didMove
- willMove(toParent:)
- childVVC.view.removeFromSuperview()
- child.removeFromParent()
- removeFromParent
removeFromParent sends didMove automatically
What’s the method call to make that removes a VC from its owner?
child.removeFromParent()
How do you tell if a UIView is on the screen?
if viewToCheck.window != nil{
print(“ON THE SCREEN:)
}
You can determine whether the view is onscreen, by checking its window property. If that property contains a valid window, it is part of an active view hierarchy. If that property is nil, the view is not part of a valid view hierarchy.
How can a UIView selectively become firstResponder?
viewToBecomeFirst.becomeFirstResponder()
How do you encrypt files on iOS?
Use Data Protection API for NSFileManager, CoreData, NSData, and SQLite.
How are secure hashes done on iOS
Using CryptoKit (SHA512.hash())