marmelroy / PhoneNumberKit

A Swift framework for parsing, formatting and validating international phone numbers. Inspired by Google's libphonenumber.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Issue #659 still happens on Xcode 15 and iOS 17 simulator

keremerkan opened this issue · comments

Issue #659 still happens on Xcode 15 and iOS 17 simulator. On iOS 16 simulator, PhoneNumberKit works correctly. The following comment from #659 explains the problem perfectly.

This issue happens when the library tries to get the region from the device's SIM card with the following code:

let countryCode = CNContactsUserDefaults.shared().countryCode.uppercased()

On iOS 17 Beta, it returns "001" on simulators (maybe on physical devices too) instead of the ISO country code.

Since it's just the first beta available, I would wait until the release candidate before changing something on PNK.

Originally posted by @bguidolim in #659 (comment)

Are you sure you're not using any Beta software? Xcode and iOS?

Yep. Xcode 15 release version and iOS 17 and 16 simulators that it downloaded from scratch.

Again, this happens only on iOS 17 simulator. iOS 16 simulator or iOS 17 on device works correctly.

Command line tools set on Xcode to 15 release?
Asking that because I am not able to reproduce this issue.

Correct. I am testing it with the following simple code.

let phoneNumberKit = PhoneNumberKit()
    
let phoneNumber = try? phoneNumberKit.parse("+908504801234")
    
if phoneNumber != nil {
  let internationalNumber = phoneNumberKit.format(phoneNumber!, toType: .international)
  print(internationalNumber)
}
else {
  print("Phone number nil")
}

The number is valid. I tried it in 3 different projects to see if it has something to do with the project settings. All fail on iOS 17 simulator and work correctly on 16 simulator and 17 device.

Can you check the build number of your iOS 17 simulator?
Screenshot 2023-09-30 at 14 36 21

It is exactly the same with yours. Do you use an Apple silicon or Intel Mac? Perhaps the problem comes from the architecture of the Mac. I am on a MacBook Pro with an M2 Max.

M1 Pro here.

Well, I don't really know how to proceed. Maybe add a check for the simulator, since there is not way to simulate a SIM card on it anyway.

Can you check if it works for you?

No, does not work. because somehow

        let currentLocale = Locale.current
        if let countryCode = (currentLocale as NSLocale).object(forKey: .countryCode) as? String {
            return countryCode.uppercased()
        }

Still returns "001". But if I override that with "US" for example and return that, it works correctly. So, the following works:

        #if !targetEnvironment(simulator)
        #if canImport(Contacts)
        if #available(iOS 12.0, macOS 10.13, macCatalyst 13.1, watchOS 4.0, *) {
            // macCatalyst OS bug if language is set to Korean
            // CNContactsUserDefaults.shared().countryCode will return ko instead of kr
            // Failed parsing any phone number.
            let countryCode = CNContactsUserDefaults.shared().countryCode.uppercased()
            #if targetEnvironment(macCatalyst)
                if "ko".caseInsensitiveCompare(countryCode) == .orderedSame {
                    return "KR"
                }
            #endif
            return countryCode
        }
        #endif
        
        let currentLocale = Locale.current
        if let countryCode = (currentLocale as NSLocale).object(forKey: .countryCode) as? String {
            return countryCode.uppercased()
        }
        #endif

I believe it would make much more sense to check using regex, if the country code is a two letter string instead of this hack though. If it is not a 2 letter code, returning default would be the best course of action.

countryCode is deprecated: https://developer.apple.com/documentation/foundation/nslocale/1643060-countrycode
Using regionCode now: https://developer.apple.com/documentation/foundation/nslocale/4172868-regioncode

Since the code was using object(forKey:), there was no deprecation warning.

Well, I only suggested what I got in the first pull request. :)

By the way, I looked at the latest pull request and believe that if somehow the region code returns "01" instead of "001" (could happen in a future simulator), we could encounter the same bug. Checking if its length is 2 characters would not be enough in my opinion, also making sure it is letters only would make it better future-proof.

By the way, I believe this is indeed some bug within my Xcode installation now. I am unable to launch "Settings" app on iOS 17 simulator. I'll try to reinstall it.

After reinstalling the simulator, the problem disappeared. I still cannot launch "Settings" app on iPhone 15 Pro/Pro Max though, so the simulator definitely has some bugs that need to be fixed by Apple (iPhone 15 and 15 Plus does not have that problem). In any case, your latest pull request that includes regex checks will eliminate any problems about this issue.

After trying fastlane snapshot for screenshots, the issue appeared again. Looks like fastlane is partially responsible for this bug.