Giter Club home page Giter Club logo

ios-cloud-notes's Introduction

๐Ÿ“ย ๋™๊ธฐํ™” ๋ฉ”๋ชจ์žฅ

  1. ํ”„๋กœ์ ํŠธ ๊ธฐ๊ฐ„: 2022.02.07 - 2022.02.25

๐Ÿ—‚ย ๋ชฉ์ฐจ


๐Ÿ“ฑ ๊ตฌํ˜„ ํ™”๋ฉด

๊ธฐ๊ธฐ ์ข…๋ฅ˜ ๊ฐ€๋กœ ํ™”๋ฉด ์„ธ๋กœ ํ™”๋ฉด ๊ฒ€์ƒ‰ ํ™”๋ฉด
์•„์ดํŒจ๋“œ
๊ธฐ๊ธฐ ์ข…๋ฅ˜ ๋ฉ”๋ชจ ๋ชฉ๋กํ™”๋ฉด ๋ฉ”๋ชจ ์ƒ์„ธํ™”๋ฉด ๊ฒ€์ƒ‰ ํ™”๋ฉด
์•„์ดํฐ

๐Ÿ“ƒ ๊ตฌํ˜„ ๋‚ด์šฉ

  • Split View Controller๋ฅผ ํ™œ์šฉํ•˜์—ฌ ํ™”๋ฉด์„ ๋‚˜๋ˆŒ ์ˆ˜ ์žˆ๋„๋ก ๊ตฌํ˜„
  • Date Formatter์„ ํ™œ์šฉํ•˜์—ฌ ๋‚ ์งœ๋ฅผ ์ง€์—ญ ๋ฐ ๊ธธ์ด๋ณ„ ํ‘œํ˜„ ํ•˜๋„๋ก ๊ตฌํ˜„
  • TextView๋ฅผ ํ™œ์šฉํ•˜์—ฌ ์‚ฌ์šฉ์ž์˜ ์ž…๋ ฅ์„ ๋ฐ›์„ ์ˆ˜ ์žˆ๋„๋ก ๊ตฌํ˜„
  • TextViewDelegate๋ฅผ ํ™œ์šฉํ•˜์—ฌ UITextView๊ฐ€ ์ˆ˜์ •๋  ๋•Œ ๋งˆ๋‹ค ๋ฐ์ดํ„ฐ๋ฅผ ์ˆ˜์ •ํ•˜๋„๋ก ๊ตฌํ˜„
  • ์ฝ”์–ด๋ฐ์ดํ„ฐ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ฐ์ดํ„ฐ๋ฅผ Local์— ์ €์žฅํ•˜๊ณ  ์ฝ๋„๋ก ๊ตฌํ˜„
  • ํ…Œ์ด๋ธ”๋ทฐ์—์„œ ์Šค์™€์ดํ”Œ์„ ํ™œ์šฉํ•œ ์‚ญ์ œ ๋ฐ ๊ณต์œ  ๊ธฐ๋Šฅ ๊ตฌํ˜„
  • ์˜์กด์„ฑ ๊ด€๋ฆฌ๋„๊ตฌ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ Dropbox๋ฅผ ์—ฐ๋™ํ•˜๊ณ  ๋ฐ์ดํ„ฐ๋ฅผ ์›๊ฒฉ์— ์ €์žฅ
  • AttributedString์„ ์‚ฌ์šฉํ•˜์—ฌ ์ œ๋ชฉ๊ณผ ๋ณธ๋ฌธ์˜ ํฐํŠธ๋ฅผ ๋‹ค๋ฅด๊ฒŒ ํ•˜์—ฌ ๊ตฌ๋ถ„ํ•˜๋Š” ๊ธฐ๋Šฅ ๊ตฌํ˜„
  • SearchController๋ฅผ ํ™œ์šฉํ•˜์—ฌ ๋ฉ”๋ชจ์˜ ์ œ๋ชฉ๊ณผ ๋ณธ๋ฌธ์— ํฌํ•จ๋œ ๋ฌธ์ž๋ฅผ ๊ฒ€์ƒ‰ํ•˜๋Š” ๊ธฐ๋Šฅ ๊ตฌํ˜„
  • ๋ฐฐ๊ฒฝ์ƒ‰, ๊ธ€์ž์ƒ‰ ๋“ฑ์„ ์‹œ์Šคํ…œ ์ปฌ๋Ÿฌ๋ฅผ ๊ณ ๋ คํ•˜์—ฌ ๋ผ์ดํŠธ๋ชจ๋“œ / ๋‹คํฌ๋ชจ๋“œ ๊ฐ€๋Šฅ ํ•˜๋„๋ก ๊ตฌํ˜„
  • ์ ‘๊ทผ์„ฑ์„ ๊ณ ๋ คํ•˜์—ฌ Dynamic Type, Voice Over๊ฐ€ ์›ํ™œํ•˜๊ฒŒ ๋™์ž‘ํ•˜๋„๋ก ๊ตฌํ˜„
  • ๋‹ค๊ตญ์–ด์ฒ˜๋ฆฌ, ๋‚ ์งœ, ์ฝ๋Š” ๋ฐฉํ–ฅ ๋“ฑ ์ง€์—ญํ™”๋ฅผ ํ†ตํ•ด ๋‹ค์–‘ํ•œ ์‚ฌ์šฉ์ž๊ฐ€ ๋ถˆํŽธํ•จ์ด ์—†๋„๋ก ๊ตฌํ˜„

