Code OxO Code OxO - 7 months ago 36
Swift Question

How to convert this Swift syntax into Objective-C?

I am converting a Swift Library into Objective-C as an exercise.

How to convert this into Objective-C ?

let formatter = NSDate.formatter(format: dateFormat)


I tried:

NSDateFormatter *formatter = [NSDate formatterWithFormat : dateFormat];


Also tried this:

NSDateFormatter *formatter = [NSDate formatterWithFormat : dateFormat : [NSTimeZone localTimeZone] : [NSLocale currentLocale]];


Also tried this:

NSDateFormatter *formatter = [NSDate formatter : dateFormat : [NSTimeZone localTimeZone] : [NSLocale currentLocale]];


Error: no know class method for selector "formatterWithFormat:" or "formatter :::"

More context:

+ (NSDateFormatter *) formatter : (NSString *) format : (NSTimeZone*) timeZone : (NSLocale *) locale {
format = DefaultFormat;
timeZone = [NSTimeZone localTimeZone];
locale = [NSLocale currentLocale];
NSString *hashKey = [NSString stringWithFormat:@"%lu%lu%lu", (unsigned long)format.hash, (unsigned long)timeZone.hash, (unsigned long)locale.hash];
NSMutableDictionary *formatters = [NSDate sharedDateFormatters];
NSDateFormatter *cachedDateFormatter = formatters[hashKey];
if (cachedDateFormatter != nil) {
return cachedDateFormatter;
}
else {
NSDateFormatter *formatter = [[NSDateFormatter alloc]init];
formatter.dateFormat = format;
formatter.timeZone = timeZone;
formatter.locale = locale;
formatters[hashKey] = formatter;
return formatter;
}
}


Some random text in-between so SO will let me add more code...

+ (NSDateFormatter *)formatter:(NSDateFormatterStyle)dateStyle timeStyle:(NSDateFormatterStyle)timeStyle relativeDateFormatting:(BOOL)doesRelativeDateFormatting timeZone:(NSTimeZone *)timeZone locale:(NSLocale *)locale {
timeZone = [NSTimeZone localTimeZone];
locale = [NSLocale currentLocale];
NSString *hashKey = [NSString stringWithFormat:@"%lu%lu%lu%lu%lu", (unsigned long)dateStyle, (unsigned long)timeStyle, (unsigned long)doesRelativeDateFormatting, (unsigned long)timeZone.hash, (unsigned long)locale.hash];
NSMutableDictionary *formatters = [NSDate sharedDateFormatters];
NSDateFormatter *cachedDateFormatter = formatters[hashKey];
if (cachedDateFormatter != nil) {
return cachedDateFormatter;
}
else {
NSDateFormatter *formatter = [[NSDateFormatter alloc]init];
formatter.dateStyle = dateStyle;
formatter.timeStyle = timeStyle;
formatter.doesRelativeDateFormatting = doesRelativeDateFormatting;
formatter.timeZone = timeZone;
formatter.locale = locale;
formatters[hashKey] = formatter;
return formatter;
}
}


Original Swift code:

private class func formatter(format format:String = DefaultFormat, timeZone: NSTimeZone = NSTimeZone.localTimeZone(), locale: NSLocale = NSLocale.currentLocale()) -> NSDateFormatter {
let hashKey = "\(format.hashValue)\(timeZone.hashValue)\(locale.hashValue)"
var formatters = NSDate.sharedDateFormatters()
if let cachedDateFormatter = formatters[hashKey] {
return cachedDateFormatter
} else {
let formatter = NSDateFormatter()
formatter.dateFormat = format
formatter.timeZone = timeZone
formatter.locale = locale
formatters[hashKey] = formatter
return formatter
}
}


Some random text in-between so SO will let me add more code...

private class func formatter(dateStyle dateStyle: NSDateFormatterStyle, timeStyle: NSDateFormatterStyle, doesRelativeDateFormatting: Bool, timeZone: NSTimeZone = NSTimeZone.localTimeZone(), locale: NSLocale = NSLocale.currentLocale()) -> NSDateFormatter {
var formatters = NSDate.sharedDateFormatters()
let hashKey = "\(dateStyle.hashValue)\(timeStyle.hashValue)\(doesRelativeDateFormatting.hashValue)\(timeZone.hashValue)\(locale.hashValue)"
if let cachedDateFormatter = formatters[hashKey] {
return cachedDateFormatter
} else {
let formatter = NSDateFormatter()
formatter.dateStyle = dateStyle
formatter.timeStyle = timeStyle
formatter.doesRelativeDateFormatting = doesRelativeDateFormatting
formatter.timeZone = timeZone
formatter.locale = locale
formatters[hashKey] = formatter
return formatter
}
}

Answer

Based on all your updates, the key difference between your Objective-C code and Swift code is that the Swift function provides default values for the parameters. This allows you to call the function (in this case) with zero or more arguments.

Since Objective-C doesn't support default parameter values, you need to pass a value for every parameter.

The method:

+ (NSDateFormatter *) formatter : (NSString *) format  : (NSTimeZone*) timeZone  : (NSLocale *) locale {
}

Needs to be called as:

[WhateverClassThisIs formatter:someFormat :someTimeZone :someLocale];

Note the ugly syntax due to you not naming all of the parameters (like I showed in your previous question.

You also need to remove the lines you added to assign values to those parameters at the start of the method.