말레이시아(쿠알라룸푸르) 지역에서 앱의 일정 화면에서 일정을 추가하거나 아웃룩 계정의 일정이 연동되지 않는 문제가 있었습니다.

확인해보니 일정 데이터를 서버에 요청 시, UTC가 아닌 AMZ시간으로 요청되어 시간 값이 깨져서 요청되는 것을 확인됐습니다. 이는 설정 앱에서 일반 → 날짜 및 시간에서 24시간제를 설정해서 해결할 수 있었습니다. 하지만 해결책이 있는 것과 별개로, 어떻게 하면 사용자 경험을 개선할 수 있을 지 고민했습니다.

현재 지역을 체크해서 말레이시아이면, 24시간제를 설정할 수 있도록 설정 앱으로 유도하는 팝업을 구현하면 좋겠다고 생각했습니다.

이를 위해서 다음과 같은 과정을 수행했습니다.

1. 24시간제를 설정했는지 확인

코드는 다음과 같습니다.

extension Locale {
    var isSet24HourFormat: Bool {
        let dateFormat = DateFormatter.dateFormat(fromTemplate: "j",
                                                  options: 0,
                                                  locale: .current) ?? ""
        print("dateFormat - \\(dateFormat)")
        return dateFormat.firstIndex(of: "a") == nil
    }
}

2. 설정 > 일반 > 날짜 및 시간으로 이동 구현

// ScemeDelegate 
class SceneDelegate: UIResponder, UIWindowSceneDelegate {

		{ ... }
    
    func sceneWillEnterForeground(_ scene: UIScene) {
        if !Locale.current.isSet24HourFormat {
            window?.rootViewController?.present(CustomAlert.alertController, 
                                                animated: true)
        }
    }
}

// CustomAlert
class CustomAlert {
    static var alertController: UIAlertController = {
        let alertController = UIAlertController(title: "시간 형식 변경",
                                                message: "앱을 24시간제로 사용하도록 설정하시겠습니까?",
                                                preferredStyle: .alert)
        let confirmAction = UIAlertAction(title: "예", style: .default) { _ in
            CustomAlert.openSettingsDeepLink()
        }

        let cancelAction = UIAlertAction(title: "아니오", style: .cancel)

        alertController.addAction(confirmAction)
        alertController.addAction(cancelAction)

        return alertController
    }()
    
    @objc static func openSettingsDeepLink() {
        **if let deepLinkURL = URL(string: "App-prefs:General&path=DATE_AND_TIME") {**
            if UIApplication.shared.canOpenURL(deepLinkURL) {
                UIApplication.shared.open(deepLinkURL, options: [:], completionHandler: nil)
            } else {
                print("해당 페이지를 열 수 없습니다.")
            }
        }
    }
}

하지만, 위와 같이 사용자의 디바이스의 설정 앱의 뎁스로 바로 이동시키는 "prefs:root=”와 같은 public하지 않은 API를 사용하는 것은 리젝사유라는 것을 알았습니다.