I am trying to convert this swift code to Objective-C
convenience init(fromString string: String, format:DateFormat)
{
if string.isEmpty {
self.init()
return
}
let string = string as NSString
switch format {
case .DotNet:
let startIndex = string.rangeOfString("(").location + 1
let endIndex = string.rangeOfString(")").location
let range = NSRange(location: startIndex, length: endIndex-startIndex)
let milliseconds = (string.substringWithRange(range) as NSString).longLongValue
let interval = NSTimeInterval(milliseconds / 1000)
self.init(timeIntervalSince1970: interval)
So far, I am doing this:
-(id) initFromString: (NSString *) string format: (DateFormat *) format{
if (string == nil) {
self = [self init];
return self;
}
switch (format) {
case .DotNet:
NSRange *startIndex = [[string rangeOfString:@"("] location]+1;
}
}
and have already run into the following errors:
for the switch(format)
: statement requires expression of integer type (DateFormat * __strong' invalid)
and for the 2 following lines: Expected expression
Any ideas ?
In Objective-C, the string is impliedly optional. Testing for nil
merely tests whether a string was supplied. It doesn't check whether an empty string was supplied. You probably want to switch to string.length == 0
as, by the magic of nil-messaging, that'll work to check for either an empty string or no string at all.
Objective-C uses C's switch
statement. So you can switch on integral types only. If this were Objective-C code originally, DateFormat
would probably be an NS_ENUM
— an integral type rather than an object type. It looks like the original was an enumeration from your use of dot syntax? If you can make it an Objective-C enumeration then do so and simply use:
- (id)initFromString:(NSString *)string format:(DateFormat)format {
....
switch(format)
{
case DateFormatDotNet: {
....
} break;
}
(with the curly brackets within the case
being because you want to declare variables in there).
Otherwise, if it must be an object format then you're looking at a painful construction like:
if([format isEqual:[DateFormat dotNetFormat]]) {
}
else if([format isEqual:[DateFormat otherFormat]]) {
}
... etc ...
Also Objective-C has a syntactic distinction between struct
s, which are exactly what they are in C — named fields but no built-in behaviour — and object types, which is again because it's a strict superset of C. NSRange
is a struct. So square bracket messaging syntax doesn't work on it. Instead of:
[[string rangeOfString:@"("] location]
Use:
[string rangeOfString:@"("].location
Square brackets around the rangeOfString
call because it's a message dispatch to an object, then a dot for location because you get back a C struct as a value, and that's how one accesses a field in a C struct.
(dot syntax also works for properties on Objective-C objects, but explicitly to alias to getter and setter calls, and only for about the most recent of Objective-C's three decades)