Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/cozzin/ios-study-note
๐ง ๋ถ์คํธ์บ ํ iOS ๋ฆฌ๋ทฐ์ด ํ๋ ๋ด์ฉ ์ ๋ฆฌ
https://github.com/cozzin/ios-study-note
boostcamp-ios ios oop swift
Last synced: 2 days ago
JSON representation
๐ง ๋ถ์คํธ์บ ํ iOS ๋ฆฌ๋ทฐ์ด ํ๋ ๋ด์ฉ ์ ๋ฆฌ
- Host: GitHub
- URL: https://github.com/cozzin/ios-study-note
- Owner: cozzin
- Created: 2021-09-08T22:10:50.000Z (about 3 years ago)
- Default Branch: main
- Last Pushed: 2021-09-29T13:04:57.000Z (about 3 years ago)
- Last Synced: 2024-10-17T21:16:47.489Z (21 days ago)
- Topics: boostcamp-ios, ios, oop, swift
- Homepage:
- Size: 45.9 KB
- Stars: 3
- Watchers: 2
- Forks: 0
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# iOS Study Note
๋ถ์คํธ์บ ํ iOS 6๊ธฐ ๋ฆฌ๋ทฐ์ด ์งํํ๋ฉด์ ๋ด์ฉ ์ ๋ฐ์ดํธ ์ค ์ ๋๋ค.# ๊ณต์๋ฌธ์
* [API Design Guidelines](https://swift.org/documentation/api-design-guidelines/)
* [About App Development with UIKit](https://developer.apple.com/documentation/uikit/about_app_development_with_uikit)
* [App and Environment](https://developer.apple.com/documentation/uikit/app_and_environment)# OOP
## ๋ช ๋ น-์ฟผ๋ฆฌ ๋ถ๋ฆฌ
- `Query`: ์ง๋ฌธํด์ ๋ต์ ์์ฒญ
- `Command `: ๋ณ๊ฒฝ์ ์์ฒญ์ฝ๋๋ฅผ ์ฌ์ฉํ๋ ์ ์ฅ์์ Query - Command ๊ฐ ๋ถ๋ฆฌ๋์ง ์๋๋ค๋ฉด ํผ๋์ ๊ฒช์ ์ ์์ต๋๋ค.
๋จ์ํ ์๋ฅผ ๋ค์ด๋ณด๋ฉด```swift
func isEmpty() -> Bool {
count += 1
return myArray.isEmpty
}
```isEmpty()๋ฅผ ํธ์ถํ ์ฌ์ฉ์๋ count๊ฐ ์ฆ๊ฐ๋๋ ๊ฒ์ ์ธ์งํ์ง ๋ชปํ ์ ์์ต๋๋ค.
๋ง์ฝ์ count๊ฐ ์ฆ๊ฐํ๋ค๋ ๊ฒ์ ์ผ๋ํด๋๊ณ ์๋๋ผ๋
`1. empty ์ธ๊ฐ?` + `2. count๊ฐ ์ฆ๊ฐํ๊ฒ ๊ตฐ` ์ผ๋ก ์๊ฐํด์ผํด์ ์ฝ๋๋ฅผ ์ดํดํ๊ณ ์ ์ง๋ณด์ ํ๋๋ฐ ์ด๋ ค์์ ๊ฒช์ ์ ์์ต๋๋ค.์์ ์ฝ๋๋ฅผ ๋๋ ๋ณด๋ฉด ์๋์ ๊ฐ์ด ์์ฑํ ์ ์์ต๋๋ค.
```swift
func isEmpty() -> Bool {
return myArray.isEmpty
}func increase() {
count += 1
}
```์ํฉ์ ๋ฐ๋ผ ์ด๊ฒ ๋ฒ๊ฑฐ๋ก์ธ ์๋ ์๋๋ฐ, ์ ์ง๋ณด์์ ํฐ ๋์์ด ๋๋ค๊ณ ์๊ฐํฉ๋๋ค.
# ๋์์ธํจํด
## ํฉํ ๋ฆฌ ํจํด
### ์ฌํ ํฉํ ๋ฆฌ
ํ๋ผ๋ฏธํฐ๋ก ์ฃผ์ด์ง type์ ๋ฐ๋ผ ๊ฐ์ฒด๋ฅผ ๋ค๋ฅด๊ฒ ์์ฑ
http://ufx.kr/blog/191### ์ถ์ ํฉํ ๋ฆฌ
์ํฉ์ ๋ฐ๋ผ ํฉํ ๋ฆฌ๋ฅผ ๊ฐ์๋ผ์ฐ๋ฉด์ ๊ฒฐ๊ณผ๋ฌผ์ ๋ค๋ฅด๊ฒ ์์ฑ
https://johngrib.github.io/wiki/abstract-factory-pattern/## Mediator
https://ko.wikipedia.org/wiki/%EC%A4%91%EC%9E%AC%EC%9E%90_%ED%8C%A8%ED%84%B4
# Architecture
## MVC
![image](https://user-images.githubusercontent.com/11647461/132593358-187369d3-0dd4-4042-9644-043a0f508eae.png)### ์ญํ ๋ถ๋ฆฌ
* Model: ๋น์ฆ๋์ค๋ก์ง ์ฒ๋ฆฌ. ๋ฐ์ดํฐ/์๊ณ ๋ฆฌ์ฆ/๋คํธ์ํน
* View: ๋์คํ๋ ์ด/์ด๋ฒคํธ ์บก์ณ/๋น์ฃผ์ผ ํํ
* Controller: ์กฐํฉ/๋ธ๋ฆฌ๊ฒ์ด์ /ํน์ดํ ์์### Loose Coupling ์งํฅ
* ๋ฉ์ธ์ง๋ฅผ ๋ณด๋ผ ๋ MVC ๊ณ์ธต์ ๊ฑด๋๋์ง ์๊ธฐ
* ํ๋์ ์ค๋ธ์ ํธ์ MVC ์ญํ ์ ์์ง ์๊ธฐ
* ๋ทฐ ํด๋์ค์์ ๋ชจ๋ธ ๋ฐ์ดํฐ๋ฅผ ์ ์ธํ์ง ์๊ธฐ### ๋ฉ์ธ์ง ๊ด๋ฆฌ
* ๋ชจ๋ธ๋ผ๋ฆฌ ์ง์ ์ ์ธ ์๋ฐฉํฅ ๋ฐ์ดํฐ ์ ์ก X
* ๋ชจ๋ธ์์ Notify ํ Controller๊ฐ ์ฌ๋ฌ๊ฐ์ผ ๋ Key-Value Observing ์ฌ์ฉ### ์ถ์ฒ
* https://developer.apple.com/library/archive/documentation/General/Conceptual/DevPedia-CocoaCore/MVC.html
* ์ฝ๋์ค์ฟผ๋ ํ์ต์๋ฃ## MVP
![image](https://user-images.githubusercontent.com/11647461/132594410-2750da4c-7268-4077-a1dd-e9fa277b9dbb.png)### ์ญํ ๋ถ๋ฆฌ
* Model: ๋น์ฆ๋์ค๋ก์ง ์ฒ๋ฆฌ
* View: UIKit ์์๋ค. UIView, UIViewController
* Presenter: Model, View ์ฌ์ด์ Mediator.### MVC์ ๋ค๋ฅธ์
* MVC์๋ ๋ค๋ฅด๊ฒ Presenter๊ฐ View๋ฅผ ์ฐธ์กฐํ์ง ์๋๋ค.
* UIView๋ฅผ Presenter๊ฐ ์ง์ ๋ค๋ฃจ์ง ์๊ณ Delegate๋ฅผ ํตํด์ View ์ ๋ฐ์ดํธ๊ฐ ํ์ํ ๋ ์๋ ค์ฃผ๋ ๋ฐฉ๋ฒ### ์ถ์ฒ
* https://medium.com/ios-os-x-development/ios-architecture-patterns-ecba4c38de52
* https://velog.io/@chagmn/iOS-Architecture-iOS-%EC%95%84%ED%82%A4%ED%85%8D%EC%B2%98-%ED%8C%A8%ED%84%B4-2-MVP# Swift
## Access Control
https://docs.swift.org/swift-book/LanguageGuide/AccessControl.html## Lazy Stored Properties
view๊ฐ load๋ ํ์ ํน์ ๊ฐ์ฒด๋ฅผ ์์ฑํด์ ์ฌ์ฉํ๊ณ ์ถ์ ๊ฒฝ์ฐ Optional Type ์ฌ์ฉ + viewDidLoad ์์ ํ ๋นํด์ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ๊ฐ ๋ง์
```swift
final class ViewController: UIViewController {
private var model: Model?override func viewDidLoad() {
super.viewDidLoad()
model = Model()
}func useModel() {
model?.use()
}
}
````lazy var`๋ฅผ ์ฌ์ฉํ๋ฉด Optional Type์ด ์๋๊ณ ๊ธฐ์กด ์ฒ๋ผ ํ์ํ ์์ ์ init ๋จ.
```swift
final class ViewController: UIViewController {
private lazy var model: Model = Model()func useModel() {
model.use()
}
}
```## Enum
### Associated Values
enum์ ๊ฐ์ ๋ด์์ ํํํ ์ ์์
```swift
enum Barcode {
case upc(Int, Int, Int, Int)
case qrCode(String)
}
```ํจํด ๋งค์นญํด์ case๋ฅผ ๋๋๊ณ Associated Values๋ฅผ ๊ฐ์ ธ์ฌ ์ ์์
```swift
switch productBarcode {
case .upc(let numberSystem, let manufacturer, let product, let check):
print("UPC: \(numberSystem), \(manufacturer), \(product), \(check).")
case .qrCode(let productCode):
print("QR code: \(productCode).")
}
// Prints "QR code: ABCDEFGHIJKLMNOP."
```https://docs.swift.org/swift-book/LanguageGuide/Enumerations.html
## ๊ณ ์ฐจํจ์
* ๋งค์นญ๋๋ ์ฒซ๋ฒ์งธ Element ๊ฐ์ ธ์ค๊ธฐ: https://developer.apple.com/documentation/swift/array/1848165-first
* ๋งค์นญ๋๋ Element ์กด์ฌ ์ฌ๋ถ: https://developer.apple.com/documentation/swift/array/2297359-contains## Delegation
* ์ด๋ฒคํธ๊ฐ ๋ฐ์ํ ๊ฐ์ฒด๋ฅผ ๊ฐ์ด ๋ด์์ ๋ณด๋ด์ฃผ๋ฉด delegate ๊ตฌํํ ๋ ํธ๋ฆฌํจ
* `delegate?.doSomething(self, additional:)` ์ด๋ฐ์์ผ๋ก ํธ์ถํจ```swift
protocol DiceGame {
var dice: Dice { get }
func play()
}
protocol DiceGameDelegate: AnyObject {
func gameDidStart(_ game: DiceGame)
func game(_ game: DiceGame, didStartNewTurnWithDiceRoll diceRoll: Int)
func gameDidEnd(_ game: DiceGame)
}
``````swift
class SnakesAndLadders: DiceGame {
let finalSquare = 25
let dice = Dice(sides: 6, generator: LinearCongruentialGenerator())
var square = 0
var board: [Int]
init() {
board = Array(repeating: 0, count: finalSquare + 1)
board[03] = +08; board[06] = +11; board[09] = +09; board[10] = +02
board[14] = -10; board[19] = -11; board[22] = -02; board[24] = -08
}
weak var delegate: DiceGameDelegate?
func play() {
square = 0
delegate?.gameDidStart(self)
gameLoop: while square != finalSquare {
let diceRoll = dice.roll()
delegate?.game(self, didStartNewTurnWithDiceRoll: diceRoll)
switch square + diceRoll {
case finalSquare:
break gameLoop
case let newSquare where newSquare > finalSquare:
continue gameLoop
default:
square += diceRoll
square += board[square]
}
}
delegate?.gameDidEnd(self)
}
}
```
https://docs.swift.org/swift-book/LanguageGuide/Protocols.html## Naming
Type, Procotocl์ UpperCamelCase, ๋๋จธ์ง๋ lowerCamelCase
![image](https://user-images.githubusercontent.com/11647461/135270908-6eacd780-6f81-4a24-ae14-da9a5c4c57fd.png)
https://swift.org/documentation/api-design-guidelines/## Weak, Unowned
https://docs.swift.org/swift-book/LanguageGuide/AutomaticReferenceCounting.html
# Foundation
## NotificationCenter
### [addObserver(_:selector:name:object:)](https://developer.apple.com/documentation/foundation/notificationcenter/1415360-addobserver)
object ํ๋ผ๋ฏธํฐ์ ์ญํ : ํน์ ๊ฐ์ฒด๋ก๋ถํฐ ๋ฐ์ํ ๋ ธํฐ๋ง ํํฐํด์ ์์ . ๋ง์ฝ nil ์ด๋ฉด ํํฐ ์์ด ์์ . ํํฐ๋ง์ด ํ์ ์์ผ๋ฉด nil๋ก ์ฌ์ฉ ๊ฐ๋ฅ.> `anObject`
The object that sends notifications to the observer. Specify a notification sender to deliver only notifications from this sender.
>
>When nil, the notification center doesnโt use sender names as criteria for delivery.### [post(name:object:userInfo:)](https://developer.apple.com/documentation/foundation/notificationcenter/1410608-post)
object ํ๋ผ๋ฏธํฐ์ ์ญํ : ๋ ธํฐ๋ฅผ ๋ฐ์์ํจ ๊ฐ์ฒด๋ฅผ ์ ๋ฌ. (sender ๊ฐ๋ ). ์์ ํ๋ ์ชฝ์์ ๊ตฌ๋ถ์ด ํ์ ์์ผ๋ฉด nil ์ ๋ฌํด๋ ์ ์์๋ํจ.> `anObject`
The object posting the notification.### object ์ ๋ฌํ๋ ์์
```swift
extension NSNotification.Name {
static let modelDidUpdateTitle: NSNotification.Name = .init("didUpdateTitle")
}
``````swift
class ViewController: UIViewController {private lazy var model: Model = Model()
override func viewDidLoad() {
NotificationCenter.default.addObserver(self, selector: #selector(didUpdateTitle(_:)), name: .modelDidUpdateTitle, object: model)
}@objc private func didUpdateTitle(_ notification: Notification) {
guard let updatedTitle = notification.userInfo?["updatedTitle"] as? String else {
return
}
// ์ถ๊ฐ ์์ ...
}private func updateTitle() {
model.update(title: "testTitle")
}
}
``````swift
final class Model {
private var title: String = ""func update(title: String) {
self.title = title
NotificationCenter.default.post(name: .modelDidUpdateTitle, object: nil, userInfo: ["updatedTitle": title])
}
}
```### object์ struct๋ฅผ ๋ฃ์ผ๋ฉด ์๋ํ์ง ์์
- ์ด์ : https://stackoverflow.com/a/56826646
- objective-c ์์ ์ ๋ง๋ค์ด์ง API ์ธ๋ฐ `id` ํ์ ์ Swift๋ก ๊ฐ์ ธ์ค๋ค๋ณด๋ `Any`๋ก ํฌํ ๋จ.
- ์ค์ ๋ก๋ `class`๋ฅผ ์ ๋ฌํด์ค์ผํจ# UIKit
## UITouch
* ํฐ์นํ View ๊ฐ์ ธ์ค๊ธฐ: https://developer.apple.com/documentation/uikit/uitouch/1618109-view## UIGestureRecognizer
* [UIGestureRecognizerDelegate](https://developer.apple.com/documentation/uikit/uigesturerecognizerdelegate) ํตํด์ ์ด๋ฒคํธ ์กฐ์ ๊ฐ๋ฅ## IBInspectable
IBDesignable + IBInspectable ์ฌ์ฉํ๋ฉด ์ธํฐํ์ด์ค ๋น๋์์ Layer ์์ฑ๋ ๊ฐํธํ๊ฒ ๋ณ๊ฒฝ ๊ฐ๋ฅ
![image](https://user-images.githubusercontent.com/11647461/132595579-bdb4d92a-96e9-4564-8cf8-1e5cbfd5b286.png)
```Swift
import UIKit@IBDesignable extension UIView {
@IBInspectable var borderColor: UIColor? {
set {
layer.borderColor = newValue?.cgColor
}
get {
guard let color = layer.borderColor else {
return nil
}
return UIColor(cgColor: color)
}
}
@IBInspectable var borderWidth: CGFloat {
set {
layer.borderWidth = newValue
}
get {
return layer.borderWidth
}
}
@IBInspectable var cornerRadius: CGFloat {
set {
layer.cornerRadius = newValue
clipsToBounds = newValue > 0
}
get {
return layer.cornerRadius
}
}
}
```https://stackoverflow.com/a/35372610
## UIGraphicsImageRenderer
* ์ด๋ฏธ์ง๋ฅผ ์ง์ ๊ทธ๋ฆด ๋ `UIGraphicsBeginImageContextWithOptions` / `UIGraphicsEndImageContext`๋ก Context๋ฅผ ์ด๊ณ ๋ซ์์ค์ผ ํจ```swift
let rect = CGRect(origin: .zero, size: size)
UIGraphicsBeginImageContextWithOptions(rect.size, false, 0.0)
UIColor.darkGray.setFill()
UIRectFill(CGRect(x: 1, y: 1, width: 140, height: 140))
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
```* `UIGraphicsImageRenderer`๋ฅผ ์ฌ์ฉํ๋ฉด ํด๋ก์ ์์์ ์์ ์ ์ํํ๊ณ ๋ฐ๋ก ์ด๊ณ ๋ซ๋ ํจ์ ํธ์ถ์ด ํ์์๋ ์ฅ์ ์ด ์์: ๊ฐ๋ ์ฑ ์ฆ๊ฐ, ์ค์ํ์ง ์์ ์ ์์
```swift
let renderer = UIGraphicsImageRenderer(size: CGSize(width: 200, height: 200))
let image = renderer.image { (context) in
UIColor.darkGray.setFill()
context.fill(CGRect(x: 1, y: 1, width: 140, height: 140))
}
```https://developer.apple.com/documentation/uikit/uigraphicsimagerenderer
# Networking
## Http ํต์
* [NSAllowsArbitraryLoads](https://developer.apple.com/documentation/bundleresources/information_property_list/nsapptransportsecurity/nsallowsarbitraryloads): ๋ชจ๋ ๋๋ฉ์ธ HTTP ํต์ ํ์ฉ
* [NSExceptionDomains](https://developer.apple.com/documentation/bundleresources/information_property_list/nsapptransportsecurity/nsexceptiondomains): ํน์ ๋๋ฉ์ธ๋ง HTTP ํต์ ํ์ฉ## Throttle
- ์๋ฐํ ๋งํ๋ฉด ๋คํธ์ํฌ๋ ์๋์ง๋ง ๋คํธ์ํฌ ๊ธฐ๋ฅ๊ณผ ๋ฐ์ ํด์ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ๊ฐ ๋ง์
https://eunjin3786.tistory.com/80# Xcode
## Debugging- https://github.com/sujinnaljin/Improving_Productivity