안녕하세요 ◠‿◠ 고고입니다.
NSOpenPanel과 NSSavePanel로 png, jpeg 등 이미지를 열고 저장하는 것과 pdf, hwp 등의 파일을 열고 저장하는 코드를 올려봤습니다. 편하게 사용해주세요~
1. NSOpenPanel
1.1 Open images
extension NSOpenPanel {
// Image 가져오기 실패 시 사용
enum ImageError: Error {
case selectionFailed
}
static func openImage(completion: @escaping (_ result: Result<NSImage, Error>) -> Void) {
let panel = NSOpenPanel()
// 다중 선택가능
panel.allowsMultipleSelection = false
// 파일 선택가능
panel.canChooseFiles = true
// 폴더 선택가능
panel.canChooseDirectories = false
// 가져올 수 있는 파일형식
panel.allowedFileTypes = ["jpg", "jpeg", "png"]
// 열기 눌렀을 때
panel.begin { result in
guard
result == .OK,
let url = panel.urls.first,
let image = NSImage(contentsOf: url) // 가져온 url을 NSImage로 변환
else {
completion(.failure(ImageError.selectionFailed))
return
}
completion(.success(image))
}
}
}
1-2. Open files
extension String {
var lastPathComponent: String {
get {
return (self as NSString).lastPathComponent
}
}
}
static func openFile(completion: @escaping (_ result: Result<(String, Data), Error>) -> Void) {
let panel = NSOpenPanel()
// 다중 선택가능?
panel.allowsMultipleSelection = false
// 파일 선택가능?
panel.canChooseFiles = true
// 폴더 선택가능?
panel.canChooseDirectories = false
// 열기 눌렀을 때
panel.begin { result in
guard
result == .OK,
let url = panel.urls.first
else {
completion(.failure(ImageError.selectionFailed))
return
}
do {
let data = try Data(contentsOf: url)
completion(.success((url.path.lastPathComponent, data))) // 파일 이름, 데이터
} catch {
completion(.failure(error))
}
}
}
2. NSSavePanel
2-1. Save images
extension NSSavePanel {
// 저장 실패 시 사용
enum SaveError: Error {
case saveFailed
}
static func saveImage(fileName: String, targetPath: String = "Downloads", image: NSImage, completion: @escaping (_ result: Result<Void, Error>) -> Void) {
let targetPath = NSHomeDirectory()
let savePanel = NSSavePanel()
savePanel.directoryURL = URL(fileURLWithPath: targetPath.appending(targetPath))
savePanel.canCreateDirectories = true
savePanel.nameFieldStringValue = fileName
savePanel.allowedFileTypes = ["png", "jpg", "jpeg"]
savePanel.begin { result in
if result.rawValue == NSApplication.ModalResponse.OK.rawValue {
if let url = savePanel.url {
let cgImage = image.cgImage(forProposedRect: nil, context: nil, hints: nil)!
let bitmapRep = NSBitmapImageRep(cgImage: cgImage)
let jpegData = bitmapRep.representation(using: NSBitmapImageRep.FileType.png, properties: [:])!
do {
try jpegData.write(to: url)
completion(.success(()))
} catch {
completion(.failure(error))
}
}
} else {
completion(.failure(SaveError.saveFailed))
}
}
}
}
2-2. Save files
class Downloader {
// 저장 실패 시 사용
enum WriteError: Error {
case writeFailed
}
class func load(url: URL, to localUrl: URL, completion: @escaping (_ result: Result<Void, Error>) -> Void) {
let sessionConfig = URLSessionConfiguration.default
let session = URLSession(configuration: sessionConfig)
let request = try! URLRequest(url: url, method: .get)
let task = session.downloadTask(with: request) { (tempLocalUrl, response, error) in
if let tempLocalUrl = tempLocalUrl, error == nil {
do {
try FileManager.default.copyItem(at: tempLocalUrl, to: localUrl)
completion(.success(()))
} catch (let writeError) {
completion(.failure(writeError))
}
} else {
completion(.failure(WriteError.writeFailed))
}
}
task.resume()
}
}
extension NSSavePanel {
// 저장 실패 시 사용
enum SaveError: Error {
case saveFailed
}
static func saveFile(fileName: String, targetPath: String = "Downloads", fileUrl: String, completion: @escaping (_ result: Result<Void, Error>) -> Void) {
let targetPath = NSHomeDirectory()
let savePanel = NSSavePanel()
savePanel.directoryURL = URL(fileURLWithPath: targetPath.appending(targetPath))
savePanel.canCreateDirectories = true
savePanel.nameFieldStringValue = fileName
savePanel.level = NSWindow.Level(rawValue: Int(CGWindowLevelForKey(.modalPanelWindow)))
savePanel.begin { result in
if result.rawValue == NSApplication.ModalResponse.OK.rawValue {
if let url = URL(string: fileUrl) {
Downloader.load(url: url, to: savePanel.url!, completion: { result in
switch result {
case .success(_):
completion(.success(()))
case .failure(let error):
completion(.failure(error))
}
})
}
} else {
completion(.failure(SaveError.saveFailed))
}
}
}
}
댓글