FileManager
A convenient interface to the contents of the file system, and the primary means of interacting with it.
➡️ 파일 시스템의 내용에 대한 편리한 인터페이스 및 상호 작용의 주요 수단입니다.
A file manager object lets you examine the contents of the file system and make changes to it. The FileManager
class provides convenient access to a shared file manager object that is suitable for most types of file-related manipulations. A file manager object is typically your primary mode of interaction with the file system. You use it to locate, create, copy, and move files and directories. You also use it to get information about a file or directory or change some of its attributes.
➡️ 파일 시스템을 확인하고, 변경하는 객체입니다. 파일이나 저장소의 위치를 변경하고, 생성하고, 복사하고 위치시킬 수 있습니다. 파일이나 저장소의 정보를 얻거나 변경할 때도 사용할 수 있습니다.
When specifying the location of files, you can use either NSURL
or NSString
objects. The use of the NSURL
class is generally preferred for specifying file-system items because URLs can convert path information to a more efficient representation internally. You can also obtain a bookmark from an NSURL
object, which is similar to an alias and offers a more sure way of locating the file or directory later.
➡️ NSURL
이나, NSString
을 활용하여 파일의 위치를 specify 할 수 있습니다. NSURL
클래스의 사용은 URL이 내부적으로 더 효율적인 표현으로 경로 정보를 변환할 수 있기 때문에 파일 시스템 항목을 지정하는 데 일반적으로 선호됩니다.
If you are moving, copying, linking, or removing files or directories, you can use a delegate in conjunction with a file manager object to manage those operations. The delegate’s role is to affirm the operation and to decide whether to proceed when errors occur. In macOS 10.7 and later, the delegate must conform to the FileManagerDelegate
protocol.
➡️ 파일이나 디렉토리를 이동, 복사, 연결 또는 제거하는 경우 파일 관리자 개체와 함께 delegate을 사용하여 이러한 작업을 관리할 수 있습니다. 델리게이트의 역할은 작업을 확인하고 오류가 발생할 때 진행할지 여부를 결정하는 것입니다. macOS 10.7 이상에서 Delegate은 FileManagerDelegate 프로토콜을 준수해야 합니다.
In iOS 5.0 and later and in macOS 10.7 and later, FileManager includes methods for managing items stored in iCloud. Files and directories tagged for cloud storage are synced to iCloud so that they can be made available to the user’s iOS devices and Macintosh computers. Changes to an item in one location are propagated to all other locations to ensure the items stay in sync.
➡️ iOS 5.0 이상 및 macOS 10.7 이상에서 FileManager에는 iCloud에 저장된 항목을 관리하는 메서드가 포함되어 있습니다. 클라우드 저장소로 태그가 지정된 파일 및 디렉터리는 iCloud에 동기화되어 사용자의 iOS 장비 및 Macintosh 컴퓨터에서 사용할 수 있습니다. 한 위치의 항목에 대한 변경 사항은 항목이 동기화된 상태를 유지하도록 다른 모든 위치로 전파됩니다.
Threading Considerations
The methods of the shared FileManager object can be called from multiple threads safely. However, if you use a delegate to receive notifications about the status of move, copy, remove, and link operations, you should create a unique instance of the file manager object, assign your delegate to that object, and use that file manager to initiate your operations.
➡️ FileManager의 메소드는 멀티 스레드에서 안전하게 불리울 수 있습니다. 그러나, 파일의 이동, 복사, 제거 등과 관련된 notification을 받기 위해서 delegate을 활용한 경우, 특정한 file manager object 인스턴스를 생성하여 delegate에게 할당시켜야합니다.
default
The shared file manager object for the process.
class var `default`: FileManager { get }
This method always represents the same file manager object. If you plan to use a delegate with the file manager to receive notifications about the completion of file-based operations, you should create a new instance of FileManager (using the init method) rather than using the shared object.
➡️ 이 메서드는 항상 동일한 파일 관리자 개체를 나타냅니다. 파일 기반 작업 완료에 대한 알림을 받기 위해 파일 관리자와 함께 대리자를 사용하려는 경우 공유 객체를 사용하는 대신 FileManager의 새 인스턴스(init 메서드 사용)를 만들어야 합니다.(위의 thread consideration에서 나온 이야기 같네요!)
urls(for:in:)
Returns an array of URLs for the specified common directory in the requested domains.
요청된 도메인의 지정된 공통 디렉토리에 대한 URL 배열을 반환합니다.
즉, 도큐먼트 URL을 가져온다.
func urls(
for directory: FileManager.SearchPathDirectory,
in domainMask: FileManager.SearchPathDomainMask
) -> [URL]
directory
→ enum 타입
- 어느 디렉토리에 저장을 할 것인가?
- applicationDirectory
- demoApplicationDirectory
…
domainMask
→ struct 타입
- 검색할 파일 시스템 도메인입니다. 이 매개 변수의 값은 FileManager.SearchPathDomainMask에 설명된 하나 이상의 상수입니다.(?..)
- 제한을 걸어주어서 해당 파라미터 이상으로는 못가게 막는 역할을 합니다.
static var userDomainMask: FileManager.SearchPathDomainMask
- The user’s home directory—the place to install user’s personal items (
~
).
static var localDomainMask: FileManager.SearchPathDomainMask
- The place to install items available to everyone on this machine.
Return value
An array of NSURL objects identifying the requested directories. The directories are ordered according to the order of the domain mask constants, with items in the user domain first and items in the system domain last.
➡️ 요청된 디렉토리를 식별하는 NSURL 객체의 배열입니다. 디렉토리는 domainMask의 순서에 따라 사용자 도메인의 항목이 먼저, 시스템 도메인의 항목이 마지막으로 정렬됩니다.
createDirectory(atPath:withIntermediateDirectories:attributes:)
폴더 추가하기
Creates a directory with given attributes at the specified path.
➡️ 특정 path에 저장소를 만드는 메소드
func createDirectory(
atPath path: String,
withIntermediateDirectories createIntermediates: Bool,
attributes: [FileAttributeKey : Any]? = nil
) throws
createIntermediates
- Boolean
- 중간 디렉토리를 만들 지 말 지를 선택할 수 있다.
attributes
- 폴더 속성 정의
appendingPathComponent(_:isDirectory:)
경로 추가하기
Returns a URL by appending the specified path component to self.
➡️ 파일 저장할 directory 설정하기
func appendingPathComponent(
_ pathComponent: String,
isDirectory: Bool
) -> URL
pathComponent
- The path component to add.
isDirectory
- If
true
, the method treats the path component as a directory.
**Return Value**
A new URL with the path component appended.
💦 단, 해당 메소드는 iOS 17 이후에는 deprecated가 되므로, iOS 16부터는 **append(path:directoryHint:)
를 활용해야된다.
write(to:options:)
파일 추가하기
Writes the data object's bytes to the location specified by a given URL.
➡️ 주어진 URL로 지정된 위치에 데이터 객체를 작성합니다.
func write(
to url: URL,
options writeOptionsMask: NSData.WritingOptions = []
) throws
writeOptionsMask
- A mask that specifies options for writing the data. Constant components are described in
NSData.WritingOptions.
Return Value
true
if the operation succeeds, otherwise false
.
실제로 사용해보기!
- 크게 아래와 같은 순서로 disk storge 세팅을 한다
- documentURL을 가져온다 → 내가 어디에 directory를 만들지 설정
- directoryURL을 설정해서, directory를 생성한다.
- documentURL을 가져오기
class DiskStorage {
static let shared: DiskStorage = DiskStorage()
let fileManager = FileManager.default
init() {
let documentURL = fileManager.urls(for: .documentDirectory, in: .userDomainMask)[0]
...
}
- directoryURL을 설정해서, directory를 생성한다.
class DiskStorage {
static let shared: DiskStorage = DiskStorage()
let fileManager = FileManager.default
let directoryURL: URL
init() {
let documentURL = fileManager.urls(for: .documentDirectory, in: .userDomainMask)[0]
let directoryURL = documentURL.appendingPathComponent("NewDirectory", isDirectory: true)
self.directoryURL = directoryURL
prepareDirectory()
}
..
// directory 생성하기
func prepareDirectory() {
do {
print(directoryURL.path)
try fileManager.createDirectory(at: directoryURL, withIntermediateDirectories: true)
} catch {
print(error)
}
}
- cache가 되어있는 지 확인하기!
func isCached(forkey key: String) -> Bool {
let fileURL = directoryURL.appendingPathComponent(key)
let filePath = fileURL.path
guard FileManager.default.fileExists(atPath: filePath) else { return false }
return true
}
- cache가 되어있지 않다면, directory에 저장하기!
func store(image: UIImage, key: String) {
// 일단 데이터로 변환하기!
guard let data = image.jpegData(compressionQuality: 1) ?? image.pngData() else { return }
let fileURL = cacheFileURL(forKey: key)
print(fileURL)
do {
try data.write(to: fileURL)
} catch {
print(error)
}
}
// fileURL 가져오기!!!
func cacheFileURL(forKey key: String) -> URL {
let fileName = cacheFileName(forKey: key)
return directoryURL.appendingPathComponent(fileName, isDirectory: false)
}
func cacheFileName(forKey key: String) -> String {
return key
}
- cache가 되어있다면, directory에서 가져오기
func value(forKey key: String) -> UIImage? {
let fileURL = cacheFileURL(forKey: key)
do {
let data = try Data(contentsOf: fileURL)
let image = UIImage(data: data)
return image
} catch {
return nil
}
}
🚨 단 조심해야될 점이 있다.
- 아래와 같이 fileName을 설정할 경우, fileName안에는
/
가 있으면 안된다!!
// fileURL 가져오기!!!
func cacheFileURL(forKey key: String) -> URL {
let fileName = cacheFileName(forKey: key)
return directoryURL.appendingPathComponent(fileName, isDirectory: false)
}
func cacheFileName(forKey key: String) -> String {
return key
}
- 만약 fileName에
/
가 있다면, 이후 data를 write하는 곳에서 문제가 path를 찾지 못할 수 있다!
func store(image: UIImage, key: String) {
// 일단 데이터로 변환하기!
guard let data = image.jpegData(compressionQuality: 1) ?? image.pngData() else { return }
let fileURL = cacheFileURL(forKey: key)
print(fileURL)
do {
// 💥 fileURL을 제대로 못 찾을 수 있다!
try data.write(to: fileURL)
} catch {
print(error)
}
}
- 오류 메세지는 아래와 같다!
'iOS' 카테고리의 다른 글
[iOS] delegate는 항상 weak var로 선언해야 될까? (0) | 2023.06.12 |
---|---|
[iOS] Diffabledatasource의 identifier는 왜 Hashable 해야 할까? (0) | 2023.06.08 |
[iOS] NotificationCenter (0) | 2023.04.13 |
[iOS] Gesture recognizer, Touch event handling (0) | 2023.02.28 |
[iOS] 의존성 관리 도구(Package Manager) (0) | 2023.02.21 |