Getting full address string from CLPLacemark using Swift 4 / Xcode 9 - ios

I have previously been able to get a full address String from a CLPlacemark using the following code for Swift 3:
let addressList = placemark.addressDictionary?["FormattedAddressLines"] as? [String]
let address = addressList!.joined(separator: "\n")
addressDictionary is now deprecated in swift 4.
I could extract each of the individual CLPlacemark address variable strings (name, country postalCode, etc) but I'm wondering if there is a simpler way to do it.
I know there is a postalAddress var which is of type CNPostalAddress but not sure how to convert that to a String.

You can get mailing address from CNPostalAddress is like :
CNPostalAddressFormatter.string(from:YOUR_POSTAL_ADDRESS, style: .mailingAddress)

Related

How to determine region from the phone number string?

I tried using PhoneNumberKit and couldn't find any proper api which would give me the region name.
I need the region from the phone number so that I can display the appropriate flag. For example using this:
let phoneNumber = try phoneNumberKit.parse("+12563335956")
let regionCode = phoneNumberKit.countries(withCode: phoneNumber.countryCode)?.first
print("region code is: " , regionCode)
// US phone number with +1 prefix, but it prints "AG" which is wrong.
As you said, the country code can tell you which flag to use.
let phoneNumber = try phoneNumberKit.parse("+1 970162651778")
let regionCode = phoneNumberKit.getRegionCode(of: phoneNumber)
print(regionCode) // Optional("US")
You can get the country region code using the country code of the phone number.

Can I use iOS9 Contacts Framework to get a formatted phone number?

I would like to be able to store a phone number in a standard way, e.g. just the digits (potentially with the '+' for the country code), something like these examples...
"17185555555"
"+17185555555"
"+447788888888"
... but I'd like to be able to DISPLAY it to a user in a properly formatted way, e.g.
"1 (718) 555-5555"
"+1 (718) 555-5555"
"+44 (7788) 888888"
...WITHOUT having to rely on a CNContactViewController to format it.
Obviously doing this just for US/Canada numbers would be easy - it's just one standard format - but I'd like it to be generic so it can work for numbers from any country. I know this question gives an answer for US/Can numbers only.
I know that I could use a CNContactViewController to display the number in the correct format, e.g.
let newContact = CNMutableContact()
newContact.givenName = "John"
newContact.familyName = "Smith"
newContact.phoneNumbers = [CNLabeledValue(label: CNLabelPhoneNumberiPhone, value: CNPhoneNumber(stringValue:"17185555555"))]
let contactView = CNContactViewController(forContact: newContact)
self.presentViewController(contactView, animated: true, completion: nil)
This will show the number on screen properly formatted, i.e.
1 (718) 555-5555
... so I know that something in the framework can do it. (This approach works for other country phone number formats, as long as you prefix the number with the right country code - e.g. "+44...")
From various other questions I know that I can get the raw digits and country code out of a CNContact, e.g. (following above example)
for pNumber: CNLabeledValue in newContact.phoneNumbers {
let value = pNumber.value as! CNPhoneNumber
let cc = value.valueForKey("countryCode") as? String
let digits = value.valueForKey("digits") as? String
print("cc:" + cc + ", " + digits)
}
... but this will just show the unformatted string again - not what I am looking for in this case.
Any help or other recommended approaches really appreciated!
My answer proposes another lib
You can format your numbers with this lib.
And you can use like this:
let phoneNumber: NBPhoneNumber = try phoneUtil.parse("17185555555", defaultRegion: yourRegion)
let formattedString: String = try phoneUtil.format(phoneNumber, numberFormat: .E164)

Create a string separated with new lines (\n) from an Array using Swift [duplicate]

