Coder1000 Coder1000 - 2 years ago 84
Swift Question

Description Label doesn't appear in my TableViewController cells

IMPORTANT: If you don't understand something or if something is unclear, please post in the comments and I will gladly answer/ edit my question:)

As an exercise to practice Objective-C, I am converting Swift code to Objective-C.
After 1.5k lines converted, I find myself blocked since days on one last issue.
In a few cells of my TableViewController, the description labels don't appear at all. I checked my code and it seems the strings that are passed are actually empty or nil.

After much frustration, searches, and hours of debugging trial and error, here is my question.




NSDate const *now = [[NSDate alloc] init];
NSDate *date = [[NSDate alloc] init];

self.sections = [[NSMutableArray<NSString *> alloc]init];
self.items = [[NSMutableArray<NSMutableArray<TableItem *> *> alloc]init];
self.sectionItems = [[NSMutableArray<TableItem *> alloc]init];


This is the cell data that doesn't load correctly (empty strings are passed to

anItem = [[TableItem alloc ]initWithTitle: @"Custom: dd MMM yyyy HH:mm:ss" theDescription: [NSString stringWithFormat:@"%@", [now toString: [DateFormat CustomDateFormat:@"dd MMM yyyy HH:mm:ss"]]]];
[_sectionItems addObject: anItem];

//theDescription should be: @"25 April 2016 15:04:57" after this ^, but is actually nil or @""

anItem = [[TableItem alloc ]initWithTitle: @"ISO8601(Year)" theDescription: [NSString stringWithFormat:@"%@", [now toString: [DateFormat ISODateFormat: ISOFormatYear]]]];
[_sectionItems addObject: anItem];

//theDescription should be: @"2016" after this ^, but is actually nil or @""

I think I was able to pinpoint the issue:

How to convert this Swift syntax to Objective-C?

Swift syntax:

toString() function

case .ISO8601(let isoFormat):
dateFormat = (isoFormat != nil) ? isoFormat!.rawValue : ISO8601Format.DateTimeMilliSec.rawValue
zone = NSTimeZone.localTimeZone()

What I tried:


else if([format.dateFormatType compare: ISO8601DateFormatType] == NSOrderedSame) {
NSString *isoFormat = ISO8601DateFormatType;
dateFormat = (isoFormat != nil) ? isoFormat : ISOFormatDateTimeMilliSec;
zone = [NSTimeZone localTimeZone];

More context:

Swift Syntax:


public enum ISO8601Format: String {

case Year = "yyyy" // 1997
case YearMonth = "yyyy-MM" // 1997-07
case Date = "yyyy-MM-dd" // 1997-07-16
case DateTime = "yyyy-MM-dd'T'HH:mmZ" // 1997-07-16T19:20+01:00
case DateTimeSec = "yyyy-MM-dd'T'HH:mm:ssZ" // 1997-07-16T19:20:30+01:00
case DateTimeMilliSec = "yyyy-MM-dd'T'HH:mm:ss.SSSZ" // 1997-07-16T19:20:30.45+01:00

init(dateString:String) {
switch dateString.characters.count {
case 4:
self = ISO8601Format(rawValue: ISO8601Format.Year.rawValue)!
case 7:
self = ISO8601Format(rawValue: ISO8601Format.YearMonth.rawValue)!
case 10:
self = ISO8601Format(rawValue: ISO8601Format.Date.rawValue)!
case 22:
self = ISO8601Format(rawValue: ISO8601Format.DateTime.rawValue)!
case 25:
self = ISO8601Format(rawValue: ISO8601Format.DateTimeSec.rawValue)!
default:// 28:
self = ISO8601Format(rawValue: ISO8601Format.DateTimeMilliSec.rawValue)!

public enum DateFormat {
case ISO8601(ISO8601Format?), DotNet, RSS, AltRSS, Custom(String)

What I tried:


#import "DateFormat.h"

@implementation DateFormat

NSString * const ISO8601DateFormatType = @"ISO8601";
NSString * const DotNetDateFormatType = @"DotNet";
NSString * const RSSDateFormatType = @"RSS";
NSString * const AltRSSDateFormatType = @"AltRSS";
NSString * const CustomDateFormatType = @"Custom";

NSString * const ISOFormatYear = @"yyyy";
NSString * const ISOFormatYearMonth = @"yyyy-MM"; // 1997-07
NSString * const ISOFormatDate = @"yyyy-MM-dd"; // 1997-07-16
NSString * const ISOFormatDateTime = @"yyyy-MM-dd'T'HH:mmZ"; // 1997-07-16T19:20+01:00
NSString * const ISOFormatDateTimeSec = @"yyyy-MM-dd'T'HH:mm:ssZ"; // 1997-07-16T19:20:30+01:00
NSString * const ISOFormatDateTimeMilliSec = @"yyyy-MM-dd'T'HH:mm:ss.SSSZ"; // 1997-07-16T19:20:30.45+01:00

- (instancetype) initWithType: (NSString *) formatType details: (NSString *) details {

if(self = [super init]) {
_dateFormatType = formatType;
_formatDetails = details;

return self;

+ (instancetype) ISODateFormat: (NSString *) isoFormat
return [[DateFormat alloc] initWithType: ISO8601DateFormatType details: isoFormat];

+ (instancetype) DotNetDateFormat
return [[DateFormat alloc] initWithType: DotNetDateFormatType details: nil];

+ (instancetype) RSSDateFormat
return [[DateFormat alloc] initWithType: RSSDateFormatType details: nil];

+ (instancetype) AltRSSDateFormat
return [[DateFormat alloc] initWithType: AltRSSDateFormatType details: nil];

+ (instancetype) CustomDateFormat: (NSString *) formatString
return [[DateFormat alloc] initWithType: CustomDateFormatType details: formatString];


I suspect some kind of syntax error on my part. It's either the toString() function or the way I converted the original swift enums:

How would you convert those 2 Swift enums to Objective-C?

TL;DR: For me the error that generates empty strings is either in my Dateformat Class or in the toString() function. I am sure it's actually something very simple (as always, GRRR), but I can't seem to find it!

Answer Source

The problem is in this line:

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

dateFormat is @"Custom", as it was set here:

else if([format.dateFormatType compare: CustomDateFormatType] == NSOrderedSame) {
    NSString *string = CustomDateFormatType;
    dateFormat = string;

This is passed into your NSDateFormatter constructor here:

formatter.dateFormat = format;

@"Custom" is not a valid date format string. Instead, pass in format.formatDetails:

NSDateFormatter *formatter = [NSDate formatter : format.formatDetails : [NSTimeZone localTimeZone] : [NSLocale currentLocale]];

I should note that not using named arguments in Objective-C makes your code much harder to read.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download