diff --git a/BindKit.podspec b/BindKit.podspec deleted file mode 100644 index 51251c9..0000000 --- a/BindKit.podspec +++ /dev/null @@ -1,45 +0,0 @@ -Pod::Spec.new do |s| - s.name = "BindKit" - s.version = "1.0.0" - s.summary = "Two-way data binding framework for iOS." - s.description = "Two-way data binding framework for iOS (static library) supporting i386, x86_64, armv7s, armv7, arm64 and bitcode." - s.homepage = "https://github.com/electricbolt/bindkit" - s.license = { - :type => 'Copyright', - :text => <<-LICENCETEXT - BSD 2-Clause License - - Copyright © 2018 Electric Bolt Limited - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - LICENCETEXT - } - - s.author = { 'Electric Bolt Limited' => 'support@electricbolt.co.nz' } - s.source = { :git => "https://github.com/electricbolt/BindKit.git", :tag => '1.0.0' } - - s.platform = :ios, '8.0' - s.source_files = 'release/*.h' - s.vendored_libraries = 'release/*.a' - -end diff --git a/BindKit.xcframework/Info.plist b/BindKit.xcframework/Info.plist new file mode 100644 index 0000000..155abcb --- /dev/null +++ b/BindKit.xcframework/Info.plist @@ -0,0 +1,44 @@ + + + + + AvailableLibraries + + + BinaryPath + BindKit.framework/BindKit + LibraryIdentifier + ios-arm64_x86_64-simulator + LibraryPath + BindKit.framework + SupportedArchitectures + + arm64 + x86_64 + + SupportedPlatform + ios + SupportedPlatformVariant + simulator + + + BinaryPath + BindKit.framework/BindKit + LibraryIdentifier + ios-arm64 + LibraryPath + BindKit.framework + SupportedArchitectures + + arm64 + + SupportedPlatform + ios + + + CFBundlePackageType + XFWK + XCFrameworkFormatVersion + 1.0 + + diff --git a/BindKit.xcframework/_CodeSignature/CodeDirectory b/BindKit.xcframework/_CodeSignature/CodeDirectory new file mode 100644 index 0000000..f8c31ba Binary files /dev/null and b/BindKit.xcframework/_CodeSignature/CodeDirectory differ diff --git a/BindKit.xcframework/_CodeSignature/CodeRequirements b/BindKit.xcframework/_CodeSignature/CodeRequirements new file mode 100644 index 0000000..04e81c7 Binary files /dev/null and b/BindKit.xcframework/_CodeSignature/CodeRequirements differ diff --git a/BindKit.xcframework/_CodeSignature/CodeRequirements-1 b/BindKit.xcframework/_CodeSignature/CodeRequirements-1 new file mode 100644 index 0000000..f47266d Binary files /dev/null and b/BindKit.xcframework/_CodeSignature/CodeRequirements-1 differ diff --git a/BindKit.xcframework/_CodeSignature/CodeResources b/BindKit.xcframework/_CodeSignature/CodeResources new file mode 100644 index 0000000..8c41c97 --- /dev/null +++ b/BindKit.xcframework/_CodeSignature/CodeResources @@ -0,0 +1,398 @@ + + + + + files + + ios-arm64/BindKit.framework/BindKit + + YOypKkK09DV/xm3ZK9ziBc6AbkU= + + ios-arm64/BindKit.framework/Headers/BindKit.h + + cLZvtvaNnQ7PattArdpmP2mRST4= + + ios-arm64/BindKit.framework/Info.plist + + w6vPSIeow92/gWHKMn2EkhSYXUE= + + ios-arm64/BindKit.framework/Modules/module.modulemap + + cBD5IYs7ZDarz+IlMGtjTPAomVA= + + ios-arm64/BindKit.framework/PrivacyInfo.xcprivacy + + J3jCDET/Yn1lAQbrw44v61PrV7c= + + ios-arm64/BindKit.framework/_CodeSignature/CodeDirectory + + 8XvlU0GObB2dDe3lMYDhIUYb8Ek= + + ios-arm64/BindKit.framework/_CodeSignature/CodeRequirements + + PQzrnCWErl9HDjWxjLp9R6stEHA= + + ios-arm64/BindKit.framework/_CodeSignature/CodeRequirements-1 + + xtJ3MSyfe0xIjuzse4z1xOlSMeY= + + ios-arm64/BindKit.framework/_CodeSignature/CodeResources + + iwUzz8o8FLgYoJzHXD+EZRVHiIM= + + ios-arm64/BindKit.framework/_CodeSignature/CodeSignature + + cVpB1uTN+3tkT122yzKBNBsS87E= + + ios-arm64_x86_64-simulator/BindKit.framework/BindKit + + i65sDIayOi3V2Ty7z7lSp3D0+6c= + + ios-arm64_x86_64-simulator/BindKit.framework/Headers/BindKit.h + + cLZvtvaNnQ7PattArdpmP2mRST4= + + ios-arm64_x86_64-simulator/BindKit.framework/Info.plist + + 1pmHCHPT3rfxXGUDsahGcSc46pU= + + ios-arm64_x86_64-simulator/BindKit.framework/Modules/module.modulemap + + cBD5IYs7ZDarz+IlMGtjTPAomVA= + + ios-arm64_x86_64-simulator/BindKit.framework/PrivacyInfo.xcprivacy + + J3jCDET/Yn1lAQbrw44v61PrV7c= + + ios-arm64_x86_64-simulator/BindKit.framework/_CodeSignature/CodeDirectory + + Q3r/2fQxI+i/lfk8jdHUjd8D+3M= + + ios-arm64_x86_64-simulator/BindKit.framework/_CodeSignature/CodeRequirements + + OnX22wWFKRSOFN1+obRynMCeyXM= + + ios-arm64_x86_64-simulator/BindKit.framework/_CodeSignature/CodeRequirements-1 + + 55kr89C1i/9WcUjQxoN9yrVau3c= + + ios-arm64_x86_64-simulator/BindKit.framework/_CodeSignature/CodeResources + + OhFcthWv7m15tXAHDBdQ85Rd8WM= + + ios-arm64_x86_64-simulator/BindKit.framework/_CodeSignature/CodeSignature + + 2jmj7l5rSw0yVb/vlWAYkK/YBwk= + + + files2 + + ios-arm64/BindKit.framework/BindKit + + hash + + YOypKkK09DV/xm3ZK9ziBc6AbkU= + + hash2 + + col1F8yuBfjZyolmK+Ko8f+HEHHrsmHs0g7ThO771RU= + + + ios-arm64/BindKit.framework/Headers/BindKit.h + + hash + + cLZvtvaNnQ7PattArdpmP2mRST4= + + hash2 + + 4H/B1PLN8rcydl29hUVNFt0cn9H/JVcFyW+m3qxKrLU= + + + ios-arm64/BindKit.framework/Info.plist + + hash + + w6vPSIeow92/gWHKMn2EkhSYXUE= + + hash2 + + faFaecWUVK31yD4mvxo5RDvphPXLdre5dUm4wyZhyEs= + + + ios-arm64/BindKit.framework/Modules/module.modulemap + + hash + + cBD5IYs7ZDarz+IlMGtjTPAomVA= + + hash2 + + z7OYBPWLYkel6T7lWL+Gm0+2SFbMIDjp3+0hS/trHQE= + + + ios-arm64/BindKit.framework/PrivacyInfo.xcprivacy + + hash + + J3jCDET/Yn1lAQbrw44v61PrV7c= + + hash2 + + Uoqz/KkQ0qwvPvJW1epMIycwOnpKXvuSNph/MBjjEfM= + + + ios-arm64/BindKit.framework/_CodeSignature/CodeDirectory + + hash + + 8XvlU0GObB2dDe3lMYDhIUYb8Ek= + + hash2 + + lq3ChZ/NhuCcwuJl9nLouwGk9DIacixgXGo/U+LeBC4= + + + ios-arm64/BindKit.framework/_CodeSignature/CodeRequirements + + hash + + PQzrnCWErl9HDjWxjLp9R6stEHA= + + hash2 + + +aBRYou+PkGlTYOdvdCKaMwC/8t8TGk5xO09gns0Npc= + + + ios-arm64/BindKit.framework/_CodeSignature/CodeRequirements-1 + + hash + + xtJ3MSyfe0xIjuzse4z1xOlSMeY= + + hash2 + + sE8HOxMk/u0hz5tuyCfQ9p02A22GWQiSuE128wkmWVA= + + + ios-arm64/BindKit.framework/_CodeSignature/CodeResources + + hash + + iwUzz8o8FLgYoJzHXD+EZRVHiIM= + + hash2 + + VWqZsWgUO4UcdkPbuuopOBqpn7QmxIybJwgVCM9I1jg= + + + ios-arm64/BindKit.framework/_CodeSignature/CodeSignature + + hash + + cVpB1uTN+3tkT122yzKBNBsS87E= + + hash2 + + KB6PsJ71hB+jRrPXg+zrywk4JDteuoAsanYejndOw8Q= + + + ios-arm64_x86_64-simulator/BindKit.framework/BindKit + + hash + + i65sDIayOi3V2Ty7z7lSp3D0+6c= + + hash2 + + vD1PgRrFd/hZlxdiJEVr8danVNHLQCMArPa2TMBW2o4= + + + ios-arm64_x86_64-simulator/BindKit.framework/Headers/BindKit.h + + hash + + cLZvtvaNnQ7PattArdpmP2mRST4= + + hash2 + + 4H/B1PLN8rcydl29hUVNFt0cn9H/JVcFyW+m3qxKrLU= + + + ios-arm64_x86_64-simulator/BindKit.framework/Info.plist + + hash + + 1pmHCHPT3rfxXGUDsahGcSc46pU= + + hash2 + + dYvpGy1AZ7LE6zhkGNYE2l3FcFKWKYh9NG/DJdwPySg= + + + ios-arm64_x86_64-simulator/BindKit.framework/Modules/module.modulemap + + hash + + cBD5IYs7ZDarz+IlMGtjTPAomVA= + + hash2 + + z7OYBPWLYkel6T7lWL+Gm0+2SFbMIDjp3+0hS/trHQE= + + + ios-arm64_x86_64-simulator/BindKit.framework/PrivacyInfo.xcprivacy + + hash + + J3jCDET/Yn1lAQbrw44v61PrV7c= + + hash2 + + Uoqz/KkQ0qwvPvJW1epMIycwOnpKXvuSNph/MBjjEfM= + + + ios-arm64_x86_64-simulator/BindKit.framework/_CodeSignature/CodeDirectory + + hash + + Q3r/2fQxI+i/lfk8jdHUjd8D+3M= + + hash2 + + SDceACCXPmqL9Bp/gTHRl5oaOL5YSR5lshlG+LH6Fes= + + + ios-arm64_x86_64-simulator/BindKit.framework/_CodeSignature/CodeRequirements + + hash + + OnX22wWFKRSOFN1+obRynMCeyXM= + + hash2 + + mHkgkE6rZQ51eIwFSqCwUk5qgL/HGqMt+NI3phdD+YY= + + + ios-arm64_x86_64-simulator/BindKit.framework/_CodeSignature/CodeRequirements-1 + + hash + + 55kr89C1i/9WcUjQxoN9yrVau3c= + + hash2 + + zMNnt/tdCf9Y+YYRL1zgij3L0BxZYnDbF4A2Ykcr42k= + + + ios-arm64_x86_64-simulator/BindKit.framework/_CodeSignature/CodeResources + + hash + + OhFcthWv7m15tXAHDBdQ85Rd8WM= + + hash2 + + lUijuaaEC7XmBxa0ibAwCX93udus41dnka1MWdZEUDk= + + + ios-arm64_x86_64-simulator/BindKit.framework/_CodeSignature/CodeSignature + + hash + + 2jmj7l5rSw0yVb/vlWAYkK/YBwk= + + hash2 + + 47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU= + + + + rules + + ^.* + + ^.*\.lproj/ + + optional + + weight + 1000 + + ^.*\.lproj/locversion.plist$ + + omit + + weight + 1100 + + ^Base\.lproj/ + + weight + 1010 + + ^version.plist$ + + + rules2 + + .*\.dSYM($|/) + + weight + 11 + + ^(.*/)?\.DS_Store$ + + omit + + weight + 2000 + + ^.* + + ^.*\.lproj/ + + optional + + weight + 1000 + + ^.*\.lproj/locversion.plist$ + + omit + + weight + 1100 + + ^Base\.lproj/ + + weight + 1010 + + ^Info\.plist$ + + omit + + weight + 20 + + ^PkgInfo$ + + omit + + weight + 20 + + ^embedded\.provisionprofile$ + + weight + 20 + + ^version\.plist$ + + weight + 20 + + + + diff --git a/BindKit.xcframework/_CodeSignature/CodeSignature b/BindKit.xcframework/_CodeSignature/CodeSignature new file mode 100644 index 0000000..1f48e4b Binary files /dev/null and b/BindKit.xcframework/_CodeSignature/CodeSignature differ diff --git a/BindKit.xcframework/ios-arm64/BindKit.framework/BindKit b/BindKit.xcframework/ios-arm64/BindKit.framework/BindKit new file mode 100644 index 0000000..c1a3902 Binary files /dev/null and b/BindKit.xcframework/ios-arm64/BindKit.framework/BindKit differ diff --git a/BindKit/BindKit/public/BindKit.h b/BindKit.xcframework/ios-arm64/BindKit.framework/Headers/BindKit.h similarity index 53% rename from BindKit/BindKit/public/BindKit.h rename to BindKit.xcframework/ios-arm64/BindKit.framework/Headers/BindKit.h index a6e0b07..71cdd29 100644 --- a/BindKit/BindKit/public/BindKit.h +++ b/BindKit.xcframework/ios-arm64/BindKit.framework/Headers/BindKit.h @@ -1,14 +1,12 @@ -/******************************************************************************* - * BindKit.h * - * BindKit Copyright (c) 2018; Electric Bolt Limited. * - ******************************************************************************/ +// BindKit.h +// BindKit Copyright (c) 2018-2024; Electric Bolt Limited. #ifndef BindKit_h #define BindKit_h #import -// Not all views inherit from UIView (e.g. UIBarButtonItem). +// Not all UIKit views inherit from UIView (e.g. UIBarButtonItem). #define EBKView NSObject @protocol EBKBoundPropertiesDelegate @@ -177,6 +175,132 @@ NS_ASSUME_NONNULL_END */ extern NSString* _Nonnull EBKVersion(void); -#include "BindKitVendor.h" +#pragma mark Vendor integration APIs - dynamic subclassing of views + +/** + @brief The name of the NSException that is thrown when a programmer error + is detected during binding. + @remark See also bindSel:toView:viewSel: for details of exceptions + */ +extern NSString* _Nonnull EBKBindingException; + +/* + @brief This macro can be used in an overidden bindableProperties to return an + property type string of the property type v. + @code + return @{UISwitchEnabled: EBKTypeEncode(BOOL)}; // "enabled"="B" + @endCode + */ +#define EBKTypeEncode(v) [NSString stringWithCString: @encode(v) encoding: NSASCIIStringEncoding] + +@interface EBKView (EBKDynamicSubclass) + +/** + @brief Override this method to return a dictionary of valid property names and + types. + @discussion Valid property types are those specified in "Objective-C type encodings" + https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtTypeEncodings.html + */ +- (NSDictionary* _Nonnull) bindableProperties; + +/** + @brief This method will be called when the view has been bound with the model's + first property only. + @discussion Override this method if your view needs to subscribe to + notifications or control events to listen for changes input by the user. + See EBKUI* classes for more details. + */ +- (void) viewDidBindWithModel; + +/** + @brief This method is called when the bound object's properties have been updated, + and the view's properties need to be updated to keep in sync. + @discussion See EBKUI* classes for more details. + */ +- (void) updateViewFromBoundModel; + +/** + @brief If the view property is bound to an model property, then the value is + set onto the model against the bound model property. + */ +- (void) setBoundValue: (NSObject* _Nullable) value viewKey: (NSString* _Nonnull) viewKey; + +/** + @brief If the view property is mapped to an model property, then the value is + retrieved from the model against the mapped model property. + @discussion If the value is non-nil then the value is returned. If the value is + nil, the [NSNull null] is returned. If the view property is not mapped to an + object property, then nil is returned. + */ +- (NSObject* _Nullable) boundValueForViewKey: (NSString* _Nonnull) viewKey NS_SWIFT_NAME(boundValue(viewKey:)); + +@end + +@interface EBKView (EBKDynamicSubclassRegistry) + +/** + @brief Override to return the EBKUI* version of a UIKit view. + */ +- (Class _Nullable) EBKDynamicSubclass NS_SWIFT_NAME(EBKDynamicSubclass()); + +@end + +#pragma mark Vendor integration - debug logging + +typedef NS_OPTIONS(NSUInteger, EBKLogFlag) { + EBKLogFlagError = 1 << 0, // 0...00001 + EBKLogFlagWarn = 1 << 1, // 0...00010 + EBKLogFlagInfo = 1 << 2, // 0...00100 + EBKLogFlagDebug = 1 << 3, // 0...01000 + EBKLogFlagVerbose = 1 << 4, // 0...10000 +}; + +typedef NS_ENUM(NSUInteger, EBKLogLevel) { + EBKLogLevelOff = 0, // 0...00000 + EBKLogLevelError = (EBKLogFlagError), // 0...00001 + EBKLogLevelWarn = (EBKLogLevelError|EBKLogFlagWarn), // 0...00011 + EBKLogLevelInfo = (EBKLogLevelWarn|EBKLogFlagInfo), // 0...00111 + EBKLogLevelDebug = (EBKLogLevelInfo|EBKLogFlagDebug), // 0...01111 + EBKLogLevelVerbose = (EBKLogLevelDebug|EBKLogFlagVerbose), // 0...11111 + EBKLogLevelAll = NSUIntegerMax // 1111...1111 +}; + +#define EBKERROR(msg,...) EBKLogO(EBKLogFlagError,__FILE__,NSStringFromSelector(_cmd),__LINE__,msg,##__VA_ARGS__) +#define EBKDEBUG(msg,...) EBKLogO(EBKLogFlagDebug,__FILE__,NSStringFromSelector(_cmd),__LINE__,msg,##__VA_ARGS__) +#define EBKVERBOSE(msg,...) EBKLogO(EBKLogFlagVerbose,__FILE__,NSStringFromSelector(_cmd),__LINE__,msg,##__VA_ARGS__) + +/** + @brief Enables or disables logging to the console based upon the level specified. + @discussion Valid logging levels are EBKLogLevelOff < EBKLogLevelError < EBKLogLevelWarn < EBKLogLevelInfo < EBKLogLevelDebug < EBKLogLevelVerbose. + The default logging level is EBKLogLevelError. + */ +extern void EBKSetLogging(EBKLogLevel logLevel); + +/** + @brief Logs an ObjC style string and variable arguments in sprintf format to the + console if logging is enabled. + */ +extern void EBKLogO(EBKLogFlag logFlag, const char* _Nonnull path, NSString* _Nonnull method, int line, NSString* _Nonnull msg, ...); + +/** + @brief Logs an Swift style string to the console if logging is enabled. + */ +extern void EBKLogS(EBKLogFlag logFlag, NSString* _Nonnull msg); + +#pragma mark Vendor integration - multicasting delegates for dynamic subclasses + +/** + @brief Multi-casting delegate + @discussion If a dynamic subclass needs to use delegation to be notified of changes + to the view (as opposed to target-action or notifications), then it can + use this class to multi-cast delegate methods. + @remark See MySearchBar.swift for usage. + */ +@interface EBKMulticastDelegate : NSObject + +@property(weak, nullable) id primaryDelegate; +@property(weak, nullable) id secondaryDelegate; + +@end #endif // BindKit_h diff --git a/BindKit.xcframework/ios-arm64/BindKit.framework/Info.plist b/BindKit.xcframework/ios-arm64/BindKit.framework/Info.plist new file mode 100644 index 0000000..cff1cec Binary files /dev/null and b/BindKit.xcframework/ios-arm64/BindKit.framework/Info.plist differ diff --git a/BindKit.xcframework/ios-arm64/BindKit.framework/Modules/module.modulemap b/BindKit.xcframework/ios-arm64/BindKit.framework/Modules/module.modulemap new file mode 100644 index 0000000..bd7cc2c --- /dev/null +++ b/BindKit.xcframework/ios-arm64/BindKit.framework/Modules/module.modulemap @@ -0,0 +1,5 @@ +framework module BindKit { + umbrella header "BindKit.h" + export * + module * { export * } +} diff --git a/BindKit.xcframework/ios-arm64/BindKit.framework/PrivacyInfo.xcprivacy b/BindKit.xcframework/ios-arm64/BindKit.framework/PrivacyInfo.xcprivacy new file mode 100644 index 0000000..2009fb7 --- /dev/null +++ b/BindKit.xcframework/ios-arm64/BindKit.framework/PrivacyInfo.xcprivacy @@ -0,0 +1,14 @@ + + + + + NSPrivacyTracking + + NSPrivacyTrackingDomains + + NSPrivacyCollectedDataTypes + + NSPrivacyAccessedAPITypes + + + diff --git a/BindKit.xcframework/ios-arm64/BindKit.framework/_CodeSignature/CodeDirectory b/BindKit.xcframework/ios-arm64/BindKit.framework/_CodeSignature/CodeDirectory new file mode 100644 index 0000000..1303503 Binary files /dev/null and b/BindKit.xcframework/ios-arm64/BindKit.framework/_CodeSignature/CodeDirectory differ diff --git a/BindKit.xcframework/ios-arm64/BindKit.framework/_CodeSignature/CodeRequirements b/BindKit.xcframework/ios-arm64/BindKit.framework/_CodeSignature/CodeRequirements new file mode 100644 index 0000000..9b8bf74 Binary files /dev/null and b/BindKit.xcframework/ios-arm64/BindKit.framework/_CodeSignature/CodeRequirements differ diff --git a/BindKit.xcframework/ios-arm64/BindKit.framework/_CodeSignature/CodeRequirements-1 b/BindKit.xcframework/ios-arm64/BindKit.framework/_CodeSignature/CodeRequirements-1 new file mode 100644 index 0000000..fc8f8ee Binary files /dev/null and b/BindKit.xcframework/ios-arm64/BindKit.framework/_CodeSignature/CodeRequirements-1 differ diff --git a/BindKit.xcframework/ios-arm64/BindKit.framework/_CodeSignature/CodeResources b/BindKit.xcframework/ios-arm64/BindKit.framework/_CodeSignature/CodeResources new file mode 100644 index 0000000..732ec31 --- /dev/null +++ b/BindKit.xcframework/ios-arm64/BindKit.framework/_CodeSignature/CodeResources @@ -0,0 +1,147 @@ + + + + + files + + Headers/BindKit.h + + cLZvtvaNnQ7PattArdpmP2mRST4= + + Info.plist + + w6vPSIeow92/gWHKMn2EkhSYXUE= + + Modules/module.modulemap + + cBD5IYs7ZDarz+IlMGtjTPAomVA= + + PrivacyInfo.xcprivacy + + J3jCDET/Yn1lAQbrw44v61PrV7c= + + + files2 + + Headers/BindKit.h + + hash + + cLZvtvaNnQ7PattArdpmP2mRST4= + + hash2 + + 4H/B1PLN8rcydl29hUVNFt0cn9H/JVcFyW+m3qxKrLU= + + + Modules/module.modulemap + + hash + + cBD5IYs7ZDarz+IlMGtjTPAomVA= + + hash2 + + z7OYBPWLYkel6T7lWL+Gm0+2SFbMIDjp3+0hS/trHQE= + + + PrivacyInfo.xcprivacy + + hash + + J3jCDET/Yn1lAQbrw44v61PrV7c= + + hash2 + + Uoqz/KkQ0qwvPvJW1epMIycwOnpKXvuSNph/MBjjEfM= + + + + rules + + ^.* + + ^.*\.lproj/ + + optional + + weight + 1000 + + ^.*\.lproj/locversion.plist$ + + omit + + weight + 1100 + + ^Base\.lproj/ + + weight + 1010 + + ^version.plist$ + + + rules2 + + .*\.dSYM($|/) + + weight + 11 + + ^(.*/)?\.DS_Store$ + + omit + + weight + 2000 + + ^.* + + ^.*\.lproj/ + + optional + + weight + 1000 + + ^.*\.lproj/locversion.plist$ + + omit + + weight + 1100 + + ^Base\.lproj/ + + weight + 1010 + + ^Info\.plist$ + + omit + + weight + 20 + + ^PkgInfo$ + + omit + + weight + 20 + + ^embedded\.provisionprofile$ + + weight + 20 + + ^version\.plist$ + + weight + 20 + + + + diff --git a/BindKit.xcframework/ios-arm64/BindKit.framework/_CodeSignature/CodeSignature b/BindKit.xcframework/ios-arm64/BindKit.framework/_CodeSignature/CodeSignature new file mode 100644 index 0000000..3ccd202 Binary files /dev/null and b/BindKit.xcframework/ios-arm64/BindKit.framework/_CodeSignature/CodeSignature differ diff --git a/BindKit.xcframework/ios-arm64_x86_64-simulator/BindKit.framework/BindKit b/BindKit.xcframework/ios-arm64_x86_64-simulator/BindKit.framework/BindKit new file mode 100644 index 0000000..3b37c40 Binary files /dev/null and b/BindKit.xcframework/ios-arm64_x86_64-simulator/BindKit.framework/BindKit differ diff --git a/release/BindKit.h b/BindKit.xcframework/ios-arm64_x86_64-simulator/BindKit.framework/Headers/BindKit.h similarity index 53% rename from release/BindKit.h rename to BindKit.xcframework/ios-arm64_x86_64-simulator/BindKit.framework/Headers/BindKit.h index a6e0b07..71cdd29 100644 --- a/release/BindKit.h +++ b/BindKit.xcframework/ios-arm64_x86_64-simulator/BindKit.framework/Headers/BindKit.h @@ -1,14 +1,12 @@ -/******************************************************************************* - * BindKit.h * - * BindKit Copyright (c) 2018; Electric Bolt Limited. * - ******************************************************************************/ +// BindKit.h +// BindKit Copyright (c) 2018-2024; Electric Bolt Limited. #ifndef BindKit_h #define BindKit_h #import -// Not all views inherit from UIView (e.g. UIBarButtonItem). +// Not all UIKit views inherit from UIView (e.g. UIBarButtonItem). #define EBKView NSObject @protocol EBKBoundPropertiesDelegate @@ -177,6 +175,132 @@ NS_ASSUME_NONNULL_END */ extern NSString* _Nonnull EBKVersion(void); -#include "BindKitVendor.h" +#pragma mark Vendor integration APIs - dynamic subclassing of views + +/** + @brief The name of the NSException that is thrown when a programmer error + is detected during binding. + @remark See also bindSel:toView:viewSel: for details of exceptions + */ +extern NSString* _Nonnull EBKBindingException; + +/* + @brief This macro can be used in an overidden bindableProperties to return an + property type string of the property type v. + @code + return @{UISwitchEnabled: EBKTypeEncode(BOOL)}; // "enabled"="B" + @endCode + */ +#define EBKTypeEncode(v) [NSString stringWithCString: @encode(v) encoding: NSASCIIStringEncoding] + +@interface EBKView (EBKDynamicSubclass) + +/** + @brief Override this method to return a dictionary of valid property names and + types. + @discussion Valid property types are those specified in "Objective-C type encodings" + https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtTypeEncodings.html + */ +- (NSDictionary* _Nonnull) bindableProperties; + +/** + @brief This method will be called when the view has been bound with the model's + first property only. + @discussion Override this method if your view needs to subscribe to + notifications or control events to listen for changes input by the user. + See EBKUI* classes for more details. + */ +- (void) viewDidBindWithModel; + +/** + @brief This method is called when the bound object's properties have been updated, + and the view's properties need to be updated to keep in sync. + @discussion See EBKUI* classes for more details. + */ +- (void) updateViewFromBoundModel; + +/** + @brief If the view property is bound to an model property, then the value is + set onto the model against the bound model property. + */ +- (void) setBoundValue: (NSObject* _Nullable) value viewKey: (NSString* _Nonnull) viewKey; + +/** + @brief If the view property is mapped to an model property, then the value is + retrieved from the model against the mapped model property. + @discussion If the value is non-nil then the value is returned. If the value is + nil, the [NSNull null] is returned. If the view property is not mapped to an + object property, then nil is returned. + */ +- (NSObject* _Nullable) boundValueForViewKey: (NSString* _Nonnull) viewKey NS_SWIFT_NAME(boundValue(viewKey:)); + +@end + +@interface EBKView (EBKDynamicSubclassRegistry) + +/** + @brief Override to return the EBKUI* version of a UIKit view. + */ +- (Class _Nullable) EBKDynamicSubclass NS_SWIFT_NAME(EBKDynamicSubclass()); + +@end + +#pragma mark Vendor integration - debug logging + +typedef NS_OPTIONS(NSUInteger, EBKLogFlag) { + EBKLogFlagError = 1 << 0, // 0...00001 + EBKLogFlagWarn = 1 << 1, // 0...00010 + EBKLogFlagInfo = 1 << 2, // 0...00100 + EBKLogFlagDebug = 1 << 3, // 0...01000 + EBKLogFlagVerbose = 1 << 4, // 0...10000 +}; + +typedef NS_ENUM(NSUInteger, EBKLogLevel) { + EBKLogLevelOff = 0, // 0...00000 + EBKLogLevelError = (EBKLogFlagError), // 0...00001 + EBKLogLevelWarn = (EBKLogLevelError|EBKLogFlagWarn), // 0...00011 + EBKLogLevelInfo = (EBKLogLevelWarn|EBKLogFlagInfo), // 0...00111 + EBKLogLevelDebug = (EBKLogLevelInfo|EBKLogFlagDebug), // 0...01111 + EBKLogLevelVerbose = (EBKLogLevelDebug|EBKLogFlagVerbose), // 0...11111 + EBKLogLevelAll = NSUIntegerMax // 1111...1111 +}; + +#define EBKERROR(msg,...) EBKLogO(EBKLogFlagError,__FILE__,NSStringFromSelector(_cmd),__LINE__,msg,##__VA_ARGS__) +#define EBKDEBUG(msg,...) EBKLogO(EBKLogFlagDebug,__FILE__,NSStringFromSelector(_cmd),__LINE__,msg,##__VA_ARGS__) +#define EBKVERBOSE(msg,...) EBKLogO(EBKLogFlagVerbose,__FILE__,NSStringFromSelector(_cmd),__LINE__,msg,##__VA_ARGS__) + +/** + @brief Enables or disables logging to the console based upon the level specified. + @discussion Valid logging levels are EBKLogLevelOff < EBKLogLevelError < EBKLogLevelWarn < EBKLogLevelInfo < EBKLogLevelDebug < EBKLogLevelVerbose. + The default logging level is EBKLogLevelError. + */ +extern void EBKSetLogging(EBKLogLevel logLevel); + +/** + @brief Logs an ObjC style string and variable arguments in sprintf format to the + console if logging is enabled. + */ +extern void EBKLogO(EBKLogFlag logFlag, const char* _Nonnull path, NSString* _Nonnull method, int line, NSString* _Nonnull msg, ...); + +/** + @brief Logs an Swift style string to the console if logging is enabled. + */ +extern void EBKLogS(EBKLogFlag logFlag, NSString* _Nonnull msg); + +#pragma mark Vendor integration - multicasting delegates for dynamic subclasses + +/** + @brief Multi-casting delegate + @discussion If a dynamic subclass needs to use delegation to be notified of changes + to the view (as opposed to target-action or notifications), then it can + use this class to multi-cast delegate methods. + @remark See MySearchBar.swift for usage. + */ +@interface EBKMulticastDelegate : NSObject + +@property(weak, nullable) id primaryDelegate; +@property(weak, nullable) id secondaryDelegate; + +@end #endif // BindKit_h diff --git a/BindKit.xcframework/ios-arm64_x86_64-simulator/BindKit.framework/Info.plist b/BindKit.xcframework/ios-arm64_x86_64-simulator/BindKit.framework/Info.plist new file mode 100644 index 0000000..5b12500 Binary files /dev/null and b/BindKit.xcframework/ios-arm64_x86_64-simulator/BindKit.framework/Info.plist differ diff --git a/BindKit.xcframework/ios-arm64_x86_64-simulator/BindKit.framework/Modules/module.modulemap b/BindKit.xcframework/ios-arm64_x86_64-simulator/BindKit.framework/Modules/module.modulemap new file mode 100644 index 0000000..bd7cc2c --- /dev/null +++ b/BindKit.xcframework/ios-arm64_x86_64-simulator/BindKit.framework/Modules/module.modulemap @@ -0,0 +1,5 @@ +framework module BindKit { + umbrella header "BindKit.h" + export * + module * { export * } +} diff --git a/BindKit.xcframework/ios-arm64_x86_64-simulator/BindKit.framework/PrivacyInfo.xcprivacy b/BindKit.xcframework/ios-arm64_x86_64-simulator/BindKit.framework/PrivacyInfo.xcprivacy new file mode 100644 index 0000000..2009fb7 --- /dev/null +++ b/BindKit.xcframework/ios-arm64_x86_64-simulator/BindKit.framework/PrivacyInfo.xcprivacy @@ -0,0 +1,14 @@ + + + + + NSPrivacyTracking + + NSPrivacyTrackingDomains + + NSPrivacyCollectedDataTypes + + NSPrivacyAccessedAPITypes + + + diff --git a/BindKit.xcframework/ios-arm64_x86_64-simulator/BindKit.framework/_CodeSignature/CodeDirectory b/BindKit.xcframework/ios-arm64_x86_64-simulator/BindKit.framework/_CodeSignature/CodeDirectory new file mode 100644 index 0000000..e39b273 Binary files /dev/null and b/BindKit.xcframework/ios-arm64_x86_64-simulator/BindKit.framework/_CodeSignature/CodeDirectory differ diff --git a/BindKit.xcframework/ios-arm64_x86_64-simulator/BindKit.framework/_CodeSignature/CodeRequirements b/BindKit.xcframework/ios-arm64_x86_64-simulator/BindKit.framework/_CodeSignature/CodeRequirements new file mode 100644 index 0000000..dbf9d61 Binary files /dev/null and b/BindKit.xcframework/ios-arm64_x86_64-simulator/BindKit.framework/_CodeSignature/CodeRequirements differ diff --git a/BindKit.xcframework/ios-arm64_x86_64-simulator/BindKit.framework/_CodeSignature/CodeRequirements-1 b/BindKit.xcframework/ios-arm64_x86_64-simulator/BindKit.framework/_CodeSignature/CodeRequirements-1 new file mode 100644 index 0000000..88ce71d Binary files /dev/null and b/BindKit.xcframework/ios-arm64_x86_64-simulator/BindKit.framework/_CodeSignature/CodeRequirements-1 differ diff --git a/BindKit.xcframework/ios-arm64_x86_64-simulator/BindKit.framework/_CodeSignature/CodeResources b/BindKit.xcframework/ios-arm64_x86_64-simulator/BindKit.framework/_CodeSignature/CodeResources new file mode 100644 index 0000000..810e4ef --- /dev/null +++ b/BindKit.xcframework/ios-arm64_x86_64-simulator/BindKit.framework/_CodeSignature/CodeResources @@ -0,0 +1,147 @@ + + + + + files + + Headers/BindKit.h + + cLZvtvaNnQ7PattArdpmP2mRST4= + + Info.plist + + 1pmHCHPT3rfxXGUDsahGcSc46pU= + + Modules/module.modulemap + + cBD5IYs7ZDarz+IlMGtjTPAomVA= + + PrivacyInfo.xcprivacy + + J3jCDET/Yn1lAQbrw44v61PrV7c= + + + files2 + + Headers/BindKit.h + + hash + + cLZvtvaNnQ7PattArdpmP2mRST4= + + hash2 + + 4H/B1PLN8rcydl29hUVNFt0cn9H/JVcFyW+m3qxKrLU= + + + Modules/module.modulemap + + hash + + cBD5IYs7ZDarz+IlMGtjTPAomVA= + + hash2 + + z7OYBPWLYkel6T7lWL+Gm0+2SFbMIDjp3+0hS/trHQE= + + + PrivacyInfo.xcprivacy + + hash + + J3jCDET/Yn1lAQbrw44v61PrV7c= + + hash2 + + Uoqz/KkQ0qwvPvJW1epMIycwOnpKXvuSNph/MBjjEfM= + + + + rules + + ^.* + + ^.*\.lproj/ + + optional + + weight + 1000 + + ^.*\.lproj/locversion.plist$ + + omit + + weight + 1100 + + ^Base\.lproj/ + + weight + 1010 + + ^version.plist$ + + + rules2 + + .*\.dSYM($|/) + + weight + 11 + + ^(.*/)?\.DS_Store$ + + omit + + weight + 2000 + + ^.* + + ^.*\.lproj/ + + optional + + weight + 1000 + + ^.*\.lproj/locversion.plist$ + + omit + + weight + 1100 + + ^Base\.lproj/ + + weight + 1010 + + ^Info\.plist$ + + omit + + weight + 20 + + ^PkgInfo$ + + omit + + weight + 20 + + ^embedded\.provisionprofile$ + + weight + 20 + + ^version\.plist$ + + weight + 20 + + + + diff --git a/BindKit.xcframework/ios-arm64_x86_64-simulator/BindKit.framework/_CodeSignature/CodeSignature b/BindKit.xcframework/ios-arm64_x86_64-simulator/BindKit.framework/_CodeSignature/CodeSignature new file mode 100644 index 0000000..e69de29 diff --git a/BindKit.xcworkspace/contents.xcworkspacedata b/BindKit.xcworkspace/contents.xcworkspacedata index 4f2edee..2302615 100644 --- a/BindKit.xcworkspace/contents.xcworkspacedata +++ b/BindKit.xcworkspace/contents.xcworkspacedata @@ -5,6 +5,6 @@ location = "group:BindingExample/BindingExample.xcodeproj"> + location = "group:/Users/Shared/build/bindkit/BindKit/BindKit.xcodeproj"> diff --git a/BindKit.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/BindKit.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/BindKit.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/BindKit/BindKit.xcodeproj/project.pbxproj b/BindKit/BindKit.xcodeproj/project.pbxproj index 4159e69..223721e 100644 --- a/BindKit/BindKit.xcodeproj/project.pbxproj +++ b/BindKit/BindKit.xcodeproj/project.pbxproj @@ -9,25 +9,6 @@ /* Begin PBXBuildFile section */ 344278082058B17B002A5EA8 /* dog.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 344278072058B17B002A5EA8 /* dog.jpg */; }; 3442780A2058B186002A5EA8 /* cat.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 344278092058B186002A5EA8 /* cat.jpg */; }; - 346007C3204CEA14007059C4 /* EBKDeallocationObserver.m in Sources */ = {isa = PBXBuildFile; fileRef = 346007C2204CEA14007059C4 /* EBKDeallocationObserver.m */; }; - 743BC36A204E32A2007A0EEB /* EBKMulticastDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 743BC369204E32A2007A0EEB /* EBKMulticastDelegate.m */; }; - 747B7DFF2044A64F002BD36E /* EBKView+EBKSubclass.m in Sources */ = {isa = PBXBuildFile; fileRef = 747B7DEC2044A64E002BD36E /* EBKView+EBKSubclass.m */; }; - 747B7E002044A64F002BD36E /* EBKUISegmentedControl.m in Sources */ = {isa = PBXBuildFile; fileRef = 747B7DED2044A64F002BD36E /* EBKUISegmentedControl.m */; }; - 747B7E012044A64F002BD36E /* EBKUISlider.m in Sources */ = {isa = PBXBuildFile; fileRef = 747B7DEF2044A64F002BD36E /* EBKUISlider.m */; }; - 747B7E022044A64F002BD36E /* EBKUISwitch.m in Sources */ = {isa = PBXBuildFile; fileRef = 747B7DF02044A64F002BD36E /* EBKUISwitch.m */; }; - 747B7E032044A64F002BD36E /* EBKProperty.m in Sources */ = {isa = PBXBuildFile; fileRef = 747B7DF12044A64F002BD36E /* EBKProperty.m */; }; - 747B7E042044A64F002BD36E /* EBKUITextField.m in Sources */ = {isa = PBXBuildFile; fileRef = 747B7DF22044A64F002BD36E /* EBKUITextField.m */; }; - 747B7E052044A64F002BD36E /* EBKView+EBKDynamicSubclass.m in Sources */ = {isa = PBXBuildFile; fileRef = 747B7DF52044A64F002BD36E /* EBKView+EBKDynamicSubclass.m */; }; - 747B7E062044A64F002BD36E /* NSObject+EBKBinding.m in Sources */ = {isa = PBXBuildFile; fileRef = 747B7DF72044A64F002BD36E /* NSObject+EBKBinding.m */; }; - 747B7E072044A64F002BD36E /* EBKLog.m in Sources */ = {isa = PBXBuildFile; fileRef = 747B7DF82044A64F002BD36E /* EBKLog.m */; }; - 747B7E082044A64F002BD36E /* EBKUIStepper.m in Sources */ = {isa = PBXBuildFile; fileRef = 747B7DF92044A64F002BD36E /* EBKUIStepper.m */; }; - 747B7E092044A64F002BD36E /* EBKBinding.m in Sources */ = {isa = PBXBuildFile; fileRef = 747B7DFA2044A64F002BD36E /* EBKBinding.m */; }; - 747B7E0A2044A64F002BD36E /* EBKUITextView.m in Sources */ = {isa = PBXBuildFile; fileRef = 747B7DFD2044A64F002BD36E /* EBKUITextView.m */; }; - 748177872046938A003A8E13 /* EBKUILabel.m in Sources */ = {isa = PBXBuildFile; fileRef = 748177862046938A003A8E13 /* EBKUILabel.m */; }; - 7495CBDF204A62C80099C0E6 /* EBKInternalBinding.m in Sources */ = {isa = PBXBuildFile; fileRef = 7495CBDE204A62C80099C0E6 /* EBKInternalBinding.m */; }; - 7495CC10204BD9C80099C0E6 /* EBKUIDatePicker.m in Sources */ = {isa = PBXBuildFile; fileRef = 7495CC0F204BD9C80099C0E6 /* EBKUIDatePicker.m */; }; - 7495CC12204BDE770099C0E6 /* EBKUIImageView.m in Sources */ = {isa = PBXBuildFile; fileRef = 7495CC11204BDE770099C0E6 /* EBKUIImageView.m */; }; - 7495CC14204BE0860099C0E6 /* EBKUIPageControl.m in Sources */ = {isa = PBXBuildFile; fileRef = 7495CC13204BE0860099C0E6 /* EBKUIPageControl.m */; }; 74A6908B205773FA000F8AD9 /* EBKUIImageViewTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 74A6908A205773FA000F8AD9 /* EBKUIImageViewTests.m */; }; 74A6909120577C20000F8AD9 /* EBKUILabelTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 74A6909020577C20000F8AD9 /* EBKUILabelTests.m */; }; 74A6909320577DE2000F8AD9 /* EBKUIPageControlTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 74A6909220577DE2000F8AD9 /* EBKUIPageControlTests.m */; }; @@ -42,45 +23,54 @@ 74D72B4D20579188003CD4FE /* EBKUISwitchTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 74D72B4C20579188003CD4FE /* EBKUISwitchTests.m */; }; 74D72B4F205795EC003CD4FE /* EBKUITextFieldTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 74D72B4E205795EC003CD4FE /* EBKUITextFieldTests.m */; }; 74D72B5120579777003CD4FE /* EBKUITextViewTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 74D72B5020579777003CD4FE /* EBKUITextViewTests.m */; }; - 74EDA31420479E6A007066F8 /* EBKUIButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 74EDA31320479E6A007066F8 /* EBKUIButton.m */; }; - 74EDA31620479F9D007066F8 /* EBKUIBarButtonItem.m in Sources */ = {isa = PBXBuildFile; fileRef = 74EDA31520479F9D007066F8 /* EBKUIBarButtonItem.m */; }; 74F214C120525D5F0030DA11 /* EBKDeallocationObserverTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 74F214C020525D5F0030DA11 /* EBKDeallocationObserverTests.m */; }; - 74F214C320525D5F0030DA11 /* libBindKit.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 747B7DD82044A45B002BD36E /* libBindKit.a */; }; 74F214CC205272820030DA11 /* EBKMulticastDelegateTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 74F214CB205272820030DA11 /* EBKMulticastDelegateTests.m */; }; 74F214CE205359340030DA11 /* EBKPropertyTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 74F214CD205359340030DA11 /* EBKPropertyTests.m */; }; 74F214D0205377500030DA11 /* EBKViewSubclassTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 74F214CF205377500030DA11 /* EBKViewSubclassTests.m */; }; 74F214D22053BB2C0030DA11 /* EBKBindingTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 74F214D12053BB2C0030DA11 /* EBKBindingTests.m */; }; + C35A9A482C5E2545008B9A80 /* NSObject+EBKBinding.m in Sources */ = {isa = PBXBuildFile; fileRef = 747B7DF72044A64F002BD36E /* NSObject+EBKBinding.m */; }; + C35A9A492C5E2545008B9A80 /* EBKMulticastDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 743BC369204E32A2007A0EEB /* EBKMulticastDelegate.m */; }; + C35A9A4A2C5E2545008B9A80 /* EBKUIButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 74EDA31320479E6A007066F8 /* EBKUIButton.m */; }; + C35A9A4B2C5E2545008B9A80 /* EBKInternalBinding.m in Sources */ = {isa = PBXBuildFile; fileRef = 7495CBDE204A62C80099C0E6 /* EBKInternalBinding.m */; }; + C35A9A4C2C5E2545008B9A80 /* EBKUISegmentedControl.m in Sources */ = {isa = PBXBuildFile; fileRef = 747B7DED2044A64F002BD36E /* EBKUISegmentedControl.m */; }; + C35A9A4D2C5E2545008B9A80 /* EBKUITextField.m in Sources */ = {isa = PBXBuildFile; fileRef = 747B7DF22044A64F002BD36E /* EBKUITextField.m */; }; + C35A9A4E2C5E2545008B9A80 /* EBKView+EBKSubclass.m in Sources */ = {isa = PBXBuildFile; fileRef = 747B7DEC2044A64E002BD36E /* EBKView+EBKSubclass.m */; }; + C35A9A4F2C5E2545008B9A80 /* EBKLog.m in Sources */ = {isa = PBXBuildFile; fileRef = 747B7DF82044A64F002BD36E /* EBKLog.m */; }; + C35A9A502C5E2545008B9A80 /* EBKView+EBKDynamicSubclass.m in Sources */ = {isa = PBXBuildFile; fileRef = 747B7DF52044A64F002BD36E /* EBKView+EBKDynamicSubclass.m */; }; + C35A9A512C5E2545008B9A80 /* EBKProperty.m in Sources */ = {isa = PBXBuildFile; fileRef = 747B7DF12044A64F002BD36E /* EBKProperty.m */; }; + C35A9A522C5E2545008B9A80 /* EBKDeallocationObserver.m in Sources */ = {isa = PBXBuildFile; fileRef = 346007C2204CEA14007059C4 /* EBKDeallocationObserver.m */; }; + C35A9A532C5E2545008B9A80 /* EBKUILabel.m in Sources */ = {isa = PBXBuildFile; fileRef = 748177862046938A003A8E13 /* EBKUILabel.m */; }; + C35A9A542C5E2545008B9A80 /* EBKBinding.m in Sources */ = {isa = PBXBuildFile; fileRef = 747B7DFA2044A64F002BD36E /* EBKBinding.m */; }; + C35A9A552C5E2545008B9A80 /* EBKUISlider.m in Sources */ = {isa = PBXBuildFile; fileRef = 747B7DEF2044A64F002BD36E /* EBKUISlider.m */; }; + C35A9A562C5E2545008B9A80 /* EBKUIDatePicker.m in Sources */ = {isa = PBXBuildFile; fileRef = 7495CC0F204BD9C80099C0E6 /* EBKUIDatePicker.m */; }; + C35A9A572C5E2545008B9A80 /* EBKUIImageView.m in Sources */ = {isa = PBXBuildFile; fileRef = 7495CC11204BDE770099C0E6 /* EBKUIImageView.m */; }; + C35A9A582C5E2545008B9A80 /* EBKUITextView.m in Sources */ = {isa = PBXBuildFile; fileRef = 747B7DFD2044A64F002BD36E /* EBKUITextView.m */; }; + C35A9A592C5E2545008B9A80 /* EBKUIPageControl.m in Sources */ = {isa = PBXBuildFile; fileRef = 7495CC13204BE0860099C0E6 /* EBKUIPageControl.m */; }; + C35A9A5A2C5E2545008B9A80 /* EBKUIBarButtonItem.m in Sources */ = {isa = PBXBuildFile; fileRef = 74EDA31520479F9D007066F8 /* EBKUIBarButtonItem.m */; }; + C35A9A5B2C5E2545008B9A80 /* EBKUIStepper.m in Sources */ = {isa = PBXBuildFile; fileRef = 747B7DF92044A64F002BD36E /* EBKUIStepper.m */; }; + C35A9A5C2C5E2545008B9A80 /* EBKUISwitch.m in Sources */ = {isa = PBXBuildFile; fileRef = 747B7DF02044A64F002BD36E /* EBKUISwitch.m */; }; + C35A9A5E2C5E2828008B9A80 /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = C35A9A5D2C5E2828008B9A80 /* PrivacyInfo.xcprivacy */; }; + C35A9A6B2C5E2D5A008B9A80 /* BindKit-Prefix.pch in Headers */ = {isa = PBXBuildFile; fileRef = C35A9A6A2C5E2D5A008B9A80 /* BindKit-Prefix.pch */; }; + C35A9A7A2C5E32CC008B9A80 /* BindKit.h in Headers */ = {isa = PBXBuildFile; fileRef = 749ECAA92057A7C000D3706B /* BindKit.h */; settings = {ATTRIBUTES = (Public, ); }; }; + C35D3CFE2C5E34F5005539FF /* BindKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C35A9A412C5E24CE008B9A80 /* BindKit.framework */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ - 74F214C420525D5F0030DA11 /* PBXContainerItemProxy */ = { + C35D3CFB2C5E34E9005539FF /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 747B7DD02044A45B002BD36E /* Project object */; proxyType = 1; - remoteGlobalIDString = 747B7DD72044A45B002BD36E; + remoteGlobalIDString = C35A9A402C5E24CE008B9A80; remoteInfo = BindKit; }; /* End PBXContainerItemProxy section */ -/* Begin PBXCopyFilesBuildPhase section */ - 747B7DD62044A45B002BD36E /* CopyFiles */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = "include/$(PRODUCT_NAME)"; - dstSubfolderSpec = 16; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXCopyFilesBuildPhase section */ - /* Begin PBXFileReference section */ 344278072058B17B002A5EA8 /* dog.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; name = dog.jpg; path = ../../BindingExample/BindingExample/Assets.xcassets/dog.imageset/dog.jpg; sourceTree = ""; }; 344278092058B186002A5EA8 /* cat.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; name = cat.jpg; path = ../../BindingExample/BindingExample/Assets.xcassets/cat.imageset/cat.jpg; sourceTree = ""; }; 346007C1204CEA14007059C4 /* EBKDeallocationObserver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EBKDeallocationObserver.h; sourceTree = ""; }; 346007C2204CEA14007059C4 /* EBKDeallocationObserver.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EBKDeallocationObserver.m; sourceTree = ""; }; 743BC369204E32A2007A0EEB /* EBKMulticastDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = EBKMulticastDelegate.m; sourceTree = ""; }; - 747B7DD82044A45B002BD36E /* libBindKit.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libBindKit.a; sourceTree = BUILT_PRODUCTS_DIR; }; 747B7DEC2044A64E002BD36E /* EBKView+EBKSubclass.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "EBKView+EBKSubclass.m"; sourceTree = ""; }; 747B7DED2044A64F002BD36E /* EBKUISegmentedControl.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EBKUISegmentedControl.m; sourceTree = ""; }; 747B7DEE2044A64F002BD36E /* EBKBinding.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EBKBinding.h; sourceTree = ""; }; @@ -98,12 +88,10 @@ 747B7DFD2044A64F002BD36E /* EBKUITextView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EBKUITextView.m; sourceTree = ""; }; 747B7E0E2044A9C6002BD36E /* NSObject+EBKBinding.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "NSObject+EBKBinding.h"; sourceTree = ""; }; 748177862046938A003A8E13 /* EBKUILabel.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = EBKUILabel.m; sourceTree = ""; }; - 7495CBDD204A62C80099C0E6 /* EBKInternalBinding.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = EBKInternalBinding.h; sourceTree = ""; }; 7495CBDE204A62C80099C0E6 /* EBKInternalBinding.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = EBKInternalBinding.m; sourceTree = ""; }; 7495CC0F204BD9C80099C0E6 /* EBKUIDatePicker.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = EBKUIDatePicker.m; sourceTree = ""; }; 7495CC11204BDE770099C0E6 /* EBKUIImageView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = EBKUIImageView.m; sourceTree = ""; }; 7495CC13204BE0860099C0E6 /* EBKUIPageControl.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = EBKUIPageControl.m; sourceTree = ""; }; - 749ECAA82057A7C000D3706B /* BindKitVendor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BindKitVendor.h; sourceTree = ""; }; 749ECAA92057A7C000D3706B /* BindKit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BindKit.h; sourceTree = ""; }; 74A6908A205773FA000F8AD9 /* EBKUIImageViewTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = EBKUIImageViewTests.m; sourceTree = ""; }; 74A6909020577C20000F8AD9 /* EBKUILabelTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = EBKUILabelTests.m; sourceTree = ""; }; @@ -129,21 +117,26 @@ 74F214CD205359340030DA11 /* EBKPropertyTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = EBKPropertyTests.m; sourceTree = ""; }; 74F214CF205377500030DA11 /* EBKViewSubclassTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = EBKViewSubclassTests.m; sourceTree = ""; }; 74F214D12053BB2C0030DA11 /* EBKBindingTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = EBKBindingTests.m; sourceTree = ""; }; + C35A9A412C5E24CE008B9A80 /* BindKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = BindKit.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + C35A9A5D2C5E2828008B9A80 /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = PrivacyInfo.xcprivacy; sourceTree = ""; }; + C35A9A692C5E2D5A008B9A80 /* BindKit.modulemap */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = "sourcecode.module-map"; path = BindKit.modulemap; sourceTree = ""; }; + C35A9A6A2C5E2D5A008B9A80 /* BindKit-Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "BindKit-Prefix.pch"; sourceTree = ""; }; + C35A9A782C5E3202008B9A80 /* EBKInternalBinding.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EBKInternalBinding.h; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ - 747B7DD52044A45B002BD36E /* Frameworks */ = { + 74F214BB20525D5F0030DA11 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + C35D3CFE2C5E34F5005539FF /* BindKit.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; - 74F214BB20525D5F0030DA11 /* Frameworks */ = { + C35A9A3E2C5E24CE008B9A80 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 74F214C320525D5F0030DA11 /* libBindKit.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -153,57 +146,112 @@ 747B7DCF2044A45B002BD36E = { isa = PBXGroup; children = ( - 747B7DDA2044A45B002BD36E /* BindKit */, + C35A9A422C5E24CE008B9A80 /* BindKit */, 74F214BF20525D5F0030DA11 /* BindKitTests */, 747B7DD92044A45B002BD36E /* Products */, + C35D3CFD2C5E34F5005539FF /* Frameworks */, ); sourceTree = ""; }; 747B7DD92044A45B002BD36E /* Products */ = { isa = PBXGroup; children = ( - 747B7DD82044A45B002BD36E /* libBindKit.a */, 74F214BE20525D5F0030DA11 /* BindKitTests.xctest */, + C35A9A412C5E24CE008B9A80 /* BindKit.framework */, ); name = Products; sourceTree = ""; }; - 747B7DDA2044A45B002BD36E /* BindKit */ = { + 74F214BF20525D5F0030DA11 /* BindKitTests */ = { isa = PBXGroup; children = ( - 747B7DE72044A5AD002BD36E /* public */, - 747B7DE82044A604002BD36E /* private */, + 344278092058B186002A5EA8 /* cat.jpg */, + 344278072058B17B002A5EA8 /* dog.jpg */, + 74F214C020525D5F0030DA11 /* EBKDeallocationObserverTests.m */, + 74F214CB205272820030DA11 /* EBKMulticastDelegateTests.m */, + 74F214CD205359340030DA11 /* EBKPropertyTests.m */, + 74F214CF205377500030DA11 /* EBKViewSubclassTests.m */, + 74F214D12053BB2C0030DA11 /* EBKBindingTests.m */, + 74B7F49120550A0700E608C9 /* EBKInternalBindingTests.m */, + 74B7F49420551DF200E608C9 /* NSObjectEBKBindingTests.m */, + 74B7F4972055259000E608C9 /* EBKUIBarButtonItemTests.m */, + 74B7F499205526E500E608C9 /* EBKUIButtonTests.m */, + 74B7F49B2055281B00E608C9 /* EBKUIDatePickerTests.m */, + 74A6908A205773FA000F8AD9 /* EBKUIImageViewTests.m */, + 74A6909020577C20000F8AD9 /* EBKUILabelTests.m */, + 74A6909220577DE2000F8AD9 /* EBKUIPageControlTests.m */, + 74D72B4620578C9E003CD4FE /* EBKUISegmentedControlTests.m */, + 74D72B4820578E48003CD4FE /* EBKUISliderTests.m */, + 74D72B4A20578FD5003CD4FE /* EBKUIStepperTests.m */, + 74D72B4C20579188003CD4FE /* EBKUISwitchTests.m */, + 74D72B4E205795EC003CD4FE /* EBKUITextFieldTests.m */, + 74D72B5020579777003CD4FE /* EBKUITextViewTests.m */, + 74F214C220525D5F0030DA11 /* Info.plist */, + ); + path = BindKitTests; + sourceTree = ""; + }; + C35A9A422C5E24CE008B9A80 /* BindKit */ = { + isa = PBXGroup; + children = ( + C35A9A6C2C5E305E008B9A80 /* public */, + C35A9A6E2C5E3089008B9A80 /* private */, + C35A9A682C5E2D32008B9A80 /* other */, ); path = BindKit; sourceTree = ""; }; - 747B7DE72044A5AD002BD36E /* public */ = { + C35A9A682C5E2D32008B9A80 /* other */ = { + isa = PBXGroup; + children = ( + C35A9A6A2C5E2D5A008B9A80 /* BindKit-Prefix.pch */, + C35A9A692C5E2D5A008B9A80 /* BindKit.modulemap */, + C35A9A5D2C5E2828008B9A80 /* PrivacyInfo.xcprivacy */, + ); + name = other; + sourceTree = ""; + }; + C35A9A6C2C5E305E008B9A80 /* public */ = { isa = PBXGroup; children = ( 749ECAA92057A7C000D3706B /* BindKit.h */, - 749ECAA82057A7C000D3706B /* BindKitVendor.h */, ); - path = public; + name = public; sourceTree = ""; }; - 747B7DE82044A604002BD36E /* private */ = { + C35A9A6E2C5E3089008B9A80 /* private */ = { isa = PBXGroup; children = ( - 747B7E0D2044A95C002BD36E /* util */, - 747B7E0B2044A655002BD36E /* views */, + C35A9A6F2C5E308E008B9A80 /* util */, + C35A9A702C5E3094008B9A80 /* views */, 747B7DEE2044A64F002BD36E /* EBKBinding.h */, 747B7DFA2044A64F002BD36E /* EBKBinding.m */, - 7495CBDD204A62C80099C0E6 /* EBKInternalBinding.h */, + C35A9A782C5E3202008B9A80 /* EBKInternalBinding.h */, 7495CBDE204A62C80099C0E6 /* EBKInternalBinding.m */, 747B7E0E2044A9C6002BD36E /* NSObject+EBKBinding.h */, 747B7DF72044A64F002BD36E /* NSObject+EBKBinding.m */, 74C42E232048C9A100E6E2A9 /* EBKView+EBKDynamicSubclass.h */, 747B7DF52044A64F002BD36E /* EBKView+EBKDynamicSubclass.m */, ); - path = private; + name = private; sourceTree = ""; }; - 747B7E0B2044A655002BD36E /* views */ = { + C35A9A6F2C5E308E008B9A80 /* util */ = { + isa = PBXGroup; + children = ( + 346007C1204CEA14007059C4 /* EBKDeallocationObserver.h */, + 346007C2204CEA14007059C4 /* EBKDeallocationObserver.m */, + 747B7DF82044A64F002BD36E /* EBKLog.m */, + 743BC369204E32A2007A0EEB /* EBKMulticastDelegate.m */, + 747B7DF32044A64F002BD36E /* EBKProperty.h */, + 747B7DF12044A64F002BD36E /* EBKProperty.m */, + 747B7DF42044A64F002BD36E /* EBKView+EBKSubclass.h */, + 747B7DEC2044A64E002BD36E /* EBKView+EBKSubclass.m */, + ); + name = util; + sourceTree = ""; + }; + C35A9A702C5E3094008B9A80 /* views */ = { isa = PBXGroup; children = ( 74EDA31520479F9D007066F8 /* EBKUIBarButtonItem.m */, @@ -222,70 +270,28 @@ name = views; sourceTree = ""; }; - 747B7E0D2044A95C002BD36E /* util */ = { + C35D3CFD2C5E34F5005539FF /* Frameworks */ = { isa = PBXGroup; children = ( - 346007C1204CEA14007059C4 /* EBKDeallocationObserver.h */, - 346007C2204CEA14007059C4 /* EBKDeallocationObserver.m */, - 747B7DF82044A64F002BD36E /* EBKLog.m */, - 743BC369204E32A2007A0EEB /* EBKMulticastDelegate.m */, - 747B7DF32044A64F002BD36E /* EBKProperty.h */, - 747B7DF12044A64F002BD36E /* EBKProperty.m */, - 747B7DF42044A64F002BD36E /* EBKView+EBKSubclass.h */, - 747B7DEC2044A64E002BD36E /* EBKView+EBKSubclass.m */, ); - name = util; - sourceTree = ""; - }; - 74F214BF20525D5F0030DA11 /* BindKitTests */ = { - isa = PBXGroup; - children = ( - 344278092058B186002A5EA8 /* cat.jpg */, - 344278072058B17B002A5EA8 /* dog.jpg */, - 74F214C020525D5F0030DA11 /* EBKDeallocationObserverTests.m */, - 74F214CB205272820030DA11 /* EBKMulticastDelegateTests.m */, - 74F214CD205359340030DA11 /* EBKPropertyTests.m */, - 74F214CF205377500030DA11 /* EBKViewSubclassTests.m */, - 74F214D12053BB2C0030DA11 /* EBKBindingTests.m */, - 74B7F49120550A0700E608C9 /* EBKInternalBindingTests.m */, - 74B7F49420551DF200E608C9 /* NSObjectEBKBindingTests.m */, - 74B7F4972055259000E608C9 /* EBKUIBarButtonItemTests.m */, - 74B7F499205526E500E608C9 /* EBKUIButtonTests.m */, - 74B7F49B2055281B00E608C9 /* EBKUIDatePickerTests.m */, - 74A6908A205773FA000F8AD9 /* EBKUIImageViewTests.m */, - 74A6909020577C20000F8AD9 /* EBKUILabelTests.m */, - 74A6909220577DE2000F8AD9 /* EBKUIPageControlTests.m */, - 74D72B4620578C9E003CD4FE /* EBKUISegmentedControlTests.m */, - 74D72B4820578E48003CD4FE /* EBKUISliderTests.m */, - 74D72B4A20578FD5003CD4FE /* EBKUIStepperTests.m */, - 74D72B4C20579188003CD4FE /* EBKUISwitchTests.m */, - 74D72B4E205795EC003CD4FE /* EBKUITextFieldTests.m */, - 74D72B5020579777003CD4FE /* EBKUITextViewTests.m */, - 74F214C220525D5F0030DA11 /* Info.plist */, - ); - path = BindKitTests; + name = Frameworks; sourceTree = ""; }; /* End PBXGroup section */ -/* Begin PBXNativeTarget section */ - 747B7DD72044A45B002BD36E /* BindKit */ = { - isa = PBXNativeTarget; - buildConfigurationList = 747B7DE12044A45B002BD36E /* Build configuration list for PBXNativeTarget "BindKit" */; - buildPhases = ( - 747B7DD42044A45B002BD36E /* Sources */, - 747B7DD52044A45B002BD36E /* Frameworks */, - 747B7DD62044A45B002BD36E /* CopyFiles */, - ); - buildRules = ( - ); - dependencies = ( +/* Begin PBXHeadersBuildPhase section */ + C35A9A3C2C5E24CE008B9A80 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + C35A9A7A2C5E32CC008B9A80 /* BindKit.h in Headers */, + C35A9A6B2C5E2D5A008B9A80 /* BindKit-Prefix.pch in Headers */, ); - name = BindKit; - productName = BindKit; - productReference = 747B7DD82044A45B002BD36E /* libBindKit.a */; - productType = "com.apple.product-type.library.static"; + runOnlyForDeploymentPostprocessing = 0; }; +/* End PBXHeadersBuildPhase section */ + +/* Begin PBXNativeTarget section */ 74F214BD20525D5F0030DA11 /* BindKitTests */ = { isa = PBXNativeTarget; buildConfigurationList = 74F214C620525D5F0030DA11 /* Build configuration list for PBXNativeTarget "BindKitTests" */; @@ -297,13 +303,31 @@ buildRules = ( ); dependencies = ( - 74F214C520525D5F0030DA11 /* PBXTargetDependency */, + C35D3CFC2C5E34E9005539FF /* PBXTargetDependency */, ); name = BindKitTests; productName = BindKitTests; productReference = 74F214BE20525D5F0030DA11 /* BindKitTests.xctest */; productType = "com.apple.product-type.bundle.unit-test"; }; + C35A9A402C5E24CE008B9A80 /* BindKit */ = { + isa = PBXNativeTarget; + buildConfigurationList = C35A9A452C5E24CE008B9A80 /* Build configuration list for PBXNativeTarget "BindKit" */; + buildPhases = ( + C35A9A3C2C5E24CE008B9A80 /* Headers */, + C35A9A3D2C5E24CE008B9A80 /* Sources */, + C35A9A3E2C5E24CE008B9A80 /* Frameworks */, + C35A9A3F2C5E24CE008B9A80 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = BindKit; + productName = BindKit; + productReference = C35A9A412C5E24CE008B9A80 /* BindKit.framework */; + productType = "com.apple.product-type.framework"; + }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ @@ -313,15 +337,15 @@ LastUpgradeCheck = 1010; ORGANIZATIONNAME = "Electric Bolt Limited"; TargetAttributes = { - 747B7DD72044A45B002BD36E = { - CreatedOnToolsVersion = 9.2; - ProvisioningStyle = Automatic; - }; 74F214BD20525D5F0030DA11 = { CreatedOnToolsVersion = 9.2; LastSwiftMigration = 0920; ProvisioningStyle = Automatic; }; + C35A9A402C5E24CE008B9A80 = { + CreatedOnToolsVersion = 15.4; + ProvisioningStyle = Automatic; + }; }; }; buildConfigurationList = 747B7DD32044A45B002BD36E /* Build configuration list for PBXProject "BindKit" */; @@ -337,7 +361,7 @@ projectDirPath = ""; projectRoot = ""; targets = ( - 747B7DD72044A45B002BD36E /* BindKit */, + C35A9A402C5E24CE008B9A80 /* BindKit */, 74F214BD20525D5F0030DA11 /* BindKitTests */, ); }; @@ -353,37 +377,17 @@ ); runOnlyForDeploymentPostprocessing = 0; }; -/* End PBXResourcesBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - 747B7DD42044A45B002BD36E /* Sources */ = { - isa = PBXSourcesBuildPhase; + C35A9A3F2C5E24CE008B9A80 /* Resources */ = { + isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( - 747B7E092044A64F002BD36E /* EBKBinding.m in Sources */, - 747B7E042044A64F002BD36E /* EBKUITextField.m in Sources */, - 747B7E072044A64F002BD36E /* EBKLog.m in Sources */, - 747B7DFF2044A64F002BD36E /* EBKView+EBKSubclass.m in Sources */, - 743BC36A204E32A2007A0EEB /* EBKMulticastDelegate.m in Sources */, - 7495CC12204BDE770099C0E6 /* EBKUIImageView.m in Sources */, - 747B7E032044A64F002BD36E /* EBKProperty.m in Sources */, - 747B7E062044A64F002BD36E /* NSObject+EBKBinding.m in Sources */, - 747B7E052044A64F002BD36E /* EBKView+EBKDynamicSubclass.m in Sources */, - 7495CC10204BD9C80099C0E6 /* EBKUIDatePicker.m in Sources */, - 747B7E082044A64F002BD36E /* EBKUIStepper.m in Sources */, - 7495CBDF204A62C80099C0E6 /* EBKInternalBinding.m in Sources */, - 747B7E022044A64F002BD36E /* EBKUISwitch.m in Sources */, - 747B7E002044A64F002BD36E /* EBKUISegmentedControl.m in Sources */, - 748177872046938A003A8E13 /* EBKUILabel.m in Sources */, - 346007C3204CEA14007059C4 /* EBKDeallocationObserver.m in Sources */, - 747B7E012044A64F002BD36E /* EBKUISlider.m in Sources */, - 74EDA31620479F9D007066F8 /* EBKUIBarButtonItem.m in Sources */, - 7495CC14204BE0860099C0E6 /* EBKUIPageControl.m in Sources */, - 747B7E0A2044A64F002BD36E /* EBKUITextView.m in Sources */, - 74EDA31420479E6A007066F8 /* EBKUIButton.m in Sources */, + C35A9A5E2C5E2828008B9A80 /* PrivacyInfo.xcprivacy in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ 74F214BA20525D5F0030DA11 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -410,13 +414,41 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + C35A9A3D2C5E24CE008B9A80 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + C35A9A482C5E2545008B9A80 /* NSObject+EBKBinding.m in Sources */, + C35A9A492C5E2545008B9A80 /* EBKMulticastDelegate.m in Sources */, + C35A9A4A2C5E2545008B9A80 /* EBKUIButton.m in Sources */, + C35A9A4B2C5E2545008B9A80 /* EBKInternalBinding.m in Sources */, + C35A9A4C2C5E2545008B9A80 /* EBKUISegmentedControl.m in Sources */, + C35A9A4D2C5E2545008B9A80 /* EBKUITextField.m in Sources */, + C35A9A4E2C5E2545008B9A80 /* EBKView+EBKSubclass.m in Sources */, + C35A9A4F2C5E2545008B9A80 /* EBKLog.m in Sources */, + C35A9A502C5E2545008B9A80 /* EBKView+EBKDynamicSubclass.m in Sources */, + C35A9A512C5E2545008B9A80 /* EBKProperty.m in Sources */, + C35A9A522C5E2545008B9A80 /* EBKDeallocationObserver.m in Sources */, + C35A9A532C5E2545008B9A80 /* EBKUILabel.m in Sources */, + C35A9A542C5E2545008B9A80 /* EBKBinding.m in Sources */, + C35A9A552C5E2545008B9A80 /* EBKUISlider.m in Sources */, + C35A9A562C5E2545008B9A80 /* EBKUIDatePicker.m in Sources */, + C35A9A572C5E2545008B9A80 /* EBKUIImageView.m in Sources */, + C35A9A582C5E2545008B9A80 /* EBKUITextView.m in Sources */, + C35A9A592C5E2545008B9A80 /* EBKUIPageControl.m in Sources */, + C35A9A5A2C5E2545008B9A80 /* EBKUIBarButtonItem.m in Sources */, + C35A9A5B2C5E2545008B9A80 /* EBKUIStepper.m in Sources */, + C35A9A5C2C5E2545008B9A80 /* EBKUISwitch.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ - 74F214C520525D5F0030DA11 /* PBXTargetDependency */ = { + C35D3CFC2C5E34E9005539FF /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 747B7DD72044A45B002BD36E /* BindKit */; - targetProxy = 74F214C420525D5F0030DA11 /* PBXContainerItemProxy */; + target = C35A9A402C5E24CE008B9A80 /* BindKit */; + targetProxy = C35D3CFB2C5E34E9005539FF /* PBXContainerItemProxy */; }; /* End PBXTargetDependency section */ @@ -471,7 +503,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; OTHER_LDFLAGS = ( @@ -526,7 +558,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; MTL_ENABLE_DEBUG_INFO = NO; OTHER_LDFLAGS = ( "-ObjC", @@ -537,63 +569,117 @@ }; name = Release; }; - 747B7DE22044A45B002BD36E /* Debug */ = { + 74F214C720525D5F0030DA11 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + CLANG_ENABLE_MODULES = YES; CODE_SIGN_STYLE = Automatic; - DEPLOYMENT_POSTPROCESSING = NO; DEVELOPMENT_TEAM = KLCLPVKM8C; - OTHER_LDFLAGS = "-ObjC"; + INFOPLIST_FILE = BindKitTests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = nz.co.electricbolt.BindKitTests; PRODUCT_NAME = "$(TARGET_NAME)"; - SKIP_INSTALL = YES; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 3.0; TARGETED_DEVICE_FAMILY = "1,2"; }; name = Debug; }; - 747B7DE32044A45B002BD36E /* Release */ = { + 74F214C820525D5F0030DA11 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + CLANG_ENABLE_MODULES = YES; CODE_SIGN_STYLE = Automatic; - DEPLOYMENT_POSTPROCESSING = YES; DEVELOPMENT_TEAM = KLCLPVKM8C; - OTHER_CFLAGS = "-fembed-bitcode"; - OTHER_LDFLAGS = "-ObjC"; + INFOPLIST_FILE = BindKitTests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = nz.co.electricbolt.BindKitTests; PRODUCT_NAME = "$(TARGET_NAME)"; - SKIP_INSTALL = YES; + SWIFT_VERSION = 3.0; TARGETED_DEVICE_FAMILY = "1,2"; }; name = Release; }; - 74F214C720525D5F0030DA11 /* Debug */ = { + C35A9A462C5E24CE008B9A80 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - CLANG_ENABLE_MODULES = YES; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + BUILD_LIBRARY_FOR_DISTRIBUTION = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; DEVELOPMENT_TEAM = KLCLPVKM8C; - INFOPLIST_FILE = BindKitTests/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 11.2; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + ENABLE_MODULE_VERIFIER = YES; + ENABLE_USER_SCRIPT_SANDBOXING = YES; + GCC_C_LANGUAGE_STANDARD = gnu17; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_KEY_NSHumanReadableCopyright = "Copyright © 2024 Electric Bolt Limited. All rights reserved."; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = nz.co.electricbolt.BindKitTests; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - SWIFT_VERSION = 3.0; + LOCALIZATION_PREFERS_STRING_CATALOGS = YES; + MACH_O_TYPE = staticlib; + MARKETING_VERSION = 1.0; + MODULEMAP_FILE = BindKit/BindKit.modulemap; + MODULE_VERIFIER_SUPPORTED_LANGUAGES = "objective-c objective-c++"; + MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu17 gnu++20"; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = nz.co.electricbolt.BindKit; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + SKIP_INSTALL = NO; + SWIFT_EMIT_LOC_STRINGS = YES; TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; }; name = Debug; }; - 74F214C820525D5F0030DA11 /* Release */ = { + C35A9A472C5E24CE008B9A80 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - CLANG_ENABLE_MODULES = YES; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + BUILD_LIBRARY_FOR_DISTRIBUTION = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; DEVELOPMENT_TEAM = KLCLPVKM8C; - INFOPLIST_FILE = BindKitTests/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 11.2; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + ENABLE_MODULE_VERIFIER = YES; + ENABLE_USER_SCRIPT_SANDBOXING = YES; + GCC_C_LANGUAGE_STANDARD = gnu17; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_KEY_NSHumanReadableCopyright = "Copyright © 2024 Electric Bolt Limited. All rights reserved."; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = nz.co.electricbolt.BindKitTests; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_VERSION = 3.0; + LOCALIZATION_PREFERS_STRING_CATALOGS = YES; + MACH_O_TYPE = staticlib; + MARKETING_VERSION = 1.0; + MODULEMAP_FILE = BindKit/BindKit.modulemap; + MODULE_VERIFIER_SUPPORTED_LANGUAGES = "objective-c objective-c++"; + MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu17 gnu++20"; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = nz.co.electricbolt.BindKit; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + SKIP_INSTALL = NO; + SWIFT_EMIT_LOC_STRINGS = YES; TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; }; name = Release; }; @@ -609,20 +695,20 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 747B7DE12044A45B002BD36E /* Build configuration list for PBXNativeTarget "BindKit" */ = { + 74F214C620525D5F0030DA11 /* Build configuration list for PBXNativeTarget "BindKitTests" */ = { isa = XCConfigurationList; buildConfigurations = ( - 747B7DE22044A45B002BD36E /* Debug */, - 747B7DE32044A45B002BD36E /* Release */, + 74F214C720525D5F0030DA11 /* Debug */, + 74F214C820525D5F0030DA11 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 74F214C620525D5F0030DA11 /* Build configuration list for PBXNativeTarget "BindKitTests" */ = { + C35A9A452C5E24CE008B9A80 /* Build configuration list for PBXNativeTarget "BindKit" */ = { isa = XCConfigurationList; buildConfigurations = ( - 74F214C720525D5F0030DA11 /* Debug */, - 74F214C820525D5F0030DA11 /* Release */, + C35A9A462C5E24CE008B9A80 /* Debug */, + C35A9A472C5E24CE008B9A80 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; diff --git a/BindKit/BindKit/BindKit-Prefix.pch b/BindKit/BindKit/BindKit-Prefix.pch new file mode 100644 index 0000000..ecac3fb --- /dev/null +++ b/BindKit/BindKit/BindKit-Prefix.pch @@ -0,0 +1,7 @@ +// +// Prefix header for all source files of the 'BindKit' target in the 'BindKit' project +// + +#ifdef __OBJC__ + @import Foundation; +#endif diff --git a/BindKit/BindKit/BindKit.h b/BindKit/BindKit/BindKit.h new file mode 100644 index 0000000..71cdd29 --- /dev/null +++ b/BindKit/BindKit/BindKit.h @@ -0,0 +1,306 @@ +// BindKit.h +// BindKit Copyright (c) 2018-2024; Electric Bolt Limited. + +#ifndef BindKit_h +#define BindKit_h + +#import + +// Not all UIKit views inherit from UIView (e.g. UIBarButtonItem). +#define EBKView NSObject + +@protocol EBKBoundPropertiesDelegate + +- (void) boundPropertiesDidUpdate; + +@end + +/** + @brief Properties of model objects can be bound to user interface elements to + access and modify their values. + */ +@interface NSObject (EBKBinding) + +/** + @brief This update block will be called when any of the model's bound + properties are updated. + @remark See also boundPropertiesDelegate and boundPropertiesDidUpdate. + */ +@property(nonatomic, copy, nullable) dispatch_block_t boundPropertiesUpdateBlock; + +/** + @brief This delegate will be called when any of the model's bound properties are + updated. + + @remark See also boundPropertiesUpdateBlock and boundPropertiesDidUpdate. + */ +@property(nonatomic, weak, nullable) id boundPropertiesDelegate; + +/** + @abstract This method will be called when any of the model's bound properties + are updated. + + @remark See also boundPropertiesUpdateBlock and boundPropertiesDelegate. + */ +- (void) boundPropertiesDidUpdate; + +/** + @abstract This method signals to the system that you are about to make + modifications to model's bound properties. + + @discussion Any modifications to properties are coalesced. When you have + finished making modifications, call the endUpdatingBoundProperties method. + boundPropertiesDidUpdate, boundPropertiesDelegate, boundPropertiesUpdateBlock + are called once (in that order). Calls to beginUpdatingBoundProperties must be + balanced with endUpdatingBoundProperties. + + @remark See also updateBoundProperties. + */ +- (void) beginUpdatingBoundProperties; +- (void) endUpdatingBoundProperties; + +/** + @abstract This method coalesces all modifications to the model's bound properties made + within the block. + + @discussion When the block completes, boundPropertiesDidUpdate, + boundPropertiesDelegate, boundPropertiesUpdateBlock are called once (in that + order). + + @remark See also beginUpdatingBoundProperties. + */ +- (void) updateBoundProperties: (dispatch_block_t _Nonnull) block; + +/** + @abstract Binds a model property to a view property using selectors. + + @discussion Objective-C usage example: + @code + [model bindSel: @selector(nameStr) view: nameTextField viewSel: @selector(text)]; + @endcode + + @param modelSel Selector for the model property to bind. Must not be nil. + @param view View to bind with the model. Must not be nil. + @param viewKey Keypath string for the view property to bind. Must not be nil. e.g. UISwitchEnabled -> "enabled" + + @throws EBKBindingException will be thrown if the following programmer errors + are detected during the binding process: + "Model property parameter cannot be nil", + "View parameter cannot be nil", + "View property parameter cannot be nil", + "Model [model] property with name [name] not found", + "Model [model] property getter with name [name] is not defined", + "Model [model] property setter with name [name] is not defined", + "Model [model] property with name [name] is read only", + "Duplicate binding exists with model [model] property name [name] and view [view] property name [name]", + "Model [model] property with name [name] unsupported type [type] expecting [type]", + "View [view] unsupported property [name]" + + @remark See also beginUpdatingBoundProperties. + */ +- (void) bindSel: (SEL _Nonnull) modelSel view: (EBKView* _Nonnull) view viewKey: (NSString* _Nonnull) viewKey; + +/*! + @brief Binds a model property to a view property using key paths. + + @discussion + Swift usage example: + @code + model.bindKey(#keyPath(model.name) toView: nameTextField viewKey: UITextFieldText) + @endcode + + @param modelKey Keypath string for the model property to bind. Must not be nil. + @param view View to bind with the model. Must not be nil. + @param viewKey Keypath string for the view property to bind. Must not be nil. e.g. UISwitchEnabled -> "enabled" + + @remark See also bindSel:toView:viewSel: + */ +- (void) bindKey: (NSString* _Nonnull) modelKey view: (EBKView* _Nonnull) view viewKey: (NSString* _Nonnull) viewKey; + +@end + +#pragma mark Supported out-of-the-box bindable views and properties + +NS_ASSUME_NONNULL_BEGIN +extern NSString* UIBarButtonItemEnabled; // BOOL + +extern NSString* UIButtonEnabled; // BOOL +extern NSString* UIButtonHidden; // BOOL + +extern NSString* UIDatePickerDate; // NSDate +extern NSString* UIDatePickerEnabled; // BOOL - available on OS10+ +extern NSString* UIDatePickerHidden; // BOOL + +extern NSString* UIImageViewImage; // UIImage +extern NSString* UIImageViewHidden; // BOOL + +extern NSString* UILabelText; // NSString +extern NSString* UILabelAttributedText; // NSAttributedString +extern NSString* UILabelHidden; // BOOL + +extern NSString* UIPageControlCurrentPage; // NSInteger +extern NSString* UIPageControlNumberOfPages; // NSInteger +extern NSString* UIPageControlEnabled; // BOOL +extern NSString* UIPageControlHidden; // BOOL + +extern NSString* UISegmentedControlSelectedSegmentIndex; // NSInteger +extern NSString* UISegmentedControlEnabled; // BOOL +extern NSString* UISegmentedControlHidden; // BOOL + +extern NSString* UISliderValue; // float +extern NSString* UISliderEnabled; // BOOL +extern NSString* UISliderHidden; // BOOL + +extern NSString* UIStepperValue; // double +extern NSString* UIStepperEnabled; // BOOL +extern NSString* UIStepperHidden; // BOOL + +extern NSString* UISwitchOn; // BOOL +extern NSString* UISwitchEnabled; // BOOL +extern NSString* UISwitchHidden; // BOOL + +extern NSString* UITextFieldText; // NSString +extern NSString* UITextFieldAttributedText; // NSAttributedString +extern NSString* UITextFieldEnabled; // BOOL +extern NSString* UITextFieldHidden; // BOOL + +extern NSString* UITextViewText; // NSString +extern NSString* UITextViewAttributedText; // NSAttributedString +extern NSString* UITextViewEditable; // BOOL +extern NSString* UITextViewHidden; // BOOL +NS_ASSUME_NONNULL_END + +/** + @brief Returns the version of the BindKit library. + */ +extern NSString* _Nonnull EBKVersion(void); + +#pragma mark Vendor integration APIs - dynamic subclassing of views + +/** + @brief The name of the NSException that is thrown when a programmer error + is detected during binding. + @remark See also bindSel:toView:viewSel: for details of exceptions + */ +extern NSString* _Nonnull EBKBindingException; + +/* + @brief This macro can be used in an overidden bindableProperties to return an + property type string of the property type v. + @code + return @{UISwitchEnabled: EBKTypeEncode(BOOL)}; // "enabled"="B" + @endCode + */ +#define EBKTypeEncode(v) [NSString stringWithCString: @encode(v) encoding: NSASCIIStringEncoding] + +@interface EBKView (EBKDynamicSubclass) + +/** + @brief Override this method to return a dictionary of valid property names and + types. + @discussion Valid property types are those specified in "Objective-C type encodings" + https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtTypeEncodings.html + */ +- (NSDictionary* _Nonnull) bindableProperties; + +/** + @brief This method will be called when the view has been bound with the model's + first property only. + @discussion Override this method if your view needs to subscribe to + notifications or control events to listen for changes input by the user. + See EBKUI* classes for more details. + */ +- (void) viewDidBindWithModel; + +/** + @brief This method is called when the bound object's properties have been updated, + and the view's properties need to be updated to keep in sync. + @discussion See EBKUI* classes for more details. + */ +- (void) updateViewFromBoundModel; + +/** + @brief If the view property is bound to an model property, then the value is + set onto the model against the bound model property. + */ +- (void) setBoundValue: (NSObject* _Nullable) value viewKey: (NSString* _Nonnull) viewKey; + +/** + @brief If the view property is mapped to an model property, then the value is + retrieved from the model against the mapped model property. + @discussion If the value is non-nil then the value is returned. If the value is + nil, the [NSNull null] is returned. If the view property is not mapped to an + object property, then nil is returned. + */ +- (NSObject* _Nullable) boundValueForViewKey: (NSString* _Nonnull) viewKey NS_SWIFT_NAME(boundValue(viewKey:)); + +@end + +@interface EBKView (EBKDynamicSubclassRegistry) + +/** + @brief Override to return the EBKUI* version of a UIKit view. + */ +- (Class _Nullable) EBKDynamicSubclass NS_SWIFT_NAME(EBKDynamicSubclass()); + +@end + +#pragma mark Vendor integration - debug logging + +typedef NS_OPTIONS(NSUInteger, EBKLogFlag) { + EBKLogFlagError = 1 << 0, // 0...00001 + EBKLogFlagWarn = 1 << 1, // 0...00010 + EBKLogFlagInfo = 1 << 2, // 0...00100 + EBKLogFlagDebug = 1 << 3, // 0...01000 + EBKLogFlagVerbose = 1 << 4, // 0...10000 +}; + +typedef NS_ENUM(NSUInteger, EBKLogLevel) { + EBKLogLevelOff = 0, // 0...00000 + EBKLogLevelError = (EBKLogFlagError), // 0...00001 + EBKLogLevelWarn = (EBKLogLevelError|EBKLogFlagWarn), // 0...00011 + EBKLogLevelInfo = (EBKLogLevelWarn|EBKLogFlagInfo), // 0...00111 + EBKLogLevelDebug = (EBKLogLevelInfo|EBKLogFlagDebug), // 0...01111 + EBKLogLevelVerbose = (EBKLogLevelDebug|EBKLogFlagVerbose), // 0...11111 + EBKLogLevelAll = NSUIntegerMax // 1111...1111 +}; + +#define EBKERROR(msg,...) EBKLogO(EBKLogFlagError,__FILE__,NSStringFromSelector(_cmd),__LINE__,msg,##__VA_ARGS__) +#define EBKDEBUG(msg,...) EBKLogO(EBKLogFlagDebug,__FILE__,NSStringFromSelector(_cmd),__LINE__,msg,##__VA_ARGS__) +#define EBKVERBOSE(msg,...) EBKLogO(EBKLogFlagVerbose,__FILE__,NSStringFromSelector(_cmd),__LINE__,msg,##__VA_ARGS__) + +/** + @brief Enables or disables logging to the console based upon the level specified. + @discussion Valid logging levels are EBKLogLevelOff < EBKLogLevelError < EBKLogLevelWarn < EBKLogLevelInfo < EBKLogLevelDebug < EBKLogLevelVerbose. + The default logging level is EBKLogLevelError. + */ +extern void EBKSetLogging(EBKLogLevel logLevel); + +/** + @brief Logs an ObjC style string and variable arguments in sprintf format to the + console if logging is enabled. + */ +extern void EBKLogO(EBKLogFlag logFlag, const char* _Nonnull path, NSString* _Nonnull method, int line, NSString* _Nonnull msg, ...); + +/** + @brief Logs an Swift style string to the console if logging is enabled. + */ +extern void EBKLogS(EBKLogFlag logFlag, NSString* _Nonnull msg); + +#pragma mark Vendor integration - multicasting delegates for dynamic subclasses + +/** + @brief Multi-casting delegate + @discussion If a dynamic subclass needs to use delegation to be notified of changes + to the view (as opposed to target-action or notifications), then it can + use this class to multi-cast delegate methods. + @remark See MySearchBar.swift for usage. + */ +@interface EBKMulticastDelegate : NSObject + +@property(weak, nullable) id primaryDelegate; +@property(weak, nullable) id secondaryDelegate; + +@end + +#endif // BindKit_h diff --git a/BindKit/BindKit/BindKit.modulemap b/BindKit/BindKit/BindKit.modulemap new file mode 100644 index 0000000..bd7cc2c --- /dev/null +++ b/BindKit/BindKit/BindKit.modulemap @@ -0,0 +1,5 @@ +framework module BindKit { + umbrella header "BindKit.h" + export * + module * { export * } +} diff --git a/BindKit/BindKit/EBKBinding.h b/BindKit/BindKit/EBKBinding.h new file mode 100644 index 0000000..c464765 --- /dev/null +++ b/BindKit/BindKit/EBKBinding.h @@ -0,0 +1,13 @@ +// EBKBinding.h +// BindKit Copyright (c) 2018-2024; Electric Bolt Limited. + +#import "EBKProperty.h" + +@interface EBKBinding : NSObject + +@property(strong, nonnull) NSObject* model; +@property(strong, nonnull) EBKProperty* modelProperty; +@property(strong, nonnull) EBKView* view; +@property(strong, nonnull) NSString* viewProperty; + +@end diff --git a/BindKit/BindKit/private/EBKBinding.m b/BindKit/BindKit/EBKBinding.m similarity index 73% rename from BindKit/BindKit/private/EBKBinding.m rename to BindKit/BindKit/EBKBinding.m index 2405ba7..603995c 100644 --- a/BindKit/BindKit/private/EBKBinding.m +++ b/BindKit/BindKit/EBKBinding.m @@ -1,7 +1,5 @@ -/******************************************************************************* - * EBKBinding.m * - * BindKit Copyright (c) 2018; Electric Bolt Limited. * - ******************************************************************************/ +// EBKBinding.m +// BindKit Copyright (c) 2018-2024; Electric Bolt Limited. #import "EBKBinding.h" diff --git a/BindKit/BindKit/EBKDeallocationObserver.h b/BindKit/BindKit/EBKDeallocationObserver.h new file mode 100644 index 0000000..b2f68d7 --- /dev/null +++ b/BindKit/BindKit/EBKDeallocationObserver.h @@ -0,0 +1,13 @@ +// EBKDeallocationObserver.h +// BindKit Copyright (c) 2018-2024; Electric Bolt Limited. + +@import Foundation; + +@interface EBKDeallocationObserver : NSObject + +/** + @brief Calls the block provided when the object has been deallocated. + */ ++ (void) associate: (NSObject* _Nonnull) object block: (dispatch_block_t _Nonnull) block; + +@end diff --git a/BindKit/BindKit/private/EBKDeallocationObserver.m b/BindKit/BindKit/EBKDeallocationObserver.m similarity index 71% rename from BindKit/BindKit/private/EBKDeallocationObserver.m rename to BindKit/BindKit/EBKDeallocationObserver.m index 3415825..89c211d 100644 --- a/BindKit/BindKit/private/EBKDeallocationObserver.m +++ b/BindKit/BindKit/EBKDeallocationObserver.m @@ -1,7 +1,5 @@ -/******************************************************************************* - * EBKDeallocationObserver.m * - * BindKit Copyright (c) 2018; Electric Bolt Limited. * - ******************************************************************************/ +// EBKDeallocationObserver.m +// BindKit Copyright (c) 2018-2024; Electric Bolt Limited. #import "EBKDeallocationObserver.h" #import diff --git a/BindKit/BindKit/private/EBKInternalBinding.h b/BindKit/BindKit/EBKInternalBinding.h similarity index 83% rename from BindKit/BindKit/private/EBKInternalBinding.h rename to BindKit/BindKit/EBKInternalBinding.h index 454d26e..a360aae 100644 --- a/BindKit/BindKit/private/EBKInternalBinding.h +++ b/BindKit/BindKit/EBKInternalBinding.h @@ -1,7 +1,5 @@ -/******************************************************************************* - * EBKInternalBinding.h * - * BindKit Copyright (c) 2018; Electric Bolt Limited. * - ******************************************************************************/ +// EBKInternalBinding.h +// BindKit Copyright (c) 2018-2024; Electric Bolt Limited. @import Foundation; #import "BindKit.h" @@ -47,7 +45,7 @@ - (NSObject* _Nullable) _boundValueForView: (EBKView* _Nullable) view viewKey: (NSString* _Nonnull) viewKey; /** - These methods signals to the system that you are about to make modifications to + These methods signal to the system that you are about to make modifications to bound properties. Any modifications to properties are coalesced, boundPropertiesUpdateBlock, boundPropertiesDelegate, boundPropertiesDidUpdate are called once. diff --git a/BindKit/BindKit/private/EBKInternalBinding.m b/BindKit/BindKit/EBKInternalBinding.m similarity index 100% rename from BindKit/BindKit/private/EBKInternalBinding.m rename to BindKit/BindKit/EBKInternalBinding.m diff --git a/BindKit/BindKit/private/EBKLog.m b/BindKit/BindKit/EBKLog.m similarity index 54% rename from BindKit/BindKit/private/EBKLog.m rename to BindKit/BindKit/EBKLog.m index 8312f4e..2af85e0 100644 --- a/BindKit/BindKit/private/EBKLog.m +++ b/BindKit/BindKit/EBKLog.m @@ -1,7 +1,5 @@ -/******************************************************************************* - * EBKLog.m * - * BindKit Copyright (c) 2018; Electric Bolt Limited. * - ******************************************************************************/ +// EBKLog.h +// BindKit Copyright (c) 2018-2024; Electric Bolt Limited. #import "BindKit.h" #import @@ -9,17 +7,11 @@ #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wunguarded-availability" -#define OS10 (([[[UIDevice currentDevice] systemVersion] compare: @"10.0" options:NSNumericSearch] != NSOrderedAscending)) - #define LOGSIZE 256 ///< Maximum size that os_log_* can log to the console in one go. #define LOGCHUNKSIZE (LOGSIZE-16) ///< What we allow to log taking into account we also have to have "X of Y:" prefixed to each chunk. -#define NSLOGSIZE 2048 ///< Maximum size that NSLog can log to the console in one go. -#define NSCHUNKSIZE (NSLOGSIZE-16) ///< What we allow to log taking into account we also have to have "X of Y:" prefixed to each chunk. static EBKLogLevel logLevel = EBKLogLevelError; static os_log_t app_log; -static int maxSize; -static int chunkSize; void EBKSetLogging(EBKLogLevel _logLevel) { logLevel = _logLevel; @@ -31,37 +23,22 @@ void EBKLogS(EBKLogFlag _logFlag, NSString* _Nonnull msg) { static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ - if (OS10) { - // OS10 and above uses the unified logging APIs. - app_log = os_log_create("nz.co.electricbolt.bindkit", "lib"); - maxSize = LOGSIZE; - chunkSize = LOGCHUNKSIZE; - } else { - // OS9 and below uses NSLog. - maxSize = NSLOGSIZE; - chunkSize = NSCHUNKSIZE; - } + app_log = os_log_create("nz.co.electricbolt.bindkit", "lib"); }); - if ([msg length] < maxSize) { - if (OS10) - os_log_info(app_log, "%{public}@", msg); - else - NSLog(@"%@", msg); + if ([msg length] < LOGSIZE) { + os_log_info(app_log, "%{public}@", msg); } else { - int count = (int) [msg length] / chunkSize; - int rem = [msg length] % chunkSize; + int count = (int) [msg length] / LOGCHUNKSIZE; + int rem = [msg length] % LOGCHUNKSIZE; count += (rem != 0 ? 1 : 0); int offset = 0, len = 0, i = 0; while (offset < [msg length]) { len = (int) [msg length] - offset; - if (len > chunkSize) - len = chunkSize; - if (OS10) - os_log_info(app_log, "%d of %d=%{public}@", ++i, count, [msg substringWithRange: NSMakeRange(offset, len)]); - else - NSLog(@"%d of %d=%@", ++i, count, [msg substringWithRange: NSMakeRange(offset, len)]); - offset += chunkSize; + if (len > LOGCHUNKSIZE) + len = LOGCHUNKSIZE; + os_log_info(app_log, "%d of %d=%{public}@", ++i, count, [msg substringWithRange: NSMakeRange(offset, len)]); + offset += LOGCHUNKSIZE; } } } diff --git a/BindKit/BindKit/private/EBKMulticastDelegate.m b/BindKit/BindKit/EBKMulticastDelegate.m similarity index 78% rename from BindKit/BindKit/private/EBKMulticastDelegate.m rename to BindKit/BindKit/EBKMulticastDelegate.m index 5b3585c..57edf72 100644 --- a/BindKit/BindKit/private/EBKMulticastDelegate.m +++ b/BindKit/BindKit/EBKMulticastDelegate.m @@ -1,7 +1,5 @@ -/******************************************************************************* - * EBKMulticastDelegate.m * - * BindKit Copyright (c) 2018; Electric Bolt Limited. * - ******************************************************************************/ +// EBKMulticastDelegate.m +// BindKit Copyright (c) 2018-2024; Electric Bolt Limited. #import "BindKit.h" diff --git a/BindKit/BindKit/private/EBKProperty.h b/BindKit/BindKit/EBKProperty.h similarity index 86% rename from BindKit/BindKit/private/EBKProperty.h rename to BindKit/BindKit/EBKProperty.h index 740d525..c1b9d48 100644 --- a/BindKit/BindKit/private/EBKProperty.h +++ b/BindKit/BindKit/EBKProperty.h @@ -1,7 +1,5 @@ -/******************************************************************************* - * EBKProperty.h * - * BindKit Copyright (c) 2018; Electric Bolt Limited. * - ******************************************************************************/ +// EBKProperty.h +// BindKit Copyright (c) 2018-2024; Electric Bolt Limited. #import "BindKit.h" #import diff --git a/BindKit/BindKit/private/EBKProperty.m b/BindKit/BindKit/EBKProperty.m similarity index 93% rename from BindKit/BindKit/private/EBKProperty.m rename to BindKit/BindKit/EBKProperty.m index 3907f18..4c274e8 100644 --- a/BindKit/BindKit/private/EBKProperty.m +++ b/BindKit/BindKit/EBKProperty.m @@ -1,7 +1,5 @@ -/******************************************************************************* - * EBKProperty.m * - * BindKit Copyright (c) 2018; Electric Bolt Limited. * - ******************************************************************************/ +// EBKProperty.h +// BindKit Copyright (c) 2018-2024; Electric Bolt Limited. #import "BindKit.h" #import "EBKProperty.h" diff --git a/BindKit/BindKit/private/EBKUIBarButtonItem.m b/BindKit/BindKit/EBKUIBarButtonItem.m similarity index 77% rename from BindKit/BindKit/private/EBKUIBarButtonItem.m rename to BindKit/BindKit/EBKUIBarButtonItem.m index 698cb12..521ccbd 100644 --- a/BindKit/BindKit/private/EBKUIBarButtonItem.m +++ b/BindKit/BindKit/EBKUIBarButtonItem.m @@ -1,7 +1,5 @@ -/******************************************************************************* - * EBKUIBarButtonItem.m * - * BindKit Copyright (c) 2018; Electric Bolt Limited. * - ******************************************************************************/ +// EBKUIBarButtonItem.m +// BindKit Copyright (c) 2018-2024; Electric Bolt Limited. #import "BindKit.h" diff --git a/BindKit/BindKit/private/EBKUIButton.m b/BindKit/BindKit/EBKUIButton.m similarity index 83% rename from BindKit/BindKit/private/EBKUIButton.m rename to BindKit/BindKit/EBKUIButton.m index ed1ae47..4e5487d 100644 --- a/BindKit/BindKit/private/EBKUIButton.m +++ b/BindKit/BindKit/EBKUIButton.m @@ -1,7 +1,5 @@ -/******************************************************************************* - * EBKUIButton.m * - * BindKit Copyright (c) 2018; Electric Bolt Limited. * - ******************************************************************************/ +// EBKUIButton.m +// BindKit Copyright (c) 2018; Electric Bolt Limited. #import "BindKit.h" diff --git a/BindKit/BindKit/private/EBKUIDatePicker.m b/BindKit/BindKit/EBKUIDatePicker.m similarity index 91% rename from BindKit/BindKit/private/EBKUIDatePicker.m rename to BindKit/BindKit/EBKUIDatePicker.m index 38755d8..4171da6 100644 --- a/BindKit/BindKit/private/EBKUIDatePicker.m +++ b/BindKit/BindKit/EBKUIDatePicker.m @@ -1,7 +1,5 @@ -/******************************************************************************* - * EBKUIDatePicker.m * - * BindKit Copyright (c) 2018; Electric Bolt Limited. * - ******************************************************************************/ +// EBKUIDatePicker.m +// BindKit Copyright (c) 2018-2024; Electric Bolt Limited. #import "BindKit.h" diff --git a/BindKit/BindKit/private/EBKUIImageView.m b/BindKit/BindKit/EBKUIImageView.m similarity index 85% rename from BindKit/BindKit/private/EBKUIImageView.m rename to BindKit/BindKit/EBKUIImageView.m index 6d86a21..3c73f92 100644 --- a/BindKit/BindKit/private/EBKUIImageView.m +++ b/BindKit/BindKit/EBKUIImageView.m @@ -1,7 +1,5 @@ -/******************************************************************************* - * EBKUIImageView.m * - * BindKit Copyright (c) 2018; Electric Bolt Limited. * - ******************************************************************************/ +// EBKUIImageView.m +// BindKit Copyright (c) 2018-2024; Electric Bolt Limited. #import "BindKit.h" diff --git a/BindKit/BindKit/private/EBKUILabel.m b/BindKit/BindKit/EBKUILabel.m similarity index 90% rename from BindKit/BindKit/private/EBKUILabel.m rename to BindKit/BindKit/EBKUILabel.m index 0aa7381..bfe58e5 100644 --- a/BindKit/BindKit/private/EBKUILabel.m +++ b/BindKit/BindKit/EBKUILabel.m @@ -1,7 +1,5 @@ -/******************************************************************************* - * EBKUILabel.m * - * BindKit Copyright (c) 2018; Electric Bolt Limited. * - ******************************************************************************/ +// EBKUILabel.m +// BindKit Copyright (c) 2018-2024; Electric Bolt Limited. #import "BindKit.h" diff --git a/BindKit/BindKit/private/EBKUIPageControl.m b/BindKit/BindKit/EBKUIPageControl.m similarity index 92% rename from BindKit/BindKit/private/EBKUIPageControl.m rename to BindKit/BindKit/EBKUIPageControl.m index 2fcbcc8..3739c03 100644 --- a/BindKit/BindKit/private/EBKUIPageControl.m +++ b/BindKit/BindKit/EBKUIPageControl.m @@ -1,7 +1,5 @@ -/******************************************************************************* - * EBKUIPageControl.m * - * BindKit Copyright (c) 2018; Electric Bolt Limited. * - ******************************************************************************/ +// EBKUIPageControl.m +// BindKit Copyright (c) 2018-2024; Electric Bolt Limited. #import "BindKit.h" diff --git a/BindKit/BindKit/private/EBKUISegmentedControl.m b/BindKit/BindKit/EBKUISegmentedControl.m similarity index 90% rename from BindKit/BindKit/private/EBKUISegmentedControl.m rename to BindKit/BindKit/EBKUISegmentedControl.m index 28942ec..fe51dea 100644 --- a/BindKit/BindKit/private/EBKUISegmentedControl.m +++ b/BindKit/BindKit/EBKUISegmentedControl.m @@ -1,7 +1,5 @@ -/******************************************************************************* - * EBKUISegmentedControl.m * - * BindKit Copyright (c) 2018; Electric Bolt Limited. * - ******************************************************************************/ +// EBKUISegmentedControl.m +// BindKit Copyright (c) 2018-2024; Electric Bolt Limited. #import "BindKit.h" diff --git a/BindKit/BindKit/private/EBKUISlider.m b/BindKit/BindKit/EBKUISlider.m similarity index 89% rename from BindKit/BindKit/private/EBKUISlider.m rename to BindKit/BindKit/EBKUISlider.m index 31df7e7..1decd17 100644 --- a/BindKit/BindKit/private/EBKUISlider.m +++ b/BindKit/BindKit/EBKUISlider.m @@ -1,7 +1,5 @@ -/******************************************************************************* - * EBKUISlider.m * - * BindKit Copyright (c) 2018; Electric Bolt Limited. * - ******************************************************************************/ +// EBKUISlider.m +// BindKit Copyright (c) 2018; Electric Bolt Limited. #import "BindKit.h" diff --git a/BindKit/BindKit/private/EBKUIStepper.m b/BindKit/BindKit/EBKUIStepper.m similarity index 89% rename from BindKit/BindKit/private/EBKUIStepper.m rename to BindKit/BindKit/EBKUIStepper.m index cae8cf5..b67c1f3 100644 --- a/BindKit/BindKit/private/EBKUIStepper.m +++ b/BindKit/BindKit/EBKUIStepper.m @@ -1,7 +1,5 @@ -/******************************************************************************* - * EBKUIStepper.m * - * BindKit Copyright (c) 2018; Electric Bolt Limited. * - ******************************************************************************/ +// EBKUIStepper.m +// BindKit Copyright (c) 2018-2024; Electric Bolt Limited. #import "BindKit.h" diff --git a/BindKit/BindKit/private/EBKUISwitch.m b/BindKit/BindKit/EBKUISwitch.m similarity index 90% rename from BindKit/BindKit/private/EBKUISwitch.m rename to BindKit/BindKit/EBKUISwitch.m index 3d0e60c..b45ba47 100644 --- a/BindKit/BindKit/private/EBKUISwitch.m +++ b/BindKit/BindKit/EBKUISwitch.m @@ -1,7 +1,5 @@ -/******************************************************************************* - * EBKUISwitch.m * - * BindKit Copyright (c) 2018; Electric Bolt Limited. * - ******************************************************************************/ +// EBKUISwitch.m +// BindKit Copyright (c) 2018-2024; Electric Bolt Limited. #import "BindKit.h" diff --git a/BindKit/BindKit/private/EBKUITextField.m b/BindKit/BindKit/EBKUITextField.m similarity index 94% rename from BindKit/BindKit/private/EBKUITextField.m rename to BindKit/BindKit/EBKUITextField.m index 4c233fe..b9bb527 100644 --- a/BindKit/BindKit/private/EBKUITextField.m +++ b/BindKit/BindKit/EBKUITextField.m @@ -1,7 +1,5 @@ -/******************************************************************************* - * EBKUITextField.m * - * BindKit Copyright (c) 2018; Electric Bolt Limited. * - ******************************************************************************/ +// EBKUITextField.m +// BindKit Copyright (c) 2018-2024; Electric Bolt Limited. #import "BindKit.h" #import diff --git a/BindKit/BindKit/private/EBKUITextView.m b/BindKit/BindKit/EBKUITextView.m similarity index 93% rename from BindKit/BindKit/private/EBKUITextView.m rename to BindKit/BindKit/EBKUITextView.m index 8b15b9c..e735c38 100644 --- a/BindKit/BindKit/private/EBKUITextView.m +++ b/BindKit/BindKit/EBKUITextView.m @@ -1,7 +1,5 @@ -/******************************************************************************* - * EBKUITextView.m * - * BindKit Copyright (c) 2018; Electric Bolt Limited. * - ******************************************************************************/ +// EBKUITextView.m +// BindKit Copyright (c) 2018-2024; Electric Bolt Limited. #import "BindKit.h" diff --git a/BindKit/BindKit/EBKView+EBKDynamicSubclass.h b/BindKit/BindKit/EBKView+EBKDynamicSubclass.h new file mode 100644 index 0000000..591e269 --- /dev/null +++ b/BindKit/BindKit/EBKView+EBKDynamicSubclass.h @@ -0,0 +1,13 @@ +// EBKView+EBKDynamicSubclass.h +// BindKit Copyright (c) 2018-2024; Electric Bolt Limited. + +@import Foundation; + +@interface EBKView (EBKDynamicSubclassInternal) + +/** + Called by EKInternalBinding._bindKey:view:viewKey: + */ +- (void) bindModel: (NSObject* _Nonnull) obj; + +@end diff --git a/BindKit/BindKit/private/EBKView+EBKDynamicSubclass.m b/BindKit/BindKit/EBKView+EBKDynamicSubclass.m similarity index 87% rename from BindKit/BindKit/private/EBKView+EBKDynamicSubclass.m rename to BindKit/BindKit/EBKView+EBKDynamicSubclass.m index 2c27913..36fb522 100644 --- a/BindKit/BindKit/private/EBKView+EBKDynamicSubclass.m +++ b/BindKit/BindKit/EBKView+EBKDynamicSubclass.m @@ -1,7 +1,5 @@ -/******************************************************************************* - * EBKView+EBKDynamicSubclass.m * - * BindKit Copyright (c) 2018; Electric Bolt Limited. * - ******************************************************************************/ +// EBKView+EBKDynamicSubclass.m +// BindKit Copyright (c) 2018-2024; Electric Bolt Limited. #import "BindKit.h" #import "EBKView+EBKDynamicSubclass.h" diff --git a/BindKit/BindKit/private/EBKView+EBKSubclass.h b/BindKit/BindKit/EBKView+EBKSubclass.h similarity index 71% rename from BindKit/BindKit/private/EBKView+EBKSubclass.h rename to BindKit/BindKit/EBKView+EBKSubclass.h index bef5250..ae24c16 100644 --- a/BindKit/BindKit/private/EBKView+EBKSubclass.h +++ b/BindKit/BindKit/EBKView+EBKSubclass.h @@ -1,7 +1,5 @@ -/******************************************************************************* - * EBKView+EBKSubclass.h * - * BindKit Copyright (c) 2018; Electric Bolt Limited. * - ******************************************************************************/ +// EBKView+EBKSubclass.h +// BindKit Copyright (c) 2018-2024; Electric Bolt Limited. @import Foundation; diff --git a/BindKit/BindKit/private/EBKView+EBKSubclass.m b/BindKit/BindKit/EBKView+EBKSubclass.m similarity index 90% rename from BindKit/BindKit/private/EBKView+EBKSubclass.m rename to BindKit/BindKit/EBKView+EBKSubclass.m index 9f9973e..013d327 100644 --- a/BindKit/BindKit/private/EBKView+EBKSubclass.m +++ b/BindKit/BindKit/EBKView+EBKSubclass.m @@ -1,7 +1,5 @@ -/******************************************************************************* - * NSObject+EBKSubclass.m * - * BindKit Copyright (c) 2018; Electric Bolt Limited. * - ******************************************************************************/ +// EBKView+EBKSubclass.m +// BindKit Copyright (c) 2018-2024; Electric Bolt Limited. #import "BindKit.h" #import "EBKView+EBKSubclass.h" diff --git a/BindKit/BindKit/private/NSObject+EBKBinding.h b/BindKit/BindKit/NSObject+EBKBinding.h similarity index 57% rename from BindKit/BindKit/private/NSObject+EBKBinding.h rename to BindKit/BindKit/NSObject+EBKBinding.h index af509fd..1cd368e 100644 --- a/BindKit/BindKit/private/NSObject+EBKBinding.h +++ b/BindKit/BindKit/NSObject+EBKBinding.h @@ -1,7 +1,5 @@ -/******************************************************************************* - * NSObject+EBKBinding.h * - * BindKit Copyright (c) 2018; Electric Bolt Limited. * - ******************************************************************************/ +// NSObject+EBKBinding.h +// BindKit Copyright (c) 2018-2024; Electric Bolt Limited. @import UIKit; diff --git a/BindKit/BindKit/private/NSObject+EBKBinding.m b/BindKit/BindKit/NSObject+EBKBinding.m similarity index 89% rename from BindKit/BindKit/private/NSObject+EBKBinding.m rename to BindKit/BindKit/NSObject+EBKBinding.m index 12bb5af..083a6c4 100644 --- a/BindKit/BindKit/private/NSObject+EBKBinding.m +++ b/BindKit/BindKit/NSObject+EBKBinding.m @@ -1,7 +1,5 @@ -/******************************************************************************* - * NSObject+EBKBinding.m * - * BindKit Copyright (c) 2018; Electric Bolt Limited. * - ******************************************************************************/ +// NSObject+EBKBinding.m +// BindKit Copyright (c) 2018-2024; Electric Bolt Limited. #import "BindKit.h" #import "EBKInternalBinding.h" @@ -10,7 +8,7 @@ NSString* EBKBindingException = @"EBKBindingException"; NSString* EBKVersion(void) { - return @"1.0.1"; + return @"1.1.0"; } @implementation NSObject (EBKBinding) diff --git a/BindKit/BindKit/PrivacyInfo.xcprivacy b/BindKit/BindKit/PrivacyInfo.xcprivacy new file mode 100644 index 0000000..2009fb7 --- /dev/null +++ b/BindKit/BindKit/PrivacyInfo.xcprivacy @@ -0,0 +1,14 @@ + + + + + NSPrivacyTracking + + NSPrivacyTrackingDomains + + NSPrivacyCollectedDataTypes + + NSPrivacyAccessedAPITypes + + + diff --git a/BindKit/BindKit/private/EBKBinding.h b/BindKit/BindKit/private/EBKBinding.h deleted file mode 100644 index 671eb92..0000000 --- a/BindKit/BindKit/private/EBKBinding.h +++ /dev/null @@ -1,14 +0,0 @@ -/******************************************************************************* - * EBKBinding.h * - * BindKit Copyright (c) 2018; Electric Bolt Limited. * - ******************************************************************************/ - -#import "EBKProperty.h" - -@interface EBKBinding : NSObject - -@property(strong, nonnull) NSObject* model; -@property(strong, nonnull) EBKProperty* modelProperty; -@property(strong, nonnull) EBKView* view; -@property(strong, nonnull) NSString* viewProperty; -@end diff --git a/BindKit/BindKit/private/EBKDeallocationObserver.h b/BindKit/BindKit/private/EBKDeallocationObserver.h deleted file mode 100644 index 64592ad..0000000 --- a/BindKit/BindKit/private/EBKDeallocationObserver.h +++ /dev/null @@ -1,15 +0,0 @@ -/******************************************************************************* - * EBKDeallocationObserver.h * - * BindKit Copyright (c) 2018; Electric Bolt Limited. * - ******************************************************************************/ - -@import Foundation; - -@interface EBKDeallocationObserver : NSObject - -/** - @brief Calls the block provided when the object has been deallocated. - */ -+ (void) associate: (NSObject* _Nonnull) object block: (dispatch_block_t _Nonnull) block; - -@end diff --git a/BindKit/BindKit/private/EBKView+EBKDynamicSubclass.h b/BindKit/BindKit/private/EBKView+EBKDynamicSubclass.h deleted file mode 100644 index 7410840..0000000 --- a/BindKit/BindKit/private/EBKView+EBKDynamicSubclass.h +++ /dev/null @@ -1,15 +0,0 @@ -/******************************************************************************* - * EBKView+EBKDynamicSubclass.h * - * BindKit Copyright (c) 2018; Electric Bolt Limited. * - ******************************************************************************/ - -@import Foundation; - -@interface EBKView (EBKDynamicSubclassInternal) - -/** - Called by EKInternalBinding._bindKey:view:viewKey: - */ -- (void) bindModel: (NSObject* _Nonnull) obj; - -@end diff --git a/BindKit/BindKit/public/BindKitVendor.h b/BindKit/BindKit/public/BindKitVendor.h deleted file mode 100644 index c6225b8..0000000 --- a/BindKit/BindKit/public/BindKitVendor.h +++ /dev/null @@ -1,137 +0,0 @@ -/******************************************************************************* - * BindKitVendor.h * - * BindKit Copyright (c) 2018; Electric Bolt Limited. * - ******************************************************************************/ - -#ifndef BindKitVendor_h -#define BindKitVendor_h - -#pragma mark Vendor integration APIs - dynamic subclassing of views - -/** - @brief The name of the NSException that is thrown when a programmer error - is detected during binding. - @remark See also bindSel:toView:viewSel: for details of exceptions - */ -extern NSString* _Nonnull EBKBindingException; - -/* - @brief This macro can be used in an overidden bindableProperties to return an - property type string of the property type v. - @code - return @{UISwitchEnabled: EBKTypeEncode(BOOL)}; // "enabled"="B" - @endCode - */ -#define EBKTypeEncode(v) [NSString stringWithCString: @encode(v) encoding: NSASCIIStringEncoding] - -@interface EBKView (EBKDynamicSubclass) - -/** - @brief Override this method to return a dictionary of valid property names and - types. - @discussion Valid property types are those specified in "Objective-C type encodings" - https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtTypeEncodings.html - */ -- (NSDictionary* _Nonnull) bindableProperties; - -/** - @brief This method will be called when the view has been bound with the model's - first property only. - @discussion Override this method if your view needs to subscribe to - notifications or control events to listen for changes input by the user. - See EBKUI* classes for more details. - */ -- (void) viewDidBindWithModel; - -/** - @brief This method is called when the bound object's properties have been updated, - and the view's properties need to be updated to keep in sync. - @discussion See EBKUI* classes for more details. - */ -- (void) updateViewFromBoundModel; - -/** - @brief If the view property is bound to an model property, then the value is - set onto the model against the bound model property. - */ -- (void) setBoundValue: (NSObject* _Nullable) value viewKey: (NSString* _Nonnull) viewKey; - -/** - @brief If the view property is mapped to an model property, then the value is - retrieved from the model against the mapped model property. - @discussion If the value is non-nil then the value is returned. If the value is - nil, the [NSNull null] is returned. If the view property is not mapped to an - object property, then nil is returned. - */ -- (NSObject* _Nullable) boundValueForViewKey: (NSString* _Nonnull) viewKey NS_SWIFT_NAME(boundValue(viewKey:)); - -@end - -@interface EBKView (EBKDynamicSubclassRegistry) - -/** - @brief Override to return the EBKUI* version of a UIKit view. - */ -- (Class _Nullable) EBKDynamicSubclass NS_SWIFT_NAME(EBKDynamicSubclass()); - -@end - -#pragma mark Vendor integration - debug logging - -typedef NS_OPTIONS(NSUInteger, EBKLogFlag) { - EBKLogFlagError = 1 << 0, // 0...00001 - EBKLogFlagWarn = 1 << 1, // 0...00010 - EBKLogFlagInfo = 1 << 2, // 0...00100 - EBKLogFlagDebug = 1 << 3, // 0...01000 - EBKLogFlagVerbose = 1 << 4, // 0...10000 -}; - -typedef NS_ENUM(NSUInteger, EBKLogLevel) { - EBKLogLevelOff = 0, // 0...00000 - EBKLogLevelError = (EBKLogFlagError), // 0...00001 - EBKLogLevelWarn = (EBKLogLevelError|EBKLogFlagWarn), // 0...00011 - EBKLogLevelInfo = (EBKLogLevelWarn|EBKLogFlagInfo), // 0...00111 - EBKLogLevelDebug = (EBKLogLevelInfo|EBKLogFlagDebug), // 0...01111 - EBKLogLevelVerbose = (EBKLogLevelDebug|EBKLogFlagVerbose), // 0...11111 - EBKLogLevelAll = NSUIntegerMax // 1111...1111 -}; - -#define EBKERROR(msg,...) EBKLogO(EBKLogFlagError,__FILE__,NSStringFromSelector(_cmd),__LINE__,msg,##__VA_ARGS__) -#define EBKDEBUG(msg,...) EBKLogO(EBKLogFlagDebug,__FILE__,NSStringFromSelector(_cmd),__LINE__,msg,##__VA_ARGS__) -#define EBKVERBOSE(msg,...) EBKLogO(EBKLogFlagVerbose,__FILE__,NSStringFromSelector(_cmd),__LINE__,msg,##__VA_ARGS__) - -/** - @brief Enables or disables logging to the console based upon the level specified. - @discussion Valid logging levels are EBKLogLevelOff < EBKLogLevelError < EBKLogLevelWarn < EBKLogLevelInfo < EBKLogLevelDebug < EBKLogLevelVerbose. - The default logging level is EBKLogLevelError. - */ -extern void EBKSetLogging(EBKLogLevel logLevel); - -/** - @brief Logs an ObjC style string and variable arguments in sprintf format to the - console if logging is enabled. - */ -extern void EBKLogO(EBKLogFlag logFlag, const char* _Nonnull path, NSString* _Nonnull method, int line, NSString* _Nonnull msg, ...); - -/** - @brief Logs an Swift style string to the console if logging is enabled. - */ -extern void EBKLogS(EBKLogFlag logFlag, NSString* _Nonnull msg); - -#pragma mark Vendor integration - multicasting delegates for dynamic subclasses - -/** - @brief Multi-casting delegate - @discussion If a dynamic subclass needs to use delegation to be notified of changes - to the view (as opposed to target-action or notifications), then it can - use this class to multi-cast delegate methods. - @remark See MySearchBar.swift for usage. - */ -@interface EBKMulticastDelegate : NSObject - -@property(weak, nullable) id primaryDelegate; -@property(weak, nullable) id secondaryDelegate; - -@end - -#endif // BindKitVendor_h diff --git a/BindKit/BindKitTests/EBKBindingTests.m b/BindKit/BindKitTests/EBKBindingTests.m index 8b7d367..60880ca 100644 --- a/BindKit/BindKitTests/EBKBindingTests.m +++ b/BindKit/BindKitTests/EBKBindingTests.m @@ -1,7 +1,5 @@ -/******************************************************************************* - * EBKBindingTests.h * - * BindKit Copyright (c) 2018; Electric Bolt Limited. * - ******************************************************************************/ +// EBKBindingTests.h +// BindKit Copyright (c) 2018-2024; Electric Bolt Limited. @import XCTest; #import "EBKBinding.h" diff --git a/BindKit/BindKitTests/EBKDeallocationObserverTests.m b/BindKit/BindKitTests/EBKDeallocationObserverTests.m index 86fa6c0..91a5c0e 100644 --- a/BindKit/BindKitTests/EBKDeallocationObserverTests.m +++ b/BindKit/BindKitTests/EBKDeallocationObserverTests.m @@ -1,7 +1,5 @@ -/******************************************************************************* - * EBKDeallocationObserverTests.h * - * BindKit Copyright (c) 2018; Electric Bolt Limited. * - ******************************************************************************/ +// EBKDeallocationObserverTests.h +// BindKit Copyright (c) 2018-2024; Electric Bolt Limited. @import XCTest; #import "EBKDeallocationObserver.h" diff --git a/BindKit/BindKitTests/EBKInternalBindingTests.m b/BindKit/BindKitTests/EBKInternalBindingTests.m index 69e2f81..acbf2d0 100644 --- a/BindKit/BindKitTests/EBKInternalBindingTests.m +++ b/BindKit/BindKitTests/EBKInternalBindingTests.m @@ -1,7 +1,5 @@ -/******************************************************************************* - * EBKInternalBindingTests.h * - * BindKit Copyright (c) 2018; Electric Bolt Limited. * - ******************************************************************************/ +// EBKInternalBindingTests.h +// BindKit Copyright (c) 2018-2024; Electric Bolt Limited. @import XCTest; #import "EBKInternalBinding.h" diff --git a/BindKit/BindKitTests/EBKMulticastDelegateTests.m b/BindKit/BindKitTests/EBKMulticastDelegateTests.m index 22673a6..6bf66e8 100644 --- a/BindKit/BindKitTests/EBKMulticastDelegateTests.m +++ b/BindKit/BindKitTests/EBKMulticastDelegateTests.m @@ -1,7 +1,5 @@ -/******************************************************************************* - * EBKMulticastDelegateTests.h * - * BindKit Copyright (c) 2018; Electric Bolt Limited. * - ******************************************************************************/ +// EBKMulticastDelegateTests.h +// BindKit Copyright (c) 2018-2024; Electric Bolt Limited. @import XCTest; #import "BindKit.h" diff --git a/BindKit/BindKitTests/EBKPropertyTests.m b/BindKit/BindKitTests/EBKPropertyTests.m index 9d75d2a..1211865 100644 --- a/BindKit/BindKitTests/EBKPropertyTests.m +++ b/BindKit/BindKitTests/EBKPropertyTests.m @@ -1,7 +1,5 @@ -/******************************************************************************* - * EBKPropertyTests.h * - * BindKit Copyright (c) 2018; Electric Bolt Limited. * - ******************************************************************************/ +// EBKPropertyTests.h +// BindKit Copyright (c) 2018-2024; Electric Bolt Limited. @import XCTest; #import "BindKit.h" diff --git a/BindKit/BindKitTests/EBKUIBarButtonItemTests.m b/BindKit/BindKitTests/EBKUIBarButtonItemTests.m index d551aad..0112cae 100644 --- a/BindKit/BindKitTests/EBKUIBarButtonItemTests.m +++ b/BindKit/BindKitTests/EBKUIBarButtonItemTests.m @@ -1,7 +1,5 @@ -/******************************************************************************* - * EBKUIBarButtonItemTests.h * - * BindKit Copyright (c) 2018; Electric Bolt Limited. * - ******************************************************************************/ +// EBKUIBarButtonItemTests.h +// BindKit Copyright (c) 2018-2024; Electric Bolt Limited. @import XCTest; #import "BindKit.h" diff --git a/BindKit/BindKitTests/EBKUIButtonTests.m b/BindKit/BindKitTests/EBKUIButtonTests.m index e708932..082046a 100644 --- a/BindKit/BindKitTests/EBKUIButtonTests.m +++ b/BindKit/BindKitTests/EBKUIButtonTests.m @@ -1,7 +1,5 @@ -/******************************************************************************* - * EBKUIButtonTests.h * - * BindKit Copyright (c) 2018; Electric Bolt Limited. * - ******************************************************************************/ +// EBKUIButtonTests.h +// BindKit Copyright (c) 2018-2024; Electric Bolt Limited. @import XCTest; #import "BindKit.h" diff --git a/BindKit/BindKitTests/EBKUIDatePickerTests.m b/BindKit/BindKitTests/EBKUIDatePickerTests.m index 812598b..7a63a20 100644 --- a/BindKit/BindKitTests/EBKUIDatePickerTests.m +++ b/BindKit/BindKitTests/EBKUIDatePickerTests.m @@ -1,7 +1,5 @@ -/******************************************************************************* - * EBKUIDatePickerTests.h * - * BindKit Copyright (c) 2018; Electric Bolt Limited. * - ******************************************************************************/ +// EBKUIDatePickerTests.h +// BindKit Copyright (c) 2018-2024; Electric Bolt Limited. @import XCTest; #import "BindKit.h" diff --git a/BindKit/BindKitTests/EBKUIImageViewTests.m b/BindKit/BindKitTests/EBKUIImageViewTests.m index 2c5acbe..b2510fb 100644 --- a/BindKit/BindKitTests/EBKUIImageViewTests.m +++ b/BindKit/BindKitTests/EBKUIImageViewTests.m @@ -1,7 +1,5 @@ -/******************************************************************************* - * EBKUIImageViewTests.h * - * BindKit Copyright (c) 2018; Electric Bolt Limited. * - ******************************************************************************/ +// EBKUIImageViewTests.h +// BindKit Copyright (c) 2018-2024; Electric Bolt Limited. @import XCTest; #import "BindKit.h" diff --git a/BindKit/BindKitTests/EBKUILabelTests.m b/BindKit/BindKitTests/EBKUILabelTests.m index f71a351..20a185d 100644 --- a/BindKit/BindKitTests/EBKUILabelTests.m +++ b/BindKit/BindKitTests/EBKUILabelTests.m @@ -1,7 +1,5 @@ -/******************************************************************************* - * EBKUILabelTests.h * - * BindKit Copyright (c) 2018; Electric Bolt Limited. * - ******************************************************************************/ +// EBKUILabelTests.h +// BindKit Copyright (c) 2018-2024; Electric Bolt Limited. @import XCTest; #import "BindKit.h" diff --git a/BindKit/BindKitTests/EBKUIPageControlTests.m b/BindKit/BindKitTests/EBKUIPageControlTests.m index ed17959..379612f 100644 --- a/BindKit/BindKitTests/EBKUIPageControlTests.m +++ b/BindKit/BindKitTests/EBKUIPageControlTests.m @@ -1,7 +1,5 @@ -/******************************************************************************* - * EBKUIPageControlTests.h * - * BindKit Copyright (c) 2018; Electric Bolt Limited. * - ******************************************************************************/ +// EBKUIPageControlTests.h +// BindKit Copyright (c) 2018-2024; Electric Bolt Limited. @import XCTest; #import "BindKit.h" diff --git a/BindKit/BindKitTests/EBKUISegmentedControlTests.m b/BindKit/BindKitTests/EBKUISegmentedControlTests.m index 8e116f6..3f4b545 100644 --- a/BindKit/BindKitTests/EBKUISegmentedControlTests.m +++ b/BindKit/BindKitTests/EBKUISegmentedControlTests.m @@ -1,7 +1,5 @@ -/******************************************************************************* - * EBKUISegmentedControlTests.h * - * BindKit Copyright (c) 2018; Electric Bolt Limited. * - ******************************************************************************/ +// EBKUISegmentedControlTests.h +// BindKit Copyright (c) 2018-2024; Electric Bolt Limited. @import XCTest; #import "BindKit.h" diff --git a/BindKit/BindKitTests/EBKUISliderTests.m b/BindKit/BindKitTests/EBKUISliderTests.m index cb45ea4..162bb24 100644 --- a/BindKit/BindKitTests/EBKUISliderTests.m +++ b/BindKit/BindKitTests/EBKUISliderTests.m @@ -1,7 +1,5 @@ -/******************************************************************************* - * EBKUISliderTests.h * - * BindKit Copyright (c) 2018; Electric Bolt Limited. * - ******************************************************************************/ +// EBKUISliderTests.h +// BindKit Copyright (c) 2018-2024; Electric Bolt Limited. @import XCTest; #import "BindKit.h" diff --git a/BindKit/BindKitTests/EBKUIStepperTests.m b/BindKit/BindKitTests/EBKUIStepperTests.m index 94bc269..704929a 100644 --- a/BindKit/BindKitTests/EBKUIStepperTests.m +++ b/BindKit/BindKitTests/EBKUIStepperTests.m @@ -1,7 +1,5 @@ -/******************************************************************************* - * EBKUIStepperTests.h * - * BindKit Copyright (c) 2018; Electric Bolt Limited. * - ******************************************************************************/ +// EBKUIStepperTests.h +// BindKit Copyright (c) 2018-2024; Electric Bolt Limited. @import XCTest; #import "BindKit.h" diff --git a/BindKit/BindKitTests/EBKUISwitchTests.m b/BindKit/BindKitTests/EBKUISwitchTests.m index 54d2524..1791999 100644 --- a/BindKit/BindKitTests/EBKUISwitchTests.m +++ b/BindKit/BindKitTests/EBKUISwitchTests.m @@ -1,7 +1,5 @@ -/******************************************************************************* - * EBKUISwitchTests.h * - * BindKit Copyright (c) 2018; Electric Bolt Limited. * - ******************************************************************************/ +// EBKUISwitchTests.h +// BindKit Copyright (c) 2018-2024; Electric Bolt Limited. @import XCTest; #import "BindKit.h" diff --git a/BindKit/BindKitTests/EBKUITextFieldTests.m b/BindKit/BindKitTests/EBKUITextFieldTests.m index ef4a315..642d719 100644 --- a/BindKit/BindKitTests/EBKUITextFieldTests.m +++ b/BindKit/BindKitTests/EBKUITextFieldTests.m @@ -1,7 +1,5 @@ -/******************************************************************************* - * EBKUITextFieldTests.h * - * BindKit Copyright (c) 2018; Electric Bolt Limited. * - ******************************************************************************/ +// EBKUITextFieldTests.h +// BindKit Copyright (c) 2018-2024; Electric Bolt Limited. @import XCTest; #import "BindKit.h" diff --git a/BindKit/BindKitTests/EBKUITextViewTests.m b/BindKit/BindKitTests/EBKUITextViewTests.m index 9cc3f16..c90732b 100644 --- a/BindKit/BindKitTests/EBKUITextViewTests.m +++ b/BindKit/BindKitTests/EBKUITextViewTests.m @@ -1,7 +1,5 @@ -/******************************************************************************* - * EBKUITextViewTests.h * - * BindKit Copyright (c) 2018; Electric Bolt Limited. * - ******************************************************************************/ +// EBKUITextViewTests.h +// BindKit Copyright (c) 2018-2024; Electric Bolt Limited. @import XCTest; #import "BindKit.h" diff --git a/BindKit/BindKitTests/EBKViewSubclassTests.m b/BindKit/BindKitTests/EBKViewSubclassTests.m index 03dec01..693f75b 100644 --- a/BindKit/BindKitTests/EBKViewSubclassTests.m +++ b/BindKit/BindKitTests/EBKViewSubclassTests.m @@ -1,7 +1,5 @@ -/******************************************************************************* - * EBKViewSubclassTests.h * - * BindKit Copyright (c) 2018; Electric Bolt Limited. * - ******************************************************************************/ +// EBKViewSubclassTests.h +// BindKit Copyright (c) 2018-2024; Electric Bolt Limited. @import XCTest; #import "BindKit.h" diff --git a/BindKit/BindKitTests/NSObjectEBKBindingTests.m b/BindKit/BindKitTests/NSObjectEBKBindingTests.m index e477536..7ee39c6 100644 --- a/BindKit/BindKitTests/NSObjectEBKBindingTests.m +++ b/BindKit/BindKitTests/NSObjectEBKBindingTests.m @@ -1,7 +1,5 @@ -/******************************************************************************* - * NSObjectEBKBindingTests.h * - * BindKit Copyright (c) 2018; Electric Bolt Limited. * - ******************************************************************************/ +// NSObjectEBKBindingTests.h +// BindKit Copyright (c) 2018-2024; Electric Bolt Limited. @import XCTest; #import "BindKit.h" @@ -43,7 +41,7 @@ - (void) tearDown { } - (void) testLibraryVersion { - XCTAssertEqualObjects(EBKVersion(), @"1.0.0"); + XCTAssertEqualObjects(EBKVersion(), @"1.1.0"); } - (void) testBindingKey { diff --git a/BindingExample/BindingExample.xcodeproj/project.pbxproj b/BindingExample/BindingExample.xcodeproj/project.pbxproj index c52a92f..bc0d999 100644 --- a/BindingExample/BindingExample.xcodeproj/project.pbxproj +++ b/BindingExample/BindingExample.xcodeproj/project.pbxproj @@ -31,9 +31,9 @@ 74B55A80204DF92C0034CC61 /* UIPageControlCtrl.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74B55A7F204DF92C0034CC61 /* UIPageControlCtrl.swift */; }; 74B55A82204E00080034CC61 /* UISegmentedControlCtrl.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74B55A81204E00080034CC61 /* UISegmentedControlCtrl.swift */; }; 74B55A84204E048B0034CC61 /* UISliderCtrl.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74B55A83204E048B0034CC61 /* UISliderCtrl.swift */; }; - 74B82D3E2044E438009D4845 /* libBindKit.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 74B82D3D2044E438009D4845 /* libBindKit.a */; }; 74BC764B204D2C58009672FA /* UIDatePickerCtrl.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74BC764A204D2C58009672FA /* UIDatePickerCtrl.swift */; }; 74BC764D204D3935009672FA /* UIImageViewCtrl.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74BC764C204D3935009672FA /* UIImageViewCtrl.swift */; }; + C35A9A652C5E2B27008B9A80 /* BindKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C35A9A642C5E2B27008B9A80 /* BindKit.framework */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -79,6 +79,9 @@ 74B82D412044F213009D4845 /* BindingExample-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "BindingExample-Bridging-Header.h"; sourceTree = ""; }; 74BC764A204D2C58009672FA /* UIDatePickerCtrl.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIDatePickerCtrl.swift; sourceTree = ""; }; 74BC764C204D3935009672FA /* UIImageViewCtrl.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIImageViewCtrl.swift; sourceTree = ""; }; + C35A9A602C5E28D9008B9A80 /* BindKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = BindKit.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + C35A9A642C5E2B27008B9A80 /* BindKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = BindKit.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + C35A9A7B2C5E3407008B9A80 /* BindKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = BindKit.framework; sourceTree = BUILT_PRODUCTS_DIR; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -86,7 +89,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 74B82D3E2044E438009D4845 /* libBindKit.a in Frameworks */, + C35A9A652C5E2B27008B9A80 /* BindKit.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -185,6 +188,9 @@ 74B82D3C2044E438009D4845 /* Frameworks */ = { isa = PBXGroup; children = ( + C35A9A7B2C5E3407008B9A80 /* BindKit.framework */, + C35A9A642C5E2B27008B9A80 /* BindKit.framework */, + C35A9A602C5E28D9008B9A80 /* BindKit.framework */, 74B82D3D2044E438009D4845 /* libBindKit.a */, ); name = Frameworks; @@ -490,6 +496,7 @@ DEVELOPMENT_TEAM = KLCLPVKM8C; HEADER_SEARCH_PATHS = ../BindKit/BindKit/public; INFOPLIST_FILE = BindingExample/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; OTHER_LDFLAGS = ( "-all_load", @@ -513,6 +520,7 @@ DEVELOPMENT_TEAM = KLCLPVKM8C; HEADER_SEARCH_PATHS = ../BindKit/BindKit/public; INFOPLIST_FILE = BindingExample/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; OTHER_LDFLAGS = ( "-all_load", @@ -534,7 +542,7 @@ DEVELOPMENT_TEAM = KLCLPVKM8C; HEADER_SEARCH_PATHS = ../BindKit/BindKit/public; INFOPLIST_FILE = BindingExampleTests/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 11.2; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = nz.co.electricbolt.BindingExampleTests; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -552,7 +560,7 @@ DEVELOPMENT_TEAM = KLCLPVKM8C; HEADER_SEARCH_PATHS = ../BindKit/BindKit/public; INFOPLIST_FILE = BindingExampleTests/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 11.2; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = nz.co.electricbolt.BindingExampleTests; PRODUCT_NAME = "$(TARGET_NAME)"; diff --git a/BindingExample/BindingExample/AppDelegate.swift b/BindingExample/BindingExample/AppDelegate.swift index 03a2110..d224dcf 100644 --- a/BindingExample/BindingExample/AppDelegate.swift +++ b/BindingExample/BindingExample/AppDelegate.swift @@ -1,7 +1,5 @@ -/******************************************************************************* - * AppDelegate.swift * - * BindingExample - BindKit Copyright (c) 2018; Electric Bolt Limited. * - ******************************************************************************/ +// AppDelegate.swift +// BindingExample - BindKit Copyright (c) 2018; Electric Bolt Limited. import UIKit diff --git a/BindingExample/BindingExample/AttrStr.swift b/BindingExample/BindingExample/AttrStr.swift index 63fd524..b2ca5f9 100644 --- a/BindingExample/BindingExample/AttrStr.swift +++ b/BindingExample/BindingExample/AttrStr.swift @@ -1,7 +1,5 @@ -/******************************************************************************* - * AttrStr.swift * - * BindingExample - BindKit Copyright (c) 2018; Electric Bolt Limited. * - ******************************************************************************/ +// AttrStr.swift +// BindingExample - BindKit Copyright (c) 2018-2024; Electric Bolt Limited. import UIKit diff --git a/BindingExample/BindingExample/BindingExample-Bridging-Header.h b/BindingExample/BindingExample/BindingExample-Bridging-Header.h index 17bb1fe..e11d920 100644 --- a/BindingExample/BindingExample/BindingExample-Bridging-Header.h +++ b/BindingExample/BindingExample/BindingExample-Bridging-Header.h @@ -1,5 +1,3 @@ // // Use this file to import your target's public headers that you would like to expose to Swift. // - -#import "BindKit.h" diff --git a/BindingExample/BindingExample/Colorize.swift b/BindingExample/BindingExample/Colorize.swift index 9391a5f..5d5b01d 100644 --- a/BindingExample/BindingExample/Colorize.swift +++ b/BindingExample/BindingExample/Colorize.swift @@ -1,9 +1,7 @@ -/******************************************************************************* - * Colorize.swift * - * BindingExample - BindKit Copyright (c) 2018; Electric Bolt Limited. * - ******************************************************************************/ +// Colorize.swift +// BindingExample - BindKit Copyright (c) 2018-2024; Electric Bolt Limited. -import Foundation +import UIKit func colorize(_ s : String) -> NSAttributedString { let s = NSMutableAttributedString(string: s) diff --git a/BindingExample/BindingExample/MySearchBar.swift b/BindingExample/BindingExample/MySearchBar.swift index 7aa4ab1..b676137 100644 --- a/BindingExample/BindingExample/MySearchBar.swift +++ b/BindingExample/BindingExample/MySearchBar.swift @@ -1,22 +1,22 @@ -/******************************************************************************* - * MySearchBar.swift * - * BindingExample - BindKit Copyright (c) 2018; Electric Bolt Limited. * - ******************************************************************************/ +// MySearchBar.swift +// BindingExample - BindKit Copyright (c) 2018-2024; Electric Bolt Limited. -import Foundation +import UIKit +import BindKit let MySearchBarText = "text" /** - Demonstrates creating a `custom` dynamic subclass of a view in Swift. - You can augment any view with binding capabilities that isn't already - supported by BindKit. + Demonstrates creating a `custom` dynamic subclass of a view in Swift. You can augment any view with binding + capabilities that isn't already supported by BindKit. */ class MySearchBar: UISearchBar { - fileprivate static var multicastContext = "multicastContext" - fileprivate static var searchBarDelegateContext = "searchBarDelegateContext" + // Changed to malloc(1)! to fix Swift 5.9 warning using strings for associated object contexts: + // https://forums.swift.org/t/handling-the-new-forming-unsaferawpointer-warning/65523/7 + fileprivate static var multicastContext = malloc(1)! + fileprivate static var searchBarDelegateContext = malloc(1)! override func viewDidBindWithModel() { // UIView subclasses can't have a delegate pointing to itself, instead @@ -45,12 +45,12 @@ class MySearchBar: UISearchBar { override var delegate: UISearchBarDelegate? { set { - // Set updates the EBKMulticastDelegate.secondaryDelegate property + // 'set' updates the EBKMulticastDelegate.secondaryDelegate property. let multicast = objc_getAssociatedObject(self, &MySearchBar.multicastContext) as! EBKMulticastDelegate? multicast!.secondaryDelegate = newValue } get { - // Get always return the EBKMulticastDelegate instance + // 'get' always return the EBKMulticastDelegate instance. return (objc_getAssociatedObject(self, &MySearchBar.multicastContext) as! UISearchBarDelegate) } } @@ -61,8 +61,7 @@ class MySearchBar: UISearchBar { override var text: String? { set { - // BindKit suggests that you don't set properties if the value - // hasn't changed. + // BindKit suggests that you don't set properties if the value hasn't changed. if self.text != newValue { super.text = newValue } @@ -83,8 +82,7 @@ class MySearchBar: UISearchBar { } override func updateViewFromBoundModel() { - // BindKit suggests that you don't set properties if the value - // hasn't changed. + // BindKit suggests that you don't set properties if the value hasn't changed. let v = boundValue(viewKey: MySearchBarText) if v is NSNull { if super.text != nil { diff --git a/BindingExample/BindingExample/MySearchBarCtrl.swift b/BindingExample/BindingExample/MySearchBarCtrl.swift index 37a34a4..1e46f81 100644 --- a/BindingExample/BindingExample/MySearchBarCtrl.swift +++ b/BindingExample/BindingExample/MySearchBarCtrl.swift @@ -1,9 +1,8 @@ -/******************************************************************************* - * MySearchBarCtrl.swift * - * BindingExample - BindKit Copyright (c) 2018; Electric Bolt Limited. * - ******************************************************************************/ +// MySearchBarCtrl.swift +// BindingExample - BindKit Copyright (c) 2018-2024; Electric Bolt Limited. -import Foundation +import UIKit +import BindKit fileprivate class Model: NSObject { diff --git a/BindingExample/BindingExample/RegistrationCtrl.swift b/BindingExample/BindingExample/RegistrationCtrl.swift index 220a2cf..f9f6d8e 100644 --- a/BindingExample/BindingExample/RegistrationCtrl.swift +++ b/BindingExample/BindingExample/RegistrationCtrl.swift @@ -1,9 +1,8 @@ -/******************************************************************************* - * RegistrationCtrl.swift * - * BindingExample - BindKit Copyright (c) 2018; Electric Bolt Limited. * - ******************************************************************************/ +// RegistrationCtrl.swift +// BindingExample - BindKit Copyright (c) 2018-2024; Electric Bolt Limited. import UIKit +import BindKit class RegistrationCtrl: UITableViewController { @@ -34,8 +33,9 @@ class RegistrationCtrl: UITableViewController { } @IBAction func donePressed(_ sender: Any) { - let v = UIAlertView(title: "Binding Example", message: "Done pressed", delegate: nil, cancelButtonTitle: "OK"); - v.show() + let alert = UIAlertController(title: "Binding Example", message: "Done pressed", preferredStyle: .alert) + alert.addAction(UIAlertAction(title: "OK", style: .default)) + self.present(alert, animated: true, completion: nil) } } diff --git a/BindingExample/BindingExample/RegistrationModel.swift b/BindingExample/BindingExample/RegistrationModel.swift index 357b84c..e5a70bb 100644 --- a/BindingExample/BindingExample/RegistrationModel.swift +++ b/BindingExample/BindingExample/RegistrationModel.swift @@ -1,9 +1,8 @@ -/******************************************************************************* - * RegistrationModel.swift * - * BindingExample - BindKit Copyright (c) 2018; Electric Bolt Limited. * - ******************************************************************************/ +// RegistrationModel.swift +// BindingExample - BindKit Copyright (c) 2018-2024; Electric Bolt Limited. -import Foundation +import UIKit +import BindKit class RegistrationModel: NSObject { diff --git a/BindingExample/BindingExample/UIBarButtonItemCtrl.swift b/BindingExample/BindingExample/UIBarButtonItemCtrl.swift index a1c18df..73411b7 100644 --- a/BindingExample/BindingExample/UIBarButtonItemCtrl.swift +++ b/BindingExample/BindingExample/UIBarButtonItemCtrl.swift @@ -1,9 +1,8 @@ -/******************************************************************************* - * UIBarButtonItemCtrl.swift * - * BindingExample - BindKit Copyright (c) 2018; Electric Bolt Limited. * - ******************************************************************************/ +// UIBarButtonItemCtrl.swift +// BindingExample - BindKit Copyright (c) 2018-2024; Electric Bolt Limited. -import Foundation +import UIKit +import BindKit fileprivate class Model: NSObject { @@ -41,8 +40,9 @@ class UIBarButtonItemCtrl: UIViewController { } @IBAction func barButtonItemPressed(_ sender: Any) { - let v = UIAlertView(title: "Binding Example", message: "UIBarButtonItem pressed", delegate: nil, cancelButtonTitle: "OK"); - v.show() + let alert = UIAlertController(title: "Binding Example", message: "UIBarButtonItem pressed", preferredStyle: .alert) + alert.addAction(UIAlertAction(title: "OK", style: .default)) + self.present(alert, animated: true, completion: nil) } } diff --git a/BindingExample/BindingExample/UIButtonCtrl.swift b/BindingExample/BindingExample/UIButtonCtrl.swift index 74ce6cd..ac4d0d4 100644 --- a/BindingExample/BindingExample/UIButtonCtrl.swift +++ b/BindingExample/BindingExample/UIButtonCtrl.swift @@ -1,9 +1,8 @@ -/******************************************************************************* - * UIButtonCtrl.swift * - * BindingExample - BindKit Copyright (c) 2018; Electric Bolt Limited. * - ******************************************************************************/ +// UIButtonCtrl.swift +// BindingExample - BindKit Copyright (c) 2018-2024; Electric Bolt Limited. -import Foundation +import UIKit +import BindKit fileprivate class Model: NSObject { @@ -54,8 +53,9 @@ class UIButtonCtrl: UIViewController { } @IBAction func buttonPressed(_ sender: Any) { - let v = UIAlertView(title: "Binding Example", message: "UIButton pressed", delegate: nil, cancelButtonTitle: "OK"); - v.show() + let alert = UIAlertController(title: "Binding Example", message: "UIButton pressed", preferredStyle: .alert) + alert.addAction(UIAlertAction(title: "OK", style: .default)) + self.present(alert, animated: true, completion: nil) } } diff --git a/BindingExample/BindingExample/UIDatePickerCtrl.swift b/BindingExample/BindingExample/UIDatePickerCtrl.swift index 3e0d015..a2eb5cb 100644 --- a/BindingExample/BindingExample/UIDatePickerCtrl.swift +++ b/BindingExample/BindingExample/UIDatePickerCtrl.swift @@ -1,9 +1,8 @@ -/******************************************************************************* - * UIDatePickerCtrl.swift * - * BindingExample - BindKit Copyright (c) 2018; Electric Bolt Limited. * - ******************************************************************************/ +// UIDatePickerCtrl.swift +// BindingExample - BindKit Copyright (c) 2018-2024; Electric Bolt Limited. -import Foundation +import UIKit +import BindKit fileprivate class Model: NSObject { diff --git a/BindingExample/BindingExample/UIImageViewCtrl.swift b/BindingExample/BindingExample/UIImageViewCtrl.swift index 1f65f02..ed531bd 100644 --- a/BindingExample/BindingExample/UIImageViewCtrl.swift +++ b/BindingExample/BindingExample/UIImageViewCtrl.swift @@ -1,9 +1,8 @@ -/******************************************************************************* - * UIImageViewCtrl.swift * - * BindingExample - BindKit Copyright (c) 2018; Electric Bolt Limited. * - ******************************************************************************/ +// UIImageViewCtrl.swift +// BindingExample - BindKit Copyright (c) 2018-2024; Electric Bolt Limited. -import Foundation +import UIKit +import BindKit fileprivate class Model: NSObject { diff --git a/BindingExample/BindingExample/UILabelCtrl.swift b/BindingExample/BindingExample/UILabelCtrl.swift index 4e1d5bc..b7ad1c9 100644 --- a/BindingExample/BindingExample/UILabelCtrl.swift +++ b/BindingExample/BindingExample/UILabelCtrl.swift @@ -1,9 +1,8 @@ -/******************************************************************************* - * UIImageViewCtrl.swift * - * BindingExample - BindKit Copyright (c) 2018; Electric Bolt Limited. * - ******************************************************************************/ +// UIImageViewCtrl.swift +// BindingExample - BindKit Copyright (c) 2018-2024; Electric Bolt Limited. -import Foundation +import UIKit +import BindKit fileprivate class Model: NSObject { diff --git a/BindingExample/BindingExample/UILabelSelectionCtrl.swift b/BindingExample/BindingExample/UILabelSelectionCtrl.swift index bd20825..db41065 100644 --- a/BindingExample/BindingExample/UILabelSelectionCtrl.swift +++ b/BindingExample/BindingExample/UILabelSelectionCtrl.swift @@ -1,9 +1,7 @@ -/******************************************************************************* - * UILabelSelectionCtrl.swift * - * BindingExample - BindKit Copyright (c) 2018; Electric Bolt Limited. * - ******************************************************************************/ +// UILabelSelectionCtrl.swift +// BindingExample - BindKit Copyright (c) 2018-2024; Electric Bolt Limited. -import Foundation +import UIKit class UILabelSelectionCtrl: UITableViewController { diff --git a/BindingExample/BindingExample/UIPageControlCtrl.swift b/BindingExample/BindingExample/UIPageControlCtrl.swift index 09bb99a..5d4d31e 100644 --- a/BindingExample/BindingExample/UIPageControlCtrl.swift +++ b/BindingExample/BindingExample/UIPageControlCtrl.swift @@ -1,9 +1,8 @@ -/******************************************************************************* - * UIPageControlCtrl.swift * - * BindingExample - BindKit Copyright (c) 2018; Electric Bolt Limited. * - ******************************************************************************/ +// UIPageControlCtrl.swift +// BindingExample - BindKit Copyright (c) 2018-2024; Electric Bolt Limited. -import Foundation +import UIKit +import BindKit fileprivate class Model: NSObject { diff --git a/BindingExample/BindingExample/UISegmentedControlCtrl.swift b/BindingExample/BindingExample/UISegmentedControlCtrl.swift index 512f3f7..4bd7a66 100644 --- a/BindingExample/BindingExample/UISegmentedControlCtrl.swift +++ b/BindingExample/BindingExample/UISegmentedControlCtrl.swift @@ -1,9 +1,8 @@ -/******************************************************************************* - * UISegmentedControlCtrl.swift * - * BindingExample - BindKit Copyright (c) 2018; Electric Bolt Limited. * - ******************************************************************************/ +// UISegmentedControlCtrl.swift +// BindingExample - BindKit Copyright (c) 2018-2024; Electric Bolt Limited. -import Foundation +import UIKit +import BindKit fileprivate class Model: NSObject { diff --git a/BindingExample/BindingExample/UISliderCtrl.swift b/BindingExample/BindingExample/UISliderCtrl.swift index 6f2ddfe..140a615 100644 --- a/BindingExample/BindingExample/UISliderCtrl.swift +++ b/BindingExample/BindingExample/UISliderCtrl.swift @@ -1,9 +1,8 @@ -/******************************************************************************* - * UISliderCtrl.swift * - * BindingExample - BindKit Copyright (c) 2018; Electric Bolt Limited. * - ******************************************************************************/ +// UISliderCtrl.swift +// BindingExample - BindKit Copyright (c) 2018-2024; Electric Bolt Limited. -import Foundation +import UIKit +import BindKit fileprivate class Model: NSObject { diff --git a/BindingExample/BindingExample/UIStepperCtrl.swift b/BindingExample/BindingExample/UIStepperCtrl.swift index 65adac7..8e3582d 100644 --- a/BindingExample/BindingExample/UIStepperCtrl.swift +++ b/BindingExample/BindingExample/UIStepperCtrl.swift @@ -1,9 +1,8 @@ -/******************************************************************************* - * UIStepperCtrl.swift * - * BindingExample - BindKit Copyright (c) 2018; Electric Bolt Limited. * - ******************************************************************************/ +// UIStepperCtrl.swift +// BindingExample - BindKit Copyright (c) 2018-2024; Electric Bolt Limited. -import Foundation +import UIKit +import BindKit fileprivate class Model: NSObject { diff --git a/BindingExample/BindingExample/UISwitch.swift b/BindingExample/BindingExample/UISwitch.swift index fb6c673..19ecc2e 100644 --- a/BindingExample/BindingExample/UISwitch.swift +++ b/BindingExample/BindingExample/UISwitch.swift @@ -1,9 +1,8 @@ -/******************************************************************************* - * UISwitchCtrl.swift * - * BindingExample - BindKit Copyright (c) 2018; Electric Bolt Limited. * - ******************************************************************************/ +// UISwitchCtrl.swift +// BindingExample - BindKit Copyright (c) 2018-2024; Electric Bolt Limited. -import Foundation +import UIKit +import BindKit fileprivate class Model: NSObject { diff --git a/BindingExample/BindingExample/UITextFieldCtrl.swift b/BindingExample/BindingExample/UITextFieldCtrl.swift index 82626b0..4836faa 100644 --- a/BindingExample/BindingExample/UITextFieldCtrl.swift +++ b/BindingExample/BindingExample/UITextFieldCtrl.swift @@ -1,9 +1,8 @@ -/******************************************************************************* - * UITextFieldCtrl.swift * - * BindingExample - BindKit Copyright (c) 2018; Electric Bolt Limited. * - ******************************************************************************/ +// UITextFieldCtrl.swift +// BindingExample - BindKit Copyright (c) 2018-2024; Electric Bolt Limited. -import Foundation +import UIKit +import BindKit fileprivate class Model: NSObject { diff --git a/BindingExample/BindingExample/UITextFieldSelectionCtrl.swift b/BindingExample/BindingExample/UITextFieldSelectionCtrl.swift index dc8dfda..cb3f962 100644 --- a/BindingExample/BindingExample/UITextFieldSelectionCtrl.swift +++ b/BindingExample/BindingExample/UITextFieldSelectionCtrl.swift @@ -1,9 +1,7 @@ -/******************************************************************************* - * UITextFieldSelectionCtrl.swift * - * BindingExample - BindKit Copyright (c) 2018; Electric Bolt Limited. * - ******************************************************************************/ +// UITextFieldSelectionCtrl.swift +// BindingExample - BindKit Copyright (c) 2018-2024; Electric Bolt Limited. -import Foundation +import UIKit class UITextFieldSelectionCtrl: UITableViewController { diff --git a/BindingExample/BindingExample/UITextViewCtrl.swift b/BindingExample/BindingExample/UITextViewCtrl.swift index 84be1c2..4ee41c0 100644 --- a/BindingExample/BindingExample/UITextViewCtrl.swift +++ b/BindingExample/BindingExample/UITextViewCtrl.swift @@ -1,9 +1,8 @@ -/******************************************************************************* - * UITextViewCtrl.swift * - * BindingExample - BindKit Copyright (c) 2018; Electric Bolt Limited. * - ******************************************************************************/ +// UITextViewCtrl.swift +// BindingExample - BindKit Copyright (c) 2018; Electric Bolt Limited. -import Foundation +import UIKit +import BindKit fileprivate class Model: NSObject { diff --git a/BindingExample/BindingExample/UITextViewSelectionCtrl.swift b/BindingExample/BindingExample/UITextViewSelectionCtrl.swift index 569f0aa..a09a7bf 100644 --- a/BindingExample/BindingExample/UITextViewSelectionCtrl.swift +++ b/BindingExample/BindingExample/UITextViewSelectionCtrl.swift @@ -1,9 +1,7 @@ -/******************************************************************************* - * UITextViewSelectionCtrl.swift * - * BindingExample - BindKit Copyright (c) 2018; Electric Bolt Limited. * - ******************************************************************************/ +// UITextViewSelectionCtrl.swift +// BindingExample - BindKit Copyright (c) 2018-2024; Electric Bolt Limited. -import Foundation +import UIKit class UITextViewSelectionCtrl: UITableViewController { diff --git a/BindingExample/BindingExampleTests/RegistrationModelTests.swift b/BindingExample/BindingExampleTests/RegistrationModelTests.swift index 9061567..29dfb0f 100644 --- a/BindingExample/BindingExampleTests/RegistrationModelTests.swift +++ b/BindingExample/BindingExampleTests/RegistrationModelTests.swift @@ -1,7 +1,5 @@ -/******************************************************************************* - * RegistrationModelTests.h * - * BindKit Copyright (c) 2018; Electric Bolt Limited. * - ******************************************************************************/ +// RegistrationModelTests.h +// BindingExample - BindKit Copyright (c) 2018-2024; Electric Bolt Limited. import Foundation; import XCTest; diff --git a/LICENSE b/LICENSE index e6dc955..f295b42 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ BSD 2-Clause License -Copyright © 2018 Electric Bolt Limited +Copyright © 2018-2024 Electric Bolt Limited All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/Package.swift b/Package.swift new file mode 100644 index 0000000..494a98b --- /dev/null +++ b/Package.swift @@ -0,0 +1,20 @@ +// swift-tools-version:5.3 +import PackageDescription + +let package = Package( + name: "BindKit", + platforms: [ + .iOS(.v13) + ], + products: [ + .library( + name: "BindKit", + targets: ["BindKit"]) + ], + targets: [ + .binaryTarget( + name: "BindKit", + path: "BindKit.xcframework" + ) + ] +) diff --git a/README.md b/README.md index 22b291a..09d2159 100644 --- a/README.md +++ b/README.md @@ -1,14 +1,8 @@ # BindKit -A simple to use two-way data binding framework for iOS. **Only one API to learn**. +A simple to use two-way data binding framework for iOS. **Only one API to learn**. -Supports Objective-C, Swift 5, Xcode 10.2, iOS 8 and above. - -Ships as a cocoapod or static library ready for you to link into your app (or you can include the source directly into your project). The static library is built as a 'fat' library and includes the following architectures: i386, x86_64, armv7s, armv7, arm64 and bitcode. - -### Looking for an older version? - -Tagged version 1.0.0 supports Objective-C, Swift 3 and 4, Xcode 8, 9 and 10, iOS 8 and above. +Supports Objective-C, Swift 5.10, Xcode 15.4, iOS 13+. Distributed as a static XCFramework ready for you to link into your app. ### Currently supported views @@ -99,25 +93,24 @@ class LogonController: UITableViewController { ### Adding BindKit to your app (Manual integration) -- Link `libBindKit.a` into your app -- Configure `Header Search Paths` to allow Xcode to find `BindKit.h` and `BindKitVendor.h` -- Add `-ObjC` and `-all_load` to `Other Linker Flags` +- Link `BindKit.xcframework` into your app. +- Add the build settings `-ObjC` and `-all_load` to `Other Linker Flags`. -### Adding BindKit to your app (Cocoapods integration) +### Adding BindKit to your app (Swift Package Manager) -- If you have not already created a Podfile for your application, create one now: `pod init` -- Add the following into your Podfile: `pod 'BindKit'` -- Save the file and run: `pod install` +- Add a Swift Package Manager dependency with the URL `https://github.com/electricbolt/bindkit`. +- Add the build settings `-ObjC` and `-all_load` to `Other Linker Flags`. ### Building -Whilst the libBindKit.a static library is prebuilt and included in the repository, if you need to rebuild then execute the following command: +Whilst the static XCFramework is prebuilt and included in the repository, if you need to rebuild then follow these steps: -`./buildlibrary.sh` +- Edit the `buildframework.sh` file. Comment out the `codesign` line. +- Execute the command `./buildframework.sh`. -The resulting static library and header files will be placed into the `release` directory. +The resulting static XCFramework will be placed into the root of the project. -The build script currently assumes Xcode 10.2/SDK12.2. If you are using a different Xcode build chain, tweak the `IOSSDK_VER` variable in the build script as appropriate. +The build script currently assumes iOS SDK 17.5. If you are using a different Xcode build chain, tweak the `IOSSDK_VER` variable in the build script as appropriate. ### Under the hood diff --git a/VERSIONS.md b/VERSIONS.md new file mode 100644 index 0000000..510e436 --- /dev/null +++ b/VERSIONS.md @@ -0,0 +1,30 @@ +# Release history + +### 1.1.0 - 11 Aug 2024 + +* Updated to Xcode 15.4 +* Packaged as a static XCFramework +* Added Swift Package Manager distribution +* Removed Cocoapods distribution + +**Requirements** + +* **Xcode:** 15.4+, Swift 5.10, **Minimum deployment target:** iOS 13.0 +* **Static XCFramework** contains: x86_64, arm64. Intel and Apple Silicon compatible. + +### 1.0.1 - 20 Apr 2019 + +* Updated to Xcode 10.2, Swift 5 + +**Requirements** + +* **Xcode:** 10.2+, Swift 5, **Minimum deployment target:** iOS 10.0 +* **Static library** contains: i386, x86_64, armv7s, armv7, arm64 and bitcode + +### 1.0.0 - 15 May 2018 + +* Initial version + +**Requirements** + +* **Xcode:** 8, 9 or 10, Swift 3 or 4, **Minimum deployment target:** iOS 10.0 diff --git a/buildframework.sh b/buildframework.sh new file mode 100755 index 0000000..95d1949 --- /dev/null +++ b/buildframework.sh @@ -0,0 +1,61 @@ +#!/bin/bash + +set -e + +IOSSDK_VER="17.5" +# xcodebuild -showsdks + +echo "" +echo "******************************************************" +echo "" +echo "Compiling framework source for iOS" +echo "" +echo "******************************************************" +echo "" + +rm -rf BindKit.xcframework +cd BindKit +rm -rf build + +xcodebuild clean build -sdk iphonesimulator${IOSSDK_VER} BUILD_LIBRARY_FOR_DISTRIBUTION=YES SKIP_INSTALL=NO ONLY_ACTIVE_ARCH=NO VALID_ARCHS="x86_64 arm64" -project BindKit.xcodeproj -scheme "BindKit" -configuration Release -derivedDataPath ./build/build-iphonesimulator +xcodebuild clean build -sdk iphoneos${IOSSDK_VER} BUILD_LIBRARY_FOR_DISTRIBUTION=YES SKIP_INSTALL=NO ONLY_ACTIVE_ARCH=NO VALID_ARCHS="arm64" -project BindKit.xcodeproj -scheme "BindKit" -configuration Release -derivedDataPath ./build/build-iphoneos + +cd build + +echo "" +echo "******************************************************" +echo "" +echo "Creating xcframework" +echo "" +echo "******************************************************" +echo "" + +xcodebuild -create-xcframework \ + -framework build-iphonesimulator/Build/Products/Release-iphonesimulator/BindKit.framework \ + -framework build-iphoneos/Build/Products/Release-iphoneos/BindKit.framework \ + -output BindKit.xcframework + +echo "" +echo "******************************************************" +echo "" +echo "Signing xcframework" +echo "" +echo "******************************************************" +echo "" + +codesign --timestamp -v --sign "Apple Distribution: Electric Bolt Limited (KLCLPVKM8C)" BindKit.xcframework + +echo "" +echo "******************************************************" +echo "" +echo "Copying xcframework" +echo "" +echo "******************************************************" +echo "" + +cd ../.. + +cp -R BindKit/build/BindKit.xcframework BindKit.xcframework +rm -rf BindKit/build + +echo "Finished" diff --git a/buildlibrary.sh b/buildlibrary.sh deleted file mode 100755 index 1ab0e91..0000000 --- a/buildlibrary.sh +++ /dev/null @@ -1,39 +0,0 @@ -#!/bin/bash - -set -e - -IOSSDK_VER="12.2" -# xcodebuild -showsdks - -echo Compiling library source - -rm -rf ./lib -mkdir release -cd BindKit -rm -rf ./build - -# iOS -xcodebuild clean build -sdk iphonesimulator${IOSSDK_VER} -arch "i386" ONLY_ACTIVE_ARCH=NO VALID_ARCHS="i386 x86_64" -project BindKit.xcodeproj -scheme "BindKit" -configuration Release -derivedDataPath ./build/build-i386 -xcodebuild clean build -sdk iphonesimulator${IOSSDK_VER} -arch "x86_64" ONLY_ACTIVE_ARCH=NO VALID_ARCHS="i386 x86_64" -project BindKit.xcodeproj -scheme "BindKit" -configuration Release -derivedDataPath ./build/build-x86_64 -xcodebuild clean build -sdk iphoneos${IOSSDK_VER} -arch "armv7s" ONLY_ACTIVE_ARCH=NO VALID_ARCHS="armv7s armv7 arm64" -project BindKit.xcodeproj -scheme "BindKit" -configuration Release -derivedDataPath ./build/build-armv7s -xcodebuild clean build -sdk iphoneos${IOSSDK_VER} -arch "armv7" ONLY_ACTIVE_ARCH=NO VALID_ARCHS="armv7s armv7 arm64" -project BindKit.xcodeproj -scheme "BindKit" -configuration Release -derivedDataPath ./build/build-armv7 -xcodebuild clean build -sdk iphoneos${IOSSDK_VER} -arch "arm64" ONLY_ACTIVE_ARCH=NO VALID_ARCHS="armv7s armv7 arm64" -project BindKit.xcodeproj -scheme "BindKit" -configuration Release -derivedDataPath ./build/build-arm64 - -cd build - -echo Creating fat library for iOS - -xcrun -sdk iphoneos lipo -create build-i386/Build/Products/Release-iphonesimulator/libBindKit.a \ - build-x86_64/Build/Products/Release-iphonesimulator/libBindKit.a \ - build-armv7s/Build/Products/Release-iphoneos/libBindKit.a \ - build-armv7/Build/Products/Release-iphoneos/libBindKit.a \ - build-arm64/Build/Products/Release-iphoneos/libBindKit.a \ - -output libBindKit.a -cd ../.. -cp BindKit/build/libBindKit.a release -cp BindKit/BindKit/public/BindKit.h release -cp BindKit/BindKit/public/BindKitVendor.h release - -rm -rf BindKit/BindKit/build - -echo Finished diff --git a/clean.sh b/clean.sh deleted file mode 100755 index 3295e07..0000000 --- a/clean.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/bash - -rm -rf ./release -rm -rf ./BindKit/build diff --git a/release/BindKitVendor.h b/release/BindKitVendor.h deleted file mode 100644 index c6225b8..0000000 --- a/release/BindKitVendor.h +++ /dev/null @@ -1,137 +0,0 @@ -/******************************************************************************* - * BindKitVendor.h * - * BindKit Copyright (c) 2018; Electric Bolt Limited. * - ******************************************************************************/ - -#ifndef BindKitVendor_h -#define BindKitVendor_h - -#pragma mark Vendor integration APIs - dynamic subclassing of views - -/** - @brief The name of the NSException that is thrown when a programmer error - is detected during binding. - @remark See also bindSel:toView:viewSel: for details of exceptions - */ -extern NSString* _Nonnull EBKBindingException; - -/* - @brief This macro can be used in an overidden bindableProperties to return an - property type string of the property type v. - @code - return @{UISwitchEnabled: EBKTypeEncode(BOOL)}; // "enabled"="B" - @endCode - */ -#define EBKTypeEncode(v) [NSString stringWithCString: @encode(v) encoding: NSASCIIStringEncoding] - -@interface EBKView (EBKDynamicSubclass) - -/** - @brief Override this method to return a dictionary of valid property names and - types. - @discussion Valid property types are those specified in "Objective-C type encodings" - https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtTypeEncodings.html - */ -- (NSDictionary* _Nonnull) bindableProperties; - -/** - @brief This method will be called when the view has been bound with the model's - first property only. - @discussion Override this method if your view needs to subscribe to - notifications or control events to listen for changes input by the user. - See EBKUI* classes for more details. - */ -- (void) viewDidBindWithModel; - -/** - @brief This method is called when the bound object's properties have been updated, - and the view's properties need to be updated to keep in sync. - @discussion See EBKUI* classes for more details. - */ -- (void) updateViewFromBoundModel; - -/** - @brief If the view property is bound to an model property, then the value is - set onto the model against the bound model property. - */ -- (void) setBoundValue: (NSObject* _Nullable) value viewKey: (NSString* _Nonnull) viewKey; - -/** - @brief If the view property is mapped to an model property, then the value is - retrieved from the model against the mapped model property. - @discussion If the value is non-nil then the value is returned. If the value is - nil, the [NSNull null] is returned. If the view property is not mapped to an - object property, then nil is returned. - */ -- (NSObject* _Nullable) boundValueForViewKey: (NSString* _Nonnull) viewKey NS_SWIFT_NAME(boundValue(viewKey:)); - -@end - -@interface EBKView (EBKDynamicSubclassRegistry) - -/** - @brief Override to return the EBKUI* version of a UIKit view. - */ -- (Class _Nullable) EBKDynamicSubclass NS_SWIFT_NAME(EBKDynamicSubclass()); - -@end - -#pragma mark Vendor integration - debug logging - -typedef NS_OPTIONS(NSUInteger, EBKLogFlag) { - EBKLogFlagError = 1 << 0, // 0...00001 - EBKLogFlagWarn = 1 << 1, // 0...00010 - EBKLogFlagInfo = 1 << 2, // 0...00100 - EBKLogFlagDebug = 1 << 3, // 0...01000 - EBKLogFlagVerbose = 1 << 4, // 0...10000 -}; - -typedef NS_ENUM(NSUInteger, EBKLogLevel) { - EBKLogLevelOff = 0, // 0...00000 - EBKLogLevelError = (EBKLogFlagError), // 0...00001 - EBKLogLevelWarn = (EBKLogLevelError|EBKLogFlagWarn), // 0...00011 - EBKLogLevelInfo = (EBKLogLevelWarn|EBKLogFlagInfo), // 0...00111 - EBKLogLevelDebug = (EBKLogLevelInfo|EBKLogFlagDebug), // 0...01111 - EBKLogLevelVerbose = (EBKLogLevelDebug|EBKLogFlagVerbose), // 0...11111 - EBKLogLevelAll = NSUIntegerMax // 1111...1111 -}; - -#define EBKERROR(msg,...) EBKLogO(EBKLogFlagError,__FILE__,NSStringFromSelector(_cmd),__LINE__,msg,##__VA_ARGS__) -#define EBKDEBUG(msg,...) EBKLogO(EBKLogFlagDebug,__FILE__,NSStringFromSelector(_cmd),__LINE__,msg,##__VA_ARGS__) -#define EBKVERBOSE(msg,...) EBKLogO(EBKLogFlagVerbose,__FILE__,NSStringFromSelector(_cmd),__LINE__,msg,##__VA_ARGS__) - -/** - @brief Enables or disables logging to the console based upon the level specified. - @discussion Valid logging levels are EBKLogLevelOff < EBKLogLevelError < EBKLogLevelWarn < EBKLogLevelInfo < EBKLogLevelDebug < EBKLogLevelVerbose. - The default logging level is EBKLogLevelError. - */ -extern void EBKSetLogging(EBKLogLevel logLevel); - -/** - @brief Logs an ObjC style string and variable arguments in sprintf format to the - console if logging is enabled. - */ -extern void EBKLogO(EBKLogFlag logFlag, const char* _Nonnull path, NSString* _Nonnull method, int line, NSString* _Nonnull msg, ...); - -/** - @brief Logs an Swift style string to the console if logging is enabled. - */ -extern void EBKLogS(EBKLogFlag logFlag, NSString* _Nonnull msg); - -#pragma mark Vendor integration - multicasting delegates for dynamic subclasses - -/** - @brief Multi-casting delegate - @discussion If a dynamic subclass needs to use delegation to be notified of changes - to the view (as opposed to target-action or notifications), then it can - use this class to multi-cast delegate methods. - @remark See MySearchBar.swift for usage. - */ -@interface EBKMulticastDelegate : NSObject - -@property(weak, nullable) id primaryDelegate; -@property(weak, nullable) id secondaryDelegate; - -@end - -#endif // BindKitVendor_h diff --git a/release/libBindKit.a b/release/libBindKit.a deleted file mode 100644 index cdbcc48..0000000 Binary files a/release/libBindKit.a and /dev/null differ