diff --git a/Rx.xcodeproj/project.pbxproj b/Rx.xcodeproj/project.pbxproj index b8ad069d..25e340cf 100644 --- a/Rx.xcodeproj/project.pbxproj +++ b/Rx.xcodeproj/project.pbxproj @@ -401,6 +401,22 @@ C8C3DA101B939767004D233E /* CurrentThreadScheduler.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8C3DA0E1B939767004D233E /* CurrentThreadScheduler.swift */; }; C8C3DA121B93A3EA004D233E /* AnonymousObservable.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8C3DA111B93A3EA004D233E /* AnonymousObservable.swift */; }; C8C3DA131B93A3EA004D233E /* AnonymousObservable.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8C3DA111B93A3EA004D233E /* AnonymousObservable.swift */; }; + C8DB967E1BF7496C0084BD53 /* KVORepresentable.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8DB967D1BF7496C0084BD53 /* KVORepresentable.swift */; }; + C8DB967F1BF7496C0084BD53 /* KVORepresentable.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8DB967D1BF7496C0084BD53 /* KVORepresentable.swift */; }; + C8DB96801BF7496C0084BD53 /* KVORepresentable.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8DB967D1BF7496C0084BD53 /* KVORepresentable.swift */; }; + C8DB96811BF7496C0084BD53 /* KVORepresentable.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8DB967D1BF7496C0084BD53 /* KVORepresentable.swift */; }; + C8DB96831BF754C80084BD53 /* NSObject+Rx+KVORepresentable.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8DB96821BF754C80084BD53 /* NSObject+Rx+KVORepresentable.swift */; }; + C8DB96841BF754C80084BD53 /* NSObject+Rx+KVORepresentable.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8DB96821BF754C80084BD53 /* NSObject+Rx+KVORepresentable.swift */; }; + C8DB96851BF754C80084BD53 /* NSObject+Rx+KVORepresentable.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8DB96821BF754C80084BD53 /* NSObject+Rx+KVORepresentable.swift */; }; + C8DB96861BF754C80084BD53 /* NSObject+Rx+KVORepresentable.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8DB96821BF754C80084BD53 /* NSObject+Rx+KVORepresentable.swift */; }; + C8DB96881BF756F40084BD53 /* KVORepresentable+CoreGraphics.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8DB96871BF756F40084BD53 /* KVORepresentable+CoreGraphics.swift */; }; + C8DB96891BF756F40084BD53 /* KVORepresentable+CoreGraphics.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8DB96871BF756F40084BD53 /* KVORepresentable+CoreGraphics.swift */; }; + C8DB968A1BF756F40084BD53 /* KVORepresentable+CoreGraphics.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8DB96871BF756F40084BD53 /* KVORepresentable+CoreGraphics.swift */; }; + C8DB968B1BF756F40084BD53 /* KVORepresentable+CoreGraphics.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8DB96871BF756F40084BD53 /* KVORepresentable+CoreGraphics.swift */; }; + C8DB968D1BF7595D0084BD53 /* KVORepresentable+Swift.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8DB968C1BF7595D0084BD53 /* KVORepresentable+Swift.swift */; }; + C8DB968E1BF7595D0084BD53 /* KVORepresentable+Swift.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8DB968C1BF7595D0084BD53 /* KVORepresentable+Swift.swift */; }; + C8DB968F1BF7595D0084BD53 /* KVORepresentable+Swift.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8DB968C1BF7595D0084BD53 /* KVORepresentable+Swift.swift */; }; + C8DB96901BF7595D0084BD53 /* KVORepresentable+Swift.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8DB968C1BF7595D0084BD53 /* KVORepresentable+Swift.swift */; }; C8F0BF921BBBFB8B001B112F /* Observable+Creation.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8093C981B8A72BE0088E94D /* Observable+Creation.swift */; }; C8F0BF931BBBFB8B001B112F /* ConnectableObservableType.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8093C4D1B8A72BE0088E94D /* ConnectableObservableType.swift */; }; C8F0BF941BBBFB8B001B112F /* Just.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8C3DA021B9390C4004D233E /* Just.swift */; }; @@ -582,6 +598,10 @@ C8F6A0FF1BEE42DD007DF367 /* AnonymousInvocable.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8F6A0FD1BEE42DD007DF367 /* AnonymousInvocable.swift */; }; C8F6A1001BEE42DD007DF367 /* AnonymousInvocable.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8F6A0FD1BEE42DD007DF367 /* AnonymousInvocable.swift */; }; C8F6A1011BEE42DD007DF367 /* AnonymousInvocable.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8F6A0FD1BEE42DD007DF367 /* AnonymousInvocable.swift */; }; + C8F6A1451BF0B9B1007DF367 /* NSObject+Rx+RawRepresentable.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8F6A1441BF0B9B1007DF367 /* NSObject+Rx+RawRepresentable.swift */; }; + C8F6A1461BF0B9B2007DF367 /* NSObject+Rx+RawRepresentable.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8F6A1441BF0B9B1007DF367 /* NSObject+Rx+RawRepresentable.swift */; }; + C8F6A1471BF0B9B2007DF367 /* NSObject+Rx+RawRepresentable.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8F6A1441BF0B9B1007DF367 /* NSObject+Rx+RawRepresentable.swift */; }; + C8F6A1481BF0B9B2007DF367 /* NSObject+Rx+RawRepresentable.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8F6A1441BF0B9B1007DF367 /* NSObject+Rx+RawRepresentable.swift */; }; CB255BD71BC46A9C00798A4C /* RetryWhen.swift in Sources */ = {isa = PBXBuildFile; fileRef = CB255BD61BC46A9C00798A4C /* RetryWhen.swift */; }; CB255BD81BC46A9C00798A4C /* RetryWhen.swift in Sources */ = {isa = PBXBuildFile; fileRef = CB255BD61BC46A9C00798A4C /* RetryWhen.swift */; }; CB255BD91BC46A9C00798A4C /* RetryWhen.swift in Sources */ = {isa = PBXBuildFile; fileRef = CB255BD61BC46A9C00798A4C /* RetryWhen.swift */; }; @@ -1059,6 +1079,10 @@ C8C3DA0B1B93959F004D233E /* Never.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Never.swift; sourceTree = ""; }; C8C3DA0E1B939767004D233E /* CurrentThreadScheduler.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CurrentThreadScheduler.swift; sourceTree = ""; }; C8C3DA111B93A3EA004D233E /* AnonymousObservable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = AnonymousObservable.swift; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.swift; }; + C8DB967D1BF7496C0084BD53 /* KVORepresentable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KVORepresentable.swift; sourceTree = ""; }; + C8DB96821BF754C80084BD53 /* NSObject+Rx+KVORepresentable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSObject+Rx+KVORepresentable.swift"; sourceTree = ""; }; + C8DB96871BF756F40084BD53 /* KVORepresentable+CoreGraphics.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "KVORepresentable+CoreGraphics.swift"; sourceTree = ""; }; + C8DB968C1BF7595D0084BD53 /* KVORepresentable+Swift.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "KVORepresentable+Swift.swift"; sourceTree = ""; }; C8F0C0021BBBFB8B001B112F /* RxSwift.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = RxSwift.framework; sourceTree = BUILT_PRODUCTS_DIR; }; C8F0C04B1BBBFBB9001B112F /* RxCocoa.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = RxCocoa.framework; sourceTree = BUILT_PRODUCTS_DIR; }; C8F0C0581BBBFBCE001B112F /* RxBlocking.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = RxBlocking.framework; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -1066,6 +1090,7 @@ C8F6A0F31BEE3395007DF367 /* InvocableType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = InvocableType.swift; sourceTree = ""; }; C8F6A0F81BEE33C1007DF367 /* InvocableScheduledItem.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = InvocableScheduledItem.swift; sourceTree = ""; }; C8F6A0FD1BEE42DD007DF367 /* AnonymousInvocable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AnonymousInvocable.swift; sourceTree = ""; }; + C8F6A1441BF0B9B1007DF367 /* NSObject+Rx+RawRepresentable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSObject+Rx+RawRepresentable.swift"; sourceTree = ""; }; CB255BD61BC46A9C00798A4C /* RetryWhen.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RetryWhen.swift; sourceTree = ""; }; CB30D9E81BF0E3500084C1C0 /* SingleAsync.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SingleAsync.swift; sourceTree = ""; }; CB883B3A1BE24355000AC2EE /* Window.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Window.swift; sourceTree = ""; }; @@ -1410,6 +1435,9 @@ C8093E991B8A732E0088E94D /* Proxies */, C8093E9B1B8A732E0088E94D /* RxCocoa.swift */, C8093E9C1B8A732E0088E94D /* RxTarget.swift */, + C8DB967D1BF7496C0084BD53 /* KVORepresentable.swift */, + C8DB96871BF756F40084BD53 /* KVORepresentable+CoreGraphics.swift */, + C8DB968C1BF7595D0084BD53 /* KVORepresentable+Swift.swift */, ); path = Common; sourceTree = ""; @@ -1421,6 +1449,8 @@ C8093E951B8A732E0088E94D /* NSNotificationCenter+Rx.swift */, C8093E961B8A732E0088E94D /* NSObject+Rx+CoreGraphics.swift */, C8093E971B8A732E0088E94D /* NSObject+Rx.swift */, + C8F6A1441BF0B9B1007DF367 /* NSObject+Rx+RawRepresentable.swift */, + C8DB96821BF754C80084BD53 /* NSObject+Rx+KVORepresentable.swift */, C8093E981B8A732E0088E94D /* NSURLSession+Rx.swift */, ); path = Observables; @@ -2094,6 +2124,8 @@ C80D33981B922FB00014629D /* ControlEvent.swift in Sources */, C8093EF31B8A732E0088E94D /* NSObject+Rx+CoreGraphics.swift in Sources */, C882542A1B8A752B00B02D69 /* UIControl+Rx.swift in Sources */, + C8F6A1451BF0B9B1007DF367 /* NSObject+Rx+RawRepresentable.swift in Sources */, + C8DB967E1BF7496C0084BD53 /* KVORepresentable.swift in Sources */, C88254341B8A752B00B02D69 /* UITableView+Rx.swift in Sources */, C88254161B8A752B00B02D69 /* RxCollectionViewReactiveArrayDataSource.swift in Sources */, C8093EEF1B8A732E0088E94D /* KVOObserver.swift in Sources */, @@ -2108,6 +2140,7 @@ C80D338F1B91EF9E0014629D /* Observable+Bind.swift in Sources */, C88254311B8A752B00B02D69 /* UISegmentedControl+Rx.swift in Sources */, C8093EED1B8A732E0088E94D /* KVOObservable.swift in Sources */, + C8DB968D1BF7595D0084BD53 /* KVORepresentable+Swift.swift in Sources */, C80DDEB11BCE8CA3006A1832 /* Driver+Operators+arity.swift in Sources */, C88254281B8A752B00B02D69 /* UIButton+Rx.swift in Sources */, C8093EDF1B8A732E0088E94D /* CLLocationManager+Rx.swift in Sources */, @@ -2128,6 +2161,7 @@ C8093EE11B8A732E0088E94D /* DelegateProxy.swift in Sources */, C8093EF91B8A732E0088E94D /* RxCLLocationManagerDelegateProxy.swift in Sources */, C88254331B8A752B00B02D69 /* UISwitch+Rx.swift in Sources */, + C8DB96831BF754C80084BD53 /* NSObject+Rx+KVORepresentable.swift in Sources */, C8093EE51B8A732E0088E94D /* Logging.swift in Sources */, C88254291B8A752B00B02D69 /* UICollectionView+Rx.swift in Sources */, C882541A1B8A752B00B02D69 /* RxCollectionViewDataSourceType.swift in Sources */, @@ -2137,6 +2171,7 @@ C8093EE71B8A732E0088E94D /* ControlTarget.swift in Sources */, C88254301B8A752B00B02D69 /* UISearchBar+Rx.swift in Sources */, C88254181B8A752B00B02D69 /* ItemEvents.swift in Sources */, + C8DB96881BF756F40084BD53 /* KVORepresentable+CoreGraphics.swift in Sources */, C882541B1B8A752B00B02D69 /* RxTableViewDataSourceType.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -2147,21 +2182,26 @@ files = ( C80DDEA41BCE69BA006A1832 /* Driver.swift in Sources */, C8093F4A1B8A732E0088E94D /* NSImageView+Rx.swift in Sources */, + C8DB96891BF756F40084BD53 /* KVORepresentable+CoreGraphics.swift in Sources */, C8093EDA1B8A732E0088E94D /* _RXKVOObserver.m in Sources */, C8093EE41B8A732E0088E94D /* DelegateProxyType.swift in Sources */, C8093F481B8A732E0088E94D /* NSControl+Rx.swift in Sources */, C8093F4E1B8A732E0088E94D /* NSTextField+Rx.swift in Sources */, + C8DB967F1BF7496C0084BD53 /* KVORepresentable.swift in Sources */, C8093EFE1B8A732E0088E94D /* RxTarget.swift in Sources */, C8093ED21B8A732E0088E94D /* _RX.m in Sources */, C8093EFC1B8A732E0088E94D /* RxCocoa.swift in Sources */, + C8DB968E1BF7595D0084BD53 /* KVORepresentable+Swift.swift in Sources */, C80D33991B922FB00014629D /* ControlEvent.swift in Sources */, C80DDEA81BCE69BA006A1832 /* ObservableConvertibleType+Driver.swift in Sources */, C80D339B1B922FB00014629D /* ControlProperty.swift in Sources */, C8093EF41B8A732E0088E94D /* NSObject+Rx+CoreGraphics.swift in Sources */, C8093EF01B8A732E0088E94D /* KVOObserver.swift in Sources */, C8093EEE1B8A732E0088E94D /* KVOObservable.swift in Sources */, + C8F6A1461BF0B9B2007DF367 /* NSObject+Rx+RawRepresentable.swift in Sources */, C8093EE01B8A732E0088E94D /* CLLocationManager+Rx.swift in Sources */, C8093EEC1B8A732E0088E94D /* DeinitAction.swift in Sources */, + C8DB96841BF754C80084BD53 /* NSObject+Rx+KVORepresentable.swift in Sources */, C8093F461B8A732E0088E94D /* NSButton+Rx.swift in Sources */, C80DDEA01BCE69BA006A1832 /* Driver+Subscription.swift in Sources */, C8093ED61B8A732E0088E94D /* _RXDelegateProxy.m in Sources */, @@ -2642,6 +2682,8 @@ C8F0C0131BBBFBB9001B112F /* ControlEvent.swift in Sources */, C8F0C0141BBBFBB9001B112F /* NSObject+Rx+CoreGraphics.swift in Sources */, C8F0C0151BBBFBB9001B112F /* UIControl+Rx.swift in Sources */, + C8F6A1481BF0B9B2007DF367 /* NSObject+Rx+RawRepresentable.swift in Sources */, + C8DB96811BF7496C0084BD53 /* KVORepresentable.swift in Sources */, C8F0C0161BBBFBB9001B112F /* UITableView+Rx.swift in Sources */, C8F0C0171BBBFBB9001B112F /* RxCollectionViewReactiveArrayDataSource.swift in Sources */, C8F0C0181BBBFBB9001B112F /* KVOObserver.swift in Sources */, @@ -2656,6 +2698,7 @@ C8F0C01F1BBBFBB9001B112F /* Observable+Bind.swift in Sources */, C8F0C0201BBBFBB9001B112F /* UISegmentedControl+Rx.swift in Sources */, C8F0C0211BBBFBB9001B112F /* KVOObservable.swift in Sources */, + C8DB96901BF7595D0084BD53 /* KVORepresentable+Swift.swift in Sources */, C80DDEB41BCE8CA3006A1832 /* Driver+Operators+arity.swift in Sources */, C8F0C0221BBBFBB9001B112F /* UIButton+Rx.swift in Sources */, C8F0C0231BBBFBB9001B112F /* CLLocationManager+Rx.swift in Sources */, @@ -2676,6 +2719,7 @@ C8F0C0311BBBFBB9001B112F /* DelegateProxy.swift in Sources */, C8F0C0321BBBFBB9001B112F /* RxCLLocationManagerDelegateProxy.swift in Sources */, C8F0C0331BBBFBB9001B112F /* UISwitch+Rx.swift in Sources */, + C8DB96861BF754C80084BD53 /* NSObject+Rx+KVORepresentable.swift in Sources */, C8F0C0341BBBFBB9001B112F /* Logging.swift in Sources */, C8F0C0351BBBFBB9001B112F /* UICollectionView+Rx.swift in Sources */, C8F0C0361BBBFBB9001B112F /* RxCollectionViewDataSourceType.swift in Sources */, @@ -2685,6 +2729,7 @@ C8F0C03A1BBBFBB9001B112F /* ControlTarget.swift in Sources */, C8F0C03B1BBBFBB9001B112F /* UISearchBar+Rx.swift in Sources */, C8F0C03C1BBBFBB9001B112F /* ItemEvents.swift in Sources */, + C8DB968B1BF756F40084BD53 /* KVORepresentable+CoreGraphics.swift in Sources */, C8F0C03D1BBBFBB9001B112F /* RxTableViewDataSourceType.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -2723,6 +2768,8 @@ D203C5101BB9C53E00D02D00 /* UISwitch+Rx.swift in Sources */, D203C5121BB9C53E00D02D00 /* UITextField+Rx.swift in Sources */, D203C4F91BB9C53700D02D00 /* RxAlertViewDelegateProxy.swift in Sources */, + C8F6A1471BF0B9B2007DF367 /* NSObject+Rx+RawRepresentable.swift in Sources */, + C8DB96801BF7496C0084BD53 /* KVORepresentable.swift in Sources */, D203C4F31BB9C4CA00D02D00 /* RxCollectionViewReactiveArrayDataSource.swift in Sources */, D203C50B1BB9C53E00D02D00 /* UIScrollView+Rx.swift in Sources */, D203C50C1BB9C53E00D02D00 /* UISearchBar+Rx.swift in Sources */, @@ -2737,6 +2784,7 @@ D2138C921BB9BED600339B5C /* KVOObserver.swift in Sources */, D2138C831BB9BEBE00339B5C /* _RXKVOObserver.m in Sources */, C80DDEB31BCE8CA3006A1832 /* Driver+Operators+arity.swift in Sources */, + C8DB968F1BF7595D0084BD53 /* KVORepresentable+Swift.swift in Sources */, D203C5061BB9C53E00D02D00 /* UIControl+Rx.swift in Sources */, D203C5111BB9C53E00D02D00 /* UITableView+Rx.swift in Sources */, C80DDEA51BCE69BA006A1832 /* Driver.swift in Sources */, @@ -2757,6 +2805,7 @@ D2138C7F1BB9BEBE00339B5C /* _RX.m in Sources */, D203C4FE1BB9C53700D02D00 /* RxTableViewDataSourceProxy.swift in Sources */, D203C5001BB9C53700D02D00 /* RxTextViewDelegateProxy.swift in Sources */, + C8DB96851BF754C80084BD53 /* NSObject+Rx+KVORepresentable.swift in Sources */, D203C5091BB9C53E00D02D00 /* UIImageView+Rx.swift in Sources */, D2138C871BB9BEBE00339B5C /* CLLocationManager+Rx.swift in Sources */, D203C4FF1BB9C53700D02D00 /* RxTableViewDelegateProxy.swift in Sources */, @@ -2766,6 +2815,7 @@ D2138C8A1BB9BEBE00339B5C /* Logging.swift in Sources */, D2138C851BB9BEBE00339B5C /* _RXSwizzling.m in Sources */, D203C5011BB9C53E00D02D00 /* UIActionSheet+Rx.swift in Sources */, + C8DB968A1BF756F40084BD53 /* KVORepresentable+CoreGraphics.swift in Sources */, D203C50F1BB9C53E00D02D00 /* UIStepper+Rx.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; diff --git a/RxCocoa/Common/KVORepresentable+CoreGraphics.swift b/RxCocoa/Common/KVORepresentable+CoreGraphics.swift new file mode 100644 index 00000000..19abf65b --- /dev/null +++ b/RxCocoa/Common/KVORepresentable+CoreGraphics.swift @@ -0,0 +1,71 @@ +// +// KVORepresentable+CoreGraphics.swift +// Rx +// +// Created by Krunoslav Zaher on 11/14/15. +// Copyright © 2015 Krunoslav Zaher. All rights reserved. +// + +import Foundation +#if !RX_NO_MODULE + import RxSwift +#endif +import CoreGraphics + +#if arch(x86_64) || arch(arm64) +let CGRectType = "{CGRect={CGPoint=dd}{CGSize=dd}}" +let CGSizeType = "{CGSize=dd}" +let CGPointType = "{CGPoint=dd}" +#elseif arch(i386) || arch(arm) +let CGRectType = "{CGRect={CGPoint=ff}{CGSize=ff}}" +let CGSizeType = "{CGSize=ff}" +let CGPointType = "{CGPoint=ff}" +#endif + +extension CGRect : KVORepresentable { + public typealias KVOType = NSValue + + /** + Constructs self from `NSValue`. + */ + public init?(KVOValue: KVOType) { + if strcmp(KVOValue.objCType, CGRectType) != 0 { + return nil + } + var typedValue = CGRect(x: 0, y: 0, width: 0, height: 0) + KVOValue.getValue(&typedValue) + self = typedValue + } +} + +extension CGPoint : KVORepresentable { + public typealias KVOType = NSValue + + /** + Constructs self from `NSValue`. + */ + public init?(KVOValue: KVOType) { + if strcmp(KVOValue.objCType, CGPointType) != 0 { + return nil + } + var typedValue = CGPoint(x: 0, y: 0) + KVOValue.getValue(&typedValue) + self = typedValue + } +} + +extension CGSize : KVORepresentable { + public typealias KVOType = NSValue + + /** + Constructs self from `NSValue`. + */ + public init?(KVOValue: KVOType) { + if strcmp(KVOValue.objCType, CGSizeType) != 0 { + return nil + } + var typedValue = CGSize(width: 0, height: 0) + KVOValue.getValue(&typedValue) + self = typedValue + } +} \ No newline at end of file diff --git a/RxCocoa/Common/KVORepresentable+Swift.swift b/RxCocoa/Common/KVORepresentable+Swift.swift new file mode 100644 index 00000000..a118bc4b --- /dev/null +++ b/RxCocoa/Common/KVORepresentable+Swift.swift @@ -0,0 +1,93 @@ +// +// KVORepresentable+Swift.swift +// Rx +// +// Created by Krunoslav Zaher on 11/14/15. +// Copyright © 2015 Krunoslav Zaher. All rights reserved. +// + +import Foundation + +extension Int : KVORepresentable { + public typealias KVOType = NSNumber + + /** + Constructs `Self` using KVO value. + */ + public init?(KVOValue: KVOType) { + self.init(KVOValue.integerValue) + } +} + +extension Int32 : KVORepresentable { + public typealias KVOType = NSNumber + + /** + Constructs `Self` using KVO value. + */ + public init?(KVOValue: KVOType) { + self.init(KVOValue.intValue) + } +} + +extension Int64 : KVORepresentable { + public typealias KVOType = NSNumber + + /** + Constructs `Self` using KVO value. + */ + public init?(KVOValue: KVOType) { + self.init(KVOValue.longLongValue) + } +} + +extension UInt : KVORepresentable { + public typealias KVOType = NSNumber + + /** + Constructs `Self` using KVO value. + */ + public init?(KVOValue: KVOType) { + self.init(KVOValue.unsignedLongValue) + } +} + +extension UInt32 : KVORepresentable { + public typealias KVOType = NSNumber + + /** + Constructs `Self` using KVO value. + */ + public init?(KVOValue: KVOType) { + self.init(KVOValue.unsignedIntValue) + } +} + +extension UInt64 : KVORepresentable { + public typealias KVOType = NSNumber + + /** + Constructs `Self` using KVO value. + */ + public init?(KVOValue: KVOType) { + self.init(KVOValue.unsignedLongLongValue) + } +} + + +extension RawRepresentable where RawValue: KVORepresentable { + /** + Constructs `Self` using optional KVO value. + */ + init?(KVOValue: RawValue.KVOType?) { + guard let KVOValue = KVOValue else { + return nil + } + + guard let rawValue = RawValue(KVOValue: KVOValue) else { + return nil + } + + self.init(rawValue: rawValue) + } +} \ No newline at end of file diff --git a/RxCocoa/Common/KVORepresentable.swift b/RxCocoa/Common/KVORepresentable.swift new file mode 100644 index 00000000..481b06ee --- /dev/null +++ b/RxCocoa/Common/KVORepresentable.swift @@ -0,0 +1,35 @@ +// +// KVORepresentable.swift +// Rx +// +// Created by Krunoslav Zaher on 11/14/15. +// Copyright © 2015 Krunoslav Zaher. All rights reserved. +// + +import Foundation + +/** +Type that is KVO representable (KVO mechanism can be used to observe it). +*/ +public protocol KVORepresentable { + /** + Associated KVO type. + */ + typealias KVOType + + /** + Constructs `Self` using KVO value. + */ + init?(KVOValue: KVOType) +} + +extension KVORepresentable { + init?(KVOValue: KVOType?) { + guard let KVOValue = KVOValue else { + return nil + } + + self.init(KVOValue: KVOValue) + } +} + diff --git a/RxCocoa/Common/Observables/NSObject+Rx+CoreGraphics.swift b/RxCocoa/Common/Observables/NSObject+Rx+CoreGraphics.swift index dc22a2fe..435d11e4 100644 --- a/RxCocoa/Common/Observables/NSObject+Rx+CoreGraphics.swift +++ b/RxCocoa/Common/Observables/NSObject+Rx+CoreGraphics.swift @@ -12,190 +12,19 @@ import RxSwift #endif import CoreGraphics -#if arch(x86_64) || arch(arm64) -let CGRectType = "{CGRect={CGPoint=dd}{CGSize=dd}}" -let CGSizeType = "{CGSize=dd}" -let CGPointType = "{CGPoint=dd}" -#elseif arch(i386) || arch(arm) -let CGRectType = "{CGRect={CGPoint=ff}{CGSize=ff}}" -let CGSizeType = "{CGSize=ff}" -let CGPointType = "{CGPoint=ff}" -#endif - -extension NSObject { - /** - Specialization of generic `rx_observe` method. - - For more information take a look at `rx_observe` method. - */ - @warn_unused_result(message="http://git.io/rxs.uo") - public func rx_observe(type: CGRect.Type, _ keyPath: String, options: NSKeyValueObservingOptions = [.New, .Initial], retainSelf: Bool = true) -> Observable { - return rx_observe(keyPath, options: options, retainSelf: retainSelf) - .map { (value: NSValue?) in - if let value = value { - if strcmp(value.objCType, CGRectType) != 0 { - return nil - } - var typedValue = CGRect(x: 0, y: 0, width: 0, height: 0) - value.getValue(&typedValue) - return typedValue - } - else { - return nil - } - } - } - - /** - Specialization of generic `rx_observe` method. - - For more information take a look at `rx_observe` method. - */ - @warn_unused_result(message="http://git.io/rxs.uo") - public func rx_observe(type: CGSize.Type, _ keyPath: String, options: NSKeyValueObservingOptions = [.New, .Initial], retainSelf: Bool = true) -> Observable { - return rx_observe(keyPath, options: options, retainSelf: retainSelf) - .map { (value: NSValue?) in - if let value = value { - if strcmp(value.objCType, CGSizeType) != 0 { - return nil - } - var typedValue = CGSize(width: 0, height: 0) - value.getValue(&typedValue) - return typedValue - } - else { - return nil - } - } - } - - /** - Specialization of generic `rx_observe` method. - - For more information take a look at `rx_observe` method. - */ - @warn_unused_result(message="http://git.io/rxs.uo") - public func rx_observe(type: CGPoint.Type, _ keyPath: String, options: NSKeyValueObservingOptions = [.New, .Initial], retainSelf: Bool = true) -> Observable { - return rx_observe(keyPath, options: options, retainSelf: retainSelf) - .map { (value: NSValue?) in - if let value = value { - if strcmp(value.objCType, CGPointType) != 0 { - return nil - } - var typedValue = CGPoint(x: 0, y: 0) - value.getValue(&typedValue) - return typedValue - } - else { - return nil - } - } - } -} - -#if !DISABLE_SWIZZLING - - // rx_observeWeakly + CoreGraphics - extension NSObject { - - /** - Specialization of generic `rx_observeWeakly` method. - - For more information take a look at `rx_observeWeakly` method. - */ - @warn_unused_result(message="http://git.io/rxs.uo") - public func rx_observeWeakly(type: CGRect.Type, _ keyPath: String, options: NSKeyValueObservingOptions = [.New, .Initial]) -> Observable { - return rx_observeWeakly(keyPath, options: options) - .map { (value: NSValue?) in - if let value = value { - if strcmp(value.objCType, CGRectType) != 0 { - return nil - } - var typedValue = CGRect(x: 0, y: 0, width: 0, height: 0) - value.getValue(&typedValue) - return typedValue - } - else { - return nil - } - } - } - - /** - Specialization of generic `rx_observeWeakly` method. - - For more information take a look at `rx_observeWeakly` method. - */ - @warn_unused_result(message="http://git.io/rxs.uo") - public func rx_observeWeakly(type: CGSize.Type, _ keyPath: String, options: NSKeyValueObservingOptions = [.New, .Initial]) -> Observable { - return rx_observeWeakly(keyPath, options: options) - .map { (value: NSValue?) in - if let value = value { - if strcmp(value.objCType, CGSizeType) != 0 { - return nil - } - var typedValue = CGSize(width: 0, height: 0) - value.getValue(&typedValue) - return typedValue - } - else { - return nil - } - } - } - - /** - Specialization of generic `rx_observeWeakly` method. - - For more information take a look at `rx_observeWeakly` method. - */ - @warn_unused_result(message="http://git.io/rxs.uo") - public func rx_observeWeakly(type: CGPoint.Type, _ keyPath: String, options: NSKeyValueObservingOptions = [.New, .Initial]) -> Observable { - return rx_observeWeakly(keyPath, options: options) - .map { (value: NSValue?) in - if let value = value { - if strcmp(value.objCType, CGPointType) != 0 { - return nil - } - var typedValue = CGPoint(x: 0, y: 0) - value.getValue(&typedValue) - return typedValue - } - else { - return nil - } - } - } - } - -#endif - - -// MARK: Deprecated +// MARK: Deprecated, CGPoint, CGRect, CGSize are now KVORepresentable extension NSObject { /** Specialization of generic `rx_observe` method. - + For more information take a look at `rx_observe` method. */ @warn_unused_result(message="http://git.io/rxs.uo") @available(*, deprecated=2.0.0, message="Please use version that takes type as first argument.") public func rx_observe(keyPath: String, options: NSKeyValueObservingOptions = [.New, .Initial], retainSelf: Bool = true) -> Observable { - return rx_observe(keyPath, options: options, retainSelf: retainSelf) - .map { (value: NSValue?) in - if let value = value { - if strcmp(value.objCType, CGRectType) != 0 { - return nil - } - var typedValue = CGRect(x: 0, y: 0, width: 0, height: 0) - value.getValue(&typedValue) - return typedValue - } - else { - return nil - } - } + return rx_observe(NSValue.self, keyPath, options: options, retainSelf: retainSelf) + .map(CGRect.init) } /** @@ -206,20 +35,8 @@ extension NSObject { @warn_unused_result(message="http://git.io/rxs.uo") @available(*, deprecated=2.0.0, message="Please use version that takes type as first argument.") public func rx_observe(keyPath: String, options: NSKeyValueObservingOptions = [.New, .Initial], retainSelf: Bool = true) -> Observable { - return rx_observe(keyPath, options: options, retainSelf: retainSelf) - .map { (value: NSValue?) in - if let value = value { - if strcmp(value.objCType, CGSizeType) != 0 { - return nil - } - var typedValue = CGSize(width: 0, height: 0) - value.getValue(&typedValue) - return typedValue - } - else { - return nil - } - } + return rx_observe(NSValue.self, keyPath, options: options, retainSelf: retainSelf) + .map(CGSize.init) } /** @@ -230,20 +47,8 @@ extension NSObject { @warn_unused_result(message="http://git.io/rxs.uo") @available(*, deprecated=2.0.0, message="Please use version that takes type as first argument.") public func rx_observe(keyPath: String, options: NSKeyValueObservingOptions = [.New, .Initial], retainSelf: Bool = true) -> Observable { - return rx_observe(keyPath, options: options, retainSelf: retainSelf) - .map { (value: NSValue?) in - if let value = value { - if strcmp(value.objCType, CGPointType) != 0 { - return nil - } - var typedValue = CGPoint(x: 0, y: 0) - value.getValue(&typedValue) - return typedValue - } - else { - return nil - } - } + return rx_observe(NSValue.self, keyPath, options: options, retainSelf: retainSelf) + .map(CGPoint.init) } } @@ -260,20 +65,8 @@ extension NSObject { @warn_unused_result(message="http://git.io/rxs.uo") @available(*, deprecated=2.0.0, message="Please use version that takes type as first argument.") public func rx_observeWeakly(keyPath: String, options: NSKeyValueObservingOptions = [.New, .Initial]) -> Observable { - return rx_observeWeakly(keyPath, options: options) - .map { (value: NSValue?) in - if let value = value { - if strcmp(value.objCType, CGRectType) != 0 { - return nil - } - var typedValue = CGRect(x: 0, y: 0, width: 0, height: 0) - value.getValue(&typedValue) - return typedValue - } - else { - return nil - } - } + return rx_observeWeakly(NSValue.self, keyPath, options: options) + .map(CGRect.init) } /** @@ -284,20 +77,8 @@ extension NSObject { @warn_unused_result(message="http://git.io/rxs.uo") @available(*, deprecated=2.0.0, message="Please use version that takes type as first argument.") public func rx_observeWeakly(keyPath: String, options: NSKeyValueObservingOptions = [.New, .Initial]) -> Observable { - return rx_observeWeakly(keyPath, options: options) - .map { (value: NSValue?) in - if let value = value { - if strcmp(value.objCType, CGSizeType) != 0 { - return nil - } - var typedValue = CGSize(width: 0, height: 0) - value.getValue(&typedValue) - return typedValue - } - else { - return nil - } - } + return rx_observeWeakly(NSValue.self, keyPath, options: options) + .map(CGSize.init) } /** @@ -308,20 +89,8 @@ extension NSObject { @warn_unused_result(message="http://git.io/rxs.uo") @available(*, deprecated=2.0.0, message="Please use version that takes type as first argument.") public func rx_observeWeakly(keyPath: String, options: NSKeyValueObservingOptions = [.New, .Initial]) -> Observable { - return rx_observeWeakly(keyPath, options: options) - .map { (value: NSValue?) in - if let value = value { - if strcmp(value.objCType, CGPointType) != 0 { - return nil - } - var typedValue = CGPoint(x: 0, y: 0) - value.getValue(&typedValue) - return typedValue - } - else { - return nil - } - } + return rx_observeWeakly(NSValue.self, keyPath, options: options) + .map(CGPoint.init) } } diff --git a/RxCocoa/Common/Observables/NSObject+Rx+KVORepresentable.swift b/RxCocoa/Common/Observables/NSObject+Rx+KVORepresentable.swift new file mode 100644 index 00000000..91ac2894 --- /dev/null +++ b/RxCocoa/Common/Observables/NSObject+Rx+KVORepresentable.swift @@ -0,0 +1,45 @@ +// +// NSObject+Rx+KVORepresentable.swift +// Rx +// +// Created by Krunoslav Zaher on 11/14/15. +// Copyright © 2015 Krunoslav Zaher. All rights reserved. +// + +import Foundation +#if !RX_NO_MODULE + import RxSwift +#endif + +extension NSObject { + + /** + Specialization of generic `rx_observe` method. + + This is a special overload because to observe values of some type (for example `Int`), first values of KVO type + need to be observed (`NSNumber`), and then converted to result type. + + For more information take a look at `rx_observe` method. + */ + @warn_unused_result(message="http://git.io/rxs.uo") + public func rx_observe(type: E.Type, _ keyPath: String, options: NSKeyValueObservingOptions = [.New, .Initial], retainSelf: Bool = true) -> Observable { + return rx_observe(E.KVOType.self, keyPath, options: options, retainSelf: retainSelf) + .map(E.init) + } +} + +#if !DISABLE_SWIZZLING + // KVO + extension NSObject { + /** + Specialization of generic `rx_observeWeakly` method. + + For more information take a look at `rx_observeWeakly` method. + */ + @warn_unused_result(message="http://git.io/rxs.uo") + public func rx_observeWeakly(type: E.Type, _ keyPath: String, options: NSKeyValueObservingOptions = [.New, .Initial]) -> Observable { + return rx_observeWeakly(E.KVOType.self, keyPath, options: options) + .map(E.init) + } + } +#endif diff --git a/RxCocoa/Common/Observables/NSObject+Rx+RawRepresentable.swift b/RxCocoa/Common/Observables/NSObject+Rx+RawRepresentable.swift new file mode 100644 index 00000000..7ff37f45 --- /dev/null +++ b/RxCocoa/Common/Observables/NSObject+Rx+RawRepresentable.swift @@ -0,0 +1,51 @@ +// +// NSObject+Rx+RawRepresentable.swift +// Rx +// +// Created by Krunoslav Zaher on 11/9/15. +// Copyright © 2015 Krunoslav Zaher. All rights reserved. +// + +import Foundation +#if !RX_NO_MODULE + import RxSwift +#endif + +extension NSObject { + /** + Specialization of generic `rx_observe` method. + + This specialization first observes `KVORepresentable` value and then converts it to `RawRepresentable` value. + + It is useful for observing bridged ObjC enum values. + + For more information take a look at `rx_observe` method. + */ + @warn_unused_result(message="http://git.io/rxs.uo") + public func rx_observe(type: E.Type, _ keyPath: String, options: NSKeyValueObservingOptions = [.New, .Initial], retainSelf: Bool = true) -> Observable { + return rx_observe(E.RawValue.KVOType.self, keyPath, options: options, retainSelf: retainSelf) + .map(E.init) + } +} + +#if !DISABLE_SWIZZLING + + // rx_observeWeakly + RawRepresentable + extension NSObject { + + /** + Specialization of generic `rx_observeWeakly` method. + + This specialization first observes `KVORepresentable` value and then converts it to `RawRepresentable` value. + + It is useful for observing bridged ObjC enum values. + + For more information take a look at `rx_observeWeakly` method. + */ + @warn_unused_result(message="http://git.io/rxs.uo") + public func rx_observeWeakly(type: E.Type, _ keyPath: String, options: NSKeyValueObservingOptions = [.New, .Initial]) -> Observable { + return rx_observeWeakly(E.RawValue.KVOType.self, keyPath, options: options) + .map(E.init) + } + } +#endif diff --git a/RxCocoa/Common/Observables/NSObject+Rx.swift b/RxCocoa/Common/Observables/NSObject+Rx.swift index c274f1b0..8629066a 100644 --- a/RxCocoa/Common/Observables/NSObject+Rx.swift +++ b/RxCocoa/Common/Observables/NSObject+Rx.swift @@ -59,10 +59,11 @@ extension NSObject { - returns: Observable sequence of objects on `keyPath`. */ @warn_unused_result(message="http://git.io/rxs.uo") - public func rx_observe(type: Element.Type, _ keyPath: String, options: NSKeyValueObservingOptions = [.New, .Initial], retainSelf: Bool = true) -> Observable { + public func rx_observe(type: E.Type, _ keyPath: String, options: NSKeyValueObservingOptions = [.New, .Initial], retainSelf: Bool = true) -> Observable { return KVOObservable(object: self, keyPath: keyPath, options: options, retainTarget: retainSelf).asObservable() } + /** Observes values on `keyPath` starting from `self` with `options` and retains `self` if `retainSelf` is set. @@ -106,11 +107,11 @@ extension NSObject { - returns: Observable sequence of objects on `keyPath`. */ @warn_unused_result(message="http://git.io/rxs.uo") - public func rx_observeWeakly(type: Element.Type, _ keyPath: String, options: NSKeyValueObservingOptions = [.New, .Initial]) -> Observable { + public func rx_observeWeakly(type: E.Type, _ keyPath: String, options: NSKeyValueObservingOptions = [.New, .Initial]) -> Observable { return observeWeaklyKeyPathFor(self, keyPath: keyPath, options: options) .map { n in - return n as? Element - } + return n as? E + } } /** diff --git a/RxExample/RxExample.xcodeproj/project.pbxproj b/RxExample/RxExample.xcodeproj/project.pbxproj index 617d5884..38b2aa91 100644 --- a/RxExample/RxExample.xcodeproj/project.pbxproj +++ b/RxExample/RxExample.xcodeproj/project.pbxproj @@ -107,6 +107,11 @@ C83367231AD029AE00C668A7 /* Example.swift in Sources */ = {isa = PBXBuildFile; fileRef = C833670F1AD029AE00C668A7 /* Example.swift */; }; C83367241AD029AE00C668A7 /* HtmlParsing.swift in Sources */ = {isa = PBXBuildFile; fileRef = C83367111AD029AE00C668A7 /* HtmlParsing.swift */; }; C83367251AD029AE00C668A7 /* ImageService.swift in Sources */ = {isa = PBXBuildFile; fileRef = C83367121AD029AE00C668A7 /* ImageService.swift */; }; + C83974121BF77406004F02CC /* KVORepresentable.swift in Sources */ = {isa = PBXBuildFile; fileRef = C839740F1BF77406004F02CC /* KVORepresentable.swift */; }; + C83974131BF77406004F02CC /* KVORepresentable+CoreGraphics.swift in Sources */ = {isa = PBXBuildFile; fileRef = C83974101BF77406004F02CC /* KVORepresentable+CoreGraphics.swift */; }; + C83974141BF77406004F02CC /* KVORepresentable+Swift.swift in Sources */ = {isa = PBXBuildFile; fileRef = C83974111BF77406004F02CC /* KVORepresentable+Swift.swift */; }; + C83974231BF77413004F02CC /* NSObject+Rx+KVORepresentable.swift in Sources */ = {isa = PBXBuildFile; fileRef = C83974211BF77413004F02CC /* NSObject+Rx+KVORepresentable.swift */; }; + C83974241BF77413004F02CC /* NSObject+Rx+RawRepresentable.swift in Sources */ = {isa = PBXBuildFile; fileRef = C83974221BF77413004F02CC /* NSObject+Rx+RawRepresentable.swift */; }; C84B91381B8A282000C9CCCF /* RxTableViewSectionedAnimatedDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = C88C78631B3EB0A00061C5AB /* RxTableViewSectionedAnimatedDataSource.swift */; }; C84B91391B8A282000C9CCCF /* RxTableViewSectionedDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = C88C78641B3EB0A00061C5AB /* RxTableViewSectionedDataSource.swift */; }; C84B913A1B8A282000C9CCCF /* RxTableViewSectionedReloadDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = C88C78651B3EB0A00061C5AB /* RxTableViewSectionedReloadDataSource.swift */; }; @@ -521,6 +526,11 @@ C833670F1AD029AE00C668A7 /* Example.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Example.swift; sourceTree = ""; }; C83367111AD029AE00C668A7 /* HtmlParsing.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HtmlParsing.swift; sourceTree = ""; }; C83367121AD029AE00C668A7 /* ImageService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ImageService.swift; sourceTree = ""; }; + C839740F1BF77406004F02CC /* KVORepresentable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KVORepresentable.swift; sourceTree = ""; }; + C83974101BF77406004F02CC /* KVORepresentable+CoreGraphics.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "KVORepresentable+CoreGraphics.swift"; sourceTree = ""; }; + C83974111BF77406004F02CC /* KVORepresentable+Swift.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "KVORepresentable+Swift.swift"; sourceTree = ""; }; + C83974211BF77413004F02CC /* NSObject+Rx+KVORepresentable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSObject+Rx+KVORepresentable.swift"; sourceTree = ""; }; + C83974221BF77413004F02CC /* NSObject+Rx+RawRepresentable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSObject+Rx+RawRepresentable.swift"; sourceTree = ""; }; C84CC52D1BDC344100E06A64 /* ElementAt.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ElementAt.swift; sourceTree = ""; }; C84CC56B1BDD08F500E06A64 /* LockOwnerType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LockOwnerType.swift; sourceTree = ""; }; C84CC56C1BDD08F500E06A64 /* SynchronizedDisposeType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SynchronizedDisposeType.swift; sourceTree = ""; }; @@ -1293,6 +1303,9 @@ C894650D1BC6C2BC0055219D /* Common */ = { isa = PBXGroup; children = ( + C839740F1BF77406004F02CC /* KVORepresentable.swift */, + C83974101BF77406004F02CC /* KVORepresentable+CoreGraphics.swift */, + C83974111BF77406004F02CC /* KVORepresentable+Swift.swift */, C894650E1BC6C2BC0055219D /* _RX.h */, C894650F1BC6C2BC0055219D /* _RX.m */, C89465101BC6C2BC0055219D /* _RXDelegateProxy.h */, @@ -1328,6 +1341,8 @@ C89465241BC6C2BC0055219D /* Observables */ = { isa = PBXGroup; children = ( + C83974211BF77413004F02CC /* NSObject+Rx+KVORepresentable.swift */, + C83974221BF77413004F02CC /* NSObject+Rx+RawRepresentable.swift */, C89465251BC6C2BC0055219D /* Implementations */, C894652B1BC6C2BC0055219D /* NSNotificationCenter+Rx.swift */, C894652C1BC6C2BC0055219D /* NSObject+Rx+CoreGraphics.swift */, @@ -1721,6 +1736,7 @@ C89464A51BC6C2B00055219D /* Disposable.swift in Sources */, C89464F91BC6C2B00055219D /* ObserverType+Extensions.swift in Sources */, C84CC58D1BDD486300E06A64 /* SynchronizedOnType.swift in Sources */, + C83974121BF77406004F02CC /* KVORepresentable.swift in Sources */, C89464DC1BC6C2B00055219D /* Scan.swift in Sources */, C89464B21BC6C2B00055219D /* StableCompositeDisposable.swift in Sources */, C89464AE1BC6C2B00055219D /* ScheduledDisposable.swift in Sources */, @@ -1730,6 +1746,7 @@ C894658D1BC6C2BC0055219D /* UIActionSheet+Rx.swift in Sources */, C89464EA1BC6C2B00055219D /* Zip.swift in Sources */, C89464E51BC6C2B00055219D /* Throttle.swift in Sources */, + C83974241BF77413004F02CC /* NSObject+Rx+RawRepresentable.swift in Sources */, C89465831BC6C2BC0055219D /* RxTableViewDataSourceType.swift in Sources */, C80DDE881BCDAA0F006A1832 /* SkipWhile.swift in Sources */, C89464ED1BC6C2B00055219D /* Observable+Concurrency.swift in Sources */, @@ -1774,6 +1791,7 @@ C89464B71BC6C2B00055219D /* Observable+Extensions.swift in Sources */, C89464A01BC6C2B00055219D /* Lock.swift in Sources */, CB883B601BE3AC72000AC2EE /* Window.swift in Sources */, + C83974141BF77406004F02CC /* KVORepresentable+Swift.swift in Sources */, C89464C91BC6C2B00055219D /* Do.swift in Sources */, C89464A41BC6C2B00055219D /* Queue.swift in Sources */, C89464B91BC6C2B00055219D /* ObservableConvertibleType.swift in Sources */, @@ -1817,6 +1835,7 @@ C809E97E1BE697100058D948 /* UIImage+Extensions.swift in Sources */, C89464E61BC6C2B00055219D /* Timer.swift in Sources */, C8297E3E1B6CF905000589EA /* DetailViewController.swift in Sources */, + C83974131BF77406004F02CC /* KVORepresentable+CoreGraphics.swift in Sources */, C8297E3F1B6CF905000589EA /* SectionModelType.swift in Sources */, C8297E401B6CF905000589EA /* ImageService.swift in Sources */, C89464AD1BC6C2B00055219D /* NopDisposable.swift in Sources */, @@ -1852,6 +1871,7 @@ C8297E451B6CF905000589EA /* SectionedViewType.swift in Sources */, C89464D51BC6C2B00055219D /* ObserveOnSerialDispatchQueue.swift in Sources */, C894658E1BC6C2BC0055219D /* UIAlertView+Rx.swift in Sources */, + C83974231BF77413004F02CC /* NSObject+Rx+KVORepresentable.swift in Sources */, C8297E461B6CF905000589EA /* Example.swift in Sources */, C89465081BC6C2B00055219D /* PublishSubject.swift in Sources */, C89464FC1BC6C2B00055219D /* RxBox.swift in Sources */, diff --git a/RxTests/RxCocoaTests/KVOObservableTests.swift b/RxTests/RxCocoaTests/KVOObservableTests.swift index 2273094b..353ce0a6 100644 --- a/RxTests/RxCocoaTests/KVOObservableTests.swift +++ b/RxTests/RxCocoaTests/KVOObservableTests.swift @@ -28,7 +28,7 @@ class Parent : NSObject { var disposeBag: DisposeBag! = DisposeBag() dynamic var val: String = "" - + init(callback: String? -> Void) { super.init() @@ -68,13 +68,51 @@ class ParentWithChild : NSObject { } } +@objc enum IntEnum: Int { + typealias RawValue = Int + case One + case Two +} + +@objc enum UIntEnum: UInt { + case One + case Two +} + +@objc enum Int32Enum: Int32 { + case One + case Two +} + +@objc enum UInt32Enum: UInt32 { + case One + case Two +} + +@objc enum Int64Enum: Int64 { + case One + case Two +} + +@objc enum UInt64Enum: UInt64 { + case One + case Two +} + class HasStrongProperty : NSObject { dynamic var property: NSObject? = nil dynamic var frame: CGRect dynamic var point: CGPoint dynamic var size: CGSize + dynamic var intEnum: IntEnum = .One + dynamic var uintEnum: UIntEnum = .One + dynamic var int32Enum: Int32Enum = .One + dynamic var uint32Enum: UInt32Enum = .One + dynamic var int64Enum: Int64Enum = .One + dynamic var uint64Enum: UInt64Enum = .One dynamic var integer: Int + dynamic var uinteger: UInt override init() { self.frame = CGRect(x: 0, y: 0, width: 100, height: 100) @@ -82,6 +120,7 @@ class HasStrongProperty : NSObject { self.size = CGSizeMake(1, 2) self.integer = 1 + self.uinteger = 1 super.init() } } @@ -647,8 +686,8 @@ extension KVOObservableTests { XCTAssertTrue(latest.value == nil) - let disposable = root.rx_observe("frame") - .subscribeNext { (n: NSRect?) in + let disposable = root.rx_observe(NSRect.self, "frame") + .subscribeNext { n in latest.value = n } XCTAssertTrue(latest.value == root.frame) @@ -948,7 +987,7 @@ extension KVOObservableTests { XCTAssertTrue(latest.value == nil) XCTAssertTrue(rootDeallocated) } - + func testObserveWeak_PropertyDoesntExist() { var root: HasStrongProperty! = HasStrongProperty() @@ -1005,3 +1044,752 @@ extension KVOObservableTests { } } #endif + +// MARK: KVORepresentable + +extension KVOObservableTests { + func testObserve_ObserveIntegerRepresentable() { + var root: HasStrongProperty! = HasStrongProperty() + + var latest: Int? + + XCTAssertTrue(latest == nil) + + let disposable = root.rx_observe(Int.self, "integer") + .subscribeNext { n in + latest = n + } + XCTAssertTrue(latest == 1) + + root.integer = 2 + + XCTAssertTrue(latest == 2) + + var rootDeallocated = false + + _ = root + .rx_deallocated + .subscribeCompleted { + rootDeallocated = true + } + + root = nil + + XCTAssertTrue(latest == 2) + XCTAssertTrue(!rootDeallocated) + + disposable.dispose() + } + + func testObserve_ObserveUIntegerRepresentable() { + var root: HasStrongProperty! = HasStrongProperty() + + var latest: UInt? + + XCTAssertTrue(latest == nil) + + let disposable = root.rx_observe(UInt.self, "uinteger") + .subscribeNext { n in + latest = n + } + XCTAssertTrue(latest == 1) + + root.uinteger = 2 + + XCTAssertTrue(latest == 2) + + var rootDeallocated = false + + _ = root + .rx_deallocated + .subscribeCompleted { + rootDeallocated = true + } + + root = nil + + XCTAssertTrue(latest == 2) + XCTAssertTrue(!rootDeallocated) + + disposable.dispose() + } +} + +#if !DISABLE_SWIZZLING + extension KVOObservableTests { + func testObserveWeak_ObserveIntegerRepresentable() { + var root: HasStrongProperty! = HasStrongProperty() + + var latest: Int? + + XCTAssertTrue(latest == nil) + + _ = root + .rx_observeWeakly(Int.self, "integer") + .subscribeNext { n in + latest = n + } + + XCTAssertTrue(latest == 1) + + root.integer = 2 + + XCTAssertTrue(latest == 2) + + var rootDeallocated = false + + _ = root + .rx_deallocated + .subscribeCompleted { + rootDeallocated = true + } + + root = nil + + XCTAssertTrue(latest == nil) + XCTAssertTrue(rootDeallocated) + } + + func testObserveWeak_ObserveUIntegerRepresentable() { + var root: HasStrongProperty! = HasStrongProperty() + + var latest: UInt? + + XCTAssertTrue(latest == nil) + + _ = root + .rx_observeWeakly(UInt.self, "uinteger") + .subscribeNext { n in + latest = n + } + + XCTAssertTrue(latest == 1) + + root.uinteger = 2 + + XCTAssertTrue(latest == 2) + + var rootDeallocated = false + + _ = root + .rx_deallocated + .subscribeCompleted { + rootDeallocated = true + } + + root = nil + + XCTAssertTrue(latest == nil) + XCTAssertTrue(rootDeallocated) + } + } +#endif + +// MARK: RawRepresentable +extension KVOObservableTests { + func testObserve_ObserveIntEnum() { + var root: HasStrongProperty! = HasStrongProperty() + + var latest: IntEnum? + + XCTAssertTrue(latest == nil) + + let disposable = root.rx_observe(IntEnum.self, "intEnum") + .subscribeNext { n in + latest = n + } + XCTAssertTrue(latest == .One) + + root.intEnum = .Two + + XCTAssertTrue(latest == .Two) + + var rootDeallocated = false + + _ = root + .rx_deallocated + .subscribeCompleted { + rootDeallocated = true + } + + root = nil + + XCTAssertTrue(latest == .Two) + XCTAssertTrue(!rootDeallocated) + + disposable.dispose() + } + + func testObserve_ObserveInt32Enum() { + var root: HasStrongProperty! = HasStrongProperty() + + var latest: Int32Enum? + + XCTAssertTrue(latest == nil) + + let disposable = root.rx_observe(Int32Enum.self, "int32Enum") + .subscribeNext { n in + latest = n + } + XCTAssertTrue(latest == .One) + + root.int32Enum = .Two + + XCTAssertTrue(latest == .Two) + + var rootDeallocated = false + + _ = root + .rx_deallocated + .subscribeCompleted { + rootDeallocated = true + } + + root = nil + + XCTAssertTrue(latest == .Two) + XCTAssertTrue(!rootDeallocated) + + disposable.dispose() + } + + func testObserve_ObserveInt64Enum() { + var root: HasStrongProperty! = HasStrongProperty() + + var latest: Int64Enum? + + XCTAssertTrue(latest == nil) + + let disposable = root.rx_observe(Int64Enum.self, "int64Enum") + .subscribeNext { n in + latest = n + } + XCTAssertTrue(latest == .One) + + root.int64Enum = .Two + + XCTAssertTrue(latest == .Two) + + var rootDeallocated = false + + _ = root + .rx_deallocated + .subscribeCompleted { + rootDeallocated = true + } + + root = nil + + XCTAssertTrue(latest == .Two) + XCTAssertTrue(!rootDeallocated) + + disposable.dispose() + } + + + func testObserve_ObserveUIntEnum() { + var root: HasStrongProperty! = HasStrongProperty() + + var latest: UIntEnum? + + XCTAssertTrue(latest == nil) + + let disposable = root.rx_observe(UIntEnum.self, "uintEnum") + .subscribeNext { n in + latest = n + } + XCTAssertTrue(latest == .One) + + root.uintEnum = .Two + + XCTAssertTrue(latest == .Two) + + var rootDeallocated = false + + _ = root + .rx_deallocated + .subscribeCompleted { + rootDeallocated = true + } + + root = nil + + XCTAssertTrue(latest == .Two) + XCTAssertTrue(!rootDeallocated) + + disposable.dispose() + } + + func testObserve_ObserveUInt32Enum() { + var root: HasStrongProperty! = HasStrongProperty() + + var latest: UInt32Enum? + + XCTAssertTrue(latest == nil) + + let disposable = root.rx_observe(UInt32Enum.self, "uint32Enum") + .subscribeNext { n in + latest = n + } + XCTAssertTrue(latest == .One) + + root.uint32Enum = .Two + + XCTAssertTrue(latest == .Two) + + var rootDeallocated = false + + _ = root + .rx_deallocated + .subscribeCompleted { + rootDeallocated = true + } + + root = nil + + XCTAssertTrue(latest == .Two) + XCTAssertTrue(!rootDeallocated) + + disposable.dispose() + } + + func testObserve_ObserveUInt64Enum() { + var root: HasStrongProperty! = HasStrongProperty() + + var latest: UInt64Enum? + + XCTAssertTrue(latest == nil) + + let disposable = root.rx_observe(UInt64Enum.self, "uint64Enum") + .subscribeNext { n in + latest = n + } + XCTAssertTrue(latest == .One) + + root.uint64Enum = .Two + + XCTAssertTrue(latest == .Two) + + var rootDeallocated = false + + _ = root + .rx_deallocated + .subscribeCompleted { + rootDeallocated = true + } + + root = nil + + XCTAssertTrue(latest == .Two) + XCTAssertTrue(!rootDeallocated) + + disposable.dispose() + } +} + +#if !DISABLE_SWIZZLING +extension KVOObservableTests { + func testObserveWeak_ObserveIntEnum() { + var root: HasStrongProperty! = HasStrongProperty() + + var latest: IntEnum? + + XCTAssertTrue(latest == nil) + + _ = root + .rx_observeWeakly(IntEnum.self, "intEnum") + .subscribeNext { n in + latest = n + } + XCTAssertTrue(latest == .One) + + root.intEnum = .Two + + XCTAssertTrue(latest == .Two) + + var rootDeallocated = false + + _ = root + .rx_deallocated + .subscribeCompleted { + rootDeallocated = true + } + + root = nil + + XCTAssertTrue(latest == nil) + XCTAssertTrue(rootDeallocated) + } + + func testObserveWeak_ObserveInt32Enum() { + var root: HasStrongProperty! = HasStrongProperty() + + var latest: Int32Enum? + + XCTAssertTrue(latest == nil) + + _ = root + .rx_observeWeakly(Int32Enum.self, "int32Enum") + .subscribeNext { n in + latest = n + } + XCTAssertTrue(latest == .One) + + root.int32Enum = .Two + + XCTAssertTrue(latest == .Two) + + var rootDeallocated = false + + _ = root + .rx_deallocated + .subscribeCompleted { + rootDeallocated = true + } + + root = nil + + XCTAssertTrue(latest == nil) + XCTAssertTrue(rootDeallocated) + } + + func testObserveWeak_ObserveInt64Enum() { + var root: HasStrongProperty! = HasStrongProperty() + + var latest: Int64Enum? + + XCTAssertTrue(latest == nil) + + _ = root + .rx_observeWeakly(Int64Enum.self, "int64Enum") + .subscribeNext { n in + latest = n + } + XCTAssertTrue(latest == .One) + + root.int64Enum = .Two + + XCTAssertTrue(latest == .Two) + + var rootDeallocated = false + + _ = root + .rx_deallocated + .subscribeCompleted { + rootDeallocated = true + } + + root = nil + + XCTAssertTrue(latest == nil) + XCTAssertTrue(rootDeallocated) + } + + func testObserveWeak_ObserveUIntEnum() { + var root: HasStrongProperty! = HasStrongProperty() + + var latest: UIntEnum? + + XCTAssertTrue(latest == nil) + + _ = root + .rx_observeWeakly(UIntEnum.self, "uintEnum") + .subscribeNext { n in + latest = n + } + XCTAssertTrue(latest == .One) + + root.uintEnum = .Two + + XCTAssertTrue(latest == .Two) + + var rootDeallocated = false + + _ = root + .rx_deallocated + .subscribeCompleted { + rootDeallocated = true + } + + root = nil + + XCTAssertTrue(latest == nil) + XCTAssertTrue(rootDeallocated) + } + + func testObserveWeak_ObserveUInt32Enum() { + var root: HasStrongProperty! = HasStrongProperty() + + var latest: UInt32Enum? + + XCTAssertTrue(latest == nil) + + _ = root + .rx_observeWeakly(UInt32Enum.self, "uint32Enum") + .subscribeNext { n in + latest = n + } + XCTAssertTrue(latest == .One) + + root.uint32Enum = .Two + + XCTAssertTrue(latest == .Two) + + var rootDeallocated = false + + _ = root + .rx_deallocated + .subscribeCompleted { + rootDeallocated = true + } + + root = nil + + XCTAssertTrue(latest == nil) + XCTAssertTrue(rootDeallocated) + } + + func testObserveWeak_ObserveUInt64Enum() { + var root: HasStrongProperty! = HasStrongProperty() + + var latest: UInt32Enum? + + XCTAssertTrue(latest == nil) + + _ = root + .rx_observeWeakly(UInt32Enum.self, "uint64Enum") + .subscribeNext { n in + latest = n + } + XCTAssertTrue(latest == .One) + + root.uint64Enum = .Two + + XCTAssertTrue(latest == .Two) + + var rootDeallocated = false + + _ = root + .rx_deallocated + .subscribeCompleted { + rootDeallocated = true + } + + root = nil + + XCTAssertTrue(latest == nil) + XCTAssertTrue(rootDeallocated) + } +} +#endif + +// MARK: Deprecated +extension KVOObservableTests { + func testObserve_deprecated_ObserveCGRect() { + var root: HasStrongProperty! = HasStrongProperty() + + let latest = RxMutableBox(nil) + + XCTAssertTrue(latest.value == nil) + + let d = root.rx_observe("frame") + .subscribeNext { (n: CGRect?) in + latest.value = n + } + + defer { + d.dispose() + } + + XCTAssertTrue(latest.value == root.frame) + + root.frame = CGRectMake(-2, 0, 0, 1) + + XCTAssertTrue(latest.value == CGRectMake(-2, 0, 0, 1)) + + var rootDeallocated = false + + _ = root + .rx_deallocated + .subscribeCompleted { + rootDeallocated = true + } + + root = nil + + XCTAssertTrue(latest.value == CGRectMake(-2, 0, 0, 1)) + XCTAssertTrue(!rootDeallocated) + } + + func testObserve_deprecated_ObserveCGSize() { + var root: HasStrongProperty! = HasStrongProperty() + + let latest = RxMutableBox(nil) + + XCTAssertTrue(latest.value == nil) + + let d = root.rx_observe("size") + .subscribeNext { (n: CGSize?) in + latest.value = n + } + + defer { + d.dispose() + } + + XCTAssertTrue(latest.value == root.size) + + root.size = CGSizeMake(56, 1) + + XCTAssertTrue(latest.value == CGSizeMake(56, 1)) + + var rootDeallocated = false + + _ = root + .rx_deallocated + .subscribeCompleted { + rootDeallocated = true + } + + root = nil + + XCTAssertTrue(latest.value == CGSizeMake(56, 1)) + XCTAssertTrue(!rootDeallocated) + } + + func testObserve_deprecated_ObserveCGPoint() { + var root: HasStrongProperty! = HasStrongProperty() + + let latest = RxMutableBox(nil) + + XCTAssertTrue(latest.value == nil) + + let d = root.rx_observe("point") + .subscribeNext { (n: CGPoint?) in + latest.value = n + } + defer { + d.dispose() + } + + XCTAssertTrue(latest.value == root.point) + + root.point = CGPoint(x: -100, y: 1) + + XCTAssertTrue(latest.value == CGPoint(x: -100, y: 1)) + + var rootDeallocated = false + + _ = root + .rx_deallocated + .subscribeCompleted { + rootDeallocated = true + } + + root = nil + + XCTAssertTrue(latest.value == CGPoint(x: -100, y: 1)) + XCTAssertTrue(!rootDeallocated) + } +} + +#if !DISABLE_SWIZZLING +extension KVOObservableTests { + func testObserveWeak_deprecated_ObserveCGRect() { + var root: HasStrongProperty! = HasStrongProperty() + + let latest = RxMutableBox(nil) + + XCTAssertTrue(latest.value == nil) + + _ = root + .rx_observeWeakly("frame") + .subscribeNext { (n: CGRect?) in + latest.value = n + } + XCTAssertTrue(latest.value == root.frame) + + root.frame = CGRectMake(-2, 0, 0, 1) + + XCTAssertTrue(latest.value == CGRectMake(-2, 0, 0, 1)) + + var rootDeallocated = false + + _ = root + .rx_deallocated + .subscribeCompleted { + rootDeallocated = true + } + + root = nil + + XCTAssertTrue(latest.value == nil) + XCTAssertTrue(rootDeallocated) + } + + func testObserveWeak_deprecated_ObserveCGSize() { + var root: HasStrongProperty! = HasStrongProperty() + + let latest = RxMutableBox(nil) + + XCTAssertTrue(latest.value == nil) + + _ = root + .rx_observeWeakly("size") + .subscribeNext { (n: CGSize?) in + latest.value = n + } + XCTAssertTrue(latest.value == root.size) + + root.size = CGSizeMake(56, 1) + + XCTAssertTrue(latest.value == CGSizeMake(56, 1)) + + var rootDeallocated = false + + _ = root + .rx_deallocated + .subscribeCompleted { + rootDeallocated = true + } + + root = nil + + XCTAssertTrue(latest.value == nil) + XCTAssertTrue(rootDeallocated) + } + + func testObserveWeak_deprecated_ObserveCGPoint() { + var root: HasStrongProperty! = HasStrongProperty() + + let latest = RxMutableBox(nil) + + XCTAssertTrue(latest.value == nil) + + _ = root + .rx_observeWeakly("point") + .subscribeNext { (n: CGPoint?) in + latest.value = n + } + + XCTAssertTrue(latest.value == root.point) + + root.point = CGPoint(x: -100, y: 1) + + XCTAssertTrue(latest.value == CGPoint(x: -100, y: 1)) + + var rootDeallocated = false + + _ = root + .rx_deallocated + .subscribeCompleted { + rootDeallocated = true + } + + root = nil + + XCTAssertTrue(latest.value == nil) + XCTAssertTrue(rootDeallocated) + } +} +#endif