์ค๋์ ์ฃผ์ ๋ FileManager
์ฐ๊ฒ๋ ์ด์ ๋ ๋ค์๊ณผ ๊ฐ๋ค,
์ฌ์ด๋ ํ๋ก์ ํธ๋ฅผ ํ๊ณ ์๋๋ฐ, Photo kit ๊ด๋ จ ํด๋ณธ ๊ฒฝํ์ด ์์ด์, ์ด ๋ถ๋ถ์ ์ง์ ์จ๋ณผ๋ ค๊ณ ์จ๋ฒ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์์ฐ๋๋ฐ,
์์, ์ด๋ฏธ์ง, ๋ผ์ด๋ธํฌํ ๋ฅผ ์ฑ๋ด์ ์ ์ฅํ๋ ๋ฐฉ๋ฒ์ด ํ์ํ๋ค.
NSData๋ก ์บ์คํ ํด์ Core Data์ ๋ฃ์ผ๋ คํ๋๋ฐ, ์ด๊ฑด ์ข ์๋๊ฑฐ ๊ฐ์์ ์ฌ๊ธฐ์ ๊ธฐ ๋ฌผ์ด๋ณธ ๊ฒฐ๊ณผ
๋ฐ์ด๋๋ฆฌ ํ์ผ(์ด๋ฏธ์ง, ์์ ๋ฑ๋ฑ)์ ํ์ผ์ ์ ์ฅํ๊ณ ,
๋ฉํ๋ฐ์ดํฐ(์ฌ์ง ์ ๋ณด, ๊ด๋ จ ์ ๋ณด)๋ง Core data์ ์ ์ฅ์ํค๋ ๋ฐฉ์์ด ๊ฐ์ฅ ๋ง์ด ์ฐ์ธ๋ค๊ณ ํด์ ์จ๋ณด๊ฒ ๋๋ค.
์์
File Manager
๋?- ํด๋ ์ถ๊ฐ ๋ฐฉ๋ฒ์?
- ํ์ผ ์ถ๊ฐ ๋ฐฉ๋ฒ์?
- ํ์ผ ๋ถ๋ฌ์ค๋ ๋ฐฉ๋ฒ์?
- ํ์ผ ์ญ์ ํ๋ ๋ฐฉ๋ฒ์?
File Manager
๋?
์์ดํฐ ์ฑ๋ง๋ค ์๊ธฐ๋ง์ ๊ณต๊ฐ์ ๊ฐ์ง๊ณ ์๋๋ฐ, ์ด ๊ณต๊ฐ์ ๊ด๋ฆฌํ๋ ๋งค๋์ ๋ผ ์๊ฐํ๋ฉด ๋ ๊ฒ ๊ฐ๋ค.
์ด ๊ณต๊ฐ์ ์ผ๋ฐ ๋งฅ, ์๋์ฐ์ฒ๋ผ Document ํด๋, Downloadํด๋ ๋ฑ๋ฑ ๋ค์ํ ์ข ๋ฅ์ ํด๋๊ฐ ์๋ค!
์ด ๊ธ์์ Documentํด๋๋ฅผ ์ฌ์ฉํ์ฌ ์ด๊ฒ ์ ๊ฒ ํด๋ณด๋ คํ๋ค.
๊ฒฝ๋ก ์ ๊ทผ
๋ค๋ฅธ ์์ ๋ค ํ๊ธฐ์ ๊ณตํต ์ฌํญ์ธ ํด๋น ํด๋๋ก ์ ๊ทผ ํ๋ ๋ฐฉ๋ฒ์ ๋จผ์ ์์๋ณด์
let fileManager = FileManager.default
fileManager
๋ผ๋ ์ธ์คํด์ค๋ฅผ ๋ง๋ค์ด์ค๋ค. (default๋ฅผ ํด์ค์ผ๋ก์จ ์ฑ๊ธํค ์ธ์คํด์ค!)
let documentURL = fileManager.urls(for: .documentDirectory, in: .userDomainMask)[0]
for
๋ ํด๋๋ฅผ ์ ํด์ฃผ๋ ์์์
๋๋ค. Download ํด๋ ํน์ Document ํด๋ ๋ฑ๋ฑ
in
์ ์ ํ์ ๊ฑธ์ด์ฃผ๋ ์์์
๋๋ค. ๊ทธ ์ด์์ ๋ชป๊ฐ๊ฒ ํ๋!
About - Mask
view.layer.masksToBounds = true ๋ง์ด ๋ณด์ จ์ ๊ฒ๋๋ค.
๊ทธ๋ ๊ฒ ํ๋ฉด Bound ๋ฐ์ UI๋ค์ ์๋ณด์ด๋!!
in
์ ์ธ์๋ค ์ด๋ฆ์ ๋ถ์ Mask๋ ์ด๋ฐ ์๋ฏธ๋ผ ์๊ฐํ๋ฉด ์ข์ ๊ฒ ๊ฐ๋ค.
์ ํ์ด ์ฃผ์์ ๊ต์ฅํ ์์จ๋จ์ผ๋ฏ๋ก ์ข๋ ๋ํ
์ผํ๊ฒ ๋ณด์,
for
enum ๊ฐ๋ค (Objective C Enum)
documentDirectory // documents (Documents)
developerDirectory // (Developer) DEPRECATED - there is no one single Developer directory.
desktopDirectory // location of user's desktop
downloadsDirectory // location of the user's "Downloads" directory
musicDirectory // location of user's Music directory (~/Music)
...
๊ต์ฅํ ์ค๋ช ์ ์ํด๋จ๊ณ , ๊ต์ฅํ ๋ง๋ค. ๊ทธ ์ค ์น์ํด ๋ณด์ด๋ ๋ช๊ฐ๋ง ๊ฐ์ ธ์๋ค. ์ด๋ฐ์์ผ๋ก ์ ๊ทผ ํด๋๋ฅผ ์ง์ ํด์ค๋ค.
in
enum ๊ฐ๋ค (Swift Enum)
public static var userDomainMask: FileManager.SearchPathDomainMask { get }
// user's home directory --- place to install user's personal items (~)
public static var localDomainMask: FileManager.SearchPathDomainMask { get }
// local to the current machine --- place to install items available to everyone on this machine (/Library)
public static var networkDomainMask: FileManager.SearchPathDomainMask { get }
// publically available location in the local area network --- place to install items available on the network (/Network)
public static var systemDomainMask: FileManager.SearchPathDomainMask { get }
// provided by Apple, unmodifiable (/System)
public static var allDomainsMask: FileManager.SearchPathDomainMask { get }
// all domains: all of the above and future items
ํฐ๋ฏธ๋์ ์กฐ๊ธ์ด๋ผ๋ ์จ๋ดค๋ค๋ฉด ๋ค์ ๊ดํธ๋ง ๋ด๋ ์ฝ๊ฒ ์ดํดํ ์ ์์ ๊ฒ ๊ฐ๋ค.
์ผ์ค์๊ฒ ์ ๋ ๊ฒ ํํํด์ฃผ๋ ์ข๋ค.
๊ฒฝ๋ก ์ถ๊ฐ
ํค์๋: appendingPathComponent
์์ฃผ ๊ฐ๋จํ๋ค.
let newURL = documentsURL.appendingPathComponent("App Photos")
๊ฐ๋จํ ์๋ฅผ ์จ๋ณด๋ฉด
let oldURL = URL(string: "~/Document")
let newURL = documentsURL.appendingPathComponent("Hello")
print(newURL) // ~/Document/Hello
์์ฃผ ๊ฐ๋จ!
ํด๋ ์ถ๊ฐ ๋ฐฉ๋ฒ์?
ํค์๋: createDirectory
// 1. ์ธ์คํด์ค ์์ฑ
let fileManager = FileManager.default
// 2. ๋ํ๋จผํธ URL ๊ฐ์ ธ์ค๊ธฐ
let documentsURL = fileManager.urls(for: .documentDirectory, in: .userDomainMask)[0]
// 3. ์์ฑํ ํด๋ ์ด๋ฆ ์ถ๊ฐํด์ฃผ๊ธฐ
let directoryURL = documentsURL.appendingPathComponent("NewDirectory")
// 4. ์์ฑํ๊ธฐ
do {
try fileManager.createDirectory(at: directoryURL, withIntermediateDirectories: false, attributes: nil)
} catch let e {
print(e.localizedDescription)
}
์ด๊ฒ๋ ์์ฃผ ๊ฐ๋จ!
at
: ๊ฒฝ๋ก ๋ฐ ํด๋๋ช , ์์์ ๋ง๋URL
์ฌ์ฉwithIntermediateDirectories
: โ์ค๊ฐ ๋๋ ํ ๋ฆฌ๋ค๋ ๋ง๋ค๊บผ์ผ?โ ์ด๋ฐ ์๋ฏธ.attributes
: ํ์ผ ์ ๊ทผ ๊ถํ, ๊ทธ๋ฃน ๋ฑ๋ฑ ํด๋ ์์ฑ ์ ์
๋ค์ ๋งํด, ํ์ฌ ์กด์ฌํ๋ ํด๋๊ฐ ~/Document
๋ง ์๋ ์ํ์์ appendingPathComponent
๋ฅผ ์ฌ๋ฌ๋ฒํด์ ~/Document/path1/path2/path3
๋ก ๋ง๋ค์๋ค๊ณ ๊ฐ์ ํ๋ฉด, ๊ฐ Bool
๊ฐ์ ๋ฐ๋ผ ์ฑ๊ณต, ์คํจ๊ฐ ๋๋๋ค.
withIntermediateDirectories: true
- ์ค๊ฐ ๋๋ ํ ๋ฆฌ์ธpath1/path2
๋ ๋ง๋ค๊ณpath3
๊น์ง ๋ง๋ ๋ค.withIntermediateDirectories: false
- ์ค๊ฐ ๋๋ ํ ๋ฆฌ๊ฐ ์กด์ฌํ์ง ์์ผ๋ฉดcatch
๋ก ๋น ์ง๋ค.
ํ์ผ ์ถ๊ฐ ๋ฐฉ๋ฒ์?
ํค์๋: write(to:_, atomically:_, encoding:_)
// 1. ์ธ์คํด์ค ์์ฑ - ๋์ผ
let fileManager = FileManager.default
// 2. ๋ํ๋จผํธ URL ๊ฐ์ ธ์ค๊ธฐ - ๋์ผ
let documentsURL = fileManager.urls(for: .documentDirectory, in: .userDomainMask)[0]
// 3. ํ์ผ ์ ์ฅํ Directory ์ค์
let directoryURL = documentsURL.appendingPathComponent("NewDirectory")
// 4. File ์ด๋ฆ ์ค์
let fileURL = directoryURL.appendingPathComponent("test.txt")
// 5. File ๋ด์ฉ
let text = NSString(string: "Hello world")
do {
// 6-1. ํ์ผ ์์ฑ
try text.write(to: fileURL, atomically: true, encoding: String.Encoding.utf8.rawValue)
} catch let e {
// 6-2. ์ค๋ฅ ์ฒ๋ฆฌ
print(e.localizedDescription)
}
NSString
์ ๋ด๋ถ ํจ์๋ก write
๊ฐ ์กด์ฌํ๋ฉฐ, ์ด๋ฅผ ์ด์ฉํด์ ์ฐ๊ธฐ๋ฅผ ํ๋ค.
to
: ์์ ๋ง๋URL
์ ์จ์ฃผ๋ฉด ๊ทธ๋๋ก ์์ฑ.atomically
: ์ด๊ฑฐ ๋ญ์ง ๋ชจ๋ฅด๊ฒ ,,, ์ฝ์ด๋ ๋ชจ๋ฅด๊ฒ ,,, ๋ค๋ง,true
๋ฉด URL์ด ์กด์ฌ ์ํด๋ ์์คํ ์ ์์์ด ์๋จ ๋์์ค๋ฅผ ํ๊ธฐ๋ฏ๋กtrue
๋ง,,encoding
: ์ธ์ฝ๋ฉ ์ข ๋ฅ!
์ฌ๊ธฐ์ ์๋ฌ๊ฐ ๋ฌ๋๊ฒ ํ์ผ ๊ฒฝ๋ก๊ฐ ๋ฏธ์กด์ฌ์ โThe file โtest.txtโ doesnโt exist.โ ๋ผ๊ณ catch๋ก ๊ฐ๋ค.
test.txt๋ ํ์ผ์ ์ด์ ๋ง๋ค๋ผ๋๊ฑด๋ฐ ์ ์๋ค๊ณ ๊ทธ๋,,? ๋ผ๊ณ ํ์ฐธ ์๊ฐํ๋๋ฐ, ๋ค๋ฅธ ํ ์คํธํ๋๋ผ ๊ฒฝ๋ก๋ฅผ ์๋ชป ์ ํ ํ์๋ค.
ํํ,, ์ค๊ฐ์ ๋ค๋ฅธ ๊ฒฝ๋ก๊ฐ ์๋๊ฑด๋ฐ, ์ ๋ ๊ฒ ์ค๋ช ์ ํ๋ค๋โฆ ๊ทธ๋๋ ๋ณด๋ฉด ๊ฐ๋จํ๊ฒ ์ด๋ฃจ์ด์ง๋จ๊ฑธ ์ ์ ์๋ค.
์ฌ๊ธฐ์ ๋ write
ํ ๊ฒฝ์ฐ์, ๋ฎ์ด ์์ ์๋ค.
ํ์ผ ๋ถ๋ฌ์ค๋ ๋ฐฉ๋ฒ์?
// 1. ์ธ์คํด์ค ์์ฑ - ๋์ผ
let fileManager = FileManager.default
// 2. ๋ํ๋จผํธ URL ๊ฐ์ ธ์ค๊ธฐ - ๋์ผ
let documentsURL = fileManager.urls(for: .documentDirectory, in: .userDomainMask)[0]
// 3. ํ์ผ์ด ์๋ Directory ์ค์
let directoryURL = documentsURL.appendingPathComponent("NewDirectory")
// 4. ๋ถ๋ฌ์ฌ ํ์ผ ์ค์
let helloPath = directoryURL.appendingPathComponent("test.txt")
// Try Catch
do {
// 5-1. ๋ถ๋ฌ์ค๊ธฐ
let text = try String(contentsOf: helloPath, encoding: .utf8)
print(text) // Hello world
} catch let e {
// 5-2. ์๋ฌ์ฒ๋ฆฌ
print(e.localizedDescription)
}
์ด๊ฑด ์ฐ๊ธฐ๋ณด๋ค ๊ฐ๋จ!
ํ์ผ ์ญ์ ํ๋ ๋ฐฉ๋ฒ์?
// 1. ์ธ์คํด์ค ์์ฑ - ๋์ผ
let fileManager = FileManager.default
// 2. ๋ํ๋จผํธ URL ๊ฐ์ ธ์ค๊ธฐ - ๋์ผ
let documentsURL = fileManager.urls(for: .documentDirectory, in: .userDomainMask)[0]
// 3. ํ์ผ์ด ์๋ Directory ์ค์
let directoryURL = documentsURL.appendingPathComponent("NewDirectory")
// 4. ์ญ์ ํ ํ์ผ ์ค์
let helloPath = directoryURL.appendingPathComponent("test.txt")
// Try Catch
do {
// 5-1. ์ญ์ ํ๊ธฐ
try fileManager.removeItem(at: fileURL)
} catch let e {
// 5-2. ์๋ฌ์ฒ๋ฆฌ
print(e.localizedDescription)
}
๊ด๋ฆฌ๋ฅผ ๋ด๋นํ๋ fileManager
์๊ฒ ์์ผ์ ์ญ์ ๋ฅผ ์ํค๋ฉด ๊น๋.
์ดํ ๊ทธ ํ์ผ์ ๋ถ๋ฌ์ค๋ฉด ์๋์ ๊ฐ์ด Error
๊ฐ ๋ฐ์ํ๋ค.
The file โtest.txtโ couldnโt be opened because there is no such file.
Q&A
Q . ํ ์คํธ ๋ง๊ณ ์ด๋ฏธ์ง๋ GIF ๋ฑ๋ฑ ๋ค๋ฅธ๊ฑด ์ด๋ป๊ฒ??
A. NSData ํ์์ผ๋ก!
์๋์ฒ๋ผํ๋ฉด ์ด๋ค๊ฒ์ด๋ Data
ํ์ผ๋ก ์์ฝ๊ฒ ๋ณ๊ฒฝ๊ฐ๋ฅ!
// Archive Data
let archivedData = NSKeyedArchiver.archivedData(withRootObject: file)
// Unarchive Data
let unarchivedData = NSKeyedUnarchiver.unarchiveObject(with: file as Data)
Q. ์ ํ ๋ด์ฅ ์ฑ์ค File App
์ด๋ ๊ด๋ จ์ด ์๋?
A. Yes, ํ๋ก์ ํธ๋ด์ ์ค์ ์ ํ๋ฉด, File App
์ด ํด๋น ์ดํ์ ์ ๊ทผํ ์ ์๊ฒ ๋๋ค!