지난 포스트에서 피드백을 받기 위해 앱 내에서 메일을 전송할 수 있도록 기능을 구현했었다
지난 포스트 : [iOS] 앱에서 메일 보내기 (feat. MessageUI)
그러나 앱에서 메일 발송을 실패한 경우를 대비하여 추가 장치가 필요한 상황이었고, 그 장치로 외부 메일 앱에서 메일을 전송할 수 있도록 이메일 주소 복사 기능을 추가하게 되었다
간단하게 아래처럼 복사 아이콘을 클릭하면 클립보드에 복사되도록 구현하고자 한다

간략히 적어보겠다
import SwiftUI
struct ContentView: View {
// ... 변수 선언
var body: some View {
HStack {
// ... UI 그리기
// 복사 버튼
Button(action: {
// ... 버튼 이벤트
copyToClipboard(...)
}, label: {
Image(systemName: "square.on.square")
.foregroundStyle(.gray)
.font(.system(size: 16))
})
}
.alert(...) { ... }
}
func copyToClipboard(_ text: String) { ... }
}
enum ClipboardCopyStatus { ... }
복사할 텍스트는 변수로 지정해준다
기타 필요한 변수도 모두 선언해주자
let textToCopy: String = "복사할 텍스트"
복사 기능은 사실 UIPasteboard.general.string = text 한줄이면 구현 가능하다
그러나 여러 상황에 따라 예외가 발생할 수 있으므로 예외처리도 함께 해주었다
func copyToClipboard(_ text: String) {
// 문자열이 비어있는 경우 예외처리
guard !text.isEmpty else {
return
}
if UIPasteboard.general.hasStrings {
// 복사 성공
UIPasteboard.general.string = text
} else {
// 접근 권한 없어 복사 실패
}
}
간단하게, 버튼 액션 부분에 함수를 호출해주면 된다
Button(action: {
// ... 버튼 이벤트
copyToClipboard(textToCopy)
}, label: { ... }
복사가 되는 거까진 구현했는데, 사용자 입장에서는 복사 여부를 알 수 없는 불편함이 있어보인다
따라서, 복사 상태에 따라 alert창을 띄워주겠다
케이스에 따라 alert창의 문구가 달라져야 하기에 열거형으로 복사 상태를 미리 정의해두었다
enum ClipboardCopyStatus {
case success
case emptyString
case failAccess
var message: String {
switch self {
case .success:
return "클립보드에 복사되었습니다!"
case .emptyString:
return "클립보드 복사에 실패했습니다"
case .failAccess:
return "클립보드 복사에 실패했습니다\n설정에서 권한을 확인해주세요"
}
}
}
// 변수 선언
@State var showCopyAlert: Bool = false
@State var alertMessage: String = ""
// 복사 버튼
Button()
.alert(isPresented: $showCopyAlert) {
Alert(title: Text("알림"), message: Text(alertMessage), dismissButton: .default(Text("확인")))
}
copyToClipboard 함수에서 예외 상황에 따라 alertMessage를 변경한다
(그냥 코드 복붙해도 됨)
func copyToClipboard(_ text: String) {
// 문자열이 비어있는 경우 예외처리
guard !text.isEmpty else {
alertMessage = ClipboardCopyStatus.emptyString.message
showCopyAlert = true
return
}
if UIPasteboard.general.hasStrings {
// 복사 성공
UIPasteboard.general.string = text
alertMessage = ClipboardCopyStatus.success.message
} else {
// 접근 권한 없어 복사 실패
alertMessage = ClipboardCopyStatus.success.message
}
showCopyAlert = true
}
웹에서는 라이브러리 사용해서 구현할 수 있었고, 구현하는데에도 꽤나 시행착오를 겪었던 기억이 있다
그러나 앱에서는 코드 한 줄로 완성이라 너무 편하다 (비록 예외처리 하느라 꽤 길어졌지만...)