This question already has answers here:
Cannot invoke `join` with an argument list of type (String, [String]) in Swift 2.0
(2 answers)
Closed 6 years ago.
I am facing a problem during the development of my iOS application, what I am trying to achieve is to create a single string from an array of strings. The array contains the address of a given location, obtained from a reverse geocoding using CLGeocoder, this is the code that gives me the array of strings:
let userCoordinates = CLLocation(latitude: mapView.userLocation.location!.coordinate.latitude, longitude: mapView.userLocation.location!.coordinate.longitude)
CLGeocoder().reverseGeocodeLocation(userCoordinates, completionHandler: {
placemark, error in
let reverseGeocodedLocation = placemark?.first?.addressDictionary?["FormattedAddressLines"] as? [String]
}
reverseGeocodedLocation in my case is:
["Apple Inc.", "Cupertino, CA 95014", "United States"]
The result string should separate the strings in the array and present them in a multi-line format like this:
Apple Inc.
Cupertino, CA 95014
United States
I have tried searching on the web for a solution and I found this code that should do that, and this could be the solution:
print("\n".join(reverseGeocodedLocation.map({$0})))
But the compiler says:
Cannot invoke 'join' with an argument list of type '([String]?)'
if let reverseGeocodedLocation = reverseGeocodedLocation {
print(reverseGeocodedLocation.joinWithSeparator("\n"))
}
As an answer instead of a comment.
Swift 3/4:
reverseGeocodedLocation.joined(separator: "\n")

Access Users Contacts Phone Numbers CNContacts

I am trying to get to phone numbers of my contacts using CNContact, i want to have the number as a simple string of its didgits such as "04xxxxxxxx" but the closest I can get to is the following. ("contact" is of type CNContact)
contact.phoneNumbers[0].value
\\Which prints: <CNPhoneNumber: 0x13560a550: countryCode=au, digits=04xxxxxxxx>
ive tried all the obvious things and not so obvious things, thanks
If anyone has a more legitimate solution please do post it, otherwise this rather hacky approach works:
let value = String(contact.phoneNumbers[0].value)
let start = value.rangeOfString("digits=")!.endIndex
let end = value.endIndex.predecessor()
let number = value.substringWithRange(Range<String.Index>(start: start, end: end))
Using this category you can now access the phone number via swift.
don't forget to include this file in the bridging header
#implementation CNPhoneNumber (SwiftSupport)
- (NSString*)toString {
return self.stringValue;
}
#end
Fetch the number value as follows:
let number = value.valueForKey("digits") as! String
From iOS9:
let number = value.stringValue
According to Apple's documentation on CNPhoneNumber:
stringValue
Property
The string value of the phone number. (read-only)
Declaration
SWIFT
var stringValue: String { get }

How to get detailed language of device in swift

I have a database on the server that contains all the languages keywords that I use inside my applications and these languages could be changed any time.
In the language table of database there is column for Language (id , key, value, lang).
In the android application I read the language from device and it returns for example en-GB or en-US.
But in the iOS application I can't get the language like the above example , It always returns just the language (en , es, fr).
So I can't query to database to get the language specified keywords on the iOS application. Because the languages on the database is en-GB, en-US style.
var langId: String? = NSLocale.preferredLanguages().first as? String
How can I get the language with more details ?
Start with the currentLocale() and ask questions about it. For example:
let lang = NSLocale.currentLocale().localeIdentifier
Or, at a finer level of granularity:
let langId = NSLocale.currentLocale().objectForKey(NSLocaleLanguageCode) as! String
let countryId = NSLocale.currentLocale().objectForKey(NSLocaleCountryCode) as! String
let language = "\(langId)-\(countryId)" // en-US on my machine
Swift 3 does not have an NSLocaleCountryCode, this is replaced by regionCode
https://developer.apple.com/reference/foundation/nslocale.key/1417845-countrycode
solution in Swift 5:
let langCode = Locale.current.languageCode ?? ""
let regionCode = Locale.current.regionCode ?? ""
let language = "\(langCode)-\(regionCode)"
Another solution is NSLocale.current.identifier
This will return e.g. en_us
You could replace _ for -. it will look like this: NSLocale.current.identifier.replacingOccurrences(of: "_", with: "-")
No need an extra effort, just use the following as per your requirement.
Locale.current.identifier //en_US
Locale.current.collatorIdentifier //en-US
For Swift 4 use instead:
NSLocale.current.identifier //Output: en-US, pt-BR
Swift 5
Locale.currentLanguage.rawValue
just use this code line can solve:
let identifier = Locale.current.identifier

Resources