/ios-web-browser

사용자가 요청한 페이지를 표시해주는 웹 브라우저 앱

Primary LanguageSwift

웹 브라우저

Webkit을 사용한 웹 브라우저 앱

default dynamicType


목차


프로젝트 정보

  • 코드 리뷰어: yagom
  • 학습 키워드: Webkit, TextField, UIResponder, UIAlertController, ATS

앱 구현 과정 및 트러블 슈팅

UI 및 기능 구현

주소창 이동 및 로딩 시 인디케이터 표시 당겨서 새로고침 이전, 다음 페이지 이동 및 새로고침
주소창이동 당겨서 새로고침 이전, 다음 페이지 이동 및 새로고침
주소창에 주소 입력 후 해당 페이지로 이동
페이지가 로드 중일 때 인디케이터 표시
웹 뷰를 아래로 당겨서 새로고침 이전, 다음 페이지로 이동 및 새로고침

해당 부분에서 했던 고민점들

문제
다른 유효한 주소는 접속이 가능한데, 네이버는 접속이 안되는 이유는 무엇일까?

네이버는 https로 연결됨에도 불구하고 ATS를 해제하지 않으면 페이지에 연결이 되지않는 문제가 있었습니다. 아직 특별한 이유를 찾지 못했는데, 네이버 측의 문제가 아닐까 생각됩니다. 그래서 네이버에 접속하기 위해 ATS 를 해제해줘야했는데, 전체를 다 해제하는 것은 권장되지 않으므로, 네이버만 HTTP 접속에 대해 허용하도록 추가했습니다. (ATS 정리)


고민
사용자에게 Activity Indicator를 나타내주는 이유는 무엇일까?

Human Interface Guideline에 의하면 Activity Indicator는 복잡한 데이터를 로드하거나 동기화하는 등 정량화할 수 없는 작업을 사용자에게 알려주는 역할을 한다고 명시되어 있습니다. Activity Indicator가 없으면, 사용자가 현재 페이지가 로드가 되고 있는 것인지, 프로세스가 멈춘 것인지 확인하기 어렵습니다. 그렇기 때문에 프로세스가 진행 중이라면 Indicator가 계속 회전함으로써 프로세스 진행을 알리는 것이 필요합니다.


문제 현상
당겨서 새로고침 시, UIActivityIndicatorView가 두 번 표시되는 현상 인디케이터 중복

기존에 UIRefreshControl을 구현한 뒤, 새로고침 했을 때, 다음과 같이 Activity Indicator를 두 번 표시하는 현상이 있었습니다. 그 원인은

func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) {...}

위 메소드에서 UIActivityIndicatorView가 애니메이션되도록 구현했기 때문입니다. 즉, UIRefreshControl과 연결된 targetAction 로직에 의해 새로 페이지가 로드되면서 위 메서드를 다시 호출했기 때문에 이와 같은 현상이 일어난 것입니다. 해결을 위해 UIRefreshControl이 동작 유무를 알 수 있는 isRefreshing 프로퍼티를 통해 확인하는 방법으로 구현했습니다. 만약 UIRefreshControl가 동작하고 있다면 해당 메서드를 리턴하고, 아니면 UIActivityIndicatorView가 동작하도록 했습니다.

func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) {
	if webView.scrollView.refreshControl?.isRefreshing == true {
		return
	}

	loadingIndicator.startAnimating()
}

👆 목차로 돌아가기


주소 자동 변경

현재 페이지 주소 표시
주소 자동 변경
이동한 페이지의 주소 및 경로 표시

👆 목차로 돌아가기


국제화

영어(기본) 한국어 일본어
영어 한국어 일본어
플레이스홀더 및 경고창 등 영어로 표기 플레이스홀더 및 경고창 등 한국어로 표기 플레이스홀더 및 경고창 등 일본어로 표기

해당 부분에서 했던 고민점들

고민
기존에 사용하던 문자열 코드를 모두 NSLocalizedString(_:comment:)로 변경해야 할까?

String을 연산 프로퍼티로 확장하여 사용할 수 있습니다.

extension String 
    var localized: String {
        return NSLocalizedString(self, comment: "")
    }
}

결국 이렇게 해도 기존의 문자열에 모두 적용해줘야 합니다. 하지만 기존 문자열 리터럴을 NSLocalizedString(_:comment:) 로 변경하는 것보다, 끝에 프로퍼티를 추가하는 방식이 확장성도 좋고 더 쉽게 접근할 수 있어서 더 편리한 방법이라고 생각합니다. 해당 프로젝트에서는 포맷을 적용하지 않았지만, 포맷이 필요한 경우는 String(format:)을 적용할 수 있습니다.

extension String {
    func localized(comment: String = "") -> String {
        return NSLocalizedString(self, comment: comment)
    }
    
    func localized(with argument: CVarArg = [], comment: String = "") -> String {
        return String(format: self.localized(comment: comment), argument)
    }
}

let uploadTime = "%d seconds ago" // "5 seconds ago"
let uploadTimeForKorean = "%d seconds ago".localized(with: 5) // "5분 전"

👆 목차로 돌아가기


접근성 적용

다이나믹 타입 적용 Accessibility Label 적용
dynamic type 적용 accessibility label 적용
다이나믹 타입 적용에 의한 텍스트 및 버튼 크기 증가 추후 VoiceOver 구현을 위한 Accessibility Label 설정

해당 부분에서 했던 고민점들

고민
접근성을 적용할 때, 주소창과 검색 버튼을 어떤 방식으로 구현하는 것이 좋을까?

간단하게 UITextField와 UIButton을 UIStackView로 묶어서 구현했었습니다. 그러다 접근성 지원을 생각하던 중, WWDC17 Design For Everyone 영상에서 iOS 11부터 내비게이션 바 또는 탭 바처럼 내부의 아이템의 레이아웃을 개발자 임의로 변경할 수 없는 것들에 대해 특별한 UI를 구현해놨다는 것을 봤습니다. 그래서 만약 사용자가 더 큰 텍스트 사이즈 옵션에서 접근성 사이즈를 사용하고 있다면, 내비게이션 바 또는 탭 바의 버튼을 길게 눌렀을 때 아래 이미지처럼 해당 버튼이 확대되어, 어떤 버튼인지 더 쉽게 알 수 있도록 하는 것이 좋다고 생각했습니다.

accessibility type for english accessibility type for korean accessibility type for japanese


문제
텍스트 필드가 내비게이션 바 내부에 포함된 경우에는 어떻게 동적으로 크기를 조절할 수 있을까?

내비게이션 바 또는 탭 바에서는 오토 레이아웃을 통해 해당 레이아웃을 조절할 수 없게 설정되어있었습니다. 그래서 다이나믹 타입을 적용했을 때 주소창 UI가 깨지는 현상이 발생했습니다. 그래서 뷰가 서브뷰의 레이아웃을 변경하기 직전에 호출되는 viewWillLayoutSubviews()에서 주소창의 frame을 변경해주는 작업으로 문제를 해결했습니다.

private func adjustTextFieldLayout() {
	var frame: CGRect = urlTextField.frame
	frame.size.width = view.frame.width
	urlTextField.frame = frame
}
        
// ....
        
override func viewWillLayoutSubviews() {
	super.viewWillLayoutSubviews()
	adjustTextFieldLayout()
}

👆 목차로 돌아가기