진행과정
https://yjuni22.tistory.com/57
https://yjuni22.tistory.com/58
과제 외 추가 구현 내용
1. 상세 페이지의 GuideLabel 생성
2. 텍스트 필드로 구현
3. 포켓API 에서 다른 이미지로 받아오기
4. 전화번호 입력 시 hypen 자동생성 구현
5. 전화번호 텍스트필드 11자리까지만 입력 허용
6. 새로운 정보 추가 시 입력된 데이터가 없다면 알럿창 띄우기 ( 전화번호 9자리 이하 시 알럿창 )
7. 삭제기능, 정보가 있을 시 (셀클릭시) 삭제버튼 생성, 더블체크를 위한 알럿창 띄우기
8. 텍스트 필드 키보드 관련 ( 외부 터치 시 키보드 내리기, 전화번호 - 넘버패드 적용 )
9. preparForReuse 개념 이해
트러블 슈팅
네트워킹 코드 옮기기
기존 PhoneBookViewController에 구현되어 있는 Get메서드 분리
@objc func randomButtonTapped(_ sender: UIButton) {
fetchPoketmonData()
}
// 서버에서 포켓몬 데이터를 받아오는 메서드
private func fetchPoketmonData() {
let randomNum = Int.random(in: 1...1000)
let url = URL(string: "\(requestUrl)\(randomNum)")
guard let urlString = url else {
print("잘못된 URL")
return
}
networkManager.fetchDateByAlamofire(url: urlString) { [weak self] (result: Result<PoketmonData, AFError>) in
guard let self else { return }
switch result {
case .success(let result):
guard let imageUrl = URL(string: result.sprites.other.home.imageUrl) else { return }
// Alamofire 를 사용한 이미지 로드
AF.request(imageUrl).responseData { response in
if let data = response.data, let image = UIImage(data: data) {
DispatchQueue.main.async {
self.phoneBookView.randomImageView.image = image
}
}
}
case .failure(let error):
print("데이터 로드 실패: \(error)")
}
}
}
현재 PhoneBookViewController에 get 메서드가 구현되어 있다.
fetchPoketmonDate() 를 파일 분리를 위해 네트워크매니저 파일로 이동하고 싶은데
어떻게 수정하여 넣어야 할 지 감이 오지 않았다.
클로저를 사용하여 일부 수정을 해야할 것 같은데
아직 미숙한 부분이라 고민을 해보다가
튜터님에게 도움을 요청했다.
현재 뷰컨트롤러 내에서 데이터요청과 결과를 처리하고 있다.
네트워크 매니저로 이동 시 외부에서 접근하여 메서드를 실행시키기 때문에
결과를 어딘가에 반환시켜야 그 결과를 처리할 수 있게 된다.
그렇기 때문에 결과를 반환시켜줄 클로저를 구현해주어야 한다.
수정된 코드
네트워크 매니저 파일
// Alamofire 를 사용해서 서버 데이터를 불러오는 메서드
func fetchDateByAlamofire<T: Decodable>(url: URL, completion: @escaping (Result<T, AFError>) -> Void) {
AF.request(url).responseDecodable(of: T.self) { response in
completion(response.result)
}
}
// 서버에서 포켓몬 데이터를 받아오는 메서드
func fetchPoketmonData(completion: @escaping (Result<PoketmonData,AFError>) -> Void) {
let randomNum = Int.random(in: 1...1000)
let url = URL(string: "\(requestUrl)\(randomNum)")
guard let urlString = url else {
print("잘못된 URL")
return
}
fetchDateByAlamofire(url: urlString) { [weak self] (result: Result<PoketmonData, AFError>) in
completion(result)
}
}
수정된 메서드를 보면 (completion: @escaping (Result<PoketmonData,AFError>) 을 추가 구현하여
넘겨줄 결과를 클로저에 담아주고 있다.
PhoneBookViewController : 실제 사용 메서드 ( 랜덤이미지 생성 버튼 )
// MARK: - API 랜덤 이미지 받아오기
@objc func randomButtonTapped(_ sender: UIButton) {
networkManager.fetchPoketmonData { [weak self] result in
guard let self else { return }
switch result {
case .success(let result):
guard let imageUrl = URL(string: result.sprites.other.home.imageUrl) else { return }
// Alamofire 를 사용한 이미지 로드
AF.request(imageUrl).responseData { response in
if let data = response.data, let image = UIImage(data: data) {
DispatchQueue.main.async {
self.phoneBookView.randomImageView.image = image
}
}
}
case .failure(let error):
print("데이터 로드 실패: \(error)")
}
}
}
버튼에서 fetchPoketmonData를 실행하면 결과를 클로저로 호출부에 반환시킨다.
반환된 클로저를 { } 안에 result 를 성공, 실패 처리하여 이미지를 로드한다.
아직 클로저와 네트워킹에 대한 이해가 부족하여 조금 어려운 부분인 것 같다.
더 자세하게 공부해보아야 할 것 같다.
전화번호 텍스트필드 관련
phoneNumberTextField 의 count를 11자 초과시 입력이 안되게 해놓으니
저장된 데이터 클릭시 하이픈 때문에 13자가 나와 숫자를 지우면 총 12자리가 되어 수정이 안되는 상황
해결방법 : 코어데이터에 저장된 정보를 불러올 때 hypen이 제거된 상태로 나오도록 수정
과정:
텍스트 필드 관련 코드
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
// 백스페이스 허용 코드
if string.isEmpty {
return true
}
if textField == phoneBookView.nameTextField {
return Int(string) == nil // 이름 필드에 숫자 입력 안되게
} else if textField == phoneBookView.phoneNumberTextField {
// 11글자 넘어가면 입력을 막는 코드
if (textField.text?.count)! + string.count > 11 {
return false
}
return Int(string) != nil // 전화번호 필드에 문자 입력 안되게
}
return true
}
}
// MARK: - 휴대폰 번호 하이픈 추가
extension String {
public var withHypen: String {
var stringWithHypen: String = self
guard self.count == 10 || self.count == 11 else { return self } // 10자리나 11자리만 처리
stringWithHypen.insert("-", at: stringWithHypen.index(stringWithHypen.startIndex, offsetBy: 3))
stringWithHypen.insert("-", at: stringWithHypen.index(stringWithHypen.endIndex, offsetBy: -4))
return stringWithHypen
}
}
전화번호 텍스트 필드에 11자리가 넘어갈 시 입력을 허용하지 않도록 하는 코드를 구현하고
10자리나 11자리일 시 하이픈을 추가하여 코어데이터에 저장되도록 하였다
문제상황 및 고민 :
'-' 을 포함하여 텍스트필드의 count가 세져서 더이상 입력이 되지 않았다.
저장된 정보를 받아올 때 '-' 뺀 전화번호로 가져오기
/// 하이픈 제거 메서드
public var withoutHyphen: String {
return self.replacingOccurrences(of: "-", with: "")
}
extension String 에 하이픈 제거 메서드를 추가 구현하여
저장된 정보를 수정할 때에는 하이픈이 제거된 상태로 불러오도록 구현하여 문제를 해결하였다.
@objc func applyButtonTapped() {
//적용버튼 눌렀을 때
let name = phoneBookView.nameTextField.text
let phone = phoneBookView.phoneNumberTextField.text?.withHypen
let image = phoneBookView.randomImageView.image
if (name?.count != 0) && (phone!.count > 9) && image != nil {
// 이미지의 경우 JPEG로 변환하여 코어데이터에 저장 후 pop
let imageData = image?.jpegData(compressionQuality: 0.5)
coreDataManager.saveMemberData(name: name, phone: phone, image: imageData) {
print("저장 완료")
self.navigationController?.popViewController(animated: true)
}
} else {
let alert = UIAlertController(title: "적용 실패", message: "올바른 정보를 입력해주세요!", preferredStyle: .alert)
let succes = UIAlertAction(title: "확인", style: .default)
alert.addAction(succes)
present(alert, animated: true)
}
}
추가적으로 생성시와 수정시 정보가 입력되어있지 않거나, 숫자가 9자리 이하거나,
이미지가 없으면 적용되지 않도록 알럿창을 띄우게 구현하였다.
PrepareForReuse
// 셀이 재사용되기 전에 호출되는 메서드
override func prepareForReuse() {
super.prepareForReuse()
// 이미지가 바뀌는 것처럼 보이는 현상을 없애기 위함
self.mainImageView.image = nil
}
셀은 스크롤 할때 가장 위의 셀이 맨 아래로 재사용된다.
그때 셀이 재사용 되는 속도보다 이미지가 늦게 사라져 일어날 수 있는 오류를 방지하기 위해
셀이 재사용 되기 전에 다음과 같은 코드를 추가구현해주어야 한다.
View를 다시 사용할 수 있도록 준비하는 데 필요한 초기화(clean-up)를(을) 수행합니다.
참고자료)
https://ios-daniel-yang.tistory.com/entry/UITextField
https://green1229.tistory.com/269
'내일배움캠프 iOS' 카테고리의 다른 글
UIKit) TIL # 40 팀 프로젝트 발제 - 영화상영정보 앱 (1) | 2024.12.13 |
---|---|
UIKit) TIL # 39 포켓몬 연락처 앱 과제 - URLSession 으로 수정해보기 (0) | 2024.12.12 |
UIKit) TIL # 36 포켓몬 연락처 앱 과제 (Lv 1 ~ 4) (1) | 2024.12.09 |
UIKit) TIL # 35 날씨앱 클론, 과제 맛보기 (0) | 2024.12.06 |
UIKit) TIL # 34 CRUD (CoreData , Networking) (2) | 2024.12.05 |