Can Locale identify country by currency code? - ios

I was looking for that answer in here, and also on official documentation, but I can't find the answer for that. I've got currency codes (e.g. "EUR"). I need to get country code (e.g "EU"). So I've seen that I can do it inversely (getting currency code by using country code), but I was trying to change this solution for my needs, and I got nil as result. Also I know I can use simple solution - remove last letter from currency code to get country code (It works for most cases from my API data, but not everywhere) - but I feel this approach is not safe. So my question is like in title: Can I identify country from currency code by using Locale?
Here is my approach:
with NSLocale
extension NSLocale {
static func currencySymbolFromCode(code: String) -> String? {
let localeIdentifier = NSLocale.localeIdentifier(fromComponents: [NSLocale.Key.currencyCode.rawValue : code])
let locale = NSLocale(localeIdentifier: localeIdentifier)
return locale.object(forKey: NSLocale.Key.countryCode) as? String
}
}
with Locale
extension Locale {
static let countryCode: [String: String] = Locale.isoCurrencyCodes.reduce(into: [:]) {
let locale = Locale(identifier: Locale.identifier(fromComponents: [NSLocale.Key.currencyCode.rawValue: $1]))
$0[$1] = (locale.regionCode)
}
}

A currency can be associated with multiple countries, you should create your own custom data implementation, such as following json
{
"EUR":"PL",
"USD":"CA"
}
Create a file in your Xcode project and name it for e.g. data.json, and paste such JSON as above, finally use following method
func getCountryCode(currency: String) -> String? {
var countryCode: String?
let url = Bundle.main.url(forResource: "data", withExtension: "json")!
do {
let data = try Data(contentsOf: url)
let json = try JSONSerialization.jsonObject(with: data, options: .allowFragments) as? [String: String]
countryCode = json?[currency]
} catch {
print(error.localizedDescription)
}
return countryCode
}
Usage
if let countryCode = getCountryCode(currency: "EUR") {
print(countryCode)
}

The answer from #AamirR is a bit not accurate.
EUR != PL, PL = PLN = Poland
USD != CA, CA = CAD = Canada
In majority of cases (with some exceptions), first 2 letters of currency code = ISO 3166-2 country code:
PLN = PL = Poland
GBP = GB = Great Britain
USD = US = United States of America
AMD = AM = Armenia
CZK = CZ = Czech Republic
BRL = BR = Brazilia
and so on ...
So if you have currency codes you can get country names (with 99% accuracy) as follows:
let currencyCode = "USD"
let countryCode = String(currencyCode.prefix(2))
let countryName = Locale.current.localizedString(forRegionCode: countryCode)
print(countryName)
Optional("United States")
However, as some commented above, EU for example, is not a country, and looks like in your specific case you do not need a country flag, you need "currency flag", so for EUR you will display EU flag, which is correct, as you cant determine which EU country flag to display - France, Germany, etc ... so this approach might work for mapping currencies to countries flags.
Though there are some exceptions, in terms of first 2 letters of currency code not matching first 2 letters of country name, from ISO 3166-2 country code perspective, they still match:
CHF = CH = Switzerland
HRK = HR = Croatia
DKK = DK = Denmark
... and so on
The other interesting pattern is that first 2 letters of currency codes, would usually match country internet domain, but again, there are some exceptions from this too.

Related

Using Currency in Swift