๐Ÿš€ Trouble Shooting

1. Cell์˜ Select๊ฐ€ ๋™์ž‘ํ•˜์ง€ ์•Š๋Š” ๋ฌธ์ œ

  • ์ƒํ™ฉ GestureRecognizer๋ฅผ ViewController์— ์ถ”๊ฐ€ํ•˜์ž UITableView์˜ Select๊ฐ€ ๋˜์ง€ ์•Š๋Š” ํ˜„์ƒ์ด ๋‚˜ํƒ€๋‚ฌ๋‹ค.
  • ์ด์œ  ๋“ฑ๋กํ•œ GestureRecognizer์˜ ํ”„๋กœํผํ‹ฐ์ธ cancelsTouchesInView๊ฐ€ ๊ธฐ๋ณธ๊ฐ’์œผ๋กœ true๋กœ ์„ค์ •๋˜์–ด์žˆ์–ด ๋ฌธ์ œ์˜€๋‹ค. cancelsTouchesInView๊ฐ€ true์ธ ๊ฒฝ์šฐ์—๋Š” ์ œ์Šค์ฒ˜๋ฅผ ์ธ์‹ํ•œ ํ›„์— ๋‚˜๋จธ์ง€ ํ„ฐ์น˜์ •๋ณด๋“ค์„ ๋ทฐ๋กœ ์ „๋‹ฌํ•˜์ง€ ์•Š๊ณ  ์ทจ์†Œ๋˜์—ˆ๊ธฐ ๋•Œ๋ฌธ์— UITableView์˜ Select๊ฐ€ ๋จน์ง€ ์•Š์•˜๋˜ ๊ฒƒ์ด๋‹ค.
  • ํ•ด๊ฒฐ ๋”ฐ๋ผ์„œ cancelsTouchesInView๊ฐ’์„ false๋กœ ํ• ๋‹นํ•ด์คŒ์œผ๋กœ์จ ํ•ด๋‹น ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜์˜€๋‹ค. ์ œ์Šค์ฒ˜๋ฅผ ์ธ์‹ํ•œ ํ›„์—๋„ Gesture Recognizer์˜ ํŒจํ„ด๊ณผ๋Š” ๋ฌด๊ด€ํ•˜๊ฒŒ ํ„ฐ์น˜ ์ •๋ณด๋“ค์„ ๋ทฐ์— ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋˜์—ˆ๋‹ค.

2. ๋ฉ”๋ชจ์žฅ์— ํ…์ŠคํŠธ๊ฐ€ ์—†๋Š” ๊ฒฝ์šฐ Crash๋‚˜๋Š” ๋ฌธ์ œ

  • ์ƒํ™ฉ ๋ฉ”๋ชจ์žฅ์— linebreak๊ฐ€ 1๊ฐœ์ผ ๋•Œ Crash๊ฐ€ ๋‚˜๋Š” ํ˜„์ƒ์ด ๋‚˜ํƒ€๋‚ฌ๋‹ค. ์•„๋ž˜๋Š” ๋ชจ๋“  ๋ฉ”๋ชจ๋ฅผ ์ง€์› ์„ ๊ฒฝ์šฐ Crash๊ฐ€ ๋‚˜๋Š” ์ƒํ™ฉ์ด๋‹ค.
  • ์ด์œ  ๋ฐฐ์—ด์„ ์กฐํšŒํ•  ๋•Œ ์กด์žฌํ•˜์ง€ ์•Š๋Š” ์ธ๋ฑ์Šค๋ฅผ ์กฐํšŒํ•  ๊ฒฝ์šฐ ์•ฑ์ด ์ฃฝ์–ด๋ฒ„๋ฆฌ๋Š” ์ƒํ™ฉ์ด์˜€๋˜ ๊ฒƒ์ด๋‹ค.
  • ํ•ด๊ฒฐ ๋”ฐ๋ผ์„œ ์ธ๋ฑ์Šค๋ฅผ ์•ˆ์ „ํ•˜๊ฒŒ ์กฐํšŒํ•˜๋„๋ก subscript๋ฅผ extension ํ•ด์ฃผ์–ด ์กฐํšŒ๊ฐ€ ๋ถˆ๊ฐ€๋Šฅํ•œ ์ƒํ™ฉ์— ๋งž๊ฒŒ ๋Œ€์ฒ˜ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ด๊ฒฐํ•˜์˜€๋‹ค.
    extension Collection {
        subscript (safe index: Index) -> Element? {
            return indices.contains(index) ? self[index] : nil
        }
    }

3. iPad์—์„œ UIAlertController์˜ actionSheet ์‚ฌ์šฉ์‹œ ๋ฐœ์ƒํ•˜๋Š” ์˜ค๋ฅ˜

์˜ค๋ฅ˜๋ฉ”์„ธ์ง€

  • UIActivityViewController๋ฅผ present๋ฅผ ํ•ด์ฃผ๋ ค๋Š”๋ฐ ์•„๋ž˜์™€ ๊ฐ™์€ ์˜ค๋ฅ˜๋ฉ”์„ธ์ง€๊ฐ€ ๋–ด๋‹ค.
