Немного повторяясь с ответом, который вы предоставили:
enum TimeFrame: Equatable {
case all
case countable(timeFrame: CountableTimeFrame)
case exact(date: Date)
}
enum CountableTimeFrame: Equatable {
case hour
case day
case week
case month
case year
indirect case multiple(CountableTimeFrame, Int)
var timeFrame: TimeFrame {
return .countable(timeFrame: self)
}
static func * (left: CountableTimeFrame, right: Int) -> CountableTimeFrame {
switch left {
case .multiple(let timeFrame, let count):
return .multiple(timeFrame, count * right)
default:
return .multiple(left, right)
}
}
static func * (left: Int, right: CountableTimeFrame) -> CountableTimeFrame {
return right * left
}
}
будет запрещать неправильное использование, например, disallow:
let timeFrame: TimeFrame = .multiple(.exact(date: someDate), 666)
let timeFrame: TimeFrame = .multiple(unspecified, 40)
let timeFrame: TimeFrame = .multiple(all, -1)
И разрешить умножение с помощью оператора *, например
let timeFrame: CountableTimeFrame = 4 * .hour
print(timeFrame) // multiple(__lldb_expr_5.CountableTimeFrame.hour, 4)
print(timeFrame * 2) // multiple(__lldb_expr_5.CountableTimeFrame.hour, 8)
И не уточнено:
let optionalTimeFrame: TimeFrame? = nil
Спасибо за отличную обратную связь, это побудило меня найти надежное решение.
Весь код можно найти здесь:
http://code.google.com/ p / dlocation /
Это очень грязно, но по мере того, как я его использую, оно станет намного лучше.
Решением было создание подкласса CLLocationManager
и определение нового делегата @protocol
, называется DLocationManagerDelegate
.
Он предназначен для простой замены CLLocationManagerDelegate
, который компилируется в очень ] тонкий слой при развертывании на реальном устройстве.
При работе на устройстве он будет возвращать данные в обычном режиме, используя CoreLocation
, но в симуляторе он будет считывать широту и долготу из текстового файла (определенного в файл DLocationManager.h).
Надеюсь, это поможет, реализация проста, и вам нужно startUpdatingLocation
и stopUpdatingLocation
, чтобы обновить дисплей.
Комментарии и отзывы будут с благодарностью приняты.
Use a filtering function to swap in a test instance when running on the simulator. Wherever you previously received the location (delegate call, etc), pass it through this:
+ (CLLocation *) wakkawakka: (CLLocation*) loc {
#ifdef TARGET_IPHONE_SIMULATOR
/* replace with a test instance */
return [[CLLocation alloc] initWithLatitude:10.0 longitude:20.0];
#else
return loc;
#endif
}
Memory management issues aside...
Trigger the Core Location callbacks from a test class, if you need to set a location other than the one the simulator gives you.
я думаю, что существует другой (лучше, по моему скромному мнению) подход здесь, чем разделение на подклассы CLLocationManager как в
http://code.google.com/p/dlocation/
В ObjectiveC, это, кажется, возможно к замена существующий метод от класса, не переопределяя его. Это часто называют "методом swizzling": вы определяете свою собственную категорию для существующего класса реализация существующий метод в нем.
С клиентской точки зрения, все прозрачно: у него есть чувство, что он имеет дело с реальным CLLocationManager
, но на самом деле, вы "взяли на себя управление от него" . Так, чтобы он не должен был иметь дело ни с каким специальным подклассом или любым специальным протоколом делегата: он продолжает использовать тот же класс / протокол как тот от CoreLocation.
Вот пример к, взял на себя управление над делегатом, которого введет клиент:
@implementation CLLocationManager (simulator)
-(void) setDelegate:(id)delegate {
//your own implementation of the setDelegate...
}
-(id)delegate {
//your own implementation of the delegate....
}
-(void)startUpdatingLocation {
}
-(void)stopUpdatingLocation {
}
//....
//same for the rest of any method available in the standard CLLocationManager
@end
Затем в этой реализации, вы свободны иметь дело с пред определенный набор координат (прибывающий из файла что), который будет "продвинут" делегату, использующему стандарт протокол CLLocationManagerDelegate
.
Вот мой простой хак, который заставляет CLLocationMager возвращать геокорды книжного магазина Powell's Tech Bookstore только на симуляторе:
#ifdef TARGET_IPHONE_SIMULATOR
@interface CLLocationManager (Simulator)
@end
@implementation CLLocationManager (Simulator)
-(void)startUpdatingLocation {
CLLocation *powellsTech = [[[CLLocation alloc] initWithLatitude:45.523450 longitude:-122.678897] autorelease];
[self.delegate locationManager:self
didUpdateToLocation:powellsTech
fromLocation:powellsTech];
}
@end
#endif // TARGET_IPHONE_SIMULATOR