gpt4 book ai didi

ios - 为 NSDataDetector 设置上下文日期

转载 作者:可可西里 更新时间:2023-11-01 03:17:40 25 4
gpt4 key购买 nike

假设今天是 2014 年 1 月 20 日。如果我使用 NSDataDetector 从字符串 “明天下午 4 点” 中提取日期,我将得到 2014-01-21T16:00。太好了。

但是,假设我希望 NSDataDetector 假装当前日期是 2014 年 1 月 14 日。这样,当我解析“明天下午 4 点”时,我将得到 2014-01-15T16:00。如果我更改设备上的系统时间,我会得到我想要的。但是,有没有办法以编程方式指定它?

谢谢。

最佳答案

出于测试目的,您可以使用一种称为 method swizzling 的技术.诀窍是用您自己的方法替换 NSDate 的方法之一。

如果您将 +[NSDate date] 替换为您自己的实现,NSDataDetector 会将“现在”视为您指定的任何时间。

在生产代码中调配系统类方法是有风险的。以下示例代码忽略了 Encapsulation NSDataDetector 利用知道它私下使用 NSDate 的优势。许多潜在的陷阱之一是,如果 iOS 的下一次更新更改了 NSDataDetector 的内部结构,您的生产应用可能会意外地停止为您的最终用户正常工作

像这样将类别添加到 NSDate(顺便说一句:如果您正在构建要在设备上运行的库,you may need to specify the -all_load linker flag 以从库中加载类别):

#include <objc/runtime.h>

@implementation NSDate(freezeDate)

static NSDate *_freezeDate;

// Freeze NSDate to a point in time.
// PROBABLY NOT A GOOD IDEA FOR PRODUCTION CODE
+(void)freezeToDate:(NSDate*)date
{
if(_freezeDate != nil) [NSDate unfreeze];
_freezeDate = date;
Method _original_date_method = class_getClassMethod([NSDate class], @selector(date));
Method _fake_date_method = class_getClassMethod([self class], @selector(fakeDate));
method_exchangeImplementations(_original_date_method, _fake_date_method);
}

// Unfreeze NSDate so that now will really be now.
+ (void)unfreeze
{
if(_freezeDate == nil) return;
_freezeDate = nil;
Method _original_date_method = class_getClassMethod([NSDate class], @selector(date));
Method _fake_date_method = class_getClassMethod([self class], @selector(fakeDate));
method_exchangeImplementations(_original_date_method, _fake_date_method);
}

+ (NSDate *)fakeDate
{
return _freezeDate;
}

@end

下面是它的使用:

- (void)someTestingFunction:(NSNotification *)aNotification
{
// Set date to be frozen at a point one week ago from now.
[NSDate freezeToDate:[NSDate dateWithTimeIntervalSinceNow:(-3600*24*7)]];

NSString *userInput = @"tomorrow at 7pm";
NSError *error = nil;
NSRange range = NSMakeRange(0, userInput.length);
NSDataDetector *dd = [NSDataDetector dataDetectorWithTypes:NSTextCheckingTypeDate error:&error];
[dd enumerateMatchesInString:userInput
options:0
range:range
usingBlock:^(NSTextCheckingResult *match, NSMatchingFlags flags, BOOL *stop) {
NSLog(@"From one week ago: %@", match);
}];

// Return date to normal
[NSDate unfreeze];

[dd enumerateMatchesInString:userInput
options:0
range:range
usingBlock:^(NSTextCheckingResult *match, NSMatchingFlags flags, BOOL *stop) {
NSLog(@"From now: %@", match);
}];

}

哪些输出:

2014-01-20 19:35:57.525 TestObjectiveC2[6167:303] From one week ago: {0, 15}{2014-01-15 03:00:00 +0000}2014-01-20 19:35:57.526 TestObjectiveC2[6167:303] From now: {0, 15}{2014-01-22 03:00:00 +0000}

关于ios - 为 NSDataDetector 设置上下文日期,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21244144/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com