Thread 1: "Your application has presented a UIAlertController (<UIAlertController: 0x10d813a00>) of style UIAlertControllerStyleActionSheet from CloudNotes.SplitViewController (<CloudNotes.SplitViewController: 0x11f7068f0>).
The modalPresentationStyle of a UIAlertController with this style is UIModalPresentationPopover. 
You must provide location information for this popover through the alert controller's popoverPresentationController.
You must provide either a sourceView and sourceRect or a barButtonItem. 
If this information is not known when you present the alert controller, you may provide it in the UIPopoverPresentationControllerDelegate method -prepareForPopoverPresentation."
  • ๊ฐ„๋‹จํžˆ ํ•ด์„ํ•˜์ž๋ฉด iPad์—์„œ ์•ก์…˜์‹œํŠธ๋ฅผ present๋ฅผ ํ•  ๊ฒฝ์šฐ ๋ชจ๋‹ฌ์Šคํƒ€์ผ์ด UIModalPresentationPopover์ด๊ณ , ์ด๊ฑธ ์‚ฌ์šฉํ•  ๋•Œ๋Š” barButtonItem ๋˜๋Š” ํ•ด๋‹น ์ฐฝ์˜ ๋Œ€ํ•œ ์œ„์น˜๋ฅผ ์„ค์ •ํ•ด์ฃผ์–ด์•ผ ํ•œ๋‹ค๊ณ  ๋˜์–ด์žˆ๋‹ค.
  • ๋”ฐ๋ผ์„œ ์„ค์ •ํ•ด์ฃผ์–ด์•ผ ํ•˜๋Š” ๊ฒƒ์€ 2๊ฐ€์ง€์ค‘ ํ•˜๋‚˜์ด๋‹ค.
    • ํ•„์ˆ˜์ ์œผ๋กœ sourceView ์ง€์ •ํ•ด์ฃผ๊ธฐ
    • popoverPresentationController์— sourceRect ๋˜๋Š” barButtonItem ํ• ๋‹นํ•ด์ฃผ๊ธฐ

ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•

์–ผ๋Ÿฟ์„ present ํ•ด์ฃผ๊ธฐ ์ „์— ๋‹ค์Œ๊ณผ ๊ฐ™์€ if๋ฌธ์„ ์ถ”๊ฐ€ํ•ด์ฃผ์ž!

  • UIBarButtonItem์— ์ถ”๊ฐ€ํ•ด์ฃผ๋Š” ๋ฐฉ๋ฒ•
// UIViewController extension ๋‚ด๋ถ€...
if let popoverController = activityViewController.popoverPresentationController {
    popoverController.sourceView = self.splitViewController?.view
    popoverController.barButtonItem = sender // ๋ฉ”์†Œ๋“œ ๋‚ด๋ถ€๋ผ์„œ ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ barButtonItem ์ „๋‹ฌ๋ฐ›์•„ ํ• ๋‹นํ•ด์ฃผ์—ˆ๋‹ค.
}
  • ์œ„์น˜๋ฅผ ์ •ํ•ด์ฃผ๋Š” ๋ฐฉ๋ฒ•
if let popoverController = activityViewController.popoverPresentationController {
    popoverController.sourceView = self.splitViewController?.view // presentํ•  ๋ทฐ ์ง€์ •
    popoverController.sourceRect = CGRect( // ๋ทฐ์˜ ์ • ๊ฐ€์šด๋ฐ ์œ„์น˜๋กœ ์ง€์ •
        x: self.splitViewController?.view.bounds.midX,
        y: self.splitViewController?.view.bounds.midY,
        width: 0,
        height: 0
    )
    popoverController.permittedArrowDirections = [] // ํ™”์‚ดํ‘œ๋ฅผ ๋นˆ๋ฐฐ์—ด๋กœ ๋Œ€์ž…
}
  • 4. download๊ฐ€ ๋๋‚˜๋Š” ์‹œ์ ์— ๋ทฐ๋ฅผ ์—…๋ฐ์ดํŠธ ํ•˜๊ธฐ

๋‹ค์šด๋กœ๋“œ๊ฐ€ ๋๋‚œ ํ›„ CoreData๋ฅผ fetch๋ฅผ ํ•˜๊ณ  TableView๋ฅผ reload๋ฅผ ํ•ด์ฃผ๊ณ  ์‹ถ์—ˆ์œผ๋‚˜ ์‹คํŒจํ–ˆ์—ˆ๋‹ค.

  • ์ด์œ  ํŒŒ์ผ์ด ์—ฌ๋Ÿฌ๊ฐœ๊ฐ€ ์กด์žฌํ•˜์—ฌ, ์—ฌ๋Ÿฌ๊ฐœ์˜ ํŒŒ์ผ์„ ๋‹ค์šด๋กœ๋“œ ํ•˜๊ธฐ ์œ„ํ•ด ๋ฐ˜๋ณต๋ฌธ์„ ๋Œ๋ฆฌ๊ณ  ์žˆ์—ˆ์œผ๋‚˜, fetch์™€ reload๋ฅผ for-in๋ฌธ ๋‚ด๋ถ€์—์„œ ํ•ด์ฃผ๊ณ  ์žˆ์–ด์„œ, ๋ทฐ๊ฐ€ ์—…๋ฐ์ดํŠธ ๋  ๋•Œ๊ฐ€ ์žˆ๊ณ , ์•ˆ๋˜๊ธฐ๋„ ํ•˜๋Š” ํ˜„์ƒ์ด ๋‚˜ํƒ€๋‚ฌ๋‹ค.

  • ํ•ด๊ฒฐ ๊ทธ๋ž˜์„œ for-in๋ฌธ์ด ์ข…๋ฃŒ๋œ ์‹œ์ ์— fetch๋ฅผ ํ•˜๊ณ  view๋ฅผ reload๋ฅผ ํ•ด์ฃผ๊ธฐ ์œ„ํ•ด, ๋‹ค์šด๋กœ๋“œ๊ฐ€ ๋ชจ๋‘ ์™„๋ฃŒ๋˜๋Š” ์‹œ์ ์„ DispatchGroup๋ฅผ ํ™œ์šฉํ•˜์—ฌ ์ถ”์ ํ•˜๊ณ , ๋ฐ˜๋ณต๋ฌธ์—์„œ ์‹œ์ž‘๋˜์—ˆ๋˜ ๋‹ค์šด๋กœ๋“œ ์ž‘์—…์ด ๋ชจ๋‘ ๋๋‚˜๊ฒŒ ๋˜๋ฉด ์•„๋ž˜ ๋ทฐ๋ฅผ ๋‹ค์‹œ ์„ค์ •ํ•˜๋„๋ก ์ฝ”๋“œ๋ฅผ ์ˆ˜์ •ํ•˜์˜€๋‹ค.
func download(_ tableViewController: NotesViewController?) {
    let group = DispatchGroup() // ๊ทธ๋ฃน ์ƒ์„ฑ
    for fileName in fileNames {
        let destURL = applicationSupportDirectoryURL.appendingPathComponent(fileName)
        let destination: (URL, HTTPURLResponse) -> URL = { _, _ in
            return destURL
        }
        group.enter() // ์ž‘์—… ์‹œ์ž‘
        client?.files.download(path: fileName, overwrite: true, destination: destination)
            .response { _, error in
                if let error = error {
                    print(error)
                }
                group.leave() // ์ž‘์—… ๋
            }
    }
    group.notify(queue: .main) { // ๋ชจ๋“  ์ž‘์—…์ด ๋๋‚œ๋‹ค๋ฉด ...
        PersistentManager.shared.setUpNotes()
        tableViewController?.tableView.reloadData()
        tableViewController?.stopActivityIndicator()
    }
}

5. ์ ‘๊ทผ์„ฑ์„ ์œ„ํ•ด Accessibility Inspector๋ฅผ ํ™œ์šฉ

  • Accessibility Inspector๋ฅผ ํ™œ์šฉํ•˜์—ฌ ์ ‘๊ทผ์„ฑ์„ ์œ„ํ•ด Run Audit์„ ํ†ตํ•ด ๊ฐœ์„ ํ•  ํ•ญ๋ชฉ๋“ค์ด ์—†๋Š”์ง€ ๊ฒ€์ˆ˜ํ•˜์˜€๋‹ค.
  • ๊ทธ๋ฆฌ๊ณ  VoiceOver๋ฅผ ์ง์ ‘ ์‹คํ–‰ํ•ด์„œ ํ…Œ์ŠคํŠธํ•ด๋ณด๋ฉฐ ๋ถ€์กฑํ•œ ๋ถ€๋ถ„์ด ์žˆ๋Š”์ง€ ํ™•์ธํ•ด๋ณด์•˜๋‹ค.
  • ๋‹ค์ด๋‚˜๋ฏน ํƒ€์ž…์˜ ๊ฒฝ์šฐ๋„ ํ…์ŠคํŠธ ํฌ๊ธฐ๊ฐ€ ์œ ์—ฐํ•œ์ง€ ๊ฒ€์ˆ˜ํ•˜์˜€๋‹ค.

๐Ÿค” ๊ณ ๋ฏผํ•œ ์ 

1. ํ‚ค๋ณด๋“œ ๊ฐ€๋ฆผํ˜„์ƒ ๊ฐœ์„  ๋ฐ ํŽธ์ง‘๋ชจ๋“œ ์ข…๋ฃŒ ๊ตฌํ˜„

  • NotificationCenter๋ฅผ ํ™œ์šฉํ•˜์—ฌ ํ‚ค๋ณด๋“œ๊ฐ€ ํ™”๋ฉด์— ํ‘œ์‹œ๋  ๋•Œ UITextView๋„ ํ‚ค๋ณด๋“œ์˜ ๋†’์ด๋งŒํผ contentInset์„ ์กฐ์ •ํ•˜๋„๋ก ๊ตฌํ˜„ํ•˜์˜€๋‹ค.
  • ํŽธ์ง‘์„ ๋๋‚ธ ํ›„ ๋‹ค๋ฅธ ๋ฉ”๋ชจ๋ฅผ ๋ˆŒ๋ €์„ ๋•Œ ํŽธ์ง‘๋ชจ๋“œ๋ฅผ ์ข…๋ฃŒํ•  ์ˆ˜ ์žˆ๋„๋ก ๊ตฌํ˜„ํ–ˆ๋‹ค. UITapGestureRecognizer๋ฅผ ํ™œ์šฉํ•˜์—ฌ ์‚ฌ์šฉ์ž๊ฐ€ ํ…์ŠคํŠธ๋ทฐ๊ฐ€ ์•„๋‹Œ ๋‹ค๋ฅธ ๋ถ€๋ถ„์„ ํ„ฐ์น˜ํ–ˆ์„ ๋•Œ endEditing ๋ฉ”์†Œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๋„๋ก ํ•˜์˜€๋‹ค.

2. ์‹ค์‹œ๊ฐ„์œผ๋กœ ์ˆ˜์ •๋œ ๋ฉ”๋ชจ๊ฐ€ UITableView์— ๋ฐ˜์˜๋˜๋„๋ก ๊ตฌ์„ฑ

  • ์‹ค์‹œ๊ฐ„ ๋ฐ˜์˜์„ ์œ„ํ•ด UITextViewDelegate๋ฅผ ํ™œ์šฉํ•˜์—ฌ UITextView๊ฐ€ ์ˆ˜์ •๋  ๋•Œ ๋งˆ๋‹ค ๋ฐ์ดํ„ฐ๋ฅผ ์ˆ˜์ •ํ•˜๊ณ , UITableView๋„ ์—…๋ฐ์ดํŠธํ•˜๋„๋ก ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•˜์˜€๋‹ค.

3. Crash๋ฅผ ๋ฐฉ์ง€

  • ์กด์žฌํ•˜์ง€์•Š๋Š” ์ธ๋ฑ์Šค๋ฅผ ์กฐํšŒํ–ˆ์„ ๋•Œ Crash๊ฐ€ ๋‚˜์ง€ ์•Š๋„๋ก subscript๋ฅผ ํ™œ์šฉํ•˜์—ฌ Crash๊ฐ€ ๋ฐœ์ƒํ•˜์ง€ ์•Š๋„๋ก ๊ตฌํ˜„ํ•˜์˜€๋‹ค.
extension Collection {
    subscript (safe index: Index) -> Element? {
        return indices.contains(index) ? self[index] : nil
    }
}

4. Dynamic Type

  • UILabel, UITextView์— ์‹ค์‹œ๊ฐ„์œผ๋กœ ๊ธ€์”จ ํฌ๊ธฐ๋ฅผ ์กฐ์ •ํ•  ์ˆ˜ ์žˆ๋„๋ก ๋‹ค์ด๋‚˜๋ฏน ํฐํŠธ ์„ค์ • ๋ฐ Automatically Adjusts Font ๊ธฐ๋Šฅ์„ ํ™œ์„ฑํ™” ํ•ด์ฃผ์—ˆ๋‹ค.

5. ๋ฉ”๋ชจ๋ฅผ ํ„ฐ์น˜ํ–ˆ์„ ๋•Œ secondary ๋ทฐ์ปจ์— ์ƒ์„ธ ๋ฉ”๋ชจ๋ฅผ ํ‘œ์‹œํ•˜๋„๋ก ๊ตฌํ˜„

  • MemoListViewController์˜ UITableViewDelegate ๋ฉ”์„œ๋“œ didSelectRowAt์—์„œ SplitViewController์˜ present๋ฉ”์„œ๋“œ๋ฅผ ํ†ตํ•ด ๋ˆŒ๋ฆฐ ํ…Œ์ด๋ธ”๋ทฐ ์…€์˜ indexPath๋ฅผ ํ™œ์šฉํ•˜์˜€๋‹ค.
  • indexPath๋กœ SplitViewController๊ฐ€ ๊ฐ€์ง€๊ณ ์žˆ๋Š” Memo ๋ฐฐ์—ด ํƒ€์ž…์˜ ๋ฐ์ดํ„ฐ ์ค‘์—์„œ ํ•ด๋‹น๋˜๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ๊ณจ๋ผ์„œ MemoDetailViewController์˜ text view๋ฅผ ์—…๋ฐ์ดํŠธํ•œ๋‹ค.

6. ์‚ฌ์šฉ์ž ์นœํ™”์ ์ธ UI๋ฅผ ๊ตฌํ˜„

  • ์ตœ๊ทผ์— ์ž‘์„ฑ, ์ˆ˜์ •ํ•˜์˜€๋˜ ๋ฉ”๋ชจ๊ฐ€ ์ƒ๋‹จ์œผ๋กœ ์˜ฌ๋ผ์˜ฌ ์ˆ˜ ์žˆ๋„๋ก ๋ฉ”๋ชจ ๋ฆฌ์ŠคํŠธ์˜ ์ •๋ ฌ์„ ๋‚ ์งœ๋ฅผ ๊ธฐ์ค€์œผ๋กœ ๋‚ด๋ฆผ์ฐจ์ˆœ์œผ๋กœ ์ •๋ ฌ
  • ์–ด๋–ค ๋ฉ”๋ชจ๋ฅผ ์„ ํƒํ•ด์„œ ์ž‘์„ฑํ•˜๊ณ  ์žˆ๋Š”์ง€ ํ•œ๋ˆˆ์— ๋ณด๊ธฐ ํŽธํ•˜๋„๋ก ์ž‘์„ฑํ•˜๊ณ  ์žˆ๋Š” Cell์„ ๊ณ„์† Select ๋˜๋„๋ก ๊ตฌํ˜„
  • ์ž‘์„ฑํ•˜๋Š” ๋„์ค‘ ๋‚ ์งœ๊ฐ€ ์—…๋ฐ์ดํŠธ ๋˜๋ฉด, ์ƒ๋‹จ์œผ๋กœ ์ด๋™ํ•˜๋ฉด์„œ Select๋„ ์ƒ๋‹จ์œผ๋กœ ์ด๋™.
  • ๋ฉ”๋ชจ๋ฅผ ์ถ”๊ฐ€ํ–ˆ์„ ๋•Œ ์ถ”๊ฐ€ํ•œ ์ƒˆ๋กœ์šด ๋ฉ”๋ชจ๋ฅผ Select ๋˜๋„๋ก ๊ตฌํ˜„
  • ๋ฉ”๋ชจ๋ฅผ ์‚ญ์ œํ–ˆ์„ ๋•Œ, ์‚ญ์ œํ•œ ๋ถ€๋ถ„ ์ดํ›„ ๋ฉ”๋ชจ๋ฅผ ์ž๋™์œผ๋กœ Select ๋˜๋„๋ก ๊ตฌํ˜„
  • ์Šค์™€์ดํ”„ ๋ฐ ๋”๋ณด๊ธฐ ๋ฒ„ํŠผ ํ„ฐ์น˜์‹œ ๋ณด์—ฌ์ง€๋Š” ์•ก์…˜๋ฒ„ํŠผ์ด ๋‹จ์ˆœ ํ…์ŠคํŠธ๊ฐ€ ์•„๋‹Œ ์•„์ด์ฝ˜์ด ํ‘œ๊ธฐ๋˜๋„๋ก ๊ตฌํ˜„
  • Share๋ฅผ ํ„ฐ์น˜ํ•˜์—ฌ UIActivityViewController๊ฐ€ present ๋˜์—ˆ์„ ๋•Œ ํ™”๋ฉด ํšŒ์ „ ์‹œ์—๋„ ์ปจํŠธ๋กค๋Ÿฌ๊ฐ€ ์ค‘์•™์— ๊ณ„์† ์œ„์น˜ํ•  ์ˆ˜ ์žˆ๋„๋ก ๊ตฌํ˜„

7. ์ฝ”์–ด๋ฐ์ดํ„ฐ๋ฅผ ๊ด€๋ฆฌํ•˜๋Š” ๋งค๋‹ˆ์ € ํƒ€์ž… ๊ตฌํ˜„

  • ๋ฉ”๋ชจ์˜ CRUD๋ฅผ ๊ตฌํ˜„ ๋ฐ View์— ๋ณด์—ฌ์ค„ ๋ฐ์ดํ„ฐ๋ฅผ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๋Š” PersistentManager ๊ตฌํ˜„
  • fetch๋ฅผ ํ•  ๋•Œ Predicate, Sort ๋“ฑ์„ ์œ ์—ฐํ•˜๊ฒŒ ํ•  ์ˆ˜ ์žˆ๋„๋ก ํŒŒ๋ผ๋ฏธํ„ฐ ๋ณ„๋„ ๊ตฌํ˜„

8. ์ œ๋ชฉ๊ณผ ๋ณธ๋ฌธ์˜ ํฐํŠธ๋ฅผ ๋‹ค๋ฅด๊ฒŒ ํ•˜์—ฌ ๊ตฌ๋ถ„ํ•˜๋Š” ๊ธฐ๋Šฅ ๊ตฌํ˜„

  • AttributtedString์„ ์‚ฌ์šฉํ•˜์—ฌ TextView์˜ ์ œ๋ชฉ๊ณผ ๋ณธ๋ฌธ์˜ ํฐํŠธ๋ฅผ ๋‹ค๋ฅด๊ฒŒ ํ•˜์—ฌ ์‚ฌ์šฉ์ž๊ฐ€ ๋ณด๊ธฐ์— ํŽธํ•˜๋„๋ก ๊ตฌํ˜„
  • textView์˜ delegate ๋ฉ”์„œ๋“œ(shouldChangeTextIn)์™€ textView์˜ typingAttributes ํ”„๋กœํผํ‹ฐ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ž…๋ ฅ์ค‘์—๋„ ์ œ๋ชฉ๊ณผ ๋ณธ๋ฌธ์— ๋งž๋Š” ํฐํŠธ๊ฐ€ ์ ์šฉ๋˜๋„๋ก ๊ตฌํ˜„

9. ์—…๋กœ๋“œ ์‹œ์ 

  • ์—…๋กœ๋“œ ํ•˜๋Š” ์‹œ์ ์„ ์ •ํ•  ๋•Œ ๊ณ ๋ คํ•œ ๊ฒƒ์€ ๋„ˆ๋ฌด ๋นˆ๋ฒˆํ•˜๊ฒŒ ์—…๋กœ๋“œ๋ฅผ ํ•˜์ง€ ์•Š์•„์•ผ ํ•˜๋ฉฐ, ์•ฑ์ด ์˜๋„์น˜ ์•Š๊ฒŒ ์ข…๋ฃŒ๋˜์–ด๋„ ์–ด๋Š์ •๋„ ๋ฐฉ์–ด๊ฐ€ ๋˜์–ด์•ผ ํ•œ๋‹ค๋Š” ์ ์ด์—ˆ๋‹ค.
  • ์ฒ˜์Œ์—๋Š” ํ…์ŠคํŠธ๋ทฐ์— ๋ณ€ํ™”๊ฐ€ ์ผ์–ด๋‚  ๋•Œ๋งˆ๋‹ค ํ•˜๋ ค๊ณ  ํ•˜์˜€์œผ๋‚˜ ๋„ˆ๋ฌด ๋นˆ๋ฒˆํ•˜๊ฒŒ ์ผ์–ด๋‚  ๊ฒƒ์œผ๋กœ ๋ณด์˜€๋‹ค. ๊ทธ๋ž˜์„œ ์ข…๋ฃŒํ•  ๋•Œ ํ•˜๋ ค๊ณ  ํ•˜๋‹ˆ ์˜๋„์น˜ ์•Š์€ ์ข…๋ฃŒ์— ์ „ํ˜€ ๋ฐฉ์–ด๊ฐ€ ๋˜์ง€ ์•Š์•˜๋‹ค.
  • ์—ฌ๋Ÿฌ ๊ณ ๋ฏผ์„ ํ•œ ๊ฒฐ๊ณผ ํ‚ค๋ณด๋“œ๋ฅผ ๋‚ด๋ฆด ๋•Œ ๋งˆ๋‹ค ์—…๋กœ๋“œ๋ฅผ ํ•˜๋„๋ก ํ•˜์—ฌ ์—…๋กœ๋“œ๊ฐ€ ๋นˆ๋ฒˆํ•˜๊ฒŒ ์ผ์–ด๋‚˜์ง€ ์•Š๋„๋ก ํ•˜์˜€๊ณ  ์˜๋„์น˜ ์•Š๊ฒŒ ์ข…๋ฃŒ๋˜์–ด๋„ ๋ฐฉ์–ด๋ฅผ ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•˜์˜€๋‹ค.

10. ๋‹ค์šด๋กœ๋“œ์˜ ์‹œ์ 

  • ๋‹ค์šด๋กœ๋“œ ์‹œ์ ์€ ์ฒ˜์Œ์— ์‚ฌ์šฉ์ž๊ฐ€ ๋กœ๊ทธ์ธ์„ ์„ฑ๊ณตํ•˜๋Š” ์‹œ์ ์— dropbox์˜ ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ค์šด๋กœ๋“œ ํ•˜์—ฌ ๋ณด์—ฌ์ฃผ๋Š” ์ฃผ๋„๋ก ๊ตฌํ˜„ํ•˜๊ธธ ์›ํ–ˆ๋‹ค. ๊ทธ๋ž˜์„œ ์ธ์ฆ์ด ์™„๋ฃŒ ๋˜๊ณ  authResult(์ธ์ฆ๊ฒฐ๊ณผ)๊ฐ€ success๊ฐ€ ๋˜๋ฉด download๋ฅผ ํ•˜๋„๋ก ํ•˜์˜€๋‹ค.
  • ๋˜ํ•œ, ๋‹ค์šด๋กœ๋“œ๋Š” ๋น„๋™๊ธฐ๋กœ ์ง„ํ–‰์ด ๋˜๊ธฐ ๋–„๋ฌธ์— DispatchGroup์„ ์‚ฌ์šฉํ•˜์—ฌ ๋‹ค์šด๋กœ๋“œ๊ฐ€ ์™„๋ฃŒ๋˜๋ฉด ์•ฑ์— ๋ฐ์ดํ„ฐ๋ฅผ ๋ฟŒ๋ ค์ฃผ๊ณ  ํ…Œ์ด๋ธ”๋ทฐ๋ฅผ ์—…๋ฐ์ดํŠธ ํ•˜๋„๋ก ๊ตฌํ˜„ํ•˜์˜€๋‹ค.

11. ๋‹ค์šด๋กœ๋“œ๊ฐ€ ์ง„ํ–‰์ค‘์ผ ๋•Œ ๋ทฐ์˜ ์ƒํƒœ

  • ๋‹ค์šด๋กœ๋“œ๊ฐ€ ์ง„ํ–‰๋  ๋™์•ˆ ๋ทฐ๋Š” ์•„๋ฌด๊ฒƒ๋„ ๋ณด์—ฌ์ฃผ์ง€ ์•Š๊ฒŒ ๋œ๋‹ค.
  • ๋กœ๋”ฉ์ค‘์ด๋ผ๋Š” ๊ฒƒ์„ ์‚ฌ์šฉ์ž์—๊ฒŒ ์•Œ๋ ค์ฃผ๊ธฐ ์œ„ํ•ด์„œ ActivityIndicator๋ฅผ ์‚ฌ์šฉํ•˜์˜€๋‹ค.
  • ๋‹ค์šด๋กœ๋“œ๋ฅผ ์š”์ฒญํ•˜๊ณ  ActivityIndicator๋ฅผ ์‚ฌ์šฉ์ž์—๊ฒŒ ๋ณด์—ฌ์ฃผ๋„๋ก ํ•˜๊ณ  ๋‹ค์šด๋กœ๋“œ๊ฐ€ ๋ชจ๋‘ ์™„๋ฃŒ๋˜๋ฉด ActivityIndicator๋Š” ์ข…๋ฃŒ๋˜๋ฉฐ ๋ฐ์ดํ„ฐ๋ฅผ ์‚ฌ์šฉ์ž์—๊ฒŒ ๋ณด์—ฌ์ฃผ๋„๋ก ๊ตฌํ˜„ํ•˜์˜€๋‹ค.

12. ๊ฒ€์ƒ‰ ๊ธฐ๋Šฅ

  • ๊ฒ€์ƒ‰์–ด๋ฅผ ์ž…๋ ฅํ•  ๋•Œ๋งˆ๋‹ค ๊ฒ€์ƒ‰์–ด์— ํ•ด๋‹นํ•˜๋Š” ๋ฉ”๋ชจ๋ฅผ ์‹ค์‹œ๊ฐ„์œผ๋กœ ๋ณด์—ฌ์ค„ ์ˆ˜ ์žˆ๋„๋ก NSPredicate๋ฅผ ํ™œ์šฉํ•˜์—ฌ fetchํ•˜๋Š” ๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€
  • ๊ฒ€์ƒ‰์–ด๊ฐ€ ๋นˆ ๋ฌธ์ž์—ด("")์ด๋ผ๋ฉด ๋‹ค์‹œ ๋ฉ”๋ชจ์˜ ์ „์ฒด๋ชฉ๋ก์„ ๋ณด์—ฌ์ค„ ์ˆ˜ ์žˆ๋„๋ก ๊ตฌํ˜„

13. ์ง€์—ญํ™”

  • ์–ธ์–ด ์˜์–ด๋ฅผ ๊ธฐ๋ณธ์„ค์ •์œผ๋กœ ํ•˜๊ณ  ํ•œ๊ตญ์–ด์— ๋Œ€ํ•ด์„œ๋„ ๋‹ค๊ตญ์–ดํ™”๋ฅผ ์ง€์›ํ•˜๋„๋ก ๊ตฌํ˜„
  • ๋‚ ์งœ ์‹œ๊ฐ„์€ ์‹œ์Šคํ…œ ์‹œ๊ฐ„์„ ๋”ฐ๋ฅด๋„๋ก ํ•˜๊ณ , ๋‚ ์งœ ํ˜•์‹์€ ์–ธ์–ด์— ๋”ฐ๋ผ ํฌ๋งท์„ ๋ณ€๊ฒฝ๋˜๋„๋ก ๊ตฌํ˜„

14. ์ ‘๊ทผ์„ฑ

  • ์šฐ์ธก ๋ฉ”๋ชจ ์ƒ์„ธ ๋‚ด์šฉ์˜ ๊ฒฝ์šฐ VoiceOver๊ฐ€ ๋ฆฌ์ŠคํŠธ๋ฅผ ์ฝ์€ ํ›„, ํ…์ŠคํŠธ๋ฅผ ๋ฐ”๋กœ ์ฝ์–ด์ฃผ๋Š” ๊ฒƒ์„ ํ™•์ธํ•˜๊ณ , ๋ฉ”๋ชจ ๋‚ด์šฉ์ด๋ผ๋Š” accessibilityLabel์„ ์ถ”๊ฐ€ํ•˜์—ฌ, ๋ฉ”๋ชจ ํ…์ŠคํŠธ๋ฅผ ์ฝ๊ธฐ ์ „์— ์ข€ ๋” ํ™”๋ฉด์˜ ๊ตฌ์„ฑ์š”์†Œ๋ฅผ ์ดํ•ดํ•˜๊ธฐ ์‰ฝ๋„๋ก ๊ตฌํ˜„
  • View์˜ ํ…์ŠคํŠธ ์š”์†Œ๋“ค์— Dynamic Type์„ ์ ์šฉํ•˜์—ฌ ์‚ฌ์šฉ์ž๊ฐ€ ์›ํ•˜๋Š” ์‚ฌ์ด์ฆˆ๋กœ ํ…์ŠคํŠธ ํฌ๊ธฐ๋ฅผ ์„ค์ •ํ•  ์ˆ˜ ์žˆ๋„๋ก ์œ ์—ฐ์„ฑ์„ ์ œ๊ณต

โŒจ๏ธย ํ‚ค์›Œ๋“œ

  • UISplitViewController
  • DateFormatter Locale TimeZone
  • UITapGestureRecognizer
  • subscript Collection
  • SceneDelegate
  • NavigationItem UIBarButtonItem
  • UITextView
    • typingAttributes
    • UITextViewDelegate
  • Core Data NSPersistentCloudKitContainer NSEntityDescription
    • NSFetchRequest NSPredicate NSSortDescriptor
    • NSManagedObject
  • NSMutableAttributedString
  • UIActivityViewController UIAlertController
    • popoverPresentationController
  • UITableView
    • UISwipeActionsConfiguration UIContextualAction
    • insertRows selectRow deleteRows
    • UITableViewCell
      • setSelected selectedBackgroundView
  • viewWillTransition
  • UIFont
    • UIFontMetrics UIFontDescriptor
  • flatMap
  • Swift Package Manager
  • SwifryDropbox
    • DispatchGroup
    • FileManager
  • UIActivityIndicatorView
  • UISearchController
  • Localization
    • NSLocalizedString
  • Accessibility Dynamic Type VoiceOver
    • Accessibility Inspector
  • Lite Mode Dark Mode

ios-cloud-notes's People

Contributors

hobahk avatar leeari95 avatar siwonkim0 avatar yagom avatar

Watchers

 avatar

ios-cloud-notes's Issues

Model ๊ตฌํ˜„

Model ๊ตฌํ˜„

  • ์ง„ํ–‰์ƒํƒœ(toto, doing, done) ์—ด๊ฑฐํ˜• ๊ตฌํ˜„
  • ๋ชจ๋ธํƒ€์ž…(id, ์ง„ํ–‰์ƒํƒœ, ์ œ๋ชฉ, ๊ธฐํ•œ, ์„ค๋ช…) ๊ตฌํ˜„

Service(๋กœ์ง) ๊ตฌํ˜„

Service(๋กœ์ง) ๊ตฌํ˜„

  • ์—…๋ฌด ์ถ”๊ฐ€ ๋ฉ”์„œ๋“œ ๊ตฌํ˜„
  • ์—…๋ฌด ์ˆ˜์ • ๋ฉ”์„œ๋“œ ๊ตฌํ˜„
  • ์—…๋ฌด ์‚ญ์ œ ๋ฉ”์„œ๋“œ ๊ตฌํ˜„

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.