【问题标题】:How do I convert a parameterised enum/ enum with associated values from Swift to Objective-C? [closed]如何将带有关联值的参数化枚举/枚举从 Swift 转换为 Objective-C? [关闭]
【发布时间】:2016-04-26 19:05:58
【问题描述】:

注意:作为练习,我将 Swift 代码转换为 Objective-C。


代码: 我转换的原始 Swift 代码:

case .ISO8601(let isoFormat):
    let dateFormat = (isoFormat != nil) ? isoFormat! : ISO8601Format(dateString: string as String)
    let formatter = NSDate.formatter(format: dateFormat.rawValue)
    formatter.locale = NSLocale(localeIdentifier: "en_US_POSIX")
    formatter.timeZone = NSTimeZone.localTimeZone()
    formatter.dateFormat = dateFormat.rawValue
    if let date = formatter.dateFromString(string as String) {
        self.init(timeInterval:0, sinceDate:date)
    } else {
        self.init()
    }

我尝试了什么:我尝试了 Objective-C 转换:

else if([format.dateFormatType compare: ISO8601DateFormatType] == NSOrderedSame) {
    NSString *isoFormat = // WHAT DO TO HERE ?;
    NSString *dateFormat = (isoFormat != nil) ? isoFormat : ISO8601DateFormatType;
    NSDateFormatter *formatter = [NSDate formatterWithFormat: dateFormat andTimeZone: [NSTimeZone localTimeZone ] andLocale: [NSLocale currentLocale]];
    formatter.locale = [NSLocale localeWithLocaleIdentifier: (@"en_US_POSIX")];
    NSLog([NSString stringWithFormat:@"%@", dateFormat]);
    // dateFormat = ISO8601
    NSDate *date = [formatter dateFromString:(string)];

    //
    // ISSUE IS HERRRREEEE ^
    //

    NSLog([NSString stringWithFormat:@"%@", date]);
    // date = nil

    if (date != nil){
        return [self initWithTimeInterval: 0 sinceDate: date];
    }
    else {
        return [self init];
    }
}

我采用的方法是使用一个单独的类来重现带有关联值的 swift 枚举的行为(这原本是一个带有关联值的大型 swift 枚举):

DateFormat.m

#import "DateFormat.h"

@implementation DateFormat

NSString * const ISO8601DateFormatType = @"ISO8601";
NSString * const DotNetDateFormatType = @"DotNet";
NSString * const RSSDateFormatType = @"EEE, d MMM yyyy HH:mm:ss ZZZ";
NSString * const AltRSSDateFormatType = @"d MMM yyyy HH:mm:ss ZZZ";
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];
}

@end

我的问题:

在我的代码中,dateFromString 返回nil,因为作为参数传递的格式不正确。发生这种情况的原因是因为我将枚举转换为关联值行的方式:case .ISO8601(let isoFormat):

我不知道如何将case .ISO8601(let isoFormat): 转换为Objective-C。

问题是具有关联值的枚举只存在于 Swift 中,而不存在于 Objective-C 中。

那么如何在 Objective-C 中将该枚举与关联的值行大小写 .ISO8601(let isoFormat): 进行转换?


解决方案:

编辑:答案很简单,我只需要写:NSString *isoFormat = format.formatDetails;在我在问题开头显示的 Objective-C 转换中。 (查看我的 Class DateFormat 实现文件即可理解)

【问题讨论】:

  • 这不是stackoverflow.com/questions/36753954/…的副本吗?在您写信 Minimal, Complete, and Verifiable example 之前,我们无法为您提供帮助
  • 不,与此无关。那个是日航回答的!
  • 这是另一个问题。但是 DateFormat 类无处不在,所以这就是为什么您再次看到一些代码的原因。
  • @Sulthan 我编辑了我的问题!我希望它现在更好更清晰!
  • @rmaddy 我编辑了我的问题!我希望它现在更好更清晰!

标签: objective-c enums nsdate


【解决方案1】:

让我为你解释一下你的代码:

NSString *isoFormat = ISO8601DateFormatType;

(将字符串ISO8601 分配给isoFormat

NSString *dateFormat = (isoFormat != nil) ? isoFormat : ISO8601DateFormatType;

isoFormat 永远不会是nil,因此条件始终为真。如果为假,我们将再次分配字符串ISO8601)。

NSDateFormatter *formatter = ... 

(我们得到了一些格式化程序,无论如何我们都会覆盖它的所有重要属性)

formatter.locale = [NSLocale localeWithLocaleIdentifier: (@"en_US_POSIX")];

(让我们用 POSIX 语言环境覆盖上面的[NSLocale currentLocale],这很好)

formatter.timeZone = [NSTimeZone localTimeZone];

(让我们重新设置时区)

formatter.dateFormat = dateFormat;

(让我们将字符串ISO8601设置为日期格式,这不是有效的日期格式)

NSDate *date = [formatter dateFromString:(string)];

(让我们尝试使用无效的日期格式ISO8601解析日期。显然,这将返回nil

简而言之-问题与您上一个问题Error in dateFormat returns nil中的问题完全相同

【讨论】:

  • @Coder1000 为您分配正确的日期格式formatter。如果你想要一个更好的答案,你必须先问一个更好的问题。
  • 我的问题基本上归结为:如何转换case .ISO8601(let isoFormat):
  • @Coder1000 不知道你的实现很难知道,但也许你想使用NSString *isoFormat = format.formatDetails;
猜你喜欢
  • 2021-05-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-02-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多