I am trying to create a function in Swift that accepts an integer as a param and returns a double in the locale currency e.g:
input : 1250
output : £12.50
input: 12500
output: £125.00
I noticed there is a third party library that supports this but unfortunately the repo is archived. The type of units used is the smallest type of currency which is minorUnits.
Network Call
/// GET - Retrive a feed of transactions during a certain period
static func get(accountUID: String, categoryUID: String, queryStartDate: String, queryEndDate: String , completionHandler: #escaping ([FeedItem], Error?) -> Void) {
let sessionObject : URLSession = URLSession.shared
let taskObject = sessionObject.dataTask(with: URLS().feedURLObject(accountUID,categoryUID,queryStartDate,queryEndDate)) { (Data, Response, Error) in
guard Error == nil else {
return
}
guard let Data = Data else {
return
}
do {
let feed = try JSONDecoder().decode(Feed.self, from: Data).feedItems.filter({ (item) -> Bool in
item.direction == Direction.out
})
completionHandler(feed, nil)
} catch let error {
print(error.localizedDescription)
}
}
taskObject.resume()
}
Model Feed Struct Amount
struct Amount: Codable {
let currency: Currency
let minorUnits: Int}
Single Item JSON response
FeedItem(feedItemUid: "0651afe9-f568-4623-ad26-31974e26015c", categoryUid: "a68f9445-4d59-44e5-9c3f-dce2df0f53d2", amount: Banking_App.Amount(currency: Banking_App.Currency.gbp, minorUnits: 551), sourceAmount: Banking_App.Amount(currency: Banking_App.Currency.gbp, minorUnits: 551), direction: Banking_App.Direction.out, updatedAt: "2020-02-04T14:09:49.072Z", transactionTime: "2020-02-04T14:09:48.743Z", settlementTime: "2020-02-04T14:09:48.992Z", source: Banking_App.Source.fasterPaymentsOut, status: Banking_App.Status.settled, counterPartyType: Banking_App.CounterPartyType.payee, counterPartyUid: Optional("fed4d40b-9ccc-411d-81c7-870164876d04"), counterPartyName: Banking_App.CounterPartyName.mickeyMouse, counterPartySubEntityUid: Optional("d6d444c0-942f-4f85-b076-d30c2f745a6f"), counterPartySubEntityName: Banking_App.CounterPartySubEntityName.ukAccount, counterPartySubEntityIdentifier: "204514", counterPartySubEntitySubIdentifier: "00000825", reference: Banking_App.Reference.externalPayment, country: Banking_App.Country.gb, spendingCategory: Banking_App.SpendingCategory.payments)
Thanks
Currency codes are defined in the standard ISO 4217 and as part of the standard is the number of decimal digits used for each currency and since swift's NumberFormatter has a style for this ISO standard we can use it for this case.
Create an instance and set the style
let currencyFormatter = NumberFormatter()
currencyFormatter.numberStyle = .currencyISOCode
Set the currency code
currencyFormatter.currencyCode = "SEK"
Now currencyFormatter.minimumFractionDigit and currencyFormatter.maximumFractionDigits will both contain the number of decimals define for the given currency
So now we can put this together in a function for instance
func convertMinorUnits(_ units: Int, currencyCode: String) -> Decimal {
let currencyFormatter = NumberFormatter()
currencyFormatter.numberStyle = .currencyISOCode
currencyFormatter.currencyCode = currencyCode.uppercased()
return Decimal(units) / pow(10, currencyFormatter.minimumFractionDigits)
}
example
print(convertMinorUnits(551, currencyCode: "GBP")
5.51
Currency should never be represented using floating point types like double. The short reason is that floats are base 2 numbers and using them to represent base 10 numbers will lead to rounding errors.
The correct data type for currencies to use is INCurrencyAmount or something like it. It's properties are NSDecimalNumber for the amount and a NSString to represent the currency.
Instead of NSDecimalNumber you can use the Swift type Decimal. It also has common math operators defined like +, *, etc..
As the others rightly pointed out, decimal numbers should be used for any numbers representing amounts of money. The website 0.30000000000000004.com nicely explains it.
When it comes to converting the integer values in pennies or cents to values in pounds or dollars, you need to know the multiplicator, i.e. how many fractional currency units are there in the main currency unit (e.g. 1 GBP = 100 pennies and the multiplicator is 100 in this case). For most of the world currencies it's 100, but there are currencies which have 1000 or even don't have any fractional units (see Wikipedia).
You usually get the multiplicator from the API but if it doesn't provide it, you might store a dictionary of known currencies and their multiplicators in your app, but then it becomes your responsibility to keep it up to date.
In order to avoid dividing your amount by the multiplicator, I'd suggest to calculate the exponent and the initialize the decimal number like this:
let amountInCents = 55123
let multiplicator = 100
let exponent = -1 * Int(log10(Double(multiplicator)))
let sign: FloatingPointSign = amountInCents < 0 ? .minus : .plus
let decimalAmount = Decimal(sign: sign, exponent: exponent, significand: Decimal(amountInCents))
Then if you need to format your decimal number in order to display it in the UI, you want to use the number formatter to which you need to pass an appropriate locale:
let formatter = NumberFormatter()
formatter.locale = Locale(identifier: "en_GB")
formatter.numberStyle = .currency
let formattedAmount = formatter.string(from: NSDecimalNumber(decimal: decimalAmount)) ?? decimalAmount.description
print(formattedAmount) // prints "£551.23"

iOS: Use CNPostalAddressFormatter to show contact addresses with proper delimiter (e.g., comma) between sections

The Apple documentation suggests using CNPostalAddressFormatter to display addresses as a formatted string, which helps immensely with internationalization.
This code:
let postalString = CNPostalAddressFormatter.string(from: postalAddress.value, style: .mailingAddress)
yields this work address for the John Appleseed contact on the simulator:
3494 Kuhl Avenue
Atlanta GA 30303
The address is missing the comma between city and state.
Is there a way for CNPostalAddressFormatter to insert the comma? The documentation doesn't list anything.
If not, doesn't this mean you must manually format addresses for each locality, and are unable to use CNPostalAddressFormatter for localization?
Here is my snippet to add "," after city for US addresses.
#if canImport(Contacts)
import Contacts
public extension CLPlacemark {
/// Get a formatted address.
var formattedAddress: String? {
guard let postalAddress = postalAddress else {
return nil
}
let updatedPostalAddress: CNPostalAddress
if postalAddress.isoCountryCode == "US" {
// add "," after city name
let mutablePostalAddress = postalAddress.mutableCopy() as! CNMutablePostalAddress
mutablePostalAddress.city += ","
updatedPostalAddress = mutablePostalAddress
} else {
updatedPostalAddress = postalAddress
}
return CNPostalAddressFormatter.string(from: updatedPostalAddress, style: .mailingAddress)
}
}
#endif

How to give users in iOS the choice to choose their own currency

I have an iOS app that keeps getting feedback from the users that they would like the ability to set their own currency type. Right now I'm using the currencyFormatter.locale to get the user local currency and use that for the app. My thought is that I might be able to create a tableView in the settings section of the app and let the users pick the currency they want to use.
I would save there desired currency and then use that instead of the locale one being displayed now.
To make this work what data would I need to pull? Would this data be supplied by Apple? I think I would need currency codes but would this be the correct data to display for the user to choose from?
I found this repo and it seems like this is something that would be useful, but it doesn't seem to be supported/updated anymore.
I just need some help being pointed in the correct direction for this, as my research isn't making any progress for me.
Money
EDIT
I found an app that I think is doing something similar to what I would like to implement.
You're right, you should make a list screen and let the users choose their desired currency from that. Save that currency and use it instead of the locale. You can use this code to get a list of currency names and currency symbols.
NSLocale *locale = [NSLocale currentLocale];
NSArray *currencyCodesArray = [NSLocale ISOCurrencyCodes];
NSMutableDictionary *currenciesDict = [NSMutableDictionary new];
for (NSString *currencyCode in currencyCodesArray) {
NSString *currencyName = [locale displayNameForKey:NSLocaleCurrencyCode value:currencyCode];
NSString *currencySymbol = [locale displayNameForKey:NSLocaleCurrencySymbol value:currencyCode];
if (currencyName != nil && currencySymbol != nil) {
[currenciesDict setValue:currencySymbol forKey:currencyName];
}
}
return currenciesDict;
Edit
Here's the same code in swift.
let locale = NSLocale.current as NSLocale
let currencyCodesArray = NSLocale.isoCurrencyCodes
var currenciesDict = [String: String]()
for currencyCode in currencyCodesArray {
let currencyName = locale.displayName(forKey: NSLocale.Key.currencyCode, value : currencyCode)
let currencySymbol = locale.displayName(forKey: NSLocale.Key.currencySymbol, value : currencyCode)
if let currencySymbol = currencySymbol, let currencyName = currencyName {
currenciesDict[currencySymbol] = currencyName
}
}
print(currenciesDict)
Edit 2
Same code with custom model.
This is how your custom model will look like.
class CurrencyModel {
var currencyName = ""
var currencyCode = ""
}
And this is how the code will look like.
let locale = NSLocale.current as NSLocale
let currencyCodesArray = NSLocale.isoCurrencyCodes
var currencies = [CurrencyModel]()
for currencyCode in currencyCodesArray {
let currencyName = locale.displayName(forKey:
NSLocale.Key.currencyCode, value : currencyCode)
let currencySymbol = locale.displayName(forKey:NSLocale.Key.currencySymbol, value : currencyCode)
if let currencySymbol = currencySymbol, let currencyName = currencyName {
let currencyModel = CurrencyModel()
currencyModel.currencyName = currencyName
currencyModel.currencyCode = currencyCode
currencies.append(currencyModel)
}
}
print(currencies)
You should set the currencySymbol of the formatter instead:
let currencyFormatter = NumberFormatter()
currencyFormatter.numberStyle = .currency
currencyFormatter.currencySymbol = "¥"
currencyFormatter.string(from: 123) // "¥123.00"
You can provide the user with a UITextField to let them enter any arbitrary string as the currency symbol.
If you want the user to choose a locale from a list and use that locale's currency symbol, the currencySymbol property of a Locale instance can also be used.
Clarification on locales and currencies:
Currencies and locales don't have a one-to-one correspondence. One currency can be used in multiple locales, but one locale usually has one corresponding currency, as there is a currencySymbol in Locale. And locale is used to decide where the currency symbol is. In France, for example, the currency symbol would be placed at the end. This means that if you just have a currency symbol, there is no "right" place for it in a string, because you have not specified a locale. So if you want the currency symbol to be at the user's expected place, ask the user for the locale they desire, and not the currency symbol. If you don't care whether the currency symbol is displayed at the user's expected place, then display it with the user's current locale.

Decoding JSON in Swift

I am fetching JSON data from my server. I am using Alamofire in my code to fetch data from server.
Here's how I am decoding it:
Alamofire.request(URL_GET_DATA, method: .post).responseJSON { response in
//getting json
if let json = response.result.value {
print(json)
let newsJson : NSArray = json as! NSArray
self.parseData(data: ((newsJson[0] as AnyObject).value(forKey: "message") as? String)!)
}
}
func parseData(data : String){
//traversing through all elements of the array
let newsArray: NSArray = data as! NSArray
for i in 0..<newsArray.count{
//adding hero values to the hero list
self.newsList.append(Objectnews(
id : (newsArray[i] as AnyObject).value(forKey: "id") as? String,
heading: (newsArray[i] as AnyObject).value(forKey: "heading") as? String,
description : (newsArray[i] as AnyObject).value(forKey: "description") as? String,
time_stamp : (newsArray[i] as AnyObject).value(forKey: "time_stamp") as? String,
type : (newsArray[i] as AnyObject).value(forKey: "type") as? String,
imageurl: (newsArray[i] as AnyObject).value(forKey: "imageurl") as? String
))
}
print("reloading table")
//displaying data in tableview
self.tableView.reloadData()
}
Here's the log for same. It contains the response from server and the error it is throwing:
{
error = 0;
message = (
{
description = "September 5th marks Teacher\U2019s Day in India. It is celebrated on the birthday of our second President, Sarvepalli Radhakrishnan. It is a day when we pay respect to our teachers and appreciate their contribution to the society and our individual lives and plan special surprises, have a chance to thank them for their selfless work in making the leaders for tomorrow. N.S.S. unit celebrated Teacher's day by gifting a hand made card to each Teaching and Non-Teaching Staff of P.G.D.A.V. College. We will also like to put forward a special thanks to the creative department team of N.S.S. for their terrific job in making those beautiful hand made cards. Happy Teachers' Day to All!";
heading = "Teacher's Day Celebration";
id = 16;
imageurl = "http://check.png";
"time_stamp" = "05/09/2017 22:58";
type = News;
},
{
description = "Incessant rains and floods have brought a havoc in one of India's most populous state, Bihar due to which roads have been closed, houses destroyed and crores affected. Rahat - an initiative of Goonj NGO steps in such situations helping all those in need and this time NSS PGDAV is doing their share of help by donating Via GOONJ and is organising a Collection Drive for the flood survivors. Your donation will provide shelter, food and comfort to families. Below are some of the things you can donate to help the people:-\n\n-Tarpaulins\n-Old flex and ropes\n-Mosquito nets\n-Dry ration\n-Clothing\n-Good quality blankets \n-Wooden toiletries\n-Utensils \n-Bucket\n-Torch and batteries\n-Umbrella\n-Slippers\n-Candles\n-Solar lights etc\n\nGiving is not just about making a donation. It's about making a difference! So step forward and #DONATE.\n\nDate: 4th-9th September 2017.\nVenue- Lobby/Office Area.\nTime: 10AM-1PM.\n\nFor queries contact:\nEkta- 7503894368\nJhanvi- 7838401571";
heading = "Collection Drive for Flood Affected Areas";
id = 15;
imageurl = "http://check.png";
"time_stamp" = "02/09/2017 21:34";
type = News;
},
{
description = "\"Beauty isn't about having a pretty face, it is about having a pretty soul, a pretty heart and a pretty mind.\"\n\nN.S.S. P.G.D.A.V. is honoured and takes a great pride in telling that MS. LAXMI AGARWAL will be speaking at the orientation program of N.S.S. which is set to be held on 26th August from 12:00 P.M. onwards. Ms. Laxmi Agarwal has inspired this country by her courage and has been the recipient of International Women of Courage Award by Michelle Obama. She is an epitome of bravery.\n\nWe could not have been more proud and excited to have her encourage the students and motivate them to overcome barriers and achieve what they aim for. We are sure she will fill in positive vibes around the program and will inspire us all to do what we need to do, to achieve what we dream for, and to inspire others for the same.";
heading = "NSS Orientation ";
id = 14;
imageurl = "http://check.png";
"time_stamp" = "25/08/2017 16:47";
type = News;
},
{
description = "Welcome Fresher's,\nHere is the last step for final selection to become a member of N.S.S. Team.\nIt's the Personal Interview. So following is the list of students who have to appear on August 2, 2017\n\n\n\n\n\n\nDAY 1 - AUGUST 2, 2017\U00a0\nSLOT 1- 10:00 A.M. - 11:00 A.M.\n\n\nAmit\U00a0\nAditya Sapra\U00a0\nAman Gupta\U00a0\nAadesh Sachdeva\U00a0\nAkshay Gaba\U00a0\nAkansha Sharma\U00a0\nAnjali Kataria\U00a0\nAakash\U00a0\nAbhinav Kumar Malviya\U00a0\nAnkita Rai\U00a0\nAstha Kanojia\U00a0\nAnita Mandal\U00a0\nAnchal\U00a0\nArif\U00a0\nAaftab Ahmad\U00a0\nAshish\U00a0\nAashirya Mittal\U00a0\nAnshul Saini\U00a0\nAnanya Singh\U00a0\nAbhay Goyal\U00a0\nAnshu Kumari Gupta\U00a0\nAjay Kumar\U00a0\nAaftab\U00a0\nAnjali Bhatt\U00a0\nAditi Singh\U00a0\nAnirudh Ahlawat\U00a0\nAshutosh\U00a0\nAnuradha\U00a0\nAmiza\U00a0\nAsmat Khan\U00a0\nAyushi Chadha\U00a0\nAmbujakshi Bhardwaj\U00a0\nAnubhav jain\U00a0\nAshutosh Verma\U00a0\nAbhishek Anand\U00a0\nAbhiraj\U00a0\nAkansha\U00a0\nAbhishek ranjan\U00a0\nAyesha Chauhan\U00a0\nAkansha\U00a0\n\n\nSLOT 2 - 11:00 A.M. - 12:00 P.M.\n\n\nAnkit\U00a0\nAmar Jeet Verma\U00a0\nAnshika Adlakha\U00a0\nAnkur Verma\U00a0\nAnkita\U00a0\nAditya Raj Chaudhary\U00a0\nBhavay Virmani\U00a0\nBunty Kumar\U00a0\nBhawna\U00a0\nBronika Paul\U00a0\nBarkat Ali\U00a0\nBrahmadutt\U00a0\nBadal Sharma\U00a0\nBhavnish Sharma\U00a0\nChandra Prakash Bhambhu\U00a0\nChanchal\U00a0\nChetna Garg\U00a0\nChetan Verma\U00a0\nChirag Sethi\U00a0\nChetan\U00a0\nDeependra Pal Yadav\U00a0\nDivya Agnihotri\U00a0\nDeepak Sahni\U00a0\nDrishya Wahil\U00a0\nDiksha paut\U00a0\nDevendra Yadav\U00a0\nDivya Chabra\U00a0\nDeep Singh\U00a0\nDeepankar Vaid\U00a0\nDrishti Goyal\U00a0\nEkta Shankar\U00a0\nFarzan Iqram\U00a0\nGaurav Bhatt\U00a0\nGarima Behl\U00a0\nGaurav Saini\U00a0\nGarvish Nanda\U00a0\nGaurav Kumar\U00a0\nGarima Payla\U00a0\nGauri Dhamija\U00a0\nharshit Singh\U00a0\n\n\nSLOT 3 - 12:00 P.M. - 1:00 P.M.\n\n\U00a0\U00a0\nHimanshi Sharma\U00a0\nHarsh Gupta\U00a0\nHarshit Girdhar\U00a0\nHarsh Bansal\U00a0\nHarshita Chauhan\U00a0\nHeena\U00a0\nHeena\U00a0\nIrfan Khan\U00a0\nIshu Rai\U00a0\nJaspreet kaur\U00a0\nJyoti\U00a0\nJaisny\U00a0\nJyoti Nishad\U00a0\nKrishan Kumar\U00a0\nKrishna\U00a0\nKetu\U00a0\nKrishika Arora\U00a0\nKhushboo Yadav\U00a0\nKanan Makker\U00a0\nKriti Kapoor\U00a0\nKanika Yadav\U00a0\nKiran Pachori\U00a0\nKunal Nagar\U00a0\nKhushboo Bansal\U00a0\nKunal Sharma\U00a0\nKajal\U00a0\nLalit Mohan\U00a0\nLovely Mathur\U00a0\nMitali Baisoya\U00a0\nmanisha\U00a0\nMiti Dangwal\U00a0\nMukul Puri\U00a0\nMansingh\U00a0\nManoj Meena\U00a0\nMohammad faisal\U00a0\nM. Danish Ameer\U00a0\nMohit Jain\U00a0\nMantu Babu\U00a0";
heading = "NSS Interview Day 1";
id = 13;
imageurl = "http://check.png";
"time_stamp" = "01/08/2017 22:30";
type = News;
},
{
description = "Time and tide waits for none, we all learnt this proverb in our primary school but yesterday I experienced something contradictory to my learning. I saw the time stopping and taking a moment to absorb what was happening around? And guess what was it, it was you, the participants, the audience of Sevaarth whose overwhelming response took the event to a whole new level. You made the mighty time get adrenaline rush. \nThis year we brought in many technical advancement to our NSS unit. We launched our mobile app, website. We facilitated user with many problem solving features. We had more number of volunteers than previous year. Our reach set a new record in the history of all NSS Unit with a growth rate of more than 17,000%. As Sevaarth '17 ended in a great way, we are much more inspired by the work of every people who put their day and night in making sure you get what we have to offer. We are humbled by the response of people. \nWe owe a great deal to our sponsers - Little App, PaisaWapas, DCOP, DSB, Internsala, Nestle, SelfDrives.in, CareerLauncher, Student Stories, The Education Tree, DU Beat, Drama Cafe. Thank you to all.\nWe have a aim. We have people who craves great passion. And, these two thing is advancing us to a new level each and every day. Every day, NSS puts a positive value in this society. We are here to make a better world for each and every person out there. No matter what's your race, nationality, religion, we will make sure that you get what you deserve. In the coming years, NSS Unit of P.G.D.A.V College will get into different areas of society from education to better health care by acting as a bridge by them. \nSevaarth is an opportunity to showcase the talent of people who choose stay away from limelight in front of people. Sevaarth seemed to have touched its highest point with all the fun, the immense hard work, representing our culture from a different perspective. \nWe promise to bring you a more vibrant version of Sevaarth next year. Adios! ";
heading = "Thank you";
id = 12;
imageurl = "http://check.png";
"time_stamp" = "22/01/2017 00:22";
type = News;
}
);
}
Could not cast value of type '__NSDictionaryI' (0x106456288) to 'NSArray' (0x106455e28).
(lldb)
How can I properly decode it based on the error in the log? I am using Swift.
Follow this step :
Creat a class called APIManager
Create Delegates method like this
//MARK : Custom Protocol Methods protocol
apiManagerDelegate:NSObjectProtocol {
func apiSuccessResponse(_ response: Dictionary<String, AnyObject>)
func APIFailureResponse(_ msgError: String)
}
//MARK : Custom Extension Methods
extension apiManagerDelegate {
func apiSuccessResponse(_ response: Dictionary<String, AnyObject>){
// leaving this empty
}
func APIFailureResponse(_ msgError: String){
// leaving this empty
} }
In Your View Controller , Conforms this Delegate Methods .
Defined method like this to consume web service in API Manager
func signUpAPI(firstName : String, lastName:String, email:String, password:String, confirmPwd:String, mobile:String, age:String, gender:String, signUp_type:Int) {
//Payload Dict
let payloadDict = [
"first_name" : firstName,
"last_name" : lastName,
"email" : email,
....
] as [String : Any]
//Showing activity indicator
---progressbar goes here
//Call Web API using Alamofire library
AlamoFireSharedManagerInit()
Alamofire.request(HCConstants.URL.HC_BASEURL + HCConstants.URL.SIGNUP, method: .post, parameters: payloadDict, encoding: JSONEncoding.default, headers: nil).responseJSON { response in
do
{
//Checking For Error
if let error = response.result.error {
//Call failure delegate method
print(error)
//Stop AcitivityIndicator
self.hideHud()
self.delegate?.APIFailureResponse("Something goes wrong , Try after some time!!")
return
}
//Store Response
let responseValue = try JSONSerialization.jsonObject(with: response.data!, options: JSONSerialization.ReadingOptions()) as! Dictionary<String, AnyObject>
print(responseValue)
//Check Success Flag
print(responseValue["success"] as! Bool)
if let mSuccessFlag = responseValue["success"] as? Bool {
//Failure message
if !mSuccessFlag {
self.delegate?.APIFailureResponse(responseValue["message"] as! String? ?? "Something goes wrong , Please try after some time")
}
//Call success delegate method
else {
self.delegate?.apiSuccessResponse(responseValue)
}
}
//Stop AcitivityIndicator
self.hideHud()
} catch {print("Sign up API fired exception")}
}
}
Above method parse the data and send it to the success or failure method to your viewcontroller and from there you need to populate the data and just render it .
Isn't it super easy ?

NSLocale to Country name [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
I have seen this answered in objective-C, but I don't know how to convert to swift.
My app receives the public information of a user from Facebook, and I need to convert the locale into the country name.
FBRequestConnection.startForMeWithCompletionHandler({
connection, result, error in
user["locale"] = result["locale"]
user["email"] = result["email"]
user.save()
println(result.locale)
})
For example, for a French user, the code sends "Optional(fr_FR)" to the log. However I need it to just send the country name. According to localeplanet.com, the display name of "fr_FR" is "French (France)". So in the log all I want is "France".
Working off of this SO question, I've whipped up a Swift translation. Try this:
let locale: NSLocale = NSLocale(localeIdentifier: result.locale!)
let countryCode = locale.objectForKey(NSLocaleCountryCode) as String
var country: String? = locale.displayNameForKey(NSLocaleCountryCode, value: countryCode)
// According to the docs, "Not all locale property keys
// have values with display name values" (thus why the
// "country" variable's an optional). But if this one
// does have a display name value, you can print it like so.
if let foundCounty = country {
print(foundCounty)
}
Updated for Swift 4:
FBSDKGraphRequest(graphPath: "me", parameters: ["fields":"locale"]).start { (connection, result, error) in
guard let resultDictionary = result as? [String:Any],
let localeIdentifier = resultDictionary["locale"] as? String else {
return
}
let locale: NSLocale = NSLocale(localeIdentifier: localeIdentifier)
if let countryCode = locale.object(forKey: NSLocale.Key.countryCode) as? String,
let country = locale.displayName(forKey: NSLocale.Key.countryCode, value: countryCode) {
print(country)
}
}

Resources