Focus On Develop ๐ŸคŸ๐ŸคŸ

[Swift] FileManager ๋ณธ๋ฌธ

iOS [Swift]/๊ธฐ์ดˆ๋ฅผ ํƒ„ํƒ„ํžˆ!

[Swift] FileManager

๋ˆ„๋ฆฌ๋‹ฌ์ดํ‹€ 2021. 3. 2. 00:01

์ด๋ฒˆ ํฌ์ŠคํŒ…์—์„œ๋Š” swift์—์„œ ๊ธฐ๋ณธ์ ์œผ๋กœ ์ œ๊ณตํ•˜๋Š” FileManager๋ผ๋Š” ํด๋ž˜์Šค๋ฅผ ์ด์šฉํ•ด์„œ, ํŒŒ์ผ์„ ์ €์žฅํ•˜๊ณ  ๋ถˆ๋Ÿฌ์˜ค๊ณ , ์‚ญ์ œํ•˜๋Š” ๊ฑธ ํ•ด๋ณด๋ ค๊ณ  ํ•ด์š”. ์ผ๋ฐ˜์ ์œผ๋กœ ๋กœ์ปฌ์— ์ด๋ฏธ์ง€, ์Œ์›, ํ…์ŠคํŠธ ๋“ฑ ํŒŒ์ผ์„ ์ €์žฅํ–ˆ๋‹ค ๋ถˆ๋Ÿฌ์™”๋‹ค ํ• ๋•Œ๋Š” FileManager๋ฅผ ํ†ตํ•ด ๋กœ์ปฌ์— ํŒŒ์ผ์„ ์ €์žฅํ•˜๊ณ , ํŒŒ์ผ ๊ฒฝ๋กœ์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ CoreData ๋“ฑ์„ ํ†ตํ•ด์„œ ๊ด€๋ฆฌํ•˜์ฃ . ์ด ์ค‘์— ๋กœ์ปฌ์— ํŒŒ์ผ์„ ์ €์žฅํ•˜๋Š” ๋‹จ๊ณ„๋ฅผ ํ•ด๋ณด๋ ค๊ณ  ํ•ด์š”!

 

๋ฐ”๋กœ ์‹œ์ž‘ํ• ๊ป˜์š”!

 

File Domain

๋จผ์ € macOS, iOS ๋“ฑ apple์˜ ํŒŒ์ผ ์‹œ์Šคํ…œ์€ ๊ธฐ๋ณธ์ ์œผ๋กœ domain์œผ๋กœ ํŒŒ์ผ๋“ค์˜ ์œ„์น˜๋ฅผ ๊ฒฐ์ •ํ•ด์š”. ์ด domain์€ ๊ธฐ๋ณธ์ ์œผ๋กœ user, local, network, system 4๊ฐœ์˜ domain์„ ์ œ๊ณตํ•ด์š”. ์•„๋ž˜ ๊ทธ๋ฆผ์ฒ˜๋Ÿผ์š”!

 

์˜ˆ๋ฅผ ๋“ค๋ฉด, ํ„ฐ๋ฏธ๋„์„ ์—ด๋ฉด ์ตœ์ƒ๋‹จ ๋ฃจํŠธ์—์„œ pwd๋ฅผ ์น˜๋ฉด /Users/userName์ด ๋‚˜์˜ค์ฃ ?? ์ฆ‰ ์ด๊ฑด ์‚ฌ์šฉ์ž๋“ค์€ ๊ธฐ๋ณธ์ ์„ user domain์—์„œ ๋Œ€๋ถ€๋ถ„์˜ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๊ฒŒ ๋œ๋‹ค๋Š” ์˜๋ฏธ์—์š”.

 

 

FileManager

์œ„์—์„œ ๊ฐ„๋‹จํžˆ ์„ค๋ช…ํ–ˆ๋“ฏ์ด, Swift์—์„œ ํŒŒ์ผ๊ด€๋ฆฌ๋ฅผ ์œ„ํ•ด ์ œ๊ณตํ•˜๋Š” ํด๋ž˜์Šค์ž…๋‹ˆ๋‹ค. default๋ฅผ ํ†ตํ•ด ์‹ฑ๊ธ€ํ†ค ์ธ์Šคํ„ด์Šค๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ์–ด์š”.

let fileManager = FileManager.default

urls ๋ผ๋Š” ๋ฉ”์†Œ๋“œ๋ฅผ ํ†ตํ•ด์„œ, ์š”์ฒญํ•˜๋Š” ๋„๋ฉ”์ธ์—์„œ ์ง€์ •๋œ ๋””๋ ‰ํ† ๋ฆฌ์— ๋Œ€ํ•œ URL ๋ฐฐ์—ด์„ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ์–ด์š”.

let documentUrl = fileManager.urls(for: .documentDirectory, in: .userDomainMask)[0]

for ํŒŒ๋ผ๋ฏธํ„ฐ๋Š” SearchPathDirectory ํƒ€์ž…์ด์—์š”. enumํƒ€์ž…์œผ๋กœ ์ •์˜๋˜์–ด ์žˆ๊ณ , desktopDirectory, documentDirectory, downloadsDirectory ๋“ฑ ์‹ค์ œ๋กœ ์šฐ๋ฆฌ๊ฐ€ ์นœ์ˆ™ํžˆ ์‚ฌ์šฉํ•˜๋˜ ๋””๋ ‰ํ† ๋ฆฌ๋ฅผ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. ์ž์„ธํ•œ ์‚ฌํ•ญ์€ ์—ฌ๊ธฐ๋ฅผ ์ฐธ๊ณ ํ•ด์ฃผ์„ธ์š”!

in ํŒŒ๋ผ๋ฏธํ„ฐ๋Š” SearchPathDomainMask ํƒ€์ž…์œผ๋กœ ์—ญ์‹œ enum์œผ๋กœ ์ •์˜๋˜์–ด ์žˆ์–ด์š”. ์ด๊ฒŒ ๋ฐ”๋กœ ์ € ์œ„์—์„œ ์„ค๋ช…ํ–ˆ๋˜ 4๊ฐ€์ง€ Domain ์ค‘ ์–ด๋–ค ๋„๋ฉ”์ธ์„ ์‚ฌ์šฉํ• ๊ฑด์ง€ ์„ ํƒํ•ด์ฃผ๋ฉด ๋˜์š”. ์—ญ์‹œ ์ž์„ธํ•œ ์‚ฌํ•ญ์€ ์—ฌ๊ธฐ๋ฅผ ์ฐธ๊ณ ํ•ด์ฃผ์„ธ์š”!

 

documentsUrl์„ ์ถœ๋ ฅํ•ด๋ณด๋ฉด, ์ด๋ ‡๊ฒŒ ์‹ค์ œ๋กœ User ๋„๋ฉ”์ธ์˜ ๋กœ์ปฌ์˜ ์–ด๋–ค ์ฃผ์†Œ๊ณต๊ฐ„์„ ๋‚˜ํƒ€๋‚ด๊ณ  ์žˆ์–ด์š”. (Playground๋กœ ์ž‘์„ฑํ•˜๋Š” ๊ฑฐ๋ผ XCPGDevices ์ด๋Ÿฐ ๊ฒƒ๋“ค์ด ๋ณด์ด๋„ค์š” ๐Ÿ˜‚)

file:///Users/kyungtaekim/Library/Developer/XCPGDevices/5B2871C9-A4D8-492A-8048-71634DAAA618/data/Containers/Data/Application/9700E544-1347-4244-8AB0-F7C98086112E/Documents/

 

๊ทธ๋Ÿผ ์šฐ๋ฆฌ๊ฐ€ ์‚ฌ์šฉํ•  ๋กœ์ปฌ ๊ฒฝ๋กœ๋ฅผ ์„ ํƒํ–ˆ์œผ๋‹ˆ, ๊ทธ ๊ฒฝ๋กœ์— ์—ฌ๋Ÿฌ ์ž‘์—…๋“ค์„ ์‹œ๋„ํ•ด๋ณผ๊ฑฐ์—์š”.

 

๋จผ์ € ํด๋”๋ฅผ ์ƒ์„ฑํ•ด๋ณผ๊ฒŒ์š”.

let directoryPath = documentUrl.appendingPathComponent("NewDirectory")

appendingPathComponent(ํด๋”/ํŒŒ์ผ๋ช…) ๋ฉ”์†Œ๋“œ๋ฅผ ํ†ตํ•ด์„œ, ์šฐ๋ฆฌ๊ฐ€ ์œ„์—์„œ ์ •ํ–ˆ๋˜ ์ €์žฅ ๊ฒฝ๋กœ(documentUrl)์— ๋งŒ๋“ค ์–ด๋–ค ํด๋”/ํŒŒ์ผ๋ช…์„ ์ •ํ•ด์ค๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  directoryPath ์ด๋…€์„์„ ์ถœ๋ ฅํ•ด๋ณด๋ฉด

 

documentsUrl/NewDirectory

์ด๋ ‡๊ฒŒ ์œ„์—์„œ ๋ดค๋˜ documentsUrl ํ•˜์œ„์— ๊ฒฝ๋กœ ํ˜น์€ ํŒŒ์ผ์„ ๋‚˜ํƒ€๋‚ด๊ณ  ์žˆ์–ด์š”.

do {
    if !fileManager.fileExists(atPath: directoryPath.path) {
        try fileManager.createDirectory(atPath: directoryPath.path, withIntermediateDirectories: false, attributes: nil)
    }
} catch {
    print("create folder error. do something")
}

๊ทธ ๊ฒฝ๋กœ์— createDirectory ๋ฉ”์†Œ๋“œ๋ฅผ ํ†ตํ•ด ํด๋”๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ์–ด์š”. atPath ํŒŒ๋ผ๋ฏธํ„ฐ๋Š” ๊ฒฝ๋กœ๋ฅผ ๋‚˜ํƒ€๋‚ด๊ณ , withIntermediateDirectories ํŒŒ๋ผ๋ฏธํ„ฐ๋Š” "์ค‘๊ฐ„ ๋””๋ ‰ํ† ๋ฆฌ๋“ค๋„ ์ถ”๊ฐ€ํ• ๊ฑฐ์•ผ?" ๋ฅผ ๋‚˜ํƒ€๋‚ด๊ณ , attributes ํŒŒ๋ผ๋ฏธํ„ฐ๋Š” ํ•ด๋‹น ํด๋”๋กœ์˜ ์ ‘๊ทผ๊ถŒํ•œ, ๊ทธ๋ฃน ๋“ฑ์˜ ํด๋” ์†์„ฑ์ด์—์š”. ํด๋”๋Š” ์ƒˆ๋กœ ๋งŒ๋“ค๋•Œ ์ด๋ฏธ ์กด์žฌํ•˜๋ฉด ์ƒ์„ฑ์— ์‹คํŒจํ•ด์„œ, catch๋ฌธ์œผ๋กœ ์ง„์ž…ํ•ด์š”. ๊ทธ๋ž˜์„œ fileExists() ๋ฉ”์†Œ๋“œ๋กœ ๋จผ์ € ํ•ด๋‹น ๊ฒฝ๋กœ์— ์กด์žฌํ•˜๋Š”์ง€๋ฅผ ์ฒดํฌํ•œ ํ›„์— ๋งŒ๋“ค์–ด ์ค˜์•ผํ•ฉ๋‹ˆ๋‹ค.

 

๊ทธ๋Ÿผ ์šฐ๋ฆฌ๊ฐ€ ๋งŒ๋“  ํด๋”์— ํŒŒ์ผ์„ ์ถ”๊ฐ€ํ•ด๋ณผ๊ฒŒ์š”.

let filePath = directoryPath.appendingPathComponent("NewFile.txt")

๋™์ผํ•˜๊ฒŒ appendingPathComponent ๋ฉ”์†Œ๋“œ๋ฅผ ํ†ตํ•ด ํŒŒ์ผ๋ช…์„ ์ง€์ •ํ•ด์ค๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์„œ ์ค‘์š”ํ•œ ์ ์€ ํŒŒ์ผ์€ ํ™•์žฅ์ž๋ฅผ ๊ฐ™์ด ์จ์ค˜์•ผํ•ด์š”. ํ™•์žฅ์ž๋ฅผ ์จ์ฃผ์ง€ ์•Š์•„๋„ ์ €์žฅ์€ ๋˜์ง€๋งŒ, ์ฝ์–ด์˜ฌ ์ˆ˜๊ฐ€ ์—†์–ด์š” ๐Ÿ˜ญ

let textString = NSString(string: "here is new file")

do {
    if !fileManager.fileExists(atPath: filePath.path) {
        try textString.write(to: filePath, atomically: true, encoding: String.Encoding.utf8.rawValue)
    }
} catch {
    print("create file error. do something")
}

textString์— "here is new file" ์ด๋ผ๊ณ  ๋‚ด์šฉ์„ ์ž‘์„ฑํ•˜๊ณ , ์ด ๋‚ด์šฉ์„ ์œ„์—์„œ ๋งŒ๋“ค์—ˆ๋˜ "NewFile.txt"์— write ๋ฉ”์†Œ๋“œ๋ฅผ ํ†ตํ•ด์„œ ์ž‘์„ฑํ•ด์ค„ ์ˆ˜ ์žˆ์–ด์š”. ์—ฌ๊ธฐ์„œ ํ•œ๊ฐ€์ง€ ์œ ์˜ํ•ด์•ผ ํ•  ์ ์€, ์œ„์—์„œ ํด๋” ์ƒ์„ฑํ• ๋•Œ๋Š” ์ด๋ฏธ ๊ฒฝ๋กœ๊ฐ€ ์กด์žฌํ•˜๋ฉด ํด๋” ์ƒ์„ฑ์— ์‹คํŒจํ•œ๋‹ค๊ณ  ํ–ˆ์ฃ ?? ๊ทผ๋ฐ ํŒŒ์ผ์˜ ๊ฒฝ์šฐ์—๋Š” ์ด๋ฏธ ํŒŒ์ผ์ด ์žˆ์–ด๋„ ๋ฎ์–ด์“ฐ๊ธฐ๋ฅผ ํ•ด๋ฒ„๋ฆฌ๋‹ˆ, ์ƒํ™ฉ์— ๋”ฐ๋ผ fileExists๋ฅผ ์‚ฌ์šฉํ•ด ๋ฎ์–ด์“ฐ๋Š” ๊ฑธ ๋ง‰์•„ ์ฃผ๋Š” ๊ฒƒ๋„ ๊ณ ๋ คํ•ด๋ณด์„ธ์š”~!

 

ํ„ฐ๋ฏธ๋„์—์„œ ์ง€๊ธˆ ์ž˜ ๋˜๊ณ  ์žˆ๋Š”์ง€ ์ค‘๊ฐ„์ ๊ฒ€ ํ•œ๋ฒˆ ํ•ด๋ณผ๊ฒŒ์š”~~~ ์˜๋„๋Œ€๋กœ ์ž˜ ์ €์žฅ๋˜๊ณ  ์žˆ๋„ค์š”!! ๐Ÿ‘

 

์ด์ œ ํŒŒ์ผ ์ €์žฅ๊นŒ์ง€ ํ–ˆ์œผ๋‹ˆ, ์ €์žฅํ–ˆ๋˜ ํŒŒ์ผ์„ ์ฝ์–ด์™€๋ณผ๊ฒŒ์š”!

do {
    if fileManager.fileExists(atPath: filePath.path) {
        let readString = try String(contentsOf: filePath, encoding: .utf8)
        print(readString) // here is new file
    }
} catch {
    print("read file error. do something")
}

์ด๋ ‡๊ฒŒ filePath์— ์žˆ๋Š” ๋‚ด์šฉ์„ String์œผ๋กœ ๊ฐ€์ ธ์˜ค๋ฉด ๋ฉ๋‹ˆ๋‹ค. ์ด๋•Œ ํŒŒ์ผ์ด ์กด์žฌํ•˜์ง€ ์•Š์œผ๋ฉด catch ๋ธ”๋Ÿญ์œผ๋กœ ๋น ์ง€๊ฒŒ ๋˜์š”. ์—ญ์‹œ ์ด๋ฒˆ์—๋„ ํŒŒ์ผ์ด ์กด์žฌํ•˜๋Š”์ง€ ๋จผ์ € ์ฒดํฌ๋ฅผ ํ•ด์ฃผ๋Š”๊ฒŒ ์ข‹๊ฒ ์Šต๋‹ˆ๋‹ค ๐Ÿ‘

 

๋งˆ์ง€๋ง‰์œผ๋กœ ์šฐ๋ฆฌ๊ฐ€ ๋งŒ๋“  ํŒŒ์ผ์„ ์‚ญ์ œํ•ด๋ณผ๊ฑฐ์—์š”.

do {
    if fileManager.fileExists(atPath: filePath.path) {
        try fileManager.removeItem(at: filePath)
    }
} catch {
    print("remove file error. do something")
}

์ด๋ ‡๊ฒŒ removeItem() ๋ฉ”์†Œ๋“œ๋ฅผ ํ†ตํ•ด์„œ ์‚ญ์ œํ•  ์ˆ˜ ์žˆ์–ด์š”. ์ด๋•Œ๋„ ํŒŒ์ผ์ด ํ•ด๋‹น ๊ฒฝ๋กœ์— ์—†์œผ๋ฉด catch๋กœ ๋น ์ง€๋‹ˆ ํŒŒ์ผ์ด ์กด์žฌํ•˜๋Š”์ง€ ๋จผ์ € ์ฒดํฌ๋ฅผ ํ•ด์ฃผ๋„๋ก ํ•ด์š”! ๊ทธ๋ฆฌ๊ณ  ์‹ค์ œ๋กœ ํŒŒ์ผ์ด ์ž˜ ์‚ญ์ œ๋˜์—ˆ๋Š”์ง€ ํ™•์ธ๋„ ํ•ด๋ณด๊ตฌ์š”~~ ๐Ÿ‘

๊ฐ™์€ ๋ฐฉ๋ฒ•์œผ๋กœ ํด๋”๋„ ์‚ญ์ œํ•  ์ˆ˜ ์žˆ์–ด์š”!

do {
    if fileManager.fileExists(atPath: directoryPath.path) {
        try fileManager.removeItem(at: directoryPath)
    }
} catch {
    print("remove file error. do something")
}

์—ญ์‹œ๋‚˜ ์ž˜ ์‚ญ์ œ๋˜์—ˆ๋Š”์ง€ ํ•œ๋ฒˆ ํ™•์ธ ํ•ด์ฃผ๊ณ ์š”~~~ ๋ชจ๋‘ ์˜๋„๋Œ€๋กœ ์ž˜ ๋˜์—ˆ๋„ค์š” ๐Ÿ‘๐Ÿ‘

 

 

์˜ค๋Š˜์€ ์ด๋ ‡๊ฒŒ iOS์˜ ๊ธฐ๋ณธ์ ์ธ ํŒŒ์ผ ๊ตฌ์กฐ์— ๋Œ€ํ•ด์„œ ์•Œ์•„๋ณด๊ณ , Swift์—์„œ ์ œ๊ณตํ•˜๋Š” FileManager ํด๋ž˜์Šค๋ฅผ ์ด์šฉํ•ด ํด๋”/ํŒŒ์ผ์„ ๋กœ์ปฌ์˜ ํŠน์ • ๊ฒฝ๋กœ์— ์ถ”๊ฐ€/์‚ญ์ œํ•˜๋Š” ์‹ค์Šต์„ ํ•ด๋ดค์Šต๋‹ˆ๋‹ค!

์˜ค๋Š˜๋„ ๋ˆ„๊ตฐ๊ฐ€์—๊ฒŒ ๋„์›€์ด ๋˜์—ˆ๊ธธ ๋ฐ”๋ž˜์š” ๐Ÿ™

 

 

'iOS [Swift] > ๊ธฐ์ดˆ๋ฅผ ํƒ„ํƒ„ํžˆ!' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

[Swift] Class vs Struct  (0) 2021.03.16
[Swift] Singleton Pattern (์‹ฑ๊ธ€ํ†ค ํŒจํ„ด)  (0) 2021.03.16
[Swift] Audio Recording  (0) 2021.03.01
[Swift] CaseIterable  (0) 2021.02.27
[Swift] typealias  (0) 2021.02.26
Comments