From d93de8833865eb833ca72320f317bf92ba2ae52a Mon Sep 17 00:00:00 2001 From: JLChen <551775569@qq.com> Date: 星期四, 08 七月 2021 15:38:24 +0800 Subject: [PATCH] 2021-07-08 1.更新 --- Demo/EZOpensdk_iOS_4.15.1_build20201104/Demo/EZOpenSDKDemo/Global/EZSDK.h | 15 Demo/EZOpensdk_iOS_4.15.1_build20201104/Demo/EZOpenSDKDemo/Venders/YYModel/YYClassInfo.m | 362 ++++++ Demo/EZOpensdk_iOS_4.15.1_build20201104/Demo/EZOpenSDKDemo.xcodeproj/project.pbxproj | 24 EZSDK/EZSDK/EZSDK.h | 15 Demo/EZOpensdk_iOS_4.15.1_build20201104/Demo/EZOpenSDKDemo/Global/EZSDK.m | 33 EZSDK.IOS/EZSDK.IOS/ApiDefinition.cs | 179 ++ Demo/Demo/EZOpenSDKDemo/TableViewCells/DeviceListCell.m | 8 EZSDK/EZSDK/EZ/TableViewCells/DeviceListCell.m | 5 Demo/EZOpensdk_iOS_4.15.1_build20201104/Demo/EZOpenSDKDemo/Venders/YYModel/NSObject+YYModel.m | 1839 ++++++++++++++++++++++++++++++++ Demo/EZOpensdk_iOS_4.15.1_build20201104/Demo/EZOpenSDKDemo/Venders/YYModel/NSObject+YYModel.h | 440 +++++++ Demo/EZOpensdk_iOS_4.15.1_build20201104/Demo/EZOpenSDKDemo/Venders/YYModel/YYClassInfo.h | 200 +++ EZSDK/EZSDK/EZSDK.m | 29 Demo/EZOpensdk_iOS_4.15.1_build20201104/Demo/EZOpenSDKDemo/Global/GlobalKit.h | 1 EZSDK.IOS/EZSDK.IOS/Properties/AssemblyInfo.cs | 2 Demo/EZOpensdk_iOS_4.15.1_build20201104/Demo/EZOpenSDKDemo/Base.lproj/AddDevice.storyboard | 14 Demo/EZOpensdk_iOS_4.15.1_build20201104/Demo/EZOpenSDKDemo/Base.lproj/EZMain.storyboard | 14 Demo/EZOpensdk_iOS_4.15.1_build20201104/Demo/EZOpenSDKDemo/Global/GlobalKit.m | 5 EZSDK/EZSDK/DeviceInfo.h | 10 Demo/EZOpensdk_iOS_4.15.1_build20201104/Demo/EZOpenSDKDemo/ViewController.m | 46 EZSDK.IOS/EZSDK.IOS/Library/libEZSDK.a | 0 Demo/Demo/EZOpenSDKDemo/Base.lproj/EZMain.storyboard | 38 EZSDK/EZSDK/EZ/Global/GlobalKit.m | 4 Demo/EZOpensdk_iOS_4.15.1_build20201104/Demo/EZOpenSDKDemo/TableViewCells/DeviceListCell.m | 4 Demo/EZOpensdk_iOS_4.15.1_build20201104/Demo/EZOpenSDKDemo/Global/EZHttpUtil.m | 28 Demo/EZOpensdk_iOS_4.15.1_build20201104/Demo/EZOpenSDKDemo/Venders/YYModel/YYModel.h | 22 EZSDK/EZSDK/EZ/Global/EZHttpUtil.m | 28 Demo/EZOpensdk_iOS_4.15.1_build20201104/Demo/EZOpenSDKDemo/AppDelegate.m | 6 EZSDK/EZSDK/EZ/Global/GlobalKit.h | 1 28 files changed, 3,235 insertions(+), 137 deletions(-) diff --git a/Demo/Demo/EZOpenSDKDemo/Base.lproj/EZMain.storyboard b/Demo/Demo/EZOpenSDKDemo/Base.lproj/EZMain.storyboard index 4c47933..97f81ae 100644 --- a/Demo/Demo/EZOpenSDKDemo/Base.lproj/EZMain.storyboard +++ b/Demo/Demo/EZOpenSDKDemo/Base.lproj/EZMain.storyboard @@ -243,8 +243,8 @@ <color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/> <nil key="highlightedColor"/> </label> - <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="hZX-eZ-E0u"> - <rect key="frame" x="127" y="29" width="39" height="39"/> + <button hidden="YES" opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="hZX-eZ-E0u"> + <rect key="frame" x="245" y="29" width="39" height="39"/> <constraints> <constraint firstAttribute="width" constant="39" id="4QQ-tz-dPq"/> <constraint firstAttribute="height" constant="39" id="RuZ-Pc-8zE"/> @@ -258,7 +258,7 @@ </connections> </button> <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="AmG-2j-Y75"> - <rect key="frame" x="186" y="29" width="39" height="39"/> + <rect key="frame" x="127" y="29" width="39" height="39"/> <constraints> <constraint firstAttribute="width" constant="39" id="Q42-XD-P1b"/> <constraint firstAttribute="height" constant="39" id="iDX-Vm-hmw"/> @@ -288,7 +288,7 @@ </constraints> </imageView> <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="0cb-tT-6Se"> - <rect key="frame" x="245" y="29" width="39" height="39"/> + <rect key="frame" x="186" y="29" width="39" height="39"/> <constraints> <constraint firstAttribute="width" constant="39" id="Mps-h7-nX0"/> <constraint firstAttribute="height" constant="39" id="hNG-1A-X3w"/> @@ -316,12 +316,13 @@ <color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/> <constraints> <constraint firstItem="4wC-NG-1q2" firstAttribute="leading" secondItem="Iet-JC-0rQ" secondAttribute="leading" constant="5" id="2lM-8U-Coj"/> - <constraint firstItem="AmG-2j-Y75" firstAttribute="leading" secondItem="hZX-eZ-E0u" secondAttribute="trailing" constant="20" id="3AL-W4-tN5"/> <constraint firstAttribute="bottom" secondItem="AmG-2j-Y75" secondAttribute="bottom" constant="5" id="4hD-YQ-TQt"/> <constraint firstItem="4wC-NG-1q2" firstAttribute="top" secondItem="Iet-JC-0rQ" secondAttribute="top" constant="5" id="CpW-TJ-kmv"/> <constraint firstItem="yuu-Ju-MKr" firstAttribute="top" secondItem="Iet-JC-0rQ" secondAttribute="top" constant="5" id="Exf-xl-NwN"/> + <constraint firstItem="ad0-s7-tSM" firstAttribute="leading" secondItem="hZX-eZ-E0u" secondAttribute="trailing" constant="20" id="Fjs-yN-xbn"/> <constraint firstItem="oYg-rg-sRX" firstAttribute="top" secondItem="Iet-JC-0rQ" secondAttribute="top" constant="5" id="GPe-zd-5ci"/> - <constraint firstItem="hZX-eZ-E0u" firstAttribute="leading" secondItem="oYg-rg-sRX" secondAttribute="trailing" constant="10" id="GsL-bZ-Shg"/> + <constraint firstItem="AmG-2j-Y75" firstAttribute="leading" secondItem="4wC-NG-1q2" secondAttribute="trailing" constant="10" id="IvR-if-0dK"/> + <constraint firstItem="hZX-eZ-E0u" firstAttribute="leading" secondItem="0cb-tT-6Se" secondAttribute="trailing" constant="20" id="KOC-jZ-Usi"/> <constraint firstAttribute="bottom" secondItem="4wC-NG-1q2" secondAttribute="bottom" constant="5" id="VtW-8E-Wln"/> <constraint firstAttribute="bottom" secondItem="0cb-tT-6Se" secondAttribute="bottom" constant="5" id="WlZ-vF-Hr6"/> <constraint firstItem="yuu-Ju-MKr" firstAttribute="leading" secondItem="oYg-rg-sRX" secondAttribute="trailing" constant="10" id="Y4S-hv-y1P"/> @@ -330,7 +331,6 @@ <constraint firstItem="0cb-tT-6Se" firstAttribute="leading" secondItem="AmG-2j-Y75" secondAttribute="trailing" constant="20" id="iAI-d3-joG"/> <constraint firstAttribute="trailing" secondItem="yuu-Ju-MKr" secondAttribute="trailing" constant="10" id="iF6-ia-hBT"/> <constraint firstAttribute="bottom" secondItem="oYg-rg-sRX" secondAttribute="bottom" constant="5" id="mW5-ze-raR"/> - <constraint firstItem="ad0-s7-tSM" firstAttribute="leading" secondItem="0cb-tT-6Se" secondAttribute="trailing" constant="20" id="pUr-10-jnu"/> <constraint firstAttribute="bottom" secondItem="ad0-s7-tSM" secondAttribute="bottom" constant="5" id="peC-1f-wPe"/> <constraint firstAttribute="bottom" secondItem="hZX-eZ-E0u" secondAttribute="bottom" constant="5" id="xIw-Sw-cwS"/> <constraint firstItem="oYg-rg-sRX" firstAttribute="leading" secondItem="Iet-JC-0rQ" secondAttribute="leading" constant="5" id="xwT-lV-EqG"/> @@ -355,17 +355,6 @@ </connections> </tableView> <navigationItem key="navigationItem" id="QiI-QE-qqY"> - <segmentedControl key="titleView" hidden="YES" opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="top" segmentControlStyle="bar" selectedSegmentIndex="0" id="F62-D9-UTh"> - <rect key="frame" x="112.5" y="6" width="150" height="32"/> - <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/> - <segments> - <segment title="鎴戠殑"/> - <segment title="鍒嗕韩"/> - </segments> - <connections> - <action selector="segmentControl:" destination="PUV-T9-WXJ" eventType="valueChanged" id="AUJ-pw-F6P"/> - </connections> - </segmentedControl> <rightBarButtonItems> <barButtonItem systemItem="add" id="yGh-cj-oPZ"> <connections> @@ -382,7 +371,6 @@ <connections> <outlet property="addButton" destination="yGh-cj-oPZ" id="KX9-xN-pem"/> <outlet property="logoutBtn" destination="5JV-V5-93l" id="mDS-mp-F4P"/> - <outlet property="segmentedControl" destination="F62-D9-UTh" id="Ybb-pD-fvi"/> <segue destination="uBF-Yq-Qo0" kind="push" identifier="go2LivePlay" id="X3Q-o5-p8V"/> <segue destination="I6z-uV-dEU" kind="push" identifier="go2Playback" id="Qls-Y0-o2u"/> <segue destination="MVz-Sq-jf5" kind="push" identifier="go2MessageList" id="Kgx-sc-mTL"/> @@ -392,7 +380,7 @@ </tableViewController> <placeholder placeholderIdentifier="IBFirstResponder" id="NKy-d7-m62" userLabel="First Responder" sceneMemberID="firstResponder"/> </objects> - <point key="canvasLocation" x="724" y="242"/> + <point key="canvasLocation" x="724" y="241.52923538230885"/> </scene> <!--Camera Table View Controller--> <scene sceneID="TjS-bX-rfT"> @@ -1196,14 +1184,14 @@ <action selector="localButtonClicked:" destination="uBF-Yq-Qo0" eventType="touchUpInside" id="ghH-Hn-KkG"/> </connections> </button> - <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="WYB-ca-Ox6"> + <button hidden="YES" opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="WYB-ca-Ox6"> <rect key="frame" x="323" y="20" width="32" height="32"/> <state key="normal" image="cloud"/> <connections> <action selector="clickCloudBtn:" destination="uBF-Yq-Qo0" eventType="touchUpInside" id="Ft8-PW-PT5"/> </connections> </button> - <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="浜戝瓨鍌�" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="wXb-RI-dLd"> + <label hidden="YES" opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="浜戝瓨鍌�" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="wXb-RI-dLd"> <rect key="frame" x="319" y="52" width="40" height="16"/> <fontDescription key="fontDescription" type="system" pointSize="13"/> <color key="textColor" white="0.66666666669999997" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> @@ -2037,10 +2025,11 @@ <subviews> <textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" placeholder="璇疯緭鍏ヨ澶囧悕绉�" textAlignment="natural" minimumFontSize="17" clearButtonMode="whileEditing" translatesAutoresizingMaskIntoConstraints="NO" id="r1W-d8-Rg7"> <rect key="frame" x="0.0" y="94" width="375" height="40"/> - <color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/> + <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> <constraints> <constraint firstAttribute="height" constant="40" id="NLX-OK-XZ7"/> </constraints> + <color key="textColor" white="0.0" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> <fontDescription key="fontDescription" type="system" pointSize="14"/> <textInputTraits key="textInputTraits"/> </textField> @@ -2483,9 +2472,10 @@ <inferredMetricsTieBreakers> <segue reference="Qls-Y0-o2u"/> <segue reference="X3Q-o5-p8V"/> - <segue reference="q2I-Q5-CUY"/> + <segue reference="9Tu-UR-Cms"/> <segue reference="vdt-wN-aOY"/> </inferredMetricsTieBreakers> + <color key="tintColor" white="0.0" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> <resources> <image name="StreamStudio" width="24" height="24"/> <image name="StreamStudio-2" width="24" height="24"/> diff --git a/Demo/Demo/EZOpenSDKDemo/TableViewCells/DeviceListCell.m b/Demo/Demo/EZOpenSDKDemo/TableViewCells/DeviceListCell.m index dd8051f..935f895 100644 --- a/Demo/Demo/EZOpenSDKDemo/TableViewCells/DeviceListCell.m +++ b/Demo/Demo/EZOpenSDKDemo/TableViewCells/DeviceListCell.m @@ -35,15 +35,21 @@ } self.nameLabel.text = [NSString stringWithFormat:@"%@",deviceInfo.deviceName]; - [self.cameraImageView sd_setImageWithURL:[NSURL URLWithString:deviceInfo.deviceCover] placeholderImageScale:nil]; + // self.cameraImageView.contentMode = UIViewContentModeScaleAspectFit; + [self.cameraImageView sd_setImageWithURL:[NSURL URLWithString:deviceInfo.deviceCover] placeholderImage:[UIImage imageNamed:@"device_default"]]; // [EZOPENSDK capturePicture:cameraInfo.deviceSerial channelNo:cameraInfo.channelNo completion:^(NSString *url, NSError *error) { // if(!error){ // [self.cameraImageView sd_setImageWithURL:[NSURL URLWithString:url]]; // } // }]; +// [EZOPENSDK cap] + + //2021-05-08 闅愯棌褰曞儚鎸夐挳 + self.recordButton.hidden = YES; self.messageButton.hidden = NO; self.settingButton.hidden = NO; + if (self.isShared) { self.messageButton.hidden = YES; diff --git a/Demo/EZOpensdk_iOS_4.15.1_build20201104/Demo/EZOpenSDKDemo.xcodeproj/project.pbxproj b/Demo/EZOpensdk_iOS_4.15.1_build20201104/Demo/EZOpenSDKDemo.xcodeproj/project.pbxproj index 4cb039c..a00534f 100644 --- a/Demo/EZOpensdk_iOS_4.15.1_build20201104/Demo/EZOpenSDKDemo.xcodeproj/project.pbxproj +++ b/Demo/EZOpensdk_iOS_4.15.1_build20201104/Demo/EZOpenSDKDemo.xcodeproj/project.pbxproj @@ -144,6 +144,8 @@ B95004F725B929EF002D3C58 /* Launch Screen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = B95004F625B929EF002D3C58 /* Launch Screen.storyboard */; }; B96C125625E8C5EA00B69941 /* EZSDK.m in Sources */ = {isa = PBXBuildFile; fileRef = B96C125525E8C5EA00B69941 /* EZSDK.m */; }; B96C126725E8F64800B69941 /* EZHttpUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = B96C126625E8F64800B69941 /* EZHttpUtil.m */; }; + B9E6208D26969E170054E443 /* NSObject+YYModel.m in Sources */ = {isa = PBXBuildFile; fileRef = B9E6208A26969E170054E443 /* NSObject+YYModel.m */; }; + B9E6208E26969E170054E443 /* YYClassInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = B9E6208B26969E170054E443 /* YYClassInfo.m */; }; B9EA4E3825C7E7AB000FFDA2 /* LICENSE in Resources */ = {isa = PBXBuildFile; fileRef = B9EA4E0725C7E7AB000FFDA2 /* LICENSE */; }; B9EA4E3925C7E7AB000FFDA2 /* UIScrollView+MJRefresh.m in Sources */ = {isa = PBXBuildFile; fileRef = B9EA4E0925C7E7AB000FFDA2 /* UIScrollView+MJRefresh.m */; }; B9EA4E3A25C7E7AB000FFDA2 /* MJRefreshConst.m in Sources */ = {isa = PBXBuildFile; fileRef = B9EA4E0A25C7E7AB000FFDA2 /* MJRefreshConst.m */; }; @@ -573,6 +575,11 @@ B96C125525E8C5EA00B69941 /* EZSDK.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZSDK.m; sourceTree = "<group>"; }; B96C126525E8F64800B69941 /* EZHttpUtil.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = EZHttpUtil.h; sourceTree = "<group>"; }; B96C126625E8F64800B69941 /* EZHttpUtil.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = EZHttpUtil.m; sourceTree = "<group>"; }; + B9E6208826969E170054E443 /* YYClassInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = YYClassInfo.h; sourceTree = "<group>"; }; + B9E6208926969E170054E443 /* YYModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = YYModel.h; sourceTree = "<group>"; }; + B9E6208A26969E170054E443 /* NSObject+YYModel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSObject+YYModel.m"; sourceTree = "<group>"; }; + B9E6208B26969E170054E443 /* YYClassInfo.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = YYClassInfo.m; sourceTree = "<group>"; }; + B9E6208C26969E170054E443 /* NSObject+YYModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSObject+YYModel.h"; sourceTree = "<group>"; }; B9EA4E0725C7E7AB000FFDA2 /* LICENSE */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = LICENSE; sourceTree = "<group>"; }; B9EA4E0925C7E7AB000FFDA2 /* UIScrollView+MJRefresh.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIScrollView+MJRefresh.m"; sourceTree = "<group>"; }; B9EA4E0A25C7E7AB000FFDA2 /* MJRefreshConst.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MJRefreshConst.m; sourceTree = "<group>"; }; @@ -892,6 +899,7 @@ 0D8CF3A91BDF516700A50266 /* Venders */ = { isa = PBXGroup; children = ( + B9E6208726969E170054E443 /* YYModel */, B9EA4E0625C7E7AA000FFDA2 /* MJRefresh */, C4A41D7C23D6E4DC00D59722 /* Toast */, 0D9ACAD31C7EE4D100B4DE97 /* UIKit+AFNetworking */, @@ -1327,6 +1335,18 @@ name = Category; sourceTree = "<group>"; }; + B9E6208726969E170054E443 /* YYModel */ = { + isa = PBXGroup; + children = ( + B9E6208826969E170054E443 /* YYClassInfo.h */, + B9E6208926969E170054E443 /* YYModel.h */, + B9E6208A26969E170054E443 /* NSObject+YYModel.m */, + B9E6208B26969E170054E443 /* YYClassInfo.m */, + B9E6208C26969E170054E443 /* NSObject+YYModel.h */, + ); + path = YYModel; + sourceTree = "<group>"; + }; B9EA4E0625C7E7AA000FFDA2 /* MJRefresh */ = { isa = PBXGroup; children = ( @@ -1735,12 +1755,14 @@ 0D77A3301BE0F2E800B4AD0A /* EZInputSerialViewController.m in Sources */, 0DCE0C421BE227F6000EA68A /* MBProgressHUD.m in Sources */, 0DCE0C321BE2279F000EA68A /* SDWebImageCompat.m in Sources */, + B9E6208D26969E170054E443 /* NSObject+YYModel.m in Sources */, 0D9ACAEB1C7EE4D100B4DE97 /* UIProgressView+AFNetworking.m in Sources */, 0D8CF4DA1BDF898800A50266 /* UITableView+FDIndexPathHeightCache.m in Sources */, 0DCE0C081BE22761000EA68A /* UILabel+DDKit.m in Sources */, 0D5015121BF8B77500F13269 /* UIImage+MWPhotoBrowser.m in Sources */, 0D90A06B1CABC6A100E78C64 /* EZPlayDemoViewController.m in Sources */, 0DCE0C3C1BE2279F000EA68A /* UIImageView+HighlightedWebCache.m in Sources */, + B9E6208E26969E170054E443 /* YYClassInfo.m in Sources */, B9EA4E3925C7E7AB000FFDA2 /* UIScrollView+MJRefresh.m in Sources */, B96C125625E8C5EA00B69941 /* EZSDK.m in Sources */, 0D77A3361BE0F38D00B4AD0A /* EZDeviceResultViewController.m in Sources */, @@ -1978,7 +2000,7 @@ MARKETING_VERSION = 4.15.0; ONLY_ACTIVE_ARCH = YES; OTHER_LDFLAGS = "-ObjC"; - PRODUCT_BUNDLE_IDENTIFIER = com.hdl.on; + PRODUCT_BUNDLE_IDENTIFIER = com.hdl.on2; PRODUCT_NAME = EZOpenSDK; PROVISIONING_PROFILE = ""; PROVISIONING_PROFILE_SPECIFIER = ""; diff --git a/Demo/EZOpensdk_iOS_4.15.1_build20201104/Demo/EZOpenSDKDemo/AppDelegate.m b/Demo/EZOpensdk_iOS_4.15.1_build20201104/Demo/EZOpenSDKDemo/AppDelegate.m index a698773..024b58c 100644 --- a/Demo/EZOpensdk_iOS_4.15.1_build20201104/Demo/EZOpenSDKDemo/AppDelegate.m +++ b/Demo/EZOpensdk_iOS_4.15.1_build20201104/Demo/EZOpenSDKDemo/AppDelegate.m @@ -30,9 +30,9 @@ // [EZOPENSDK initLibWithAppKey:@"0311c3f70a854aacb5a099f2bfbef986"]; //ON+ -// [EZOPENSDK initLibWithAppKey:@"1aa98a90489b4838b966b57018b4b04b"]; - //home - [EZOPENSDK initLibWithAppKey:@"89f6219d561441f5b664c7475698841e"]; + [EZOPENSDK initLibWithAppKey:@"1aa98a90489b4838b966b57018b4b04b"]; +// //home +// [EZOPENSDK initLibWithAppKey:@"89f6219d561441f5b664c7475698841e"]; // NSLog(@"LanguageIsChinese :%s", LanguageIsChinese ? "YES":"NO"); // NSLog(@"NSStringFromClass :%@", NSStringFromClass(EZOPENSDK)); diff --git a/Demo/EZOpensdk_iOS_4.15.1_build20201104/Demo/EZOpenSDKDemo/Base.lproj/AddDevice.storyboard b/Demo/EZOpensdk_iOS_4.15.1_build20201104/Demo/EZOpenSDKDemo/Base.lproj/AddDevice.storyboard index 284eeed..947d393 100644 --- a/Demo/EZOpensdk_iOS_4.15.1_build20201104/Demo/EZOpenSDKDemo/Base.lproj/AddDevice.storyboard +++ b/Demo/EZOpensdk_iOS_4.15.1_build20201104/Demo/EZOpenSDKDemo/Base.lproj/AddDevice.storyboard @@ -686,12 +686,24 @@ <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" usesAttributedText="YES" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Q0X-wy-A5B"> <rect key="frame" x="47.5" y="362" width="311.5" height="40"/> <attributedString key="attributedText"> - <fragment content="杩斿洖demo锛岀瓑寰呬笌璁惧杩炴帴锛屾垚鍔熷悗鑷姩杩涘叆涓嬩竴姝ユ搷浣溿��"> + <fragment content="杩斿洖"> + <attributes> + <font key="NSFont" size="14" name=".PingFangSC-Regular"/> + <paragraphStyle key="NSParagraphStyle" alignment="left" lineBreakMode="wordWrapping" baseWritingDirection="natural" minimumLineHeight="20" tighteningFactorForTruncation="0.0"/> + </attributes> + </fragment> + <fragment content="APP"> <attributes> <font key="NSFont" metaFont="system" size="14"/> <paragraphStyle key="NSParagraphStyle" alignment="left" lineBreakMode="wordWrapping" baseWritingDirection="natural" minimumLineHeight="20" tighteningFactorForTruncation="0.0"/> </attributes> </fragment> + <fragment content="锛岀瓑寰呬笌璁惧杩炴帴锛屾垚鍔熷悗鑷姩杩涘叆涓嬩竴姝ユ搷浣溿��"> + <attributes> + <font key="NSFont" size="14" name=".PingFangSC-Regular"/> + <paragraphStyle key="NSParagraphStyle" alignment="left" lineBreakMode="wordWrapping" baseWritingDirection="natural" minimumLineHeight="20" tighteningFactorForTruncation="0.0"/> + </attributes> + </fragment> </attributedString> <nil key="highlightedColor"/> </label> diff --git a/Demo/EZOpensdk_iOS_4.15.1_build20201104/Demo/EZOpenSDKDemo/Base.lproj/EZMain.storyboard b/Demo/EZOpensdk_iOS_4.15.1_build20201104/Demo/EZOpenSDKDemo/Base.lproj/EZMain.storyboard index 0db5c3a..ac982a3 100644 --- a/Demo/EZOpensdk_iOS_4.15.1_build20201104/Demo/EZOpenSDKDemo/Base.lproj/EZMain.storyboard +++ b/Demo/EZOpensdk_iOS_4.15.1_build20201104/Demo/EZOpenSDKDemo/Base.lproj/EZMain.storyboard @@ -244,7 +244,7 @@ <nil key="highlightedColor"/> </label> <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="hZX-eZ-E0u"> - <rect key="frame" x="127" y="29" width="39" height="39"/> + <rect key="frame" x="245" y="29" width="39" height="39"/> <constraints> <constraint firstAttribute="width" constant="39" id="4QQ-tz-dPq"/> <constraint firstAttribute="height" constant="39" id="RuZ-Pc-8zE"/> @@ -258,7 +258,7 @@ </connections> </button> <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="AmG-2j-Y75"> - <rect key="frame" x="186" y="29" width="39" height="39"/> + <rect key="frame" x="127" y="29" width="39" height="39"/> <constraints> <constraint firstAttribute="width" constant="39" id="Q42-XD-P1b"/> <constraint firstAttribute="height" constant="39" id="iDX-Vm-hmw"/> @@ -288,7 +288,7 @@ </constraints> </imageView> <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="0cb-tT-6Se"> - <rect key="frame" x="245" y="29" width="39" height="39"/> + <rect key="frame" x="186" y="29" width="39" height="39"/> <constraints> <constraint firstAttribute="width" constant="39" id="Mps-h7-nX0"/> <constraint firstAttribute="height" constant="39" id="hNG-1A-X3w"/> @@ -316,12 +316,13 @@ <color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/> <constraints> <constraint firstItem="4wC-NG-1q2" firstAttribute="leading" secondItem="Iet-JC-0rQ" secondAttribute="leading" constant="5" id="2lM-8U-Coj"/> - <constraint firstItem="AmG-2j-Y75" firstAttribute="leading" secondItem="hZX-eZ-E0u" secondAttribute="trailing" constant="20" id="3AL-W4-tN5"/> <constraint firstAttribute="bottom" secondItem="AmG-2j-Y75" secondAttribute="bottom" constant="5" id="4hD-YQ-TQt"/> <constraint firstItem="4wC-NG-1q2" firstAttribute="top" secondItem="Iet-JC-0rQ" secondAttribute="top" constant="5" id="CpW-TJ-kmv"/> <constraint firstItem="yuu-Ju-MKr" firstAttribute="top" secondItem="Iet-JC-0rQ" secondAttribute="top" constant="5" id="Exf-xl-NwN"/> + <constraint firstItem="ad0-s7-tSM" firstAttribute="leading" secondItem="hZX-eZ-E0u" secondAttribute="trailing" constant="20" id="Fjs-yN-xbn"/> <constraint firstItem="oYg-rg-sRX" firstAttribute="top" secondItem="Iet-JC-0rQ" secondAttribute="top" constant="5" id="GPe-zd-5ci"/> - <constraint firstItem="hZX-eZ-E0u" firstAttribute="leading" secondItem="oYg-rg-sRX" secondAttribute="trailing" constant="10" id="GsL-bZ-Shg"/> + <constraint firstItem="AmG-2j-Y75" firstAttribute="leading" secondItem="4wC-NG-1q2" secondAttribute="trailing" constant="10" id="IvR-if-0dK"/> + <constraint firstItem="hZX-eZ-E0u" firstAttribute="leading" secondItem="0cb-tT-6Se" secondAttribute="trailing" constant="20" id="KOC-jZ-Usi"/> <constraint firstAttribute="bottom" secondItem="4wC-NG-1q2" secondAttribute="bottom" constant="5" id="VtW-8E-Wln"/> <constraint firstAttribute="bottom" secondItem="0cb-tT-6Se" secondAttribute="bottom" constant="5" id="WlZ-vF-Hr6"/> <constraint firstItem="yuu-Ju-MKr" firstAttribute="leading" secondItem="oYg-rg-sRX" secondAttribute="trailing" constant="10" id="Y4S-hv-y1P"/> @@ -330,7 +331,6 @@ <constraint firstItem="0cb-tT-6Se" firstAttribute="leading" secondItem="AmG-2j-Y75" secondAttribute="trailing" constant="20" id="iAI-d3-joG"/> <constraint firstAttribute="trailing" secondItem="yuu-Ju-MKr" secondAttribute="trailing" constant="10" id="iF6-ia-hBT"/> <constraint firstAttribute="bottom" secondItem="oYg-rg-sRX" secondAttribute="bottom" constant="5" id="mW5-ze-raR"/> - <constraint firstItem="ad0-s7-tSM" firstAttribute="leading" secondItem="0cb-tT-6Se" secondAttribute="trailing" constant="20" id="pUr-10-jnu"/> <constraint firstAttribute="bottom" secondItem="ad0-s7-tSM" secondAttribute="bottom" constant="5" id="peC-1f-wPe"/> <constraint firstAttribute="bottom" secondItem="hZX-eZ-E0u" secondAttribute="bottom" constant="5" id="xIw-Sw-cwS"/> <constraint firstItem="oYg-rg-sRX" firstAttribute="leading" secondItem="Iet-JC-0rQ" secondAttribute="leading" constant="5" id="xwT-lV-EqG"/> @@ -380,7 +380,7 @@ </tableViewController> <placeholder placeholderIdentifier="IBFirstResponder" id="NKy-d7-m62" userLabel="First Responder" sceneMemberID="firstResponder"/> </objects> - <point key="canvasLocation" x="724" y="242"/> + <point key="canvasLocation" x="724" y="241.52923538230885"/> </scene> <!--Camera Table View Controller--> <scene sceneID="TjS-bX-rfT"> diff --git a/Demo/EZOpensdk_iOS_4.15.1_build20201104/Demo/EZOpenSDKDemo/Global/EZHttpUtil.m b/Demo/EZOpensdk_iOS_4.15.1_build20201104/Demo/EZOpenSDKDemo/Global/EZHttpUtil.m index 29b7426..6c2236e 100644 --- a/Demo/EZOpensdk_iOS_4.15.1_build20201104/Demo/EZOpenSDKDemo/Global/EZHttpUtil.m +++ b/Demo/EZOpensdk_iOS_4.15.1_build20201104/Demo/EZOpenSDKDemo/Global/EZHttpUtil.m @@ -13,9 +13,9 @@ #define TestRequestHttpsHost @"https://test-gz.hdlcontrol.com" #pragma mark API -#define API_POST_EZ_AddDevice @"/home-wisdom/platform/childAddDevice" -#define API_POST_EZ_GetChildToken @"/home-wisdom/platform/childToken" -#define API_POST_EZ_ChildDelDevice @"/home-wisdom/platform/childDelDevice" +#define API_POST_EZ_AddDevice @"/home-wisdom/platform/yingshi/child/addDevice" +#define API_POST_EZ_GetChildToken @"/home-wisdom/platform/yingshi/child/token" +#define API_POST_EZ_ChildDelDevice @"/home-wisdom/platform/yingshi/child/deleteDevice" #define API_POST_EZ_RefreshToken @"/smart-footstone/member/oauth/login" @@ -51,13 +51,15 @@ //2.璁剧疆璇锋眰鍙傛暟 NSMutableDictionary *parameters = [NSMutableDictionary dictionary]; [parameters setValue: [NSString stringWithFormat:@"%d", [GlobalKit shareKit].hdlPlatform] forKey:@"platform"]; + [parameters setValue:[GlobalKit shareKit].hdlHomeId forKey:@"homeId"]; parameters = [self GetSignRequestDictionary:parameters]; [self requestHttpsPost:API_POST_EZ_GetChildToken parameters:parameters completion:^(ResponseData *responseData) { if (block) { NSString * token = @""; if(responseData.success){ - token = responseData.data[@"accessToken"]; +// token = responseData.data[@"accessToken"]; + token = [NSString stringWithFormat:@"%@",responseData.data]; } block(token); } @@ -84,9 +86,11 @@ [parameters setValue:deviceSerial forKey:@"deviceSerial"]; [parameters setValue:verifyCode forKey:@"validateCode"]; [parameters setValue: [NSString stringWithFormat:@"%d",[GlobalKit shareKit].hdlPlatform] forKey:@"platform"]; + [parameters setValue:[GlobalKit shareKit].hdlHomeId forKey:@"homeId"]; + parameters = [self GetSignRequestDictionary:parameters]; - [self requestHttpsPost:API_POST_EZ_AddDevice parameters:parameters completion:^(ResponseData *responseData) { + [self requestHttpsPost:API_POST_EZ_AddDevice parameters:parameters completion:^(ResponseData *responseData) { if (completion) { completion (responseData); } @@ -108,6 +112,8 @@ NSMutableDictionary *parameters = [NSMutableDictionary dictionary]; [parameters setValue:deviceSerial forKey:@"deviceSerial"]; [parameters setValue: [NSString stringWithFormat:@"%d",[GlobalKit shareKit].hdlPlatform] forKey:@"platform"]; + [parameters setValue:[GlobalKit shareKit].hdlHomeId forKey:@"homeId"]; + parameters = [self GetSignRequestDictionary:parameters]; [self requestHttpsPost:API_POST_EZ_ChildDelDevice parameters:parameters completion:^(ResponseData *responseData) { @@ -251,7 +257,8 @@ NSString *newString = @""; for(NSString *key in sortKeyArray){ if(params[key] != NULL){ - NSString *valueStr = params[key]; + //Key瀵瑰簲鐨剉alue寮鸿浆涓篘SString + NSString *valueStr = [NSString stringWithFormat:@"%@",[params objectForKey:key]]; //妫�娴嬪綋鍓嶅弬鏁版槸鍚﹂渶瑕佸弬涓庢牎楠� if([self IfValueNeedSign:valueStr]){ newString = [newString stringByAppendingString:[NSString stringWithFormat:@"%@=%@&", key,valueStr]]; @@ -311,7 +318,10 @@ if (( [self stringIsNullOrEmpty:valueStr])//鍒ょ┖瀛楃 || ([[valueStr substringToIndex:1] isEqual:@"{"])//鍒ゆ柇鏄惁涓哄璞� || ([[valueStr substringToIndex:1] isEqual:@"["])//鍒ゆ柇鏄惁涓烘暟缁� + || ([[valueStr substringToIndex:1] isEqual:@"("])//鍒ゆ柇鏄惁涓烘暟缁� ) { + +// HDLSDKLog(@"涓嶆牎楠�: %@",valueStr); return false; } return true; @@ -319,3 +329,9 @@ @end + + +#pragma mark - 淇敼璁板綍 +//2021-07-07 +//V1.1.3 +//1.鏇挎崲涓烘柊鎺ュ彛锛屾牴鎹甴omeId娉ㄥ唽钀ょ煶瀛愯处鍙锋柟妗堛�� diff --git a/Demo/EZOpensdk_iOS_4.15.1_build20201104/Demo/EZOpenSDKDemo/Global/EZSDK.h b/Demo/EZOpensdk_iOS_4.15.1_build20201104/Demo/EZOpenSDKDemo/Global/EZSDK.h index d9b3fe5..9325728 100644 --- a/Demo/EZOpensdk_iOS_4.15.1_build20201104/Demo/EZOpenSDKDemo/Global/EZSDK.h +++ b/Demo/EZOpensdk_iOS_4.15.1_build20201104/Demo/EZOpenSDKDemo/Global/EZSDK.h @@ -6,7 +6,7 @@ // #import <Foundation/Foundation.h> - +#import "EZDeviceInfo.h" @interface EZSDK : NSObject /** @@ -21,11 +21,11 @@ /** 璁剧疆HDLSDK鐨刟ccessToken */ -+(void)setHDlAccessToken:(NSString *) accessToken refreshToken:(NSString *) refreshToken; ++(void)setHDlAccessToken:(NSString *)accessToken refreshToken:(NSString *) refreshToken; /** 璁剧疆SDK鐨勬渤涓滄帴鍙g殑requestHttpsHost鍜屽钩鍙� 鏍囪瘑锛�1.on+(榛樿) 2.evoyo */ -+(void)setRequestHttpsHostAndPlatform:(NSString *) requestHttpsHost platform:(int) platform; ++(void)setRequestHttpsHostAndPlatform:(NSString *) requestHttpsHost platform:(int)platform homeId:(NSString *)homeId; /** 鐩存帴璺宠浆鍒拌悿鐭虫憚鍍忓ご鍒楄〃 @@ -38,14 +38,17 @@ /** 鏌ョ湅瑙嗛鐩戞帶鐩存挱 */ -+(void)Play:(NSObject*)deviceInfo; ++(void)Play:(EZDeviceInfo*)deviceInfo; +/// 鎸囧畾搴忓垪鍙� 鏌ョ湅瑙嗛鐩戞帶鐩存挱 +/// @param deviceSerial 搴忓垪鍙� ++(void)PlayWithDeviceSerial:(NSString *)deviceSerial; /** 鎵撳紑鎽勫儚澶磋缃〉闈� */ -+(void)setting:(NSObject*)deviceInfo; ++(void)setting:(EZDeviceInfo*)deviceInfo; /** 鍥炴斁鎾斁鍘嗗彶 */ -+(void)playBackVideo:(NSObject*)deviceInfo; ++(void)playBackVideo:(EZDeviceInfo*)deviceInfo; @end diff --git a/Demo/EZOpensdk_iOS_4.15.1_build20201104/Demo/EZOpenSDKDemo/Global/EZSDK.m b/Demo/EZOpensdk_iOS_4.15.1_build20201104/Demo/EZOpenSDKDemo/Global/EZSDK.m index d283890..cfb414f 100644 --- a/Demo/EZOpensdk_iOS_4.15.1_build20201104/Demo/EZOpenSDKDemo/Global/EZSDK.m +++ b/Demo/EZOpensdk_iOS_4.15.1_build20201104/Demo/EZOpenSDKDemo/Global/EZSDK.m @@ -25,13 +25,15 @@ @implementation EZSDK +static BOOL isHavelibInit=NO; + /** 鍒濆鍖朣DK 浼犲叆鍥藉唴鐗坘ey 鍜屾捣澶栫増globalAppKey */ + (BOOL)initLibWithAppKey:(NSString *)appKey globalAppKey:(NSString *)globalAppKey { - static BOOL isHavelibInit=NO; + if (!isHavelibInit) { // isHavelibInit=YES; // NSLog(@"绗竴娆″垵濮嬪寲钀ょ煶搴�"); @@ -72,9 +74,10 @@ /** 璁剧疆SDK鐨勬渤涓滄帴鍙g殑requestHttpsHost鍜屽钩鍙� 鏍囪瘑锛�1.on+(榛樿) 2.evoyo */ -+(void)setRequestHttpsHostAndPlatform:(NSString *) requestHttpsHost platform:(int) platform{ ++(void)setRequestHttpsHostAndPlatform:(NSString *) requestHttpsHost platform:(int)platform homeId:(NSString *)homeId{ [[GlobalKit shareKit] setGlobalRequestHttpsHost:requestHttpsHost]; [[GlobalKit shareKit] setHdlPlatform:platform]; + [[GlobalKit shareKit] setHdlHomeId:homeId]; } //鑾峰彇褰撳墠灞忓箷鏄剧ず鐨剉iewcontroller (杩欓噷闈㈣幏鍙栫殑鐩稿綋浜巖ootViewController) @@ -136,22 +139,40 @@ /** 鏌ョ湅瑙嗛鐩戞帶鐩存挱 */ -+(void)Play:(NSObject*)deviceInfo ++(void)Play:(EZDeviceInfo*)deviceInfo { UIStoryboard *addDeviceStoryBoard = [UIStoryboard storyboardWithName:@"EZMain" bundle:nil]; EZLivePlayViewController *rootViewController = [addDeviceStoryBoard instantiateViewControllerWithIdentifier:@"EZLivePlayViewController"]; // NSLog(@"play--iphone--rootViewController"); rootViewController.deviceInfo=(EZDeviceInfo *)deviceInfo; NSLog(@"play--iphone--deviceName -%@",rootViewController.deviceInfo.deviceName); - // rootViewController.cameraIndex=0; +// rootViewController.cameraIndex=0; [[self getCurrentVC] setNavigationBarHidden:NO]; [[self getCurrentVC] pushViewController:rootViewController animated:YES]; + + +} + +/// 鎸囧畾搴忓垪鍙锋挱鏀� +/// @param deviceSerial 搴忓垪鍙� ++(void)PlayWithDeviceSerial:(NSString *)deviceSerial{ + //鑾峰彇璁惧鍒楄〃鎺ュ彛 + [EZOpenSDK getDeviceInfo:deviceSerial completion:^(EZDeviceInfo *deviceInfo, NSError *error) { + if(error) + { + NSLog(@"EZ 鏌ヨ璁惧淇℃伅澶辫触"); + return; + } + if (deviceInfo) { + [self Play:deviceInfo]; + } + }]; } /** 鎵撳紑鎽勫儚澶磋缃〉闈� */ -+(void)setting:(NSObject*)deviceInfo ++(void)setting:(EZDeviceInfo*)deviceInfo { UIStoryboard *settingStoryBoard=[UIStoryboard storyboardWithName:@"EZMain" bundle:nil]; EZSettingViewController *settingVC=[settingStoryBoard instantiateViewControllerWithIdentifier:@"EZSettingViewController"]; @@ -163,7 +184,7 @@ /** 鍥炴斁鎾斁鍘嗗彶 */ -+(void)playBackVideo:(NSObject*)deviceInfo ++(void)playBackVideo:(EZDeviceInfo*)deviceInfo { UIStoryboard *playBackStoryBoard=[UIStoryboard storyboardWithName:@"EZMain" bundle:nil]; EZPlaybackViewController *playBackVC=[playBackStoryBoard instantiateViewControllerWithIdentifier:@"EZPlaybackViewController"]; diff --git a/Demo/EZOpensdk_iOS_4.15.1_build20201104/Demo/EZOpenSDKDemo/Global/GlobalKit.h b/Demo/EZOpensdk_iOS_4.15.1_build20201104/Demo/EZOpenSDKDemo/Global/GlobalKit.h index 1ede585..d8917f4 100644 --- a/Demo/EZOpensdk_iOS_4.15.1_build20201104/Demo/EZOpenSDKDemo/Global/GlobalKit.h +++ b/Demo/EZOpensdk_iOS_4.15.1_build20201104/Demo/EZOpenSDKDemo/Global/GlobalKit.h @@ -22,6 +22,7 @@ @property (nonatomic, copy) NSString *GlobalRequestHttpsHost; @property (nonatomic, copy) NSString *hdlAccessToken; @property (nonatomic, copy) NSString *hdlRefreshToken; +@property (nonatomic, copy) NSString *hdlHomeId; @property (nonatomic, copy) NSString *accessToken; @property (nonatomic, copy) NSString *deviceSerialNo; //璁惧搴忓垪鍙� diff --git a/Demo/EZOpensdk_iOS_4.15.1_build20201104/Demo/EZOpenSDKDemo/Global/GlobalKit.m b/Demo/EZOpensdk_iOS_4.15.1_build20201104/Demo/EZOpenSDKDemo/Global/GlobalKit.m index 4a06059..e26e622 100644 --- a/Demo/EZOpensdk_iOS_4.15.1_build20201104/Demo/EZOpenSDKDemo/Global/GlobalKit.m +++ b/Demo/EZOpensdk_iOS_4.15.1_build20201104/Demo/EZOpenSDKDemo/Global/GlobalKit.m @@ -45,6 +45,7 @@ _accessToken = accessToken; [[NSUserDefaults standardUserDefaults] setObject:accessToken?:@"" forKey:EZOpenSDKAccessToken]; [[NSUserDefaults standardUserDefaults] synchronize]; + [EZOPENSDK setAccessToken:[GlobalKit shareKit].accessToken]; } - (void)setHdlAccessToken:(NSString *)hdlAccessToken @@ -66,7 +67,7 @@ _GlobalRequestHttpsHost = GlobalRequestHttpsHost; } -- (void)sethdlPlatform:(int )hdlPlatform +- (void)sethdlPlatform:(int)hdlPlatform { _hdlPlatform = hdlPlatform; } @@ -74,7 +75,7 @@ - (void)clearSession { _accessToken = nil; - _hdlRefreshToken = nil; + _hdlAccessToken = nil; _hdlRefreshToken = nil; [[NSUserDefaults standardUserDefaults] removeObjectForKey:EZOpenSDKAccessToken]; [[NSUserDefaults standardUserDefaults] synchronize]; diff --git a/Demo/EZOpensdk_iOS_4.15.1_build20201104/Demo/EZOpenSDKDemo/TableViewCells/DeviceListCell.m b/Demo/EZOpensdk_iOS_4.15.1_build20201104/Demo/EZOpenSDKDemo/TableViewCells/DeviceListCell.m index 935f895..b3c8980 100644 --- a/Demo/EZOpensdk_iOS_4.15.1_build20201104/Demo/EZOpenSDKDemo/TableViewCells/DeviceListCell.m +++ b/Demo/EZOpensdk_iOS_4.15.1_build20201104/Demo/EZOpenSDKDemo/TableViewCells/DeviceListCell.m @@ -44,8 +44,8 @@ // }]; // [EZOPENSDK cap] - //2021-05-08 闅愯棌褰曞儚鎸夐挳 - self.recordButton.hidden = YES; +// //2021-05-08 闅愯棌褰曞儚鎸夐挳 +// self.recordButton.hidden = YES; self.messageButton.hidden = NO; self.settingButton.hidden = NO; diff --git a/Demo/EZOpensdk_iOS_4.15.1_build20201104/Demo/EZOpenSDKDemo/Venders/YYModel/NSObject+YYModel.h b/Demo/EZOpensdk_iOS_4.15.1_build20201104/Demo/EZOpenSDKDemo/Venders/YYModel/NSObject+YYModel.h new file mode 100644 index 0000000..73f62ec --- /dev/null +++ b/Demo/EZOpensdk_iOS_4.15.1_build20201104/Demo/EZOpenSDKDemo/Venders/YYModel/NSObject+YYModel.h @@ -0,0 +1,440 @@ +// +// NSObject+YYModel.h +// YYModel <https://github.com/ibireme/YYModel> +// +// Created by ibireme on 15/5/10. +// Copyright (c) 2015 ibireme. +// +// This source code is licensed under the MIT-style license found in the +// LICENSE file in the root directory of this source tree. +// + +#import <Foundation/Foundation.h> + +NS_ASSUME_NONNULL_BEGIN + +/** + Provide some data-model method: + + * Convert json to any object, or convert any object to json. + * Set object properties with a key-value dictionary (like KVC). + * Implementations of `NSCoding`, `NSCopying`, `-hash` and `-isEqual:`. + + See `YYModel` protocol for custom methods. + + + Sample Code: + + ********************** json convertor ********************* + @code + @interface YYAuthor : NSObject + @property (nonatomic, strong) NSString *name; + @property (nonatomic, assign) NSDate *birthday; + @end + @implementation YYAuthor + @end + + @interface YYBook : NSObject + @property (nonatomic, copy) NSString *name; + @property (nonatomic, assign) NSUInteger pages; + @property (nonatomic, strong) YYAuthor *author; + @end + @implementation YYBook + @end + + int main() { + // create model from json + YYBook *book = [YYBook yy_modelWithJSON:@"{\"name\": \"Harry Potter\", \"pages\": 256, \"author\": {\"name\": \"J.K.Rowling\", \"birthday\": \"1965-07-31\" }}"]; + + // convert model to json + NSString *json = [book yy_modelToJSONString]; + // {"author":{"name":"J.K.Rowling","birthday":"1965-07-31T00:00:00+0000"},"name":"Harry Potter","pages":256} + } + @endcode + + ********************** Coding/Copying/hash/equal ********************* + @code + @interface YYShadow :NSObject <NSCoding, NSCopying> + @property (nonatomic, copy) NSString *name; + @property (nonatomic, assign) CGSize size; + @end + + @implementation YYShadow + - (void)encodeWithCoder:(NSCoder *)aCoder { [self yy_modelEncodeWithCoder:aCoder]; } + - (id)initWithCoder:(NSCoder *)aDecoder { self = [super init]; return [self yy_modelInitWithCoder:aDecoder]; } + - (id)copyWithZone:(NSZone *)zone { return [self yy_modelCopy]; } + - (NSUInteger)hash { return [self yy_modelHash]; } + - (BOOL)isEqual:(id)object { return [self yy_modelIsEqual:object]; } + @end + @endcode + + */ +@interface NSObject (YYModel) + +/** + Creates and returns a new instance of the receiver from a json. + This method is thread-safe. + + @param json A json object in `NSDictionary`, `NSString` or `NSData`. + + @return A new instance created from the json, or nil if an error occurs. + */ ++ (nullable instancetype)yy_modelWithJSON:(id)json; + +/** + Creates and returns a new instance of the receiver from a key-value dictionary. + This method is thread-safe. + + @param dictionary A key-value dictionary mapped to the instance's properties. + Any invalid key-value pair in dictionary will be ignored. + + @return A new instance created from the dictionary, or nil if an error occurs. + + @discussion The key in `dictionary` will mapped to the reciever's property name, + and the value will set to the property. If the value's type does not match the + property, this method will try to convert the value based on these rules: + + `NSString` or `NSNumber` -> c number, such as BOOL, int, long, float, NSUInteger... + `NSString` -> NSDate, parsed with format "yyyy-MM-dd'T'HH:mm:ssZ", "yyyy-MM-dd HH:mm:ss" or "yyyy-MM-dd". + `NSString` -> NSURL. + `NSValue` -> struct or union, such as CGRect, CGSize, ... + `NSString` -> SEL, Class. + */ ++ (nullable instancetype)yy_modelWithDictionary:(NSDictionary *)dictionary; + +/** + Set the receiver's properties with a json object. + + @discussion Any invalid data in json will be ignored. + + @param json A json object of `NSDictionary`, `NSString` or `NSData`, mapped to the + receiver's properties. + + @return Whether succeed. + */ +- (BOOL)yy_modelSetWithJSON:(id)json; + +/** + Set the receiver's properties with a key-value dictionary. + + @param dic A key-value dictionary mapped to the receiver's properties. + Any invalid key-value pair in dictionary will be ignored. + + @discussion The key in `dictionary` will mapped to the reciever's property name, + and the value will set to the property. If the value's type doesn't match the + property, this method will try to convert the value based on these rules: + + `NSString`, `NSNumber` -> c number, such as BOOL, int, long, float, NSUInteger... + `NSString` -> NSDate, parsed with format "yyyy-MM-dd'T'HH:mm:ssZ", "yyyy-MM-dd HH:mm:ss" or "yyyy-MM-dd". + `NSString` -> NSURL. + `NSValue` -> struct or union, such as CGRect, CGSize, ... + `NSString` -> SEL, Class. + + @return Whether succeed. + */ +- (BOOL)yy_modelSetWithDictionary:(NSDictionary *)dic; + +/** + Generate a json object from the receiver's properties. + + @return A json object in `NSDictionary` or `NSArray`, or nil if an error occurs. + See [NSJSONSerialization isValidJSONObject] for more information. + + @discussion Any of the invalid property is ignored. + If the reciver is `NSArray`, `NSDictionary` or `NSSet`, it just convert + the inner object to json object. + */ +- (nullable id)yy_modelToJSONObject; + +/** + Generate a json string's data from the receiver's properties. + + @return A json string's data, or nil if an error occurs. + + @discussion Any of the invalid property is ignored. + If the reciver is `NSArray`, `NSDictionary` or `NSSet`, it will also convert the + inner object to json string. + */ +- (nullable NSData *)yy_modelToJSONData; + +/** + Generate a json string from the receiver's properties. + + @return A json string, or nil if an error occurs. + + @discussion Any of the invalid property is ignored. + If the reciver is `NSArray`, `NSDictionary` or `NSSet`, it will also convert the + inner object to json string. + */ +- (nullable NSString *)yy_modelToJSONString; + +/** + Copy a instance with the receiver's properties. + + @return A copied instance, or nil if an error occurs. + */ +- (nullable id)yy_modelCopy; + +/** + Encode the receiver's properties to a coder. + + @param aCoder An archiver object. + */ +- (void)yy_modelEncodeWithCoder:(NSCoder *)aCoder; + +/** + Decode the receiver's properties from a decoder. + + @param aDecoder An archiver object. + + @return self + */ +- (id)yy_modelInitWithCoder:(NSCoder *)aDecoder; + +/** + Get a hash code with the receiver's properties. + + @return Hash code. + */ +- (NSUInteger)yy_modelHash; + +/** + Compares the receiver with another object for equality, based on properties. + + @param model Another object. + + @return `YES` if the reciever is equal to the object, otherwise `NO`. + */ +- (BOOL)yy_modelIsEqual:(id)model; + +/** + Description method for debugging purposes based on properties. + + @return A string that describes the contents of the receiver. + */ +- (NSString *)yy_modelDescription; + +@end + + + +/** + Provide some data-model method for NSArray. + */ +@interface NSArray (YYModel) + +/** + Creates and returns an array from a json-array. + This method is thread-safe. + + @param cls The instance's class in array. + @param json A json array of `NSArray`, `NSString` or `NSData`. + Example: [{"name":"Mary"},{name:"Joe"}] + + @return A array, or nil if an error occurs. + */ ++ (nullable NSArray *)yy_modelArrayWithClass:(Class)cls json:(id)json; + +@end + + + +/** + Provide some data-model method for NSDictionary. + */ +@interface NSDictionary (YYModel) + +/** + Creates and returns a dictionary from a json. + This method is thread-safe. + + @param cls The value instance's class in dictionary. + @param json A json dictionary of `NSDictionary`, `NSString` or `NSData`. + Example: {"user1":{"name","Mary"}, "user2": {name:"Joe"}} + + @return A dictionary, or nil if an error occurs. + */ ++ (nullable NSDictionary *)yy_modelDictionaryWithClass:(Class)cls json:(id)json; +@end + + + +/** + If the default model transform does not fit to your model class, implement one or + more method in this protocol to change the default key-value transform process. + There's no need to add '<YYModel>' to your class header. + */ +@protocol YYModel <NSObject> +@optional + +/** + Custom property mapper. + + @discussion If the key in JSON/Dictionary does not match to the model's property name, + implements this method and returns the additional mapper. + + Example: + + json: + { + "n":"Harry Pottery", + "p": 256, + "ext" : { + "desc" : "A book written by J.K.Rowling." + }, + "ID" : 100010 + } + + model: + @code + @interface YYBook : NSObject + @property NSString *name; + @property NSInteger page; + @property NSString *desc; + @property NSString *bookID; + @end + + @implementation YYBook + + (NSDictionary *)modelCustomPropertyMapper { + return @{@"name" : @"n", + @"page" : @"p", + @"desc" : @"ext.desc", + @"bookID": @[@"id", @"ID", @"book_id"]}; + } + @end + @endcode + + @return A custom mapper for properties. + */ ++ (nullable NSDictionary<NSString *, id> *)modelCustomPropertyMapper; + +/** + The generic class mapper for container properties. + + @discussion If the property is a container object, such as NSArray/NSSet/NSDictionary, + implements this method and returns a property->class mapper, tells which kind of + object will be add to the array/set/dictionary. + + Example: + @code + @class YYShadow, YYBorder, YYAttachment; + + @interface YYAttributes + @property NSString *name; + @property NSArray *shadows; + @property NSSet *borders; + @property NSDictionary *attachments; + @end + + @implementation YYAttributes + + (NSDictionary *)modelContainerPropertyGenericClass { + return @{@"shadows" : [YYShadow class], + @"borders" : YYBorder.class, + @"attachments" : @"YYAttachment" }; + } + @end + @endcode + + @return A class mapper. + */ ++ (nullable NSDictionary<NSString *, id> *)modelContainerPropertyGenericClass; + +/** + If you need to create instances of different classes during json->object transform, + use the method to choose custom class based on dictionary data. + + @discussion If the model implements this method, it will be called to determine resulting class + during `+modelWithJSON:`, `+modelWithDictionary:`, conveting object of properties of parent objects + (both singular and containers via `+modelContainerPropertyGenericClass`). + + Example: + @code + @class YYCircle, YYRectangle, YYLine; + + @implementation YYShape + + + (Class)modelCustomClassForDictionary:(NSDictionary*)dictionary { + if (dictionary[@"radius"] != nil) { + return [YYCircle class]; + } else if (dictionary[@"width"] != nil) { + return [YYRectangle class]; + } else if (dictionary[@"y2"] != nil) { + return [YYLine class]; + } else { + return [self class]; + } + } + + @end + @endcode + + @param dictionary The json/kv dictionary. + + @return Class to create from this dictionary, `nil` to use current class. + + */ ++ (nullable Class)modelCustomClassForDictionary:(NSDictionary *)dictionary; + +/** + All the properties in blacklist will be ignored in model transform process. + Returns nil to ignore this feature. + + @return An array of property's name. + */ ++ (nullable NSArray<NSString *> *)modelPropertyBlacklist; + +/** + If a property is not in the whitelist, it will be ignored in model transform process. + Returns nil to ignore this feature. + + @return An array of property's name. + */ ++ (nullable NSArray<NSString *> *)modelPropertyWhitelist; + +/** + This method's behavior is similar to `- (BOOL)modelCustomTransformFromDictionary:(NSDictionary *)dic;`, + but be called before the model transform. + + @discussion If the model implements this method, it will be called before + `+modelWithJSON:`, `+modelWithDictionary:`, `-modelSetWithJSON:` and `-modelSetWithDictionary:`. + If this method returns nil, the transform process will ignore this model. + + @param dic The json/kv dictionary. + + @return Returns the modified dictionary, or nil to ignore this model. + */ +- (NSDictionary *)modelCustomWillTransformFromDictionary:(NSDictionary *)dic; + +/** + If the default json-to-model transform does not fit to your model object, implement + this method to do additional process. You can also use this method to validate the + model's properties. + + @discussion If the model implements this method, it will be called at the end of + `+modelWithJSON:`, `+modelWithDictionary:`, `-modelSetWithJSON:` and `-modelSetWithDictionary:`. + If this method returns NO, the transform process will ignore this model. + + @param dic The json/kv dictionary. + + @return Returns YES if the model is valid, or NO to ignore this model. + */ +- (BOOL)modelCustomTransformFromDictionary:(NSDictionary *)dic; + +/** + If the default model-to-json transform does not fit to your model class, implement + this method to do additional process. You can also use this method to validate the + json dictionary. + + @discussion If the model implements this method, it will be called at the end of + `-modelToJSONObject` and `-modelToJSONString`. + If this method returns NO, the transform process will ignore this json dictionary. + + @param dic The json dictionary. + + @return Returns YES if the model is valid, or NO to ignore this model. + */ +- (BOOL)modelCustomTransformToDictionary:(NSMutableDictionary *)dic; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Demo/EZOpensdk_iOS_4.15.1_build20201104/Demo/EZOpenSDKDemo/Venders/YYModel/NSObject+YYModel.m b/Demo/EZOpensdk_iOS_4.15.1_build20201104/Demo/EZOpenSDKDemo/Venders/YYModel/NSObject+YYModel.m new file mode 100644 index 0000000..3d7c470 --- /dev/null +++ b/Demo/EZOpensdk_iOS_4.15.1_build20201104/Demo/EZOpenSDKDemo/Venders/YYModel/NSObject+YYModel.m @@ -0,0 +1,1839 @@ +// +// NSObject+YYModel.m +// YYModel <https://github.com/ibireme/YYModel> +// +// Created by ibireme on 15/5/10. +// Copyright (c) 2015 ibireme. +// +// This source code is licensed under the MIT-style license found in the +// LICENSE file in the root directory of this source tree. +// + +#import "NSObject+YYModel.h" +#import "YYClassInfo.h" +#import <objc/message.h> + +#define force_inline __inline__ __attribute__((always_inline)) + +/// Foundation Class Type +typedef NS_ENUM (NSUInteger, YYEncodingNSType) { + YYEncodingTypeNSUnknown = 0, + YYEncodingTypeNSString, + YYEncodingTypeNSMutableString, + YYEncodingTypeNSValue, + YYEncodingTypeNSNumber, + YYEncodingTypeNSDecimalNumber, + YYEncodingTypeNSData, + YYEncodingTypeNSMutableData, + YYEncodingTypeNSDate, + YYEncodingTypeNSURL, + YYEncodingTypeNSArray, + YYEncodingTypeNSMutableArray, + YYEncodingTypeNSDictionary, + YYEncodingTypeNSMutableDictionary, + YYEncodingTypeNSSet, + YYEncodingTypeNSMutableSet, +}; + +/// Get the Foundation class type from property info. +static force_inline YYEncodingNSType YYClassGetNSType(Class cls) { + if (!cls) return YYEncodingTypeNSUnknown; + if ([cls isSubclassOfClass:[NSMutableString class]]) return YYEncodingTypeNSMutableString; + if ([cls isSubclassOfClass:[NSString class]]) return YYEncodingTypeNSString; + if ([cls isSubclassOfClass:[NSDecimalNumber class]]) return YYEncodingTypeNSDecimalNumber; + if ([cls isSubclassOfClass:[NSNumber class]]) return YYEncodingTypeNSNumber; + if ([cls isSubclassOfClass:[NSValue class]]) return YYEncodingTypeNSValue; + if ([cls isSubclassOfClass:[NSMutableData class]]) return YYEncodingTypeNSMutableData; + if ([cls isSubclassOfClass:[NSData class]]) return YYEncodingTypeNSData; + if ([cls isSubclassOfClass:[NSDate class]]) return YYEncodingTypeNSDate; + if ([cls isSubclassOfClass:[NSURL class]]) return YYEncodingTypeNSURL; + if ([cls isSubclassOfClass:[NSMutableArray class]]) return YYEncodingTypeNSMutableArray; + if ([cls isSubclassOfClass:[NSArray class]]) return YYEncodingTypeNSArray; + if ([cls isSubclassOfClass:[NSMutableDictionary class]]) return YYEncodingTypeNSMutableDictionary; + if ([cls isSubclassOfClass:[NSDictionary class]]) return YYEncodingTypeNSDictionary; + if ([cls isSubclassOfClass:[NSMutableSet class]]) return YYEncodingTypeNSMutableSet; + if ([cls isSubclassOfClass:[NSSet class]]) return YYEncodingTypeNSSet; + return YYEncodingTypeNSUnknown; +} + +/// Whether the type is c number. +static force_inline BOOL YYEncodingTypeIsCNumber(YYEncodingType type) { + switch (type & YYEncodingTypeMask) { + case YYEncodingTypeBool: + case YYEncodingTypeInt8: + case YYEncodingTypeUInt8: + case YYEncodingTypeInt16: + case YYEncodingTypeUInt16: + case YYEncodingTypeInt32: + case YYEncodingTypeUInt32: + case YYEncodingTypeInt64: + case YYEncodingTypeUInt64: + case YYEncodingTypeFloat: + case YYEncodingTypeDouble: + case YYEncodingTypeLongDouble: return YES; + default: return NO; + } +} + +/// Parse a number value from 'id'. +static force_inline NSNumber *YYNSNumberCreateFromID(__unsafe_unretained id value) { + static NSCharacterSet *dot; + static NSDictionary *dic; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + dot = [NSCharacterSet characterSetWithRange:NSMakeRange('.', 1)]; + dic = @{@"TRUE" : @(YES), + @"True" : @(YES), + @"true" : @(YES), + @"FALSE" : @(NO), + @"False" : @(NO), + @"false" : @(NO), + @"YES" : @(YES), + @"Yes" : @(YES), + @"yes" : @(YES), + @"NO" : @(NO), + @"No" : @(NO), + @"no" : @(NO), + @"NIL" : (id)kCFNull, + @"Nil" : (id)kCFNull, + @"nil" : (id)kCFNull, + @"NULL" : (id)kCFNull, + @"Null" : (id)kCFNull, + @"null" : (id)kCFNull, + @"(NULL)" : (id)kCFNull, + @"(Null)" : (id)kCFNull, + @"(null)" : (id)kCFNull, + @"<NULL>" : (id)kCFNull, + @"<Null>" : (id)kCFNull, + @"<null>" : (id)kCFNull}; + }); + + if (!value || value == (id)kCFNull) return nil; + if ([value isKindOfClass:[NSNumber class]]) return value; + if ([value isKindOfClass:[NSString class]]) { + NSNumber *num = dic[value]; + if (num != nil) { + if (num == (id)kCFNull) return nil; + return num; + } + if ([(NSString *)value rangeOfCharacterFromSet:dot].location != NSNotFound) { + const char *cstring = ((NSString *)value).UTF8String; + if (!cstring) return nil; + double num = atof(cstring); + if (isnan(num) || isinf(num)) return nil; + return @(num); + } else { + const char *cstring = ((NSString *)value).UTF8String; + if (!cstring) return nil; + return @(atoll(cstring)); + } + } + return nil; +} + +/// Parse string to date. +static force_inline NSDate *YYNSDateFromString(__unsafe_unretained NSString *string) { + typedef NSDate* (^YYNSDateParseBlock)(NSString *string); + #define kParserNum 34 + static YYNSDateParseBlock blocks[kParserNum + 1] = {0}; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + { + /* + 2014-01-20 // Google + */ + NSDateFormatter *formatter = [[NSDateFormatter alloc] init]; + formatter.locale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"]; + formatter.timeZone = [NSTimeZone timeZoneForSecondsFromGMT:0]; + formatter.dateFormat = @"yyyy-MM-dd"; + blocks[10] = ^(NSString *string) { return [formatter dateFromString:string]; }; + } + + { + /* + 2014-01-20 12:24:48 + 2014-01-20T12:24:48 // Google + 2014-01-20 12:24:48.000 + 2014-01-20T12:24:48.000 + */ + NSDateFormatter *formatter1 = [[NSDateFormatter alloc] init]; + formatter1.locale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"]; + formatter1.timeZone = [NSTimeZone timeZoneForSecondsFromGMT:0]; + formatter1.dateFormat = @"yyyy-MM-dd'T'HH:mm:ss"; + + NSDateFormatter *formatter2 = [[NSDateFormatter alloc] init]; + formatter2.locale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"]; + formatter2.timeZone = [NSTimeZone timeZoneForSecondsFromGMT:0]; + formatter2.dateFormat = @"yyyy-MM-dd HH:mm:ss"; + + NSDateFormatter *formatter3 = [[NSDateFormatter alloc] init]; + formatter3.locale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"]; + formatter3.timeZone = [NSTimeZone timeZoneForSecondsFromGMT:0]; + formatter3.dateFormat = @"yyyy-MM-dd'T'HH:mm:ss.SSS"; + + NSDateFormatter *formatter4 = [[NSDateFormatter alloc] init]; + formatter4.locale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"]; + formatter4.timeZone = [NSTimeZone timeZoneForSecondsFromGMT:0]; + formatter4.dateFormat = @"yyyy-MM-dd HH:mm:ss.SSS"; + + blocks[19] = ^(NSString *string) { + if ([string characterAtIndex:10] == 'T') { + return [formatter1 dateFromString:string]; + } else { + return [formatter2 dateFromString:string]; + } + }; + + blocks[23] = ^(NSString *string) { + if ([string characterAtIndex:10] == 'T') { + return [formatter3 dateFromString:string]; + } else { + return [formatter4 dateFromString:string]; + } + }; + } + + { + /* + 2014-01-20T12:24:48Z // Github, Apple + 2014-01-20T12:24:48+0800 // Facebook + 2014-01-20T12:24:48+12:00 // Google + 2014-01-20T12:24:48.000Z + 2014-01-20T12:24:48.000+0800 + 2014-01-20T12:24:48.000+12:00 + */ + NSDateFormatter *formatter = [NSDateFormatter new]; + formatter.locale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"]; + formatter.dateFormat = @"yyyy-MM-dd'T'HH:mm:ssZ"; + + NSDateFormatter *formatter2 = [NSDateFormatter new]; + formatter2.locale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"]; + formatter2.dateFormat = @"yyyy-MM-dd'T'HH:mm:ss.SSSZ"; + + blocks[20] = ^(NSString *string) { return [formatter dateFromString:string]; }; + blocks[24] = ^(NSString *string) { return [formatter dateFromString:string]?: [formatter2 dateFromString:string]; }; + blocks[25] = ^(NSString *string) { return [formatter dateFromString:string]; }; + blocks[28] = ^(NSString *string) { return [formatter2 dateFromString:string]; }; + blocks[29] = ^(NSString *string) { return [formatter2 dateFromString:string]; }; + } + + { + /* + Fri Sep 04 00:12:21 +0800 2015 // Weibo, Twitter + Fri Sep 04 00:12:21.000 +0800 2015 + */ + NSDateFormatter *formatter = [NSDateFormatter new]; + formatter.locale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"]; + formatter.dateFormat = @"EEE MMM dd HH:mm:ss Z yyyy"; + + NSDateFormatter *formatter2 = [NSDateFormatter new]; + formatter2.locale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"]; + formatter2.dateFormat = @"EEE MMM dd HH:mm:ss.SSS Z yyyy"; + + blocks[30] = ^(NSString *string) { return [formatter dateFromString:string]; }; + blocks[34] = ^(NSString *string) { return [formatter2 dateFromString:string]; }; + } + }); + if (!string) return nil; + if (string.length > kParserNum) return nil; + YYNSDateParseBlock parser = blocks[string.length]; + if (!parser) return nil; + return parser(string); + #undef kParserNum +} + + +/// Get the 'NSBlock' class. +static force_inline Class YYNSBlockClass() { + static Class cls; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + void (^block)(void) = ^{}; + cls = ((NSObject *)block).class; + while (class_getSuperclass(cls) != [NSObject class]) { + cls = class_getSuperclass(cls); + } + }); + return cls; // current is "NSBlock" +} + + + +/** + Get the ISO date formatter. + + ISO8601 format example: + 2010-07-09T16:13:30+12:00 + 2011-01-11T11:11:11+0000 + 2011-01-26T19:06:43Z + + length: 20/24/25 + */ +static force_inline NSDateFormatter *YYISODateFormatter() { + static NSDateFormatter *formatter = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + formatter = [[NSDateFormatter alloc] init]; + formatter.locale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"]; + formatter.dateFormat = @"yyyy-MM-dd'T'HH:mm:ssZ"; + }); + return formatter; +} + +/// Get the value with key paths from dictionary +/// The dic should be NSDictionary, and the keyPath should not be nil. +static force_inline id YYValueForKeyPath(__unsafe_unretained NSDictionary *dic, __unsafe_unretained NSArray *keyPaths) { + id value = nil; + for (NSUInteger i = 0, max = keyPaths.count; i < max; i++) { + value = dic[keyPaths[i]]; + if (i + 1 < max) { + if ([value isKindOfClass:[NSDictionary class]]) { + dic = value; + } else { + return nil; + } + } + } + return value; +} + +/// Get the value with multi key (or key path) from dictionary +/// The dic should be NSDictionary +static force_inline id YYValueForMultiKeys(__unsafe_unretained NSDictionary *dic, __unsafe_unretained NSArray *multiKeys) { + id value = nil; + for (NSString *key in multiKeys) { + if ([key isKindOfClass:[NSString class]]) { + value = dic[key]; + if (value) break; + } else { + value = YYValueForKeyPath(dic, (NSArray *)key); + if (value) break; + } + } + return value; +} + + + + +/// A property info in object model. +@interface _YYModelPropertyMeta : NSObject { + @package + NSString *_name; ///< property's name + YYEncodingType _type; ///< property's type + YYEncodingNSType _nsType; ///< property's Foundation type + BOOL _isCNumber; ///< is c number type + Class _cls; ///< property's class, or nil + Class _genericCls; ///< container's generic class, or nil if threr's no generic class + SEL _getter; ///< getter, or nil if the instances cannot respond + SEL _setter; ///< setter, or nil if the instances cannot respond + BOOL _isKVCCompatible; ///< YES if it can access with key-value coding + BOOL _isStructAvailableForKeyedArchiver; ///< YES if the struct can encoded with keyed archiver/unarchiver + BOOL _hasCustomClassFromDictionary; ///< class/generic class implements +modelCustomClassForDictionary: + + /* + property->key: _mappedToKey:key _mappedToKeyPath:nil _mappedToKeyArray:nil + property->keyPath: _mappedToKey:keyPath _mappedToKeyPath:keyPath(array) _mappedToKeyArray:nil + property->keys: _mappedToKey:keys[0] _mappedToKeyPath:nil/keyPath _mappedToKeyArray:keys(array) + */ + NSString *_mappedToKey; ///< the key mapped to + NSArray *_mappedToKeyPath; ///< the key path mapped to (nil if the name is not key path) + NSArray *_mappedToKeyArray; ///< the key(NSString) or keyPath(NSArray) array (nil if not mapped to multiple keys) + YYClassPropertyInfo *_info; ///< property's info + _YYModelPropertyMeta *_next; ///< next meta if there are multiple properties mapped to the same key. +} +@end + +@implementation _YYModelPropertyMeta ++ (instancetype)metaWithClassInfo:(YYClassInfo *)classInfo propertyInfo:(YYClassPropertyInfo *)propertyInfo generic:(Class)generic { + + // support pseudo generic class with protocol name + if (!generic && propertyInfo.protocols) { + for (NSString *protocol in propertyInfo.protocols) { + Class cls = objc_getClass(protocol.UTF8String); + if (cls) { + generic = cls; + break; + } + } + } + + _YYModelPropertyMeta *meta = [self new]; + meta->_name = propertyInfo.name; + meta->_type = propertyInfo.type; + meta->_info = propertyInfo; + meta->_genericCls = generic; + + if ((meta->_type & YYEncodingTypeMask) == YYEncodingTypeObject) { + meta->_nsType = YYClassGetNSType(propertyInfo.cls); + } else { + meta->_isCNumber = YYEncodingTypeIsCNumber(meta->_type); + } + if ((meta->_type & YYEncodingTypeMask) == YYEncodingTypeStruct) { + /* + It seems that NSKeyedUnarchiver cannot decode NSValue except these structs: + */ + static NSSet *types = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + NSMutableSet *set = [NSMutableSet new]; + // 32 bit + [set addObject:@"{CGSize=ff}"]; + [set addObject:@"{CGPoint=ff}"]; + [set addObject:@"{CGRect={CGPoint=ff}{CGSize=ff}}"]; + [set addObject:@"{CGAffineTransform=ffffff}"]; + [set addObject:@"{UIEdgeInsets=ffff}"]; + [set addObject:@"{UIOffset=ff}"]; + // 64 bit + [set addObject:@"{CGSize=dd}"]; + [set addObject:@"{CGPoint=dd}"]; + [set addObject:@"{CGRect={CGPoint=dd}{CGSize=dd}}"]; + [set addObject:@"{CGAffineTransform=dddddd}"]; + [set addObject:@"{UIEdgeInsets=dddd}"]; + [set addObject:@"{UIOffset=dd}"]; + types = set; + }); + if ([types containsObject:propertyInfo.typeEncoding]) { + meta->_isStructAvailableForKeyedArchiver = YES; + } + } + meta->_cls = propertyInfo.cls; + + if (generic) { + meta->_hasCustomClassFromDictionary = [generic respondsToSelector:@selector(modelCustomClassForDictionary:)]; + } else if (meta->_cls && meta->_nsType == YYEncodingTypeNSUnknown) { + meta->_hasCustomClassFromDictionary = [meta->_cls respondsToSelector:@selector(modelCustomClassForDictionary:)]; + } + + if (propertyInfo.getter) { + if ([classInfo.cls instancesRespondToSelector:propertyInfo.getter]) { + meta->_getter = propertyInfo.getter; + } + } + if (propertyInfo.setter) { + if ([classInfo.cls instancesRespondToSelector:propertyInfo.setter]) { + meta->_setter = propertyInfo.setter; + } + } + + if (meta->_getter && meta->_setter) { + /* + KVC invalid type: + long double + pointer (such as SEL/CoreFoundation object) + */ + switch (meta->_type & YYEncodingTypeMask) { + case YYEncodingTypeBool: + case YYEncodingTypeInt8: + case YYEncodingTypeUInt8: + case YYEncodingTypeInt16: + case YYEncodingTypeUInt16: + case YYEncodingTypeInt32: + case YYEncodingTypeUInt32: + case YYEncodingTypeInt64: + case YYEncodingTypeUInt64: + case YYEncodingTypeFloat: + case YYEncodingTypeDouble: + case YYEncodingTypeObject: + case YYEncodingTypeClass: + case YYEncodingTypeBlock: + case YYEncodingTypeStruct: + case YYEncodingTypeUnion: { + meta->_isKVCCompatible = YES; + } break; + default: break; + } + } + + return meta; +} +@end + + +/// A class info in object model. +@interface _YYModelMeta : NSObject { + @package + YYClassInfo *_classInfo; + /// Key:mapped key and key path, Value:_YYModelPropertyMeta. + NSDictionary *_mapper; + /// Array<_YYModelPropertyMeta>, all property meta of this model. + NSArray *_allPropertyMetas; + /// Array<_YYModelPropertyMeta>, property meta which is mapped to a key path. + NSArray *_keyPathPropertyMetas; + /// Array<_YYModelPropertyMeta>, property meta which is mapped to multi keys. + NSArray *_multiKeysPropertyMetas; + /// The number of mapped key (and key path), same to _mapper.count. + NSUInteger _keyMappedCount; + /// Model class type. + YYEncodingNSType _nsType; + + BOOL _hasCustomWillTransformFromDictionary; + BOOL _hasCustomTransformFromDictionary; + BOOL _hasCustomTransformToDictionary; + BOOL _hasCustomClassFromDictionary; +} +@end + +@implementation _YYModelMeta +- (instancetype)initWithClass:(Class)cls { + YYClassInfo *classInfo = [YYClassInfo classInfoWithClass:cls]; + if (!classInfo) return nil; + self = [super init]; + + // Get black list + NSSet *blacklist = nil; + if ([cls respondsToSelector:@selector(modelPropertyBlacklist)]) { + NSArray *properties = [(id<YYModel>)cls modelPropertyBlacklist]; + if (properties) { + blacklist = [NSSet setWithArray:properties]; + } + } + + // Get white list + NSSet *whitelist = nil; + if ([cls respondsToSelector:@selector(modelPropertyWhitelist)]) { + NSArray *properties = [(id<YYModel>)cls modelPropertyWhitelist]; + if (properties) { + whitelist = [NSSet setWithArray:properties]; + } + } + + // Get container property's generic class + NSDictionary *genericMapper = nil; + if ([cls respondsToSelector:@selector(modelContainerPropertyGenericClass)]) { + genericMapper = [(id<YYModel>)cls modelContainerPropertyGenericClass]; + if (genericMapper) { + NSMutableDictionary *tmp = [NSMutableDictionary new]; + [genericMapper enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) { + if (![key isKindOfClass:[NSString class]]) return; + Class meta = object_getClass(obj); + if (!meta) return; + if (class_isMetaClass(meta)) { + tmp[key] = obj; + } else if ([obj isKindOfClass:[NSString class]]) { + Class cls = NSClassFromString(obj); + if (cls) { + tmp[key] = cls; + } + } + }]; + genericMapper = tmp; + } + } + + // Create all property metas. + NSMutableDictionary *allPropertyMetas = [NSMutableDictionary new]; + YYClassInfo *curClassInfo = classInfo; + while (curClassInfo && curClassInfo.superCls != nil) { // recursive parse super class, but ignore root class (NSObject/NSProxy) + for (YYClassPropertyInfo *propertyInfo in curClassInfo.propertyInfos.allValues) { + if (!propertyInfo.name) continue; + if (blacklist && [blacklist containsObject:propertyInfo.name]) continue; + if (whitelist && ![whitelist containsObject:propertyInfo.name]) continue; + _YYModelPropertyMeta *meta = [_YYModelPropertyMeta metaWithClassInfo:classInfo + propertyInfo:propertyInfo + generic:genericMapper[propertyInfo.name]]; + if (!meta || !meta->_name) continue; + if (!meta->_getter || !meta->_setter) continue; + if (allPropertyMetas[meta->_name]) continue; + allPropertyMetas[meta->_name] = meta; + } + curClassInfo = curClassInfo.superClassInfo; + } + if (allPropertyMetas.count) _allPropertyMetas = allPropertyMetas.allValues.copy; + + // create mapper + NSMutableDictionary *mapper = [NSMutableDictionary new]; + NSMutableArray *keyPathPropertyMetas = [NSMutableArray new]; + NSMutableArray *multiKeysPropertyMetas = [NSMutableArray new]; + + if ([cls respondsToSelector:@selector(modelCustomPropertyMapper)]) { + NSDictionary *customMapper = [(id <YYModel>)cls modelCustomPropertyMapper]; + [customMapper enumerateKeysAndObjectsUsingBlock:^(NSString *propertyName, NSString *mappedToKey, BOOL *stop) { + _YYModelPropertyMeta *propertyMeta = allPropertyMetas[propertyName]; + if (!propertyMeta) return; + [allPropertyMetas removeObjectForKey:propertyName]; + + if ([mappedToKey isKindOfClass:[NSString class]]) { + if (mappedToKey.length == 0) return; + + propertyMeta->_mappedToKey = mappedToKey; + NSArray *keyPath = [mappedToKey componentsSeparatedByString:@"."]; + for (NSString *onePath in keyPath) { + if (onePath.length == 0) { + NSMutableArray *tmp = keyPath.mutableCopy; + [tmp removeObject:@""]; + keyPath = tmp; + break; + } + } + if (keyPath.count > 1) { + propertyMeta->_mappedToKeyPath = keyPath; + [keyPathPropertyMetas addObject:propertyMeta]; + } + propertyMeta->_next = mapper[mappedToKey] ?: nil; + mapper[mappedToKey] = propertyMeta; + + } else if ([mappedToKey isKindOfClass:[NSArray class]]) { + + NSMutableArray *mappedToKeyArray = [NSMutableArray new]; + for (NSString *oneKey in ((NSArray *)mappedToKey)) { + if (![oneKey isKindOfClass:[NSString class]]) continue; + if (oneKey.length == 0) continue; + + NSArray *keyPath = [oneKey componentsSeparatedByString:@"."]; + if (keyPath.count > 1) { + [mappedToKeyArray addObject:keyPath]; + } else { + [mappedToKeyArray addObject:oneKey]; + } + + if (!propertyMeta->_mappedToKey) { + propertyMeta->_mappedToKey = oneKey; + propertyMeta->_mappedToKeyPath = keyPath.count > 1 ? keyPath : nil; + } + } + if (!propertyMeta->_mappedToKey) return; + + propertyMeta->_mappedToKeyArray = mappedToKeyArray; + [multiKeysPropertyMetas addObject:propertyMeta]; + + propertyMeta->_next = mapper[mappedToKey] ?: nil; + mapper[mappedToKey] = propertyMeta; + } + }]; + } + + [allPropertyMetas enumerateKeysAndObjectsUsingBlock:^(NSString *name, _YYModelPropertyMeta *propertyMeta, BOOL *stop) { + propertyMeta->_mappedToKey = name; + propertyMeta->_next = mapper[name] ?: nil; + mapper[name] = propertyMeta; + }]; + + if (mapper.count) _mapper = mapper; + if (keyPathPropertyMetas) _keyPathPropertyMetas = keyPathPropertyMetas; + if (multiKeysPropertyMetas) _multiKeysPropertyMetas = multiKeysPropertyMetas; + + _classInfo = classInfo; + _keyMappedCount = _allPropertyMetas.count; + _nsType = YYClassGetNSType(cls); + _hasCustomWillTransformFromDictionary = ([cls instancesRespondToSelector:@selector(modelCustomWillTransformFromDictionary:)]); + _hasCustomTransformFromDictionary = ([cls instancesRespondToSelector:@selector(modelCustomTransformFromDictionary:)]); + _hasCustomTransformToDictionary = ([cls instancesRespondToSelector:@selector(modelCustomTransformToDictionary:)]); + _hasCustomClassFromDictionary = ([cls respondsToSelector:@selector(modelCustomClassForDictionary:)]); + + return self; +} + +/// Returns the cached model class meta ++ (instancetype)metaWithClass:(Class)cls { + if (!cls) return nil; + static CFMutableDictionaryRef cache; + static dispatch_once_t onceToken; + static dispatch_semaphore_t lock; + dispatch_once(&onceToken, ^{ + cache = CFDictionaryCreateMutable(CFAllocatorGetDefault(), 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); + lock = dispatch_semaphore_create(1); + }); + dispatch_semaphore_wait(lock, DISPATCH_TIME_FOREVER); + _YYModelMeta *meta = CFDictionaryGetValue(cache, (__bridge const void *)(cls)); + dispatch_semaphore_signal(lock); + if (!meta || meta->_classInfo.needUpdate) { + meta = [[_YYModelMeta alloc] initWithClass:cls]; + if (meta) { + dispatch_semaphore_wait(lock, DISPATCH_TIME_FOREVER); + CFDictionarySetValue(cache, (__bridge const void *)(cls), (__bridge const void *)(meta)); + dispatch_semaphore_signal(lock); + } + } + return meta; +} + +@end + + +/** + Get number from property. + @discussion Caller should hold strong reference to the parameters before this function returns. + @param model Should not be nil. + @param meta Should not be nil, meta.isCNumber should be YES, meta.getter should not be nil. + @return A number object, or nil if failed. + */ +static force_inline NSNumber *ModelCreateNumberFromProperty(__unsafe_unretained id model, + __unsafe_unretained _YYModelPropertyMeta *meta) { + switch (meta->_type & YYEncodingTypeMask) { + case YYEncodingTypeBool: { + return @(((bool (*)(id, SEL))(void *) objc_msgSend)((id)model, meta->_getter)); + } + case YYEncodingTypeInt8: { + return @(((int8_t (*)(id, SEL))(void *) objc_msgSend)((id)model, meta->_getter)); + } + case YYEncodingTypeUInt8: { + return @(((uint8_t (*)(id, SEL))(void *) objc_msgSend)((id)model, meta->_getter)); + } + case YYEncodingTypeInt16: { + return @(((int16_t (*)(id, SEL))(void *) objc_msgSend)((id)model, meta->_getter)); + } + case YYEncodingTypeUInt16: { + return @(((uint16_t (*)(id, SEL))(void *) objc_msgSend)((id)model, meta->_getter)); + } + case YYEncodingTypeInt32: { + return @(((int32_t (*)(id, SEL))(void *) objc_msgSend)((id)model, meta->_getter)); + } + case YYEncodingTypeUInt32: { + return @(((uint32_t (*)(id, SEL))(void *) objc_msgSend)((id)model, meta->_getter)); + } + case YYEncodingTypeInt64: { + return @(((int64_t (*)(id, SEL))(void *) objc_msgSend)((id)model, meta->_getter)); + } + case YYEncodingTypeUInt64: { + return @(((uint64_t (*)(id, SEL))(void *) objc_msgSend)((id)model, meta->_getter)); + } + case YYEncodingTypeFloat: { + float num = ((float (*)(id, SEL))(void *) objc_msgSend)((id)model, meta->_getter); + if (isnan(num) || isinf(num)) return nil; + return @(num); + } + case YYEncodingTypeDouble: { + double num = ((double (*)(id, SEL))(void *) objc_msgSend)((id)model, meta->_getter); + if (isnan(num) || isinf(num)) return nil; + return @(num); + } + case YYEncodingTypeLongDouble: { + double num = ((long double (*)(id, SEL))(void *) objc_msgSend)((id)model, meta->_getter); + if (isnan(num) || isinf(num)) return nil; + return @(num); + } + default: return nil; + } +} + +/** + Set number to property. + @discussion Caller should hold strong reference to the parameters before this function returns. + @param model Should not be nil. + @param num Can be nil. + @param meta Should not be nil, meta.isCNumber should be YES, meta.setter should not be nil. + */ +static force_inline void ModelSetNumberToProperty(__unsafe_unretained id model, + __unsafe_unretained NSNumber *num, + __unsafe_unretained _YYModelPropertyMeta *meta) { + switch (meta->_type & YYEncodingTypeMask) { + case YYEncodingTypeBool: { + ((void (*)(id, SEL, bool))(void *) objc_msgSend)((id)model, meta->_setter, num.boolValue); + } break; + case YYEncodingTypeInt8: { + ((void (*)(id, SEL, int8_t))(void *) objc_msgSend)((id)model, meta->_setter, (int8_t)num.charValue); + } break; + case YYEncodingTypeUInt8: { + ((void (*)(id, SEL, uint8_t))(void *) objc_msgSend)((id)model, meta->_setter, (uint8_t)num.unsignedCharValue); + } break; + case YYEncodingTypeInt16: { + ((void (*)(id, SEL, int16_t))(void *) objc_msgSend)((id)model, meta->_setter, (int16_t)num.shortValue); + } break; + case YYEncodingTypeUInt16: { + ((void (*)(id, SEL, uint16_t))(void *) objc_msgSend)((id)model, meta->_setter, (uint16_t)num.unsignedShortValue); + } break; + case YYEncodingTypeInt32: { + ((void (*)(id, SEL, int32_t))(void *) objc_msgSend)((id)model, meta->_setter, (int32_t)num.intValue); + } + case YYEncodingTypeUInt32: { + ((void (*)(id, SEL, uint32_t))(void *) objc_msgSend)((id)model, meta->_setter, (uint32_t)num.unsignedIntValue); + } break; + case YYEncodingTypeInt64: { + if ([num isKindOfClass:[NSDecimalNumber class]]) { + ((void (*)(id, SEL, int64_t))(void *) objc_msgSend)((id)model, meta->_setter, (int64_t)num.stringValue.longLongValue); + } else { + ((void (*)(id, SEL, uint64_t))(void *) objc_msgSend)((id)model, meta->_setter, (uint64_t)num.longLongValue); + } + } break; + case YYEncodingTypeUInt64: { + if ([num isKindOfClass:[NSDecimalNumber class]]) { + ((void (*)(id, SEL, int64_t))(void *) objc_msgSend)((id)model, meta->_setter, (int64_t)num.stringValue.longLongValue); + } else { + ((void (*)(id, SEL, uint64_t))(void *) objc_msgSend)((id)model, meta->_setter, (uint64_t)num.unsignedLongLongValue); + } + } break; + case YYEncodingTypeFloat: { + float f = num.floatValue; + if (isnan(f) || isinf(f)) f = 0; + ((void (*)(id, SEL, float))(void *) objc_msgSend)((id)model, meta->_setter, f); + } break; + case YYEncodingTypeDouble: { + double d = num.doubleValue; + if (isnan(d) || isinf(d)) d = 0; + ((void (*)(id, SEL, double))(void *) objc_msgSend)((id)model, meta->_setter, d); + } break; + case YYEncodingTypeLongDouble: { + long double d = num.doubleValue; + if (isnan(d) || isinf(d)) d = 0; + ((void (*)(id, SEL, long double))(void *) objc_msgSend)((id)model, meta->_setter, (long double)d); + } // break; commented for code coverage in next line + default: break; + } +} + +/** + Set value to model with a property meta. + + @discussion Caller should hold strong reference to the parameters before this function returns. + + @param model Should not be nil. + @param value Should not be nil, but can be NSNull. + @param meta Should not be nil, and meta->_setter should not be nil. + */ +static void ModelSetValueForProperty(__unsafe_unretained id model, + __unsafe_unretained id value, + __unsafe_unretained _YYModelPropertyMeta *meta) { + if (meta->_isCNumber) { + NSNumber *num = YYNSNumberCreateFromID(value); + ModelSetNumberToProperty(model, num, meta); + if (num != nil) [num class]; // hold the number + } else if (meta->_nsType) { + if (value == (id)kCFNull) { + ((void (*)(id, SEL, id))(void *) objc_msgSend)((id)model, meta->_setter, (id)nil); + } else { + switch (meta->_nsType) { + case YYEncodingTypeNSString: + case YYEncodingTypeNSMutableString: { + if ([value isKindOfClass:[NSString class]]) { + if (meta->_nsType == YYEncodingTypeNSString) { + ((void (*)(id, SEL, id))(void *) objc_msgSend)((id)model, meta->_setter, value); + } else { + ((void (*)(id, SEL, id))(void *) objc_msgSend)((id)model, meta->_setter, ((NSString *)value).mutableCopy); + } + } else if ([value isKindOfClass:[NSNumber class]]) { + ((void (*)(id, SEL, id))(void *) objc_msgSend)((id)model, + meta->_setter, + (meta->_nsType == YYEncodingTypeNSString) ? + ((NSNumber *)value).stringValue : + ((NSNumber *)value).stringValue.mutableCopy); + } else if ([value isKindOfClass:[NSData class]]) { + NSMutableString *string = [[NSMutableString alloc] initWithData:value encoding:NSUTF8StringEncoding]; + ((void (*)(id, SEL, id))(void *) objc_msgSend)((id)model, meta->_setter, string); + } else if ([value isKindOfClass:[NSURL class]]) { + ((void (*)(id, SEL, id))(void *) objc_msgSend)((id)model, + meta->_setter, + (meta->_nsType == YYEncodingTypeNSString) ? + ((NSURL *)value).absoluteString : + ((NSURL *)value).absoluteString.mutableCopy); + } else if ([value isKindOfClass:[NSAttributedString class]]) { + ((void (*)(id, SEL, id))(void *) objc_msgSend)((id)model, + meta->_setter, + (meta->_nsType == YYEncodingTypeNSString) ? + ((NSAttributedString *)value).string : + ((NSAttributedString *)value).string.mutableCopy); + } + } break; + + case YYEncodingTypeNSValue: + case YYEncodingTypeNSNumber: + case YYEncodingTypeNSDecimalNumber: { + if (meta->_nsType == YYEncodingTypeNSNumber) { + ((void (*)(id, SEL, id))(void *) objc_msgSend)((id)model, meta->_setter, YYNSNumberCreateFromID(value)); + } else if (meta->_nsType == YYEncodingTypeNSDecimalNumber) { + if ([value isKindOfClass:[NSDecimalNumber class]]) { + ((void (*)(id, SEL, id))(void *) objc_msgSend)((id)model, meta->_setter, value); + } else if ([value isKindOfClass:[NSNumber class]]) { + NSDecimalNumber *decNum = [NSDecimalNumber decimalNumberWithDecimal:[((NSNumber *)value) decimalValue]]; + ((void (*)(id, SEL, id))(void *) objc_msgSend)((id)model, meta->_setter, decNum); + } else if ([value isKindOfClass:[NSString class]]) { + NSDecimalNumber *decNum = [NSDecimalNumber decimalNumberWithString:value]; + NSDecimal dec = decNum.decimalValue; + if (dec._length == 0 && dec._isNegative) { + decNum = nil; // NaN + } + ((void (*)(id, SEL, id))(void *) objc_msgSend)((id)model, meta->_setter, decNum); + } + } else { // YYEncodingTypeNSValue + if ([value isKindOfClass:[NSValue class]]) { + ((void (*)(id, SEL, id))(void *) objc_msgSend)((id)model, meta->_setter, value); + } + } + } break; + + case YYEncodingTypeNSData: + case YYEncodingTypeNSMutableData: { + if ([value isKindOfClass:[NSData class]]) { + if (meta->_nsType == YYEncodingTypeNSData) { + ((void (*)(id, SEL, id))(void *) objc_msgSend)((id)model, meta->_setter, value); + } else { + NSMutableData *data = ((NSData *)value).mutableCopy; + ((void (*)(id, SEL, id))(void *) objc_msgSend)((id)model, meta->_setter, data); + } + } else if ([value isKindOfClass:[NSString class]]) { + NSData *data = [(NSString *)value dataUsingEncoding:NSUTF8StringEncoding]; + if (meta->_nsType == YYEncodingTypeNSMutableData) { + data = ((NSData *)data).mutableCopy; + } + ((void (*)(id, SEL, id))(void *) objc_msgSend)((id)model, meta->_setter, data); + } + } break; + + case YYEncodingTypeNSDate: { + if ([value isKindOfClass:[NSDate class]]) { + ((void (*)(id, SEL, id))(void *) objc_msgSend)((id)model, meta->_setter, value); + } else if ([value isKindOfClass:[NSString class]]) { + ((void (*)(id, SEL, id))(void *) objc_msgSend)((id)model, meta->_setter, YYNSDateFromString(value)); + } + } break; + + case YYEncodingTypeNSURL: { + if ([value isKindOfClass:[NSURL class]]) { + ((void (*)(id, SEL, id))(void *) objc_msgSend)((id)model, meta->_setter, value); + } else if ([value isKindOfClass:[NSString class]]) { + NSCharacterSet *set = [NSCharacterSet whitespaceAndNewlineCharacterSet]; + NSString *str = [value stringByTrimmingCharactersInSet:set]; + if (str.length == 0) { + ((void (*)(id, SEL, id))(void *) objc_msgSend)((id)model, meta->_setter, nil); + } else { + ((void (*)(id, SEL, id))(void *) objc_msgSend)((id)model, meta->_setter, [[NSURL alloc] initWithString:str]); + } + } + } break; + + case YYEncodingTypeNSArray: + case YYEncodingTypeNSMutableArray: { + if (meta->_genericCls) { + NSArray *valueArr = nil; + if ([value isKindOfClass:[NSArray class]]) valueArr = value; + else if ([value isKindOfClass:[NSSet class]]) valueArr = ((NSSet *)value).allObjects; + if (valueArr) { + NSMutableArray *objectArr = [NSMutableArray new]; + for (id one in valueArr) { + if ([one isKindOfClass:meta->_genericCls]) { + [objectArr addObject:one]; + } else if ([one isKindOfClass:[NSDictionary class]]) { + Class cls = meta->_genericCls; + if (meta->_hasCustomClassFromDictionary) { + cls = [cls modelCustomClassForDictionary:one]; + if (!cls) cls = meta->_genericCls; // for xcode code coverage + } + NSObject *newOne = [cls new]; + [newOne yy_modelSetWithDictionary:one]; + if (newOne) [objectArr addObject:newOne]; + } + } + ((void (*)(id, SEL, id))(void *) objc_msgSend)((id)model, meta->_setter, objectArr); + } + } else { + if ([value isKindOfClass:[NSArray class]]) { + if (meta->_nsType == YYEncodingTypeNSArray) { + ((void (*)(id, SEL, id))(void *) objc_msgSend)((id)model, meta->_setter, value); + } else { + ((void (*)(id, SEL, id))(void *) objc_msgSend)((id)model, + meta->_setter, + ((NSArray *)value).mutableCopy); + } + } else if ([value isKindOfClass:[NSSet class]]) { + if (meta->_nsType == YYEncodingTypeNSArray) { + ((void (*)(id, SEL, id))(void *) objc_msgSend)((id)model, meta->_setter, ((NSSet *)value).allObjects); + } else { + ((void (*)(id, SEL, id))(void *) objc_msgSend)((id)model, + meta->_setter, + ((NSSet *)value).allObjects.mutableCopy); + } + } + } + } break; + + case YYEncodingTypeNSDictionary: + case YYEncodingTypeNSMutableDictionary: { + if ([value isKindOfClass:[NSDictionary class]]) { + if (meta->_genericCls) { + NSMutableDictionary *dic = [NSMutableDictionary new]; + [((NSDictionary *)value) enumerateKeysAndObjectsUsingBlock:^(NSString *oneKey, id oneValue, BOOL *stop) { + if ([oneValue isKindOfClass:[NSDictionary class]]) { + Class cls = meta->_genericCls; + if (meta->_hasCustomClassFromDictionary) { + cls = [cls modelCustomClassForDictionary:oneValue]; + if (!cls) cls = meta->_genericCls; // for xcode code coverage + } + NSObject *newOne = [cls new]; + [newOne yy_modelSetWithDictionary:(id)oneValue]; + if (newOne) dic[oneKey] = newOne; + } + }]; + ((void (*)(id, SEL, id))(void *) objc_msgSend)((id)model, meta->_setter, dic); + } else { + if (meta->_nsType == YYEncodingTypeNSDictionary) { + ((void (*)(id, SEL, id))(void *) objc_msgSend)((id)model, meta->_setter, value); + } else { + ((void (*)(id, SEL, id))(void *) objc_msgSend)((id)model, + meta->_setter, + ((NSDictionary *)value).mutableCopy); + } + } + } + } break; + + case YYEncodingTypeNSSet: + case YYEncodingTypeNSMutableSet: { + NSSet *valueSet = nil; + if ([value isKindOfClass:[NSArray class]]) valueSet = [NSMutableSet setWithArray:value]; + else if ([value isKindOfClass:[NSSet class]]) valueSet = ((NSSet *)value); + + if (meta->_genericCls) { + NSMutableSet *set = [NSMutableSet new]; + for (id one in valueSet) { + if ([one isKindOfClass:meta->_genericCls]) { + [set addObject:one]; + } else if ([one isKindOfClass:[NSDictionary class]]) { + Class cls = meta->_genericCls; + if (meta->_hasCustomClassFromDictionary) { + cls = [cls modelCustomClassForDictionary:one]; + if (!cls) cls = meta->_genericCls; // for xcode code coverage + } + NSObject *newOne = [cls new]; + [newOne yy_modelSetWithDictionary:one]; + if (newOne) [set addObject:newOne]; + } + } + ((void (*)(id, SEL, id))(void *) objc_msgSend)((id)model, meta->_setter, set); + } else { + if (meta->_nsType == YYEncodingTypeNSSet) { + ((void (*)(id, SEL, id))(void *) objc_msgSend)((id)model, meta->_setter, valueSet); + } else { + ((void (*)(id, SEL, id))(void *) objc_msgSend)((id)model, + meta->_setter, + ((NSSet *)valueSet).mutableCopy); + } + } + } // break; commented for code coverage in next line + + default: break; + } + } + } else { + BOOL isNull = (value == (id)kCFNull); + switch (meta->_type & YYEncodingTypeMask) { + case YYEncodingTypeObject: { + Class cls = meta->_genericCls ?: meta->_cls; + if (isNull) { + ((void (*)(id, SEL, id))(void *) objc_msgSend)((id)model, meta->_setter, (id)nil); + } else if ([value isKindOfClass:cls] || !cls) { + ((void (*)(id, SEL, id))(void *) objc_msgSend)((id)model, meta->_setter, (id)value); + } else if ([value isKindOfClass:[NSDictionary class]]) { + NSObject *one = nil; + if (meta->_getter) { + one = ((id (*)(id, SEL))(void *) objc_msgSend)((id)model, meta->_getter); + } + if (one) { + [one yy_modelSetWithDictionary:value]; + } else { + if (meta->_hasCustomClassFromDictionary) { + cls = [cls modelCustomClassForDictionary:value] ?: cls; + } + one = [cls new]; + [one yy_modelSetWithDictionary:value]; + ((void (*)(id, SEL, id))(void *) objc_msgSend)((id)model, meta->_setter, (id)one); + } + } + } break; + + case YYEncodingTypeClass: { + if (isNull) { + ((void (*)(id, SEL, Class))(void *) objc_msgSend)((id)model, meta->_setter, (Class)NULL); + } else { + Class cls = nil; + if ([value isKindOfClass:[NSString class]]) { + cls = NSClassFromString(value); + if (cls) { + ((void (*)(id, SEL, Class))(void *) objc_msgSend)((id)model, meta->_setter, (Class)cls); + } + } else { + cls = object_getClass(value); + if (cls) { + if (class_isMetaClass(cls)) { + ((void (*)(id, SEL, Class))(void *) objc_msgSend)((id)model, meta->_setter, (Class)value); + } + } + } + } + } break; + + case YYEncodingTypeSEL: { + if (isNull) { + ((void (*)(id, SEL, SEL))(void *) objc_msgSend)((id)model, meta->_setter, (SEL)NULL); + } else if ([value isKindOfClass:[NSString class]]) { + SEL sel = NSSelectorFromString(value); + if (sel) ((void (*)(id, SEL, SEL))(void *) objc_msgSend)((id)model, meta->_setter, (SEL)sel); + } + } break; + + case YYEncodingTypeBlock: { + if (isNull) { + ((void (*)(id, SEL, void (^)()))(void *) objc_msgSend)((id)model, meta->_setter, (void (^)())NULL); + } else if ([value isKindOfClass:YYNSBlockClass()]) { + ((void (*)(id, SEL, void (^)()))(void *) objc_msgSend)((id)model, meta->_setter, (void (^)())value); + } + } break; + + case YYEncodingTypeStruct: + case YYEncodingTypeUnion: + case YYEncodingTypeCArray: { + if ([value isKindOfClass:[NSValue class]]) { + const char *valueType = ((NSValue *)value).objCType; + const char *metaType = meta->_info.typeEncoding.UTF8String; + if (valueType && metaType && strcmp(valueType, metaType) == 0) { + [model setValue:value forKey:meta->_name]; + } + } + } break; + + case YYEncodingTypePointer: + case YYEncodingTypeCString: { + if (isNull) { + ((void (*)(id, SEL, void *))(void *) objc_msgSend)((id)model, meta->_setter, (void *)NULL); + } else if ([value isKindOfClass:[NSValue class]]) { + NSValue *nsValue = value; + if (nsValue.objCType && strcmp(nsValue.objCType, "^v") == 0) { + ((void (*)(id, SEL, void *))(void *) objc_msgSend)((id)model, meta->_setter, nsValue.pointerValue); + } + } + } // break; commented for code coverage in next line + + default: break; + } + } +} + + +typedef struct { + void *modelMeta; ///< _YYModelMeta + void *model; ///< id (self) + void *dictionary; ///< NSDictionary (json) +} ModelSetContext; + +/** + Apply function for dictionary, to set the key-value pair to model. + + @param _key should not be nil, NSString. + @param _value should not be nil. + @param _context _context.modelMeta and _context.model should not be nil. + */ +static void ModelSetWithDictionaryFunction(const void *_key, const void *_value, void *_context) { + ModelSetContext *context = _context; + __unsafe_unretained _YYModelMeta *meta = (__bridge _YYModelMeta *)(context->modelMeta); + __unsafe_unretained _YYModelPropertyMeta *propertyMeta = [meta->_mapper objectForKey:(__bridge id)(_key)]; + __unsafe_unretained id model = (__bridge id)(context->model); + while (propertyMeta) { + if (propertyMeta->_setter) { + ModelSetValueForProperty(model, (__bridge __unsafe_unretained id)_value, propertyMeta); + } + propertyMeta = propertyMeta->_next; + }; +} + +/** + Apply function for model property meta, to set dictionary to model. + + @param _propertyMeta should not be nil, _YYModelPropertyMeta. + @param _context _context.model and _context.dictionary should not be nil. + */ +static void ModelSetWithPropertyMetaArrayFunction(const void *_propertyMeta, void *_context) { + ModelSetContext *context = _context; + __unsafe_unretained NSDictionary *dictionary = (__bridge NSDictionary *)(context->dictionary); + __unsafe_unretained _YYModelPropertyMeta *propertyMeta = (__bridge _YYModelPropertyMeta *)(_propertyMeta); + if (!propertyMeta->_setter) return; + id value = nil; + + if (propertyMeta->_mappedToKeyArray) { + value = YYValueForMultiKeys(dictionary, propertyMeta->_mappedToKeyArray); + } else if (propertyMeta->_mappedToKeyPath) { + value = YYValueForKeyPath(dictionary, propertyMeta->_mappedToKeyPath); + } else { + value = [dictionary objectForKey:propertyMeta->_mappedToKey]; + } + + if (value) { + __unsafe_unretained id model = (__bridge id)(context->model); + ModelSetValueForProperty(model, value, propertyMeta); + } +} + +/** + Returns a valid JSON object (NSArray/NSDictionary/NSString/NSNumber/NSNull), + or nil if an error occurs. + + @param model Model, can be nil. + @return JSON object, nil if an error occurs. + */ +static id ModelToJSONObjectRecursive(NSObject *model) { + if (!model || model == (id)kCFNull) return model; + if ([model isKindOfClass:[NSString class]]) return model; + if ([model isKindOfClass:[NSNumber class]]) return model; + if ([model isKindOfClass:[NSDictionary class]]) { + if ([NSJSONSerialization isValidJSONObject:model]) return model; + NSMutableDictionary *newDic = [NSMutableDictionary new]; + [((NSDictionary *)model) enumerateKeysAndObjectsUsingBlock:^(NSString *key, id obj, BOOL *stop) { + NSString *stringKey = [key isKindOfClass:[NSString class]] ? key : key.description; + if (!stringKey) return; + id jsonObj = ModelToJSONObjectRecursive(obj); + if (!jsonObj) jsonObj = (id)kCFNull; + newDic[stringKey] = jsonObj; + }]; + return newDic; + } + if ([model isKindOfClass:[NSSet class]]) { + NSArray *array = ((NSSet *)model).allObjects; + if ([NSJSONSerialization isValidJSONObject:array]) return array; + NSMutableArray *newArray = [NSMutableArray new]; + for (id obj in array) { + if ([obj isKindOfClass:[NSString class]] || [obj isKindOfClass:[NSNumber class]]) { + [newArray addObject:obj]; + } else { + id jsonObj = ModelToJSONObjectRecursive(obj); + if (jsonObj && jsonObj != (id)kCFNull) [newArray addObject:jsonObj]; + } + } + return newArray; + } + if ([model isKindOfClass:[NSArray class]]) { + if ([NSJSONSerialization isValidJSONObject:model]) return model; + NSMutableArray *newArray = [NSMutableArray new]; + for (id obj in (NSArray *)model) { + if ([obj isKindOfClass:[NSString class]] || [obj isKindOfClass:[NSNumber class]]) { + [newArray addObject:obj]; + } else { + id jsonObj = ModelToJSONObjectRecursive(obj); + if (jsonObj && jsonObj != (id)kCFNull) [newArray addObject:jsonObj]; + } + } + return newArray; + } + if ([model isKindOfClass:[NSURL class]]) return ((NSURL *)model).absoluteString; + if ([model isKindOfClass:[NSAttributedString class]]) return ((NSAttributedString *)model).string; + if ([model isKindOfClass:[NSDate class]]) return [YYISODateFormatter() stringFromDate:(id)model]; + if ([model isKindOfClass:[NSData class]]) return nil; + + + _YYModelMeta *modelMeta = [_YYModelMeta metaWithClass:[model class]]; + if (!modelMeta || modelMeta->_keyMappedCount == 0) return nil; + NSMutableDictionary *result = [[NSMutableDictionary alloc] initWithCapacity:64]; + __unsafe_unretained NSMutableDictionary *dic = result; // avoid retain and release in block + [modelMeta->_mapper enumerateKeysAndObjectsUsingBlock:^(NSString *propertyMappedKey, _YYModelPropertyMeta *propertyMeta, BOOL *stop) { + if (!propertyMeta->_getter) return; + + id value = nil; + if (propertyMeta->_isCNumber) { + value = ModelCreateNumberFromProperty(model, propertyMeta); + } else if (propertyMeta->_nsType) { + id v = ((id (*)(id, SEL))(void *) objc_msgSend)((id)model, propertyMeta->_getter); + value = ModelToJSONObjectRecursive(v); + } else { + switch (propertyMeta->_type & YYEncodingTypeMask) { + case YYEncodingTypeObject: { + id v = ((id (*)(id, SEL))(void *) objc_msgSend)((id)model, propertyMeta->_getter); + value = ModelToJSONObjectRecursive(v); + if (value == (id)kCFNull) value = nil; + } break; + case YYEncodingTypeClass: { + Class v = ((Class (*)(id, SEL))(void *) objc_msgSend)((id)model, propertyMeta->_getter); + value = v ? NSStringFromClass(v) : nil; + } break; + case YYEncodingTypeSEL: { + SEL v = ((SEL (*)(id, SEL))(void *) objc_msgSend)((id)model, propertyMeta->_getter); + value = v ? NSStringFromSelector(v) : nil; + } break; + default: break; + } + } + if (!value) return; + + if (propertyMeta->_mappedToKeyPath) { + NSMutableDictionary *superDic = dic; + NSMutableDictionary *subDic = nil; + for (NSUInteger i = 0, max = propertyMeta->_mappedToKeyPath.count; i < max; i++) { + NSString *key = propertyMeta->_mappedToKeyPath[i]; + if (i + 1 == max) { // end + if (!superDic[key]) superDic[key] = value; + break; + } + + subDic = superDic[key]; + if (subDic) { + if ([subDic isKindOfClass:[NSDictionary class]]) { + subDic = subDic.mutableCopy; + superDic[key] = subDic; + } else { + break; + } + } else { + subDic = [NSMutableDictionary new]; + superDic[key] = subDic; + } + superDic = subDic; + subDic = nil; + } + } else { + if (!dic[propertyMeta->_mappedToKey]) { + dic[propertyMeta->_mappedToKey] = value; + } + } + }]; + + if (modelMeta->_hasCustomTransformToDictionary) { + BOOL suc = [((id<YYModel>)model) modelCustomTransformToDictionary:dic]; + if (!suc) return nil; + } + return result; +} + +/// Add indent to string (exclude first line) +static NSMutableString *ModelDescriptionAddIndent(NSMutableString *desc, NSUInteger indent) { + for (NSUInteger i = 0, max = desc.length; i < max; i++) { + unichar c = [desc characterAtIndex:i]; + if (c == '\n') { + for (NSUInteger j = 0; j < indent; j++) { + [desc insertString:@" " atIndex:i + 1]; + } + i += indent * 4; + max += indent * 4; + } + } + return desc; +} + +/// Generate a description string +static NSString *ModelDescription(NSObject *model) { + static const int kDescMaxLength = 100; + if (!model) return @"<nil>"; + if (model == (id)kCFNull) return @"<null>"; + if (![model isKindOfClass:[NSObject class]]) return [NSString stringWithFormat:@"%@",model]; + + + _YYModelMeta *modelMeta = [_YYModelMeta metaWithClass:model.class]; + switch (modelMeta->_nsType) { + case YYEncodingTypeNSString: case YYEncodingTypeNSMutableString: { + return [NSString stringWithFormat:@"\"%@\"",model]; + } + + case YYEncodingTypeNSValue: + case YYEncodingTypeNSData: case YYEncodingTypeNSMutableData: { + NSString *tmp = model.description; + if (tmp.length > kDescMaxLength) { + tmp = [tmp substringToIndex:kDescMaxLength]; + tmp = [tmp stringByAppendingString:@"..."]; + } + return tmp; + } + + case YYEncodingTypeNSNumber: + case YYEncodingTypeNSDecimalNumber: + case YYEncodingTypeNSDate: + case YYEncodingTypeNSURL: { + return [NSString stringWithFormat:@"%@",model]; + } + + case YYEncodingTypeNSSet: case YYEncodingTypeNSMutableSet: { + model = ((NSSet *)model).allObjects; + } // no break + + case YYEncodingTypeNSArray: case YYEncodingTypeNSMutableArray: { + NSArray *array = (id)model; + NSMutableString *desc = [NSMutableString new]; + if (array.count == 0) { + return [desc stringByAppendingString:@"[]"]; + } else { + [desc appendFormat:@"[\n"]; + for (NSUInteger i = 0, max = array.count; i < max; i++) { + NSObject *obj = array[i]; + [desc appendString:@" "]; + [desc appendString:ModelDescriptionAddIndent(ModelDescription(obj).mutableCopy, 1)]; + [desc appendString:(i + 1 == max) ? @"\n" : @";\n"]; + } + [desc appendString:@"]"]; + return desc; + } + } + case YYEncodingTypeNSDictionary: case YYEncodingTypeNSMutableDictionary: { + NSDictionary *dic = (id)model; + NSMutableString *desc = [NSMutableString new]; + if (dic.count == 0) { + return [desc stringByAppendingString:@"{}"]; + } else { + NSArray *keys = dic.allKeys; + + [desc appendFormat:@"{\n"]; + for (NSUInteger i = 0, max = keys.count; i < max; i++) { + NSString *key = keys[i]; + NSObject *value = dic[key]; + [desc appendString:@" "]; + [desc appendFormat:@"%@ = %@",key, ModelDescriptionAddIndent(ModelDescription(value).mutableCopy, 1)]; + [desc appendString:(i + 1 == max) ? @"\n" : @";\n"]; + } + [desc appendString:@"}"]; + } + return desc; + } + + default: { + NSMutableString *desc = [NSMutableString new]; + [desc appendFormat:@"<%@: %p>", model.class, model]; + if (modelMeta->_allPropertyMetas.count == 0) return desc; + + // sort property names + NSArray *properties = [modelMeta->_allPropertyMetas + sortedArrayUsingComparator:^NSComparisonResult(_YYModelPropertyMeta *p1, _YYModelPropertyMeta *p2) { + return [p1->_name compare:p2->_name]; + }]; + + [desc appendFormat:@" {\n"]; + for (NSUInteger i = 0, max = properties.count; i < max; i++) { + _YYModelPropertyMeta *property = properties[i]; + NSString *propertyDesc; + if (property->_isCNumber) { + NSNumber *num = ModelCreateNumberFromProperty(model, property); + propertyDesc = num.stringValue; + } else { + switch (property->_type & YYEncodingTypeMask) { + case YYEncodingTypeObject: { + id v = ((id (*)(id, SEL))(void *) objc_msgSend)((id)model, property->_getter); + propertyDesc = ModelDescription(v); + if (!propertyDesc) propertyDesc = @"<nil>"; + } break; + case YYEncodingTypeClass: { + id v = ((id (*)(id, SEL))(void *) objc_msgSend)((id)model, property->_getter); + propertyDesc = ((NSObject *)v).description; + if (!propertyDesc) propertyDesc = @"<nil>"; + } break; + case YYEncodingTypeSEL: { + SEL sel = ((SEL (*)(id, SEL))(void *) objc_msgSend)((id)model, property->_getter); + if (sel) propertyDesc = NSStringFromSelector(sel); + else propertyDesc = @"<NULL>"; + } break; + case YYEncodingTypeBlock: { + id block = ((id (*)(id, SEL))(void *) objc_msgSend)((id)model, property->_getter); + propertyDesc = block ? ((NSObject *)block).description : @"<nil>"; + } break; + case YYEncodingTypeCArray: case YYEncodingTypeCString: case YYEncodingTypePointer: { + void *pointer = ((void* (*)(id, SEL))(void *) objc_msgSend)((id)model, property->_getter); + propertyDesc = [NSString stringWithFormat:@"%p",pointer]; + } break; + case YYEncodingTypeStruct: case YYEncodingTypeUnion: { + NSValue *value = [model valueForKey:property->_name]; + propertyDesc = value ? value.description : @"{unknown}"; + } break; + default: propertyDesc = @"<unknown>"; + } + } + + propertyDesc = ModelDescriptionAddIndent(propertyDesc.mutableCopy, 1); + [desc appendFormat:@" %@ = %@",property->_name, propertyDesc]; + [desc appendString:(i + 1 == max) ? @"\n" : @";\n"]; + } + [desc appendFormat:@"}"]; + return desc; + } + } +} + + +@implementation NSObject (YYModel) + ++ (NSDictionary *)_yy_dictionaryWithJSON:(id)json { + if (!json || json == (id)kCFNull) return nil; + NSDictionary *dic = nil; + NSData *jsonData = nil; + if ([json isKindOfClass:[NSDictionary class]]) { + dic = json; + } else if ([json isKindOfClass:[NSString class]]) { + jsonData = [(NSString *)json dataUsingEncoding : NSUTF8StringEncoding]; + } else if ([json isKindOfClass:[NSData class]]) { + jsonData = json; + } + if (jsonData) { + dic = [NSJSONSerialization JSONObjectWithData:jsonData options:kNilOptions error:NULL]; + if (![dic isKindOfClass:[NSDictionary class]]) dic = nil; + } + return dic; +} + ++ (instancetype)yy_modelWithJSON:(id)json { + NSDictionary *dic = [self _yy_dictionaryWithJSON:json]; + return [self yy_modelWithDictionary:dic]; +} + ++ (instancetype)yy_modelWithDictionary:(NSDictionary *)dictionary { + if (!dictionary || dictionary == (id)kCFNull) return nil; + if (![dictionary isKindOfClass:[NSDictionary class]]) return nil; + + Class cls = [self class]; + _YYModelMeta *modelMeta = [_YYModelMeta metaWithClass:cls]; + if (modelMeta->_hasCustomClassFromDictionary) { + cls = [cls modelCustomClassForDictionary:dictionary] ?: cls; + } + + NSObject *one = [cls new]; + if ([one yy_modelSetWithDictionary:dictionary]) return one; + return nil; +} + +- (BOOL)yy_modelSetWithJSON:(id)json { + NSDictionary *dic = [NSObject _yy_dictionaryWithJSON:json]; + return [self yy_modelSetWithDictionary:dic]; +} + +- (BOOL)yy_modelSetWithDictionary:(NSDictionary *)dic { + if (!dic || dic == (id)kCFNull) return NO; + if (![dic isKindOfClass:[NSDictionary class]]) return NO; + + + _YYModelMeta *modelMeta = [_YYModelMeta metaWithClass:object_getClass(self)]; + if (modelMeta->_keyMappedCount == 0) return NO; + + if (modelMeta->_hasCustomWillTransformFromDictionary) { + dic = [((id<YYModel>)self) modelCustomWillTransformFromDictionary:dic]; + if (![dic isKindOfClass:[NSDictionary class]]) return NO; + } + + ModelSetContext context = {0}; + context.modelMeta = (__bridge void *)(modelMeta); + context.model = (__bridge void *)(self); + context.dictionary = (__bridge void *)(dic); + + + if (modelMeta->_keyMappedCount >= CFDictionaryGetCount((CFDictionaryRef)dic)) { + CFDictionaryApplyFunction((CFDictionaryRef)dic, ModelSetWithDictionaryFunction, &context); + if (modelMeta->_keyPathPropertyMetas) { + CFArrayApplyFunction((CFArrayRef)modelMeta->_keyPathPropertyMetas, + CFRangeMake(0, CFArrayGetCount((CFArrayRef)modelMeta->_keyPathPropertyMetas)), + ModelSetWithPropertyMetaArrayFunction, + &context); + } + if (modelMeta->_multiKeysPropertyMetas) { + CFArrayApplyFunction((CFArrayRef)modelMeta->_multiKeysPropertyMetas, + CFRangeMake(0, CFArrayGetCount((CFArrayRef)modelMeta->_multiKeysPropertyMetas)), + ModelSetWithPropertyMetaArrayFunction, + &context); + } + } else { + CFArrayApplyFunction((CFArrayRef)modelMeta->_allPropertyMetas, + CFRangeMake(0, modelMeta->_keyMappedCount), + ModelSetWithPropertyMetaArrayFunction, + &context); + } + + if (modelMeta->_hasCustomTransformFromDictionary) { + return [((id<YYModel>)self) modelCustomTransformFromDictionary:dic]; + } + return YES; +} + +- (id)yy_modelToJSONObject { + /* + Apple said: + The top level object is an NSArray or NSDictionary. + All objects are instances of NSString, NSNumber, NSArray, NSDictionary, or NSNull. + All dictionary keys are instances of NSString. + Numbers are not NaN or infinity. + */ + id jsonObject = ModelToJSONObjectRecursive(self); + if ([jsonObject isKindOfClass:[NSArray class]]) return jsonObject; + if ([jsonObject isKindOfClass:[NSDictionary class]]) return jsonObject; + return nil; +} + +- (NSData *)yy_modelToJSONData { + id jsonObject = [self yy_modelToJSONObject]; + if (!jsonObject) return nil; + return [NSJSONSerialization dataWithJSONObject:jsonObject options:0 error:NULL]; +} + +- (NSString *)yy_modelToJSONString { + NSData *jsonData = [self yy_modelToJSONData]; + if (jsonData.length == 0) return nil; + return [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding]; +} + +- (id)yy_modelCopy{ + if (self == (id)kCFNull) return self; + _YYModelMeta *modelMeta = [_YYModelMeta metaWithClass:self.class]; + if (modelMeta->_nsType) return [self copy]; + + NSObject *one = [self.class new]; + for (_YYModelPropertyMeta *propertyMeta in modelMeta->_allPropertyMetas) { + if (!propertyMeta->_getter || !propertyMeta->_setter) continue; + + if (propertyMeta->_isCNumber) { + switch (propertyMeta->_type & YYEncodingTypeMask) { + case YYEncodingTypeBool: { + bool num = ((bool (*)(id, SEL))(void *) objc_msgSend)((id)self, propertyMeta->_getter); + ((void (*)(id, SEL, bool))(void *) objc_msgSend)((id)one, propertyMeta->_setter, num); + } break; + case YYEncodingTypeInt8: + case YYEncodingTypeUInt8: { + uint8_t num = ((bool (*)(id, SEL))(void *) objc_msgSend)((id)self, propertyMeta->_getter); + ((void (*)(id, SEL, uint8_t))(void *) objc_msgSend)((id)one, propertyMeta->_setter, num); + } break; + case YYEncodingTypeInt16: + case YYEncodingTypeUInt16: { + uint16_t num = ((uint16_t (*)(id, SEL))(void *) objc_msgSend)((id)self, propertyMeta->_getter); + ((void (*)(id, SEL, uint16_t))(void *) objc_msgSend)((id)one, propertyMeta->_setter, num); + } break; + case YYEncodingTypeInt32: + case YYEncodingTypeUInt32: { + uint32_t num = ((uint32_t (*)(id, SEL))(void *) objc_msgSend)((id)self, propertyMeta->_getter); + ((void (*)(id, SEL, uint32_t))(void *) objc_msgSend)((id)one, propertyMeta->_setter, num); + } break; + case YYEncodingTypeInt64: + case YYEncodingTypeUInt64: { + uint64_t num = ((uint64_t (*)(id, SEL))(void *) objc_msgSend)((id)self, propertyMeta->_getter); + ((void (*)(id, SEL, uint64_t))(void *) objc_msgSend)((id)one, propertyMeta->_setter, num); + } break; + case YYEncodingTypeFloat: { + float num = ((float (*)(id, SEL))(void *) objc_msgSend)((id)self, propertyMeta->_getter); + ((void (*)(id, SEL, float))(void *) objc_msgSend)((id)one, propertyMeta->_setter, num); + } break; + case YYEncodingTypeDouble: { + double num = ((double (*)(id, SEL))(void *) objc_msgSend)((id)self, propertyMeta->_getter); + ((void (*)(id, SEL, double))(void *) objc_msgSend)((id)one, propertyMeta->_setter, num); + } break; + case YYEncodingTypeLongDouble: { + long double num = ((long double (*)(id, SEL))(void *) objc_msgSend)((id)self, propertyMeta->_getter); + ((void (*)(id, SEL, long double))(void *) objc_msgSend)((id)one, propertyMeta->_setter, num); + } // break; commented for code coverage in next line + default: break; + } + } else { + switch (propertyMeta->_type & YYEncodingTypeMask) { + case YYEncodingTypeObject: + case YYEncodingTypeClass: + case YYEncodingTypeBlock: { + id value = ((id (*)(id, SEL))(void *) objc_msgSend)((id)self, propertyMeta->_getter); + ((void (*)(id, SEL, id))(void *) objc_msgSend)((id)one, propertyMeta->_setter, value); + } break; + case YYEncodingTypeSEL: + case YYEncodingTypePointer: + case YYEncodingTypeCString: { + size_t value = ((size_t (*)(id, SEL))(void *) objc_msgSend)((id)self, propertyMeta->_getter); + ((void (*)(id, SEL, size_t))(void *) objc_msgSend)((id)one, propertyMeta->_setter, value); + } break; + case YYEncodingTypeStruct: + case YYEncodingTypeUnion: { + @try { + NSValue *value = [self valueForKey:NSStringFromSelector(propertyMeta->_getter)]; + if (value) { + [one setValue:value forKey:propertyMeta->_name]; + } + } @catch (NSException *exception) {} + } // break; commented for code coverage in next line + default: break; + } + } + } + return one; +} + +- (void)yy_modelEncodeWithCoder:(NSCoder *)aCoder { + if (!aCoder) return; + if (self == (id)kCFNull) { + [((id<NSCoding>)self)encodeWithCoder:aCoder]; + return; + } + + _YYModelMeta *modelMeta = [_YYModelMeta metaWithClass:self.class]; + if (modelMeta->_nsType) { + [((id<NSCoding>)self)encodeWithCoder:aCoder]; + return; + } + + for (_YYModelPropertyMeta *propertyMeta in modelMeta->_allPropertyMetas) { + if (!propertyMeta->_getter) return; + + if (propertyMeta->_isCNumber) { + NSNumber *value = ModelCreateNumberFromProperty(self, propertyMeta); + if (value != nil) [aCoder encodeObject:value forKey:propertyMeta->_name]; + } else { + switch (propertyMeta->_type & YYEncodingTypeMask) { + case YYEncodingTypeObject: { + id value = ((id (*)(id, SEL))(void *)objc_msgSend)((id)self, propertyMeta->_getter); + if (value && (propertyMeta->_nsType || [value respondsToSelector:@selector(encodeWithCoder:)])) { + if ([value isKindOfClass:[NSValue class]]) { + if ([value isKindOfClass:[NSNumber class]]) { + [aCoder encodeObject:value forKey:propertyMeta->_name]; + } + } else { + [aCoder encodeObject:value forKey:propertyMeta->_name]; + } + } + } break; + case YYEncodingTypeSEL: { + SEL value = ((SEL (*)(id, SEL))(void *)objc_msgSend)((id)self, propertyMeta->_getter); + if (value) { + NSString *str = NSStringFromSelector(value); + [aCoder encodeObject:str forKey:propertyMeta->_name]; + } + } break; + case YYEncodingTypeStruct: + case YYEncodingTypeUnion: { + if (propertyMeta->_isKVCCompatible && propertyMeta->_isStructAvailableForKeyedArchiver) { + @try { + NSValue *value = [self valueForKey:NSStringFromSelector(propertyMeta->_getter)]; + [aCoder encodeObject:value forKey:propertyMeta->_name]; + } @catch (NSException *exception) {} + } + } break; + + default: + break; + } + } + } +} + +- (id)yy_modelInitWithCoder:(NSCoder *)aDecoder { + if (!aDecoder) return self; + if (self == (id)kCFNull) return self; + _YYModelMeta *modelMeta = [_YYModelMeta metaWithClass:self.class]; + if (modelMeta->_nsType) return self; + + for (_YYModelPropertyMeta *propertyMeta in modelMeta->_allPropertyMetas) { + if (!propertyMeta->_setter) continue; + + if (propertyMeta->_isCNumber) { + NSNumber *value = [aDecoder decodeObjectForKey:propertyMeta->_name]; + if ([value isKindOfClass:[NSNumber class]]) { + ModelSetNumberToProperty(self, value, propertyMeta); + [value class]; + } + } else { + YYEncodingType type = propertyMeta->_type & YYEncodingTypeMask; + switch (type) { + case YYEncodingTypeObject: { + id value = [aDecoder decodeObjectForKey:propertyMeta->_name]; + ((void (*)(id, SEL, id))(void *) objc_msgSend)((id)self, propertyMeta->_setter, value); + } break; + case YYEncodingTypeSEL: { + NSString *str = [aDecoder decodeObjectForKey:propertyMeta->_name]; + if ([str isKindOfClass:[NSString class]]) { + SEL sel = NSSelectorFromString(str); + ((void (*)(id, SEL, SEL))(void *) objc_msgSend)((id)self, propertyMeta->_setter, sel); + } + } break; + case YYEncodingTypeStruct: + case YYEncodingTypeUnion: { + if (propertyMeta->_isKVCCompatible) { + @try { + NSValue *value = [aDecoder decodeObjectForKey:propertyMeta->_name]; + if (value) [self setValue:value forKey:propertyMeta->_name]; + } @catch (NSException *exception) {} + } + } break; + + default: + break; + } + } + } + return self; +} + +- (NSUInteger)yy_modelHash { + if (self == (id)kCFNull) return [self hash]; + _YYModelMeta *modelMeta = [_YYModelMeta metaWithClass:self.class]; + if (modelMeta->_nsType) return [self hash]; + + NSUInteger value = 0; + NSUInteger count = 0; + for (_YYModelPropertyMeta *propertyMeta in modelMeta->_allPropertyMetas) { + if (!propertyMeta->_isKVCCompatible) continue; + value ^= [[self valueForKey:NSStringFromSelector(propertyMeta->_getter)] hash]; + count++; + } + if (count == 0) value = (long)((__bridge void *)self); + return value; +} + +- (BOOL)yy_modelIsEqual:(id)model { + if (self == model) return YES; + if (![model isMemberOfClass:self.class]) return NO; + _YYModelMeta *modelMeta = [_YYModelMeta metaWithClass:self.class]; + if (modelMeta->_nsType) return [self isEqual:model]; + if ([self hash] != [model hash]) return NO; + + for (_YYModelPropertyMeta *propertyMeta in modelMeta->_allPropertyMetas) { + if (!propertyMeta->_isKVCCompatible) continue; + id this = [self valueForKey:NSStringFromSelector(propertyMeta->_getter)]; + id that = [model valueForKey:NSStringFromSelector(propertyMeta->_getter)]; + if (this == that) continue; + if (this == nil || that == nil) return NO; + if (![this isEqual:that]) return NO; + } + return YES; +} + +- (NSString *)yy_modelDescription { + return ModelDescription(self); +} + +@end + + + +@implementation NSArray (YYModel) + ++ (NSArray *)yy_modelArrayWithClass:(Class)cls json:(id)json { + if (!json) return nil; + NSArray *arr = nil; + NSData *jsonData = nil; + if ([json isKindOfClass:[NSArray class]]) { + arr = json; + } else if ([json isKindOfClass:[NSString class]]) { + jsonData = [(NSString *)json dataUsingEncoding : NSUTF8StringEncoding]; + } else if ([json isKindOfClass:[NSData class]]) { + jsonData = json; + } + if (jsonData) { + arr = [NSJSONSerialization JSONObjectWithData:jsonData options:kNilOptions error:NULL]; + if (![arr isKindOfClass:[NSArray class]]) arr = nil; + } + return [self yy_modelArrayWithClass:cls array:arr]; +} + ++ (NSArray *)yy_modelArrayWithClass:(Class)cls array:(NSArray *)arr { + if (!cls || !arr) return nil; + NSMutableArray *result = [NSMutableArray new]; + for (NSDictionary *dic in arr) { + if (![dic isKindOfClass:[NSDictionary class]]) continue; + NSObject *obj = [cls yy_modelWithDictionary:dic]; + if (obj) [result addObject:obj]; + } + return result; +} + +@end + + +@implementation NSDictionary (YYModel) + ++ (NSDictionary *)yy_modelDictionaryWithClass:(Class)cls json:(id)json { + if (!json) return nil; + NSDictionary *dic = nil; + NSData *jsonData = nil; + if ([json isKindOfClass:[NSDictionary class]]) { + dic = json; + } else if ([json isKindOfClass:[NSString class]]) { + jsonData = [(NSString *)json dataUsingEncoding : NSUTF8StringEncoding]; + } else if ([json isKindOfClass:[NSData class]]) { + jsonData = json; + } + if (jsonData) { + dic = [NSJSONSerialization JSONObjectWithData:jsonData options:kNilOptions error:NULL]; + if (![dic isKindOfClass:[NSDictionary class]]) dic = nil; + } + return [self yy_modelDictionaryWithClass:cls dictionary:dic]; +} + ++ (NSDictionary *)yy_modelDictionaryWithClass:(Class)cls dictionary:(NSDictionary *)dic { + if (!cls || !dic) return nil; + NSMutableDictionary *result = [NSMutableDictionary new]; + for (NSString *key in dic.allKeys) { + if (![key isKindOfClass:[NSString class]]) continue; + NSObject *obj = [cls yy_modelWithDictionary:dic[key]]; + if (obj) result[key] = obj; + } + return result; +} + +@end diff --git a/Demo/EZOpensdk_iOS_4.15.1_build20201104/Demo/EZOpenSDKDemo/Venders/YYModel/YYClassInfo.h b/Demo/EZOpensdk_iOS_4.15.1_build20201104/Demo/EZOpenSDKDemo/Venders/YYModel/YYClassInfo.h new file mode 100644 index 0000000..6b87458 --- /dev/null +++ b/Demo/EZOpensdk_iOS_4.15.1_build20201104/Demo/EZOpenSDKDemo/Venders/YYModel/YYClassInfo.h @@ -0,0 +1,200 @@ +// +// YYClassInfo.h +// YYModel <https://github.com/ibireme/YYModel> +// +// Created by ibireme on 15/5/9. +// Copyright (c) 2015 ibireme. +// +// This source code is licensed under the MIT-style license found in the +// LICENSE file in the root directory of this source tree. +// + +#import <Foundation/Foundation.h> +#import <objc/runtime.h> + +NS_ASSUME_NONNULL_BEGIN + +/** + Type encoding's type. + */ +typedef NS_OPTIONS(NSUInteger, YYEncodingType) { + YYEncodingTypeMask = 0xFF, ///< mask of type value + YYEncodingTypeUnknown = 0, ///< unknown + YYEncodingTypeVoid = 1, ///< void + YYEncodingTypeBool = 2, ///< bool + YYEncodingTypeInt8 = 3, ///< char / BOOL + YYEncodingTypeUInt8 = 4, ///< unsigned char + YYEncodingTypeInt16 = 5, ///< short + YYEncodingTypeUInt16 = 6, ///< unsigned short + YYEncodingTypeInt32 = 7, ///< int + YYEncodingTypeUInt32 = 8, ///< unsigned int + YYEncodingTypeInt64 = 9, ///< long long + YYEncodingTypeUInt64 = 10, ///< unsigned long long + YYEncodingTypeFloat = 11, ///< float + YYEncodingTypeDouble = 12, ///< double + YYEncodingTypeLongDouble = 13, ///< long double + YYEncodingTypeObject = 14, ///< id + YYEncodingTypeClass = 15, ///< Class + YYEncodingTypeSEL = 16, ///< SEL + YYEncodingTypeBlock = 17, ///< block + YYEncodingTypePointer = 18, ///< void* + YYEncodingTypeStruct = 19, ///< struct + YYEncodingTypeUnion = 20, ///< union + YYEncodingTypeCString = 21, ///< char* + YYEncodingTypeCArray = 22, ///< char[10] (for example) + + YYEncodingTypeQualifierMask = 0xFF00, ///< mask of qualifier + YYEncodingTypeQualifierConst = 1 << 8, ///< const + YYEncodingTypeQualifierIn = 1 << 9, ///< in + YYEncodingTypeQualifierInout = 1 << 10, ///< inout + YYEncodingTypeQualifierOut = 1 << 11, ///< out + YYEncodingTypeQualifierBycopy = 1 << 12, ///< bycopy + YYEncodingTypeQualifierByref = 1 << 13, ///< byref + YYEncodingTypeQualifierOneway = 1 << 14, ///< oneway + + YYEncodingTypePropertyMask = 0xFF0000, ///< mask of property + YYEncodingTypePropertyReadonly = 1 << 16, ///< readonly + YYEncodingTypePropertyCopy = 1 << 17, ///< copy + YYEncodingTypePropertyRetain = 1 << 18, ///< retain + YYEncodingTypePropertyNonatomic = 1 << 19, ///< nonatomic + YYEncodingTypePropertyWeak = 1 << 20, ///< weak + YYEncodingTypePropertyCustomGetter = 1 << 21, ///< getter= + YYEncodingTypePropertyCustomSetter = 1 << 22, ///< setter= + YYEncodingTypePropertyDynamic = 1 << 23, ///< @dynamic +}; + +/** + Get the type from a Type-Encoding string. + + @discussion See also: + https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtTypeEncodings.html + https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtPropertyIntrospection.html + + @param typeEncoding A Type-Encoding string. + @return The encoding type. + */ +YYEncodingType YYEncodingGetType(const char *typeEncoding); + + +/** + Instance variable information. + */ +@interface YYClassIvarInfo : NSObject +@property (nonatomic, assign, readonly) Ivar ivar; ///< ivar opaque struct +@property (nonatomic, strong, readonly) NSString *name; ///< Ivar's name +@property (nonatomic, assign, readonly) ptrdiff_t offset; ///< Ivar's offset +@property (nonatomic, strong, readonly) NSString *typeEncoding; ///< Ivar's type encoding +@property (nonatomic, assign, readonly) YYEncodingType type; ///< Ivar's type + +/** + Creates and returns an ivar info object. + + @param ivar ivar opaque struct + @return A new object, or nil if an error occurs. + */ +- (instancetype)initWithIvar:(Ivar)ivar; +@end + + +/** + Method information. + */ +@interface YYClassMethodInfo : NSObject +@property (nonatomic, assign, readonly) Method method; ///< method opaque struct +@property (nonatomic, strong, readonly) NSString *name; ///< method name +@property (nonatomic, assign, readonly) SEL sel; ///< method's selector +@property (nonatomic, assign, readonly) IMP imp; ///< method's implementation +@property (nonatomic, strong, readonly) NSString *typeEncoding; ///< method's parameter and return types +@property (nonatomic, strong, readonly) NSString *returnTypeEncoding; ///< return value's type +@property (nullable, nonatomic, strong, readonly) NSArray<NSString *> *argumentTypeEncodings; ///< array of arguments' type + +/** + Creates and returns a method info object. + + @param method method opaque struct + @return A new object, or nil if an error occurs. + */ +- (instancetype)initWithMethod:(Method)method; +@end + + +/** + Property information. + */ +@interface YYClassPropertyInfo : NSObject +@property (nonatomic, assign, readonly) objc_property_t property; ///< property's opaque struct +@property (nonatomic, strong, readonly) NSString *name; ///< property's name +@property (nonatomic, assign, readonly) YYEncodingType type; ///< property's type +@property (nonatomic, strong, readonly) NSString *typeEncoding; ///< property's encoding value +@property (nonatomic, strong, readonly) NSString *ivarName; ///< property's ivar name +@property (nullable, nonatomic, assign, readonly) Class cls; ///< may be nil +@property (nullable, nonatomic, strong, readonly) NSArray<NSString *> *protocols; ///< may nil +@property (nonatomic, assign, readonly) SEL getter; ///< getter (nonnull) +@property (nonatomic, assign, readonly) SEL setter; ///< setter (nonnull) + +/** + Creates and returns a property info object. + + @param property property opaque struct + @return A new object, or nil if an error occurs. + */ +- (instancetype)initWithProperty:(objc_property_t)property; +@end + + +/** + Class information for a class. + */ +@interface YYClassInfo : NSObject +@property (nonatomic, assign, readonly) Class cls; ///< class object +@property (nullable, nonatomic, assign, readonly) Class superCls; ///< super class object +@property (nullable, nonatomic, assign, readonly) Class metaCls; ///< class's meta class object +@property (nonatomic, readonly) BOOL isMeta; ///< whether this class is meta class +@property (nonatomic, strong, readonly) NSString *name; ///< class name +@property (nullable, nonatomic, strong, readonly) YYClassInfo *superClassInfo; ///< super class's class info +@property (nullable, nonatomic, strong, readonly) NSDictionary<NSString *, YYClassIvarInfo *> *ivarInfos; ///< ivars +@property (nullable, nonatomic, strong, readonly) NSDictionary<NSString *, YYClassMethodInfo *> *methodInfos; ///< methods +@property (nullable, nonatomic, strong, readonly) NSDictionary<NSString *, YYClassPropertyInfo *> *propertyInfos; ///< properties + +/** + If the class is changed (for example: you add a method to this class with + 'class_addMethod()'), you should call this method to refresh the class info cache. + + After called this method, `needUpdate` will returns `YES`, and you should call + 'classInfoWithClass' or 'classInfoWithClassName' to get the updated class info. + */ +- (void)setNeedUpdate; + +/** + If this method returns `YES`, you should stop using this instance and call + `classInfoWithClass` or `classInfoWithClassName` to get the updated class info. + + @return Whether this class info need update. + */ +- (BOOL)needUpdate; + +/** + Get the class info of a specified Class. + + @discussion This method will cache the class info and super-class info + at the first access to the Class. This method is thread-safe. + + @param cls A class. + @return A class info, or nil if an error occurs. + */ ++ (nullable instancetype)classInfoWithClass:(Class)cls; + +/** + Get the class info of a specified Class. + + @discussion This method will cache the class info and super-class info + at the first access to the Class. This method is thread-safe. + + @param className A class name. + @return A class info, or nil if an error occurs. + */ ++ (nullable instancetype)classInfoWithClassName:(NSString *)className; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Demo/EZOpensdk_iOS_4.15.1_build20201104/Demo/EZOpenSDKDemo/Venders/YYModel/YYClassInfo.m b/Demo/EZOpensdk_iOS_4.15.1_build20201104/Demo/EZOpenSDKDemo/Venders/YYModel/YYClassInfo.m new file mode 100644 index 0000000..16df6d9 --- /dev/null +++ b/Demo/EZOpensdk_iOS_4.15.1_build20201104/Demo/EZOpenSDKDemo/Venders/YYModel/YYClassInfo.m @@ -0,0 +1,362 @@ +// +// YYClassInfo.m +// YYModel <https://github.com/ibireme/YYModel> +// +// Created by ibireme on 15/5/9. +// Copyright (c) 2015 ibireme. +// +// This source code is licensed under the MIT-style license found in the +// LICENSE file in the root directory of this source tree. +// + +#import "YYClassInfo.h" +#import <objc/runtime.h> + +YYEncodingType YYEncodingGetType(const char *typeEncoding) { + char *type = (char *)typeEncoding; + if (!type) return YYEncodingTypeUnknown; + size_t len = strlen(type); + if (len == 0) return YYEncodingTypeUnknown; + + YYEncodingType qualifier = 0; + bool prefix = true; + while (prefix) { + switch (*type) { + case 'r': { + qualifier |= YYEncodingTypeQualifierConst; + type++; + } break; + case 'n': { + qualifier |= YYEncodingTypeQualifierIn; + type++; + } break; + case 'N': { + qualifier |= YYEncodingTypeQualifierInout; + type++; + } break; + case 'o': { + qualifier |= YYEncodingTypeQualifierOut; + type++; + } break; + case 'O': { + qualifier |= YYEncodingTypeQualifierBycopy; + type++; + } break; + case 'R': { + qualifier |= YYEncodingTypeQualifierByref; + type++; + } break; + case 'V': { + qualifier |= YYEncodingTypeQualifierOneway; + type++; + } break; + default: { prefix = false; } break; + } + } + + len = strlen(type); + if (len == 0) return YYEncodingTypeUnknown | qualifier; + + switch (*type) { + case 'v': return YYEncodingTypeVoid | qualifier; + case 'B': return YYEncodingTypeBool | qualifier; + case 'c': return YYEncodingTypeInt8 | qualifier; + case 'C': return YYEncodingTypeUInt8 | qualifier; + case 's': return YYEncodingTypeInt16 | qualifier; + case 'S': return YYEncodingTypeUInt16 | qualifier; + case 'i': return YYEncodingTypeInt32 | qualifier; + case 'I': return YYEncodingTypeUInt32 | qualifier; + case 'l': return YYEncodingTypeInt32 | qualifier; + case 'L': return YYEncodingTypeUInt32 | qualifier; + case 'q': return YYEncodingTypeInt64 | qualifier; + case 'Q': return YYEncodingTypeUInt64 | qualifier; + case 'f': return YYEncodingTypeFloat | qualifier; + case 'd': return YYEncodingTypeDouble | qualifier; + case 'D': return YYEncodingTypeLongDouble | qualifier; + case '#': return YYEncodingTypeClass | qualifier; + case ':': return YYEncodingTypeSEL | qualifier; + case '*': return YYEncodingTypeCString | qualifier; + case '^': return YYEncodingTypePointer | qualifier; + case '[': return YYEncodingTypeCArray | qualifier; + case '(': return YYEncodingTypeUnion | qualifier; + case '{': return YYEncodingTypeStruct | qualifier; + case '@': { + if (len == 2 && *(type + 1) == '?') + return YYEncodingTypeBlock | qualifier; + else + return YYEncodingTypeObject | qualifier; + } + default: return YYEncodingTypeUnknown | qualifier; + } +} + +@implementation YYClassIvarInfo + +- (instancetype)initWithIvar:(Ivar)ivar { + if (!ivar) return nil; + self = [super init]; + _ivar = ivar; + const char *name = ivar_getName(ivar); + if (name) { + _name = [NSString stringWithUTF8String:name]; + } + _offset = ivar_getOffset(ivar); + const char *typeEncoding = ivar_getTypeEncoding(ivar); + if (typeEncoding) { + _typeEncoding = [NSString stringWithUTF8String:typeEncoding]; + _type = YYEncodingGetType(typeEncoding); + } + return self; +} + +@end + +@implementation YYClassMethodInfo + +- (instancetype)initWithMethod:(Method)method { + if (!method) return nil; + self = [super init]; + _method = method; + _sel = method_getName(method); + _imp = method_getImplementation(method); + const char *name = sel_getName(_sel); + if (name) { + _name = [NSString stringWithUTF8String:name]; + } + const char *typeEncoding = method_getTypeEncoding(method); + if (typeEncoding) { + _typeEncoding = [NSString stringWithUTF8String:typeEncoding]; + } + char *returnType = method_copyReturnType(method); + if (returnType) { + _returnTypeEncoding = [NSString stringWithUTF8String:returnType]; + free(returnType); + } + unsigned int argumentCount = method_getNumberOfArguments(method); + if (argumentCount > 0) { + NSMutableArray *argumentTypes = [NSMutableArray new]; + for (unsigned int i = 0; i < argumentCount; i++) { + char *argumentType = method_copyArgumentType(method, i); + NSString *type = argumentType ? [NSString stringWithUTF8String:argumentType] : nil; + [argumentTypes addObject:type ? type : @""]; + if (argumentType) free(argumentType); + } + _argumentTypeEncodings = argumentTypes; + } + return self; +} + +@end + +@implementation YYClassPropertyInfo + +- (instancetype)initWithProperty:(objc_property_t)property { + if (!property) return nil; + self = [super init]; + _property = property; + const char *name = property_getName(property); + if (name) { + _name = [NSString stringWithUTF8String:name]; + } + + YYEncodingType type = 0; + unsigned int attrCount; + objc_property_attribute_t *attrs = property_copyAttributeList(property, &attrCount); + for (unsigned int i = 0; i < attrCount; i++) { + switch (attrs[i].name[0]) { + case 'T': { // Type encoding + if (attrs[i].value) { + _typeEncoding = [NSString stringWithUTF8String:attrs[i].value]; + type = YYEncodingGetType(attrs[i].value); + + if ((type & YYEncodingTypeMask) == YYEncodingTypeObject && _typeEncoding.length) { + NSScanner *scanner = [NSScanner scannerWithString:_typeEncoding]; + if (![scanner scanString:@"@\"" intoString:NULL]) continue; + + NSString *clsName = nil; + if ([scanner scanUpToCharactersFromSet: [NSCharacterSet characterSetWithCharactersInString:@"\"<"] intoString:&clsName]) { + if (clsName.length) _cls = objc_getClass(clsName.UTF8String); + } + + NSMutableArray *protocols = nil; + while ([scanner scanString:@"<" intoString:NULL]) { + NSString* protocol = nil; + if ([scanner scanUpToString:@">" intoString: &protocol]) { + if (protocol.length) { + if (!protocols) protocols = [NSMutableArray new]; + [protocols addObject:protocol]; + } + } + [scanner scanString:@">" intoString:NULL]; + } + _protocols = protocols; + } + } + } break; + case 'V': { // Instance variable + if (attrs[i].value) { + _ivarName = [NSString stringWithUTF8String:attrs[i].value]; + } + } break; + case 'R': { + type |= YYEncodingTypePropertyReadonly; + } break; + case 'C': { + type |= YYEncodingTypePropertyCopy; + } break; + case '&': { + type |= YYEncodingTypePropertyRetain; + } break; + case 'N': { + type |= YYEncodingTypePropertyNonatomic; + } break; + case 'D': { + type |= YYEncodingTypePropertyDynamic; + } break; + case 'W': { + type |= YYEncodingTypePropertyWeak; + } break; + case 'G': { + type |= YYEncodingTypePropertyCustomGetter; + if (attrs[i].value) { + _getter = NSSelectorFromString([NSString stringWithUTF8String:attrs[i].value]); + } + } break; + case 'S': { + type |= YYEncodingTypePropertyCustomSetter; + if (attrs[i].value) { + _setter = NSSelectorFromString([NSString stringWithUTF8String:attrs[i].value]); + } + } // break; commented for code coverage in next line + default: break; + } + } + if (attrs) { + free(attrs); + attrs = NULL; + } + + _type = type; + if (_name.length) { + if (!_getter) { + _getter = NSSelectorFromString(_name); + } + if (!_setter) { + _setter = NSSelectorFromString([NSString stringWithFormat:@"set%@%@:", [_name substringToIndex:1].uppercaseString, [_name substringFromIndex:1]]); + } + } + return self; +} + +@end + +@implementation YYClassInfo { + BOOL _needUpdate; +} + +- (instancetype)initWithClass:(Class)cls { + if (!cls) return nil; + self = [super init]; + _cls = cls; + _superCls = class_getSuperclass(cls); + _isMeta = class_isMetaClass(cls); + if (!_isMeta) { + _metaCls = objc_getMetaClass(class_getName(cls)); + } + _name = NSStringFromClass(cls); + [self _update]; + + _superClassInfo = [self.class classInfoWithClass:_superCls]; + return self; +} + +- (void)_update { + _ivarInfos = nil; + _methodInfos = nil; + _propertyInfos = nil; + + Class cls = self.cls; + unsigned int methodCount = 0; + Method *methods = class_copyMethodList(cls, &methodCount); + if (methods) { + NSMutableDictionary *methodInfos = [NSMutableDictionary new]; + _methodInfos = methodInfos; + for (unsigned int i = 0; i < methodCount; i++) { + YYClassMethodInfo *info = [[YYClassMethodInfo alloc] initWithMethod:methods[i]]; + if (info.name) methodInfos[info.name] = info; + } + free(methods); + } + unsigned int propertyCount = 0; + objc_property_t *properties = class_copyPropertyList(cls, &propertyCount); + if (properties) { + NSMutableDictionary *propertyInfos = [NSMutableDictionary new]; + _propertyInfos = propertyInfos; + for (unsigned int i = 0; i < propertyCount; i++) { + YYClassPropertyInfo *info = [[YYClassPropertyInfo alloc] initWithProperty:properties[i]]; + if (info.name) propertyInfos[info.name] = info; + } + free(properties); + } + + unsigned int ivarCount = 0; + Ivar *ivars = class_copyIvarList(cls, &ivarCount); + if (ivars) { + NSMutableDictionary *ivarInfos = [NSMutableDictionary new]; + _ivarInfos = ivarInfos; + for (unsigned int i = 0; i < ivarCount; i++) { + YYClassIvarInfo *info = [[YYClassIvarInfo alloc] initWithIvar:ivars[i]]; + if (info.name) ivarInfos[info.name] = info; + } + free(ivars); + } + + if (!_ivarInfos) _ivarInfos = @{}; + if (!_methodInfos) _methodInfos = @{}; + if (!_propertyInfos) _propertyInfos = @{}; + + _needUpdate = NO; +} + +- (void)setNeedUpdate { + _needUpdate = YES; +} + +- (BOOL)needUpdate { + return _needUpdate; +} + ++ (instancetype)classInfoWithClass:(Class)cls { + if (!cls) return nil; + static CFMutableDictionaryRef classCache; + static CFMutableDictionaryRef metaCache; + static dispatch_once_t onceToken; + static dispatch_semaphore_t lock; + dispatch_once(&onceToken, ^{ + classCache = CFDictionaryCreateMutable(CFAllocatorGetDefault(), 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); + metaCache = CFDictionaryCreateMutable(CFAllocatorGetDefault(), 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); + lock = dispatch_semaphore_create(1); + }); + dispatch_semaphore_wait(lock, DISPATCH_TIME_FOREVER); + YYClassInfo *info = CFDictionaryGetValue(class_isMetaClass(cls) ? metaCache : classCache, (__bridge const void *)(cls)); + if (info && info->_needUpdate) { + [info _update]; + } + dispatch_semaphore_signal(lock); + if (!info) { + info = [[YYClassInfo alloc] initWithClass:cls]; + if (info) { + dispatch_semaphore_wait(lock, DISPATCH_TIME_FOREVER); + CFDictionarySetValue(info.isMeta ? metaCache : classCache, (__bridge const void *)(cls), (__bridge const void *)(info)); + dispatch_semaphore_signal(lock); + } + } + return info; +} + ++ (instancetype)classInfoWithClassName:(NSString *)className { + Class cls = NSClassFromString(className); + return [self classInfoWithClass:cls]; +} + +@end diff --git a/Demo/EZOpensdk_iOS_4.15.1_build20201104/Demo/EZOpenSDKDemo/Venders/YYModel/YYModel.h b/Demo/EZOpensdk_iOS_4.15.1_build20201104/Demo/EZOpenSDKDemo/Venders/YYModel/YYModel.h new file mode 100644 index 0000000..e1154ee --- /dev/null +++ b/Demo/EZOpensdk_iOS_4.15.1_build20201104/Demo/EZOpenSDKDemo/Venders/YYModel/YYModel.h @@ -0,0 +1,22 @@ +// +// YYModel.h +// YYModel <https://github.com/ibireme/YYModel> +// +// Created by ibireme on 15/5/10. +// Copyright (c) 2015 ibireme. +// +// This source code is licensed under the MIT-style license found in the +// LICENSE file in the root directory of this source tree. +// + +#import <Foundation/Foundation.h> + +#if __has_include(<YYModel/YYModel.h>) +FOUNDATION_EXPORT double YYModelVersionNumber; +FOUNDATION_EXPORT const unsigned char YYModelVersionString[]; +#import <YYModel/NSObject+YYModel.h> +#import <YYModel/YYClassInfo.h> +#else +#import "NSObject+YYModel.h" +#import "YYClassInfo.h" +#endif diff --git a/Demo/EZOpensdk_iOS_4.15.1_build20201104/Demo/EZOpenSDKDemo/ViewController.m b/Demo/EZOpensdk_iOS_4.15.1_build20201104/Demo/EZOpenSDKDemo/ViewController.m index a6a7de9..510811b 100644 --- a/Demo/EZOpensdk_iOS_4.15.1_build20201104/Demo/EZOpenSDKDemo/ViewController.m +++ b/Demo/EZOpensdk_iOS_4.15.1_build20201104/Demo/EZOpenSDKDemo/ViewController.m @@ -11,6 +11,7 @@ #import "DDKit.h" #import "EZSDK.h" #import "MBProgressHUD.h" +#import "EZCameraInfo.h" @interface ViewController () @property (weak, nonatomic) IBOutlet UIButton *ddnsDemoBtn; @@ -55,10 +56,10 @@ // */ // [self performSegueWithIdentifier:@"go2CameraList" sender:nil]; - [EZSDK setHDlAccessToken:@"Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJqdGkiOiJkODQ5ODllZDMzODQ0ZmFiYWViMWM4YTRlMDlmZDFlMCIsInJvbGUiOiIiLCJoZWFkZXJQcmVmaXgiOiJCZWFyZXIgIiwidXNlckFjY291bnQiOiIxODgyNDg2NDE0MyIsInRlbmFudElkIjoiMjAiLCJ1c2VyVHlwZSI6IlVTRVJfQyIsInRva2VuVHlwZSI6ImFjY2Vzc190b2tlbiIsInVzZXJOYW1lIjoiTEUwMDAiLCJhcHBsaWNhdGlvbklkIjoiMCIsInVzZXJJZCI6IjEzMjg4ODYyNzMwMDM4NTU4NzQiLCJleHAiOjE2MTk1MDczMDEsIm5iZiI6MTYxOTUwMDEwMX0.dS-Lme85XjrHK6fRC1_9hzednq9YLz6gtaaW-50gX3F2eidl3XDa8AP17KrCNhxkAMrOBRpZ0sxqGM7y-WPpUy0p_ytiTt5F1k8MR--Q7njpxxUMttuGzKEmj4Xk1G1Mx55zVlzvIBOHIFm44upWoIObW34nbMjnr8tIa2H7FEY" refreshToken:@"eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJqdGkiOiI4NmMwYmI1MGQ5N2Q0OGU4OWIzMmRlZDE5NjdmOGE5MiIsImhlYWRlclByZWZpeCI6IkJlYXJlciAiLCJ0ZW5hbnRJZCI6IjIwIiwidG9rZW5UeXBlIjoicmVmcmVzaF90b2tlbiIsImFwcGxpY2F0aW9uSWQiOiIwIiwidXNlcklkIjoiMTMyODg4NjI3MzAwMzg1NTg3NCIsImV4cCI6MTYyMDEwNDkwMSwibmJmIjoxNjE5NTAwMTAxfQ.AgejbuQdmsc7UItIGtcDoWAepuHo56amU7dhmbndj-0TlbmFPOPQbIxvs8nEAQeCAFavrHctWGCypaW8MTvmYTOISbf4n2-Jk8wQX5xJdwEzNI0kJrTeIY1yejo9c12LT1ZL6y-8WkDjRKATDOCrrfy-bdsqFo78VEuUtp_tFeQ"]; + [EZSDK setHDlAccessToken:@"Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJqdGkiOiIyYTAwZGRmOTNjMGY0YzlhYjljNjU2M2VhMDJjZjhmMyIsImNvbXBhbnlJZCI6IjAiLCJyb2xlIjoiIiwiaGVhZGVyUHJlZml4IjoiQmVhcmVyICIsInVzZXJBY2NvdW50Ijoid3hyIiwidGVuYW50SWQiOiIyMCIsInVzZXJUeXBlIjoiVVNFUl9DIiwidG9rZW5UeXBlIjoiYWNjZXNzX3Rva2VuIiwidXNlck5hbWUiOiJrYWVkZSIsIm9wZW5BcHBsaWNhdGlvbklkIjoiMCIsInVzZXJJZCI6IjEzOTIwMzU1NjgyMDQ0MjMxNjkiLCJleHAiOjE2MjU2NjA0NjQsIm5iZiI6MTYyNTY1MzI2NH0.I4YfZQqm1p1SwJQbNWyUEOWXCqpYCWQdmAMOR-xlOMJ0pYFh3_nyjPBiWypTTMgy5nTpj7IqUM1bHwHWGsDEInF4Bl6trxrgOE39Toj-aY1UJcViYhx7e3E3ChrlXptVfKtk3cVEtDlFkMdHdHiJi-6OZox4KOz_AallI8lFIlo" refreshToken:@"eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJqdGkiOiI1ZjdmOGFkY2I3MGU0NzYwOWE0NTcxOTZmOTAyOTY1OSIsImNvbXBhbnlJZCI6IjAiLCJoZWFkZXJQcmVmaXgiOiJCZWFyZXIgIiwidGVuYW50SWQiOiIyMCIsInRva2VuVHlwZSI6InJlZnJlc2hfdG9rZW4iLCJvcGVuQXBwbGljYXRpb25JZCI6IjAiLCJ1c2VySWQiOiIxMzkyMDM1NTY4MjA0NDIzMTY5IiwiZXhwIjoxNjI2MjU4MDY0LCJuYmYiOjE2MjU2NTMyNjR9.DB1pGaM6xtpQiP_KvaAHbWDZtxjLXZwJCgFfrp_XA0bnV8wMC8SE7K_uoP79c97WGqcmpHJVY-x8NCVJneGpIKN2oSCvX0Sn0uAttqni4zbVjmErC2AmpONJwWY27GYjHk4LFri03p38D-5zlULFo3ITtN3Il2aJOjVOpyNCcuI"]; - [EZSDK setRequestHttpsHostAndPlatform:@"https://test-gz.hdlcontrol.com" platform:2]; + [EZSDK setRequestHttpsHostAndPlatform:@"https://test-gz.hdlcontrol.com" platform:1 homeId:@"1396717478877241345"]; @@ -77,15 +78,54 @@ }]; } + + - (IBAction)logout:(id)sender { - +// [[GlobalKit shareKit] setAccessToken:@"ra.a5bfkhhx7ycscsj41if7l0cf9ytfhv5q-9keuxvphmn-1fvjt6p-jugtyy8sr"]; + [EZSDK setHDlAccessToken:@"Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJqdGkiOiI2Zjk1ZTEwZWIwNjA0ZjNiYTdmNTc0ZGUyM2QxYmNmZiIsImNvbXBhbnlJZCI6IjAiLCJyb2xlIjoiIiwiaGVhZGVyUHJlZml4IjoiQmVhcmVyICIsInVzZXJBY2NvdW50Ijoid3hyIiwidGVuYW50SWQiOiIyMCIsInVzZXJUeXBlIjoiVVNFUl9DIiwidG9rZW5UeXBlIjoiYWNjZXNzX3Rva2VuIiwidXNlck5hbWUiOiJrYWVkZSIsIm9wZW5BcHBsaWNhdGlvbklkIjoiMCIsInVzZXJJZCI6IjEzOTIwMzU1NjgyMDQ0MjMxNjkiLCJleHAiOjE2MjU3MTY3NjAsIm5iZiI6MTYyNTcwOTU2MH0.C6w0mb0YiNhqQfLPscXiNVh_DOsbza_fubUbn_T-W04L3R7egi7-Gv_iifdfvh4XTU10rEdVl6FLXKxt3JJvo2x_sjBQLkWRQINMVl1qLOz9cMew79_aykXOwl8mdroYs9SKBd90qyM2lZaA91sD4H0HMVVyc_D2TEcG4XJzSBM" refreshToken:@"eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJqdGkiOiI1M2FlMzg3NDhmNjU0MzE1OTM0MTQ0OWQyYmQ0NjE0NiIsImNvbXBhbnlJZCI6IjAiLCJoZWFkZXJQcmVmaXgiOiJCZWFyZXIgIiwidGVuYW50SWQiOiIyMCIsInRva2VuVHlwZSI6InJlZnJlc2hfdG9rZW4iLCJvcGVuQXBwbGljYXRpb25JZCI6IjAiLCJ1c2VySWQiOiIxMzkyMDM1NTY4MjA0NDIzMTY5IiwiZXhwIjoxNjI2MzE0MzYwLCJuYmYiOjE2MjU3MDk1NjB9.AZlG8jO8lFDcj5dfoY0rZsDfglGdeyLuSImzMw1enHWfAacjkIof0vXQ_qJG9Q-6qxyXXbPu_xrd0DhkGNFeHJ4WFL0iiYgDP51sJuUdKrQklUCSC6T7ZjIW0GSVmvOW4GCw0s6L51bVT_rkdrusVD4rDnOtJwWqXTUfyNanmlk"]; + + + [EZSDK setRequestHttpsHostAndPlatform:@"https://test-gz.hdlcontrol.com" platform:1 homeId:@"1396717478877241345"]; + + + __weak MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:self.view animated:YES]; + hud.labelText = NSLocalizedString(@"ad_adding_msg", @"璇风◢鍊�..."); + [EZHttpUtil.sharedManager getChildToken:^(NSString *accessToken) { + [hud hide:YES]; + if(accessToken != NULL && ![accessToken isEqual:@""]){ + NSLog(@"accessToken HDL:%@",accessToken); + [[GlobalKit shareKit] setAccessToken:accessToken]; + + [EZSDK PlayWithDeviceSerial:@"F44133728"]; + + + } + }]; + // [EZOPENSDK logout:^(NSError *error) { // }]; } +-(void)getEzDeviceInfo:(NSString *)deviceSerial{ + + //鑾峰彇璁惧鍒楄〃鎺ュ彛 + [EZOpenSDK getDeviceInfo:deviceSerial completion:^(EZDeviceInfo *deviceInfo, NSError *error) { + if(error) + { + return; + } + if (deviceInfo) { + [EZSDK Play:deviceInfo]; + } + + }]; + +// [EZOPENSDK :deviceSerial]; +} + - (void)handleTheError:(NSError *)error { if (!error) diff --git a/EZSDK.IOS/EZSDK.IOS/ApiDefinition.cs b/EZSDK.IOS/EZSDK.IOS/ApiDefinition.cs index 894ab99..0046eca 100644 --- a/EZSDK.IOS/EZSDK.IOS/ApiDefinition.cs +++ b/EZSDK.IOS/EZSDK.IOS/ApiDefinition.cs @@ -1,59 +1,148 @@ 锘縰sing System; - -using ObjCRuntime; using Foundation; -using UIKit; +using ObjCRuntime; namespace EZSDK.IOS { - // @interface EZSDK : NSObject - [BaseType (typeof(NSObject))] - interface EZSDK - { - // +(BOOL)initLibWithAppKey:(NSString *)appKey globalAppKey:(NSString *)globalAppKey; - [Static] - [Export ("initLibWithAppKey:globalAppKey:")] - bool InitLibWithAppKey (string appKey, string globalAppKey); + // @interface EZDeviceInfo : NSObject + [BaseType(typeof(NSObject))] + interface EZDeviceInfo + { + // @property (nonatomic, strong) NSArray * cameraInfo; + [Export("cameraInfo", ArgumentSemantic.Strong)] + //[Verify(StronglyTypedNSArray)] + NSArray CameraInfo { get; set; } - // +(void)setEZAccessToken:(NSString *)accessToken; - [Static] - [Export ("setEZAccessToken:")] - void SetEZAccessToken (string accessToken); + // @property (nonatomic) NSInteger cameraNum; + [Export("cameraNum")] + int CameraNum { get; set; } - // +(void)setHDlAccessToken:(NSString *)accessToken refreshToken:(NSString *)refreshToken; - [Static] - [Export ("setHDlAccessToken:refreshToken:")] - void SetHDlAccessToken (string accessToken, string refreshToken); + // @property (nonatomic) NSInteger defence; + [Export("defence")] + int Defence { get; set; } - // +(void)setRequestHttpsHostAndPlatform:(NSString *)requestHttpsHost platform:(int)platform; - [Static] - [Export("setRequestHttpsHostAndPlatform:platform:")] - void SetRequestHttpsHostAndPlatform(string requestHttpsHost, int platform); + // @property (nonatomic) NSInteger detectorNum; + [Export("detectorNum")] + int DetectorNum { get; set; } - // +(void)go2EZvizMonitor; - [Static] - [Export ("go2EZvizMonitor")] - void Go2EZvizMonitor (); + // @property (nonatomic, strong) NSArray * detectorInfo; + [Export("detectorInfo", ArgumentSemantic.Strong)] + //[Verify(StronglyTypedNSArray)] + NSArray DetectorInfo { get; set; } - // +(void)addEzvizMonitor; - [Static] - [Export ("addEzvizMonitor")] - void AddEzvizMonitor (); + // @property (copy, nonatomic) NSString * deviceCover; + [Export("deviceCover")] + string DeviceCover { get; set; } - // +(void)Play:(NSObject *)deviceInfo; - [Static] - [Export ("Play:")] - void Play (NSObject deviceInfo); + // @property (copy, nonatomic) NSString * deviceName; + [Export("deviceName")] + string DeviceName { get; set; } - // +(void)setting:(NSObject *)deviceInfo; - [Static] - [Export ("setting:")] - void Setting (NSObject deviceInfo); + // @property (copy, nonatomic) NSString * deviceSerial; + [Export("deviceSerial")] + string DeviceSerial { get; set; } - // +(void)playBackVideo:(NSObject *)deviceInfo; - [Static] - [Export ("playBackVideo:")] - void PlayBackVideo (NSObject deviceInfo); - } + // @property (copy, nonatomic) NSString * deviceType; + [Export("deviceType")] + string DeviceType { get; set; } + + // @property (copy, nonatomic) NSString * deviceVersion; + [Export("deviceVersion")] + string DeviceVersion { get; set; } + + // @property (nonatomic) BOOL isEncrypt; + [Export("isEncrypt")] + bool IsEncrypt { get; set; } + + // @property (nonatomic) NSInteger status; + [Export("status")] + int Status { get; set; } + + // @property (nonatomic) NSInteger isSupportTalk; + [Export("isSupportTalk")] + int IsSupportTalk { get; set; } + + // @property (nonatomic) BOOL isSupportPTZ; + [Export("isSupportPTZ")] + bool IsSupportPTZ { get; set; } + + // @property (nonatomic) BOOL isSupportZoom; + [Export("isSupportZoom")] + bool IsSupportZoom { get; set; } + + // @property (nonatomic) BOOL isSupportAudioOnOff; + [Export("isSupportAudioOnOff")] + bool IsSupportAudioOnOff { get; set; } + + // @property (nonatomic) BOOL isSupportMirrorCenter; + [Export("isSupportMirrorCenter")] + bool IsSupportMirrorCenter { get; set; } + + // @property (nonatomic) BOOL isSupportSoundWave; + [Export("isSupportSoundWave")] + bool IsSupportSoundWave { get; set; } + + // @property (copy, nonatomic) NSString * category; + [Export("category")] + string Category { get; set; } + + // @property (nonatomic, strong) NSDate * addTime; + [Export("addTime", ArgumentSemantic.Strong)] + NSDate AddTime { get; set; } + } + + // @interface EZSDK : NSObject + [BaseType(typeof(NSObject))] + interface EZSDK + { + // +(BOOL)initLibWithAppKey:(NSString *)appKey globalAppKey:(NSString *)globalAppKey; + [Static] + [Export("initLibWithAppKey:globalAppKey:")] + bool InitLibWithAppKey(string appKey, string globalAppKey); + + // +(void)setEZAccessToken:(NSString *)accessToken; + [Static] + [Export("setEZAccessToken:")] + void SetEZAccessToken(string accessToken); + + // +(void)setHDlAccessToken:(NSString *)accessToken refreshToken:(NSString *)refreshToken; + [Static] + [Export("setHDlAccessToken:refreshToken:")] + void SetHDlAccessToken(string accessToken, string refreshToken); + + // +(void)setRequestHttpsHostAndPlatform:(NSString *)requestHttpsHost platform:(int)platform homeId:(NSString *)homeId; + [Static] + [Export("setRequestHttpsHostAndPlatform:platform:homeId:")] + void SetRequestHttpsHostAndPlatform(string requestHttpsHost, int platform, string homeId); + + // +(void)go2EZvizMonitor; + [Static] + [Export("go2EZvizMonitor")] + void Go2EZvizMonitor(); + + // +(void)addEzvizMonitor; + [Static] + [Export("addEzvizMonitor")] + void AddEzvizMonitor(); + + // +(void)Play:(EZDeviceInfo *)deviceInfo; + [Static] + [Export("Play:")] + void Play(EZDeviceInfo deviceInfo); + + // +(void)PlayWithDeviceSerial:(NSString *)deviceSerial; + [Static] + [Export("PlayWithDeviceSerial:")] + void PlayWithDeviceSerial(string deviceSerial); + + // +(void)setting:(EZDeviceInfo *)deviceInfo; + [Static] + [Export("setting:")] + void Setting(EZDeviceInfo deviceInfo); + + // +(void)playBackVideo:(EZDeviceInfo *)deviceInfo; + [Static] + [Export("playBackVideo:")] + void PlayBackVideo(EZDeviceInfo deviceInfo); + } } - diff --git a/EZSDK.IOS/EZSDK.IOS/Library/libEZSDK.a b/EZSDK.IOS/EZSDK.IOS/Library/libEZSDK.a index 9efe895..dcd6b46 100644 --- a/EZSDK.IOS/EZSDK.IOS/Library/libEZSDK.a +++ b/EZSDK.IOS/EZSDK.IOS/Library/libEZSDK.a Binary files differ diff --git a/EZSDK.IOS/EZSDK.IOS/Properties/AssemblyInfo.cs b/EZSDK.IOS/EZSDK.IOS/Properties/AssemblyInfo.cs index 8f1a669..7cbedfc 100644 --- a/EZSDK.IOS/EZSDK.IOS/Properties/AssemblyInfo.cs +++ b/EZSDK.IOS/EZSDK.IOS/Properties/AssemblyInfo.cs @@ -25,7 +25,7 @@ // The form "{Major}.{Minor}.*" will automatically update the build and revision, // and "{Major}.{Minor}.{Build}.*" will update just the revision. -[assembly: AssemblyVersion("1.3.1")] +[assembly: AssemblyVersion("1.4.2")] // The following attributes are used to specify the signing key for the assembly, // if desired. See the Mono documentation for more information about signing. diff --git a/EZSDK/EZSDK/DeviceInfo.h b/EZSDK/EZSDK/DeviceInfo.h index 87b2fb9..294fbff 100644 --- a/EZSDK/EZSDK/DeviceInfo.h +++ b/EZSDK/EZSDK/DeviceInfo.h @@ -6,17 +6,11 @@ // #import <Foundation/Foundation.h> +#import "EZDeviceInfo.h" NS_ASSUME_NONNULL_BEGIN -@interface DeviceInfo : NSObject - -@property(nonatomic,strong)NSString *DeviceName; -@property(nonatomic,strong)NSString *DeviceSerial; -@property(nonatomic,assign)int DeviceNum; //cameraNum -@property(nonatomic,assign)int DeviceCameraInfoListSize; -@property(nonatomic,strong)NSObject* RealObject; -@property(nonatomic,strong)NSArray *cameraInfo; +@interface DeviceInfo :EZDeviceInfo @end diff --git a/EZSDK/EZSDK/EZ/Global/EZHttpUtil.m b/EZSDK/EZSDK/EZ/Global/EZHttpUtil.m index 29b7426..6c2236e 100644 --- a/EZSDK/EZSDK/EZ/Global/EZHttpUtil.m +++ b/EZSDK/EZSDK/EZ/Global/EZHttpUtil.m @@ -13,9 +13,9 @@ #define TestRequestHttpsHost @"https://test-gz.hdlcontrol.com" #pragma mark API -#define API_POST_EZ_AddDevice @"/home-wisdom/platform/childAddDevice" -#define API_POST_EZ_GetChildToken @"/home-wisdom/platform/childToken" -#define API_POST_EZ_ChildDelDevice @"/home-wisdom/platform/childDelDevice" +#define API_POST_EZ_AddDevice @"/home-wisdom/platform/yingshi/child/addDevice" +#define API_POST_EZ_GetChildToken @"/home-wisdom/platform/yingshi/child/token" +#define API_POST_EZ_ChildDelDevice @"/home-wisdom/platform/yingshi/child/deleteDevice" #define API_POST_EZ_RefreshToken @"/smart-footstone/member/oauth/login" @@ -51,13 +51,15 @@ //2.璁剧疆璇锋眰鍙傛暟 NSMutableDictionary *parameters = [NSMutableDictionary dictionary]; [parameters setValue: [NSString stringWithFormat:@"%d", [GlobalKit shareKit].hdlPlatform] forKey:@"platform"]; + [parameters setValue:[GlobalKit shareKit].hdlHomeId forKey:@"homeId"]; parameters = [self GetSignRequestDictionary:parameters]; [self requestHttpsPost:API_POST_EZ_GetChildToken parameters:parameters completion:^(ResponseData *responseData) { if (block) { NSString * token = @""; if(responseData.success){ - token = responseData.data[@"accessToken"]; +// token = responseData.data[@"accessToken"]; + token = [NSString stringWithFormat:@"%@",responseData.data]; } block(token); } @@ -84,9 +86,11 @@ [parameters setValue:deviceSerial forKey:@"deviceSerial"]; [parameters setValue:verifyCode forKey:@"validateCode"]; [parameters setValue: [NSString stringWithFormat:@"%d",[GlobalKit shareKit].hdlPlatform] forKey:@"platform"]; + [parameters setValue:[GlobalKit shareKit].hdlHomeId forKey:@"homeId"]; + parameters = [self GetSignRequestDictionary:parameters]; - [self requestHttpsPost:API_POST_EZ_AddDevice parameters:parameters completion:^(ResponseData *responseData) { + [self requestHttpsPost:API_POST_EZ_AddDevice parameters:parameters completion:^(ResponseData *responseData) { if (completion) { completion (responseData); } @@ -108,6 +112,8 @@ NSMutableDictionary *parameters = [NSMutableDictionary dictionary]; [parameters setValue:deviceSerial forKey:@"deviceSerial"]; [parameters setValue: [NSString stringWithFormat:@"%d",[GlobalKit shareKit].hdlPlatform] forKey:@"platform"]; + [parameters setValue:[GlobalKit shareKit].hdlHomeId forKey:@"homeId"]; + parameters = [self GetSignRequestDictionary:parameters]; [self requestHttpsPost:API_POST_EZ_ChildDelDevice parameters:parameters completion:^(ResponseData *responseData) { @@ -251,7 +257,8 @@ NSString *newString = @""; for(NSString *key in sortKeyArray){ if(params[key] != NULL){ - NSString *valueStr = params[key]; + //Key瀵瑰簲鐨剉alue寮鸿浆涓篘SString + NSString *valueStr = [NSString stringWithFormat:@"%@",[params objectForKey:key]]; //妫�娴嬪綋鍓嶅弬鏁版槸鍚﹂渶瑕佸弬涓庢牎楠� if([self IfValueNeedSign:valueStr]){ newString = [newString stringByAppendingString:[NSString stringWithFormat:@"%@=%@&", key,valueStr]]; @@ -311,7 +318,10 @@ if (( [self stringIsNullOrEmpty:valueStr])//鍒ょ┖瀛楃 || ([[valueStr substringToIndex:1] isEqual:@"{"])//鍒ゆ柇鏄惁涓哄璞� || ([[valueStr substringToIndex:1] isEqual:@"["])//鍒ゆ柇鏄惁涓烘暟缁� + || ([[valueStr substringToIndex:1] isEqual:@"("])//鍒ゆ柇鏄惁涓烘暟缁� ) { + +// HDLSDKLog(@"涓嶆牎楠�: %@",valueStr); return false; } return true; @@ -319,3 +329,9 @@ @end + + +#pragma mark - 淇敼璁板綍 +//2021-07-07 +//V1.1.3 +//1.鏇挎崲涓烘柊鎺ュ彛锛屾牴鎹甴omeId娉ㄥ唽钀ょ煶瀛愯处鍙锋柟妗堛�� diff --git a/EZSDK/EZSDK/EZ/Global/GlobalKit.h b/EZSDK/EZSDK/EZ/Global/GlobalKit.h index 1ede585..d8917f4 100644 --- a/EZSDK/EZSDK/EZ/Global/GlobalKit.h +++ b/EZSDK/EZSDK/EZ/Global/GlobalKit.h @@ -22,6 +22,7 @@ @property (nonatomic, copy) NSString *GlobalRequestHttpsHost; @property (nonatomic, copy) NSString *hdlAccessToken; @property (nonatomic, copy) NSString *hdlRefreshToken; +@property (nonatomic, copy) NSString *hdlHomeId; @property (nonatomic, copy) NSString *accessToken; @property (nonatomic, copy) NSString *deviceSerialNo; //璁惧搴忓垪鍙� diff --git a/EZSDK/EZSDK/EZ/Global/GlobalKit.m b/EZSDK/EZSDK/EZ/Global/GlobalKit.m index 4a06059..c58d0ad 100644 --- a/EZSDK/EZSDK/EZ/Global/GlobalKit.m +++ b/EZSDK/EZSDK/EZ/Global/GlobalKit.m @@ -66,7 +66,7 @@ _GlobalRequestHttpsHost = GlobalRequestHttpsHost; } -- (void)sethdlPlatform:(int )hdlPlatform +- (void)sethdlPlatform:(int)hdlPlatform { _hdlPlatform = hdlPlatform; } @@ -74,7 +74,7 @@ - (void)clearSession { _accessToken = nil; - _hdlRefreshToken = nil; + _hdlAccessToken = nil; _hdlRefreshToken = nil; [[NSUserDefaults standardUserDefaults] removeObjectForKey:EZOpenSDKAccessToken]; [[NSUserDefaults standardUserDefaults] synchronize]; diff --git a/EZSDK/EZSDK/EZ/TableViewCells/DeviceListCell.m b/EZSDK/EZSDK/EZ/TableViewCells/DeviceListCell.m index 935f895..abf9966 100644 --- a/EZSDK/EZSDK/EZ/TableViewCells/DeviceListCell.m +++ b/EZSDK/EZSDK/EZ/TableViewCells/DeviceListCell.m @@ -44,8 +44,9 @@ // }]; // [EZOPENSDK cap] - //2021-05-08 闅愯棌褰曞儚鎸夐挳 - self.recordButton.hidden = YES; +// //2021-05-08 闅愯棌褰曞儚鎸夐挳 +// //2021-07-07 鍙栨秷闅愯棌 +// self.recordButton.hidden = YES; self.messageButton.hidden = NO; self.settingButton.hidden = NO; diff --git a/EZSDK/EZSDK/EZSDK.h b/EZSDK/EZSDK/EZSDK.h index d9b3fe5..9325728 100644 --- a/EZSDK/EZSDK/EZSDK.h +++ b/EZSDK/EZSDK/EZSDK.h @@ -6,7 +6,7 @@ // #import <Foundation/Foundation.h> - +#import "EZDeviceInfo.h" @interface EZSDK : NSObject /** @@ -21,11 +21,11 @@ /** 璁剧疆HDLSDK鐨刟ccessToken */ -+(void)setHDlAccessToken:(NSString *) accessToken refreshToken:(NSString *) refreshToken; ++(void)setHDlAccessToken:(NSString *)accessToken refreshToken:(NSString *) refreshToken; /** 璁剧疆SDK鐨勬渤涓滄帴鍙g殑requestHttpsHost鍜屽钩鍙� 鏍囪瘑锛�1.on+(榛樿) 2.evoyo */ -+(void)setRequestHttpsHostAndPlatform:(NSString *) requestHttpsHost platform:(int) platform; ++(void)setRequestHttpsHostAndPlatform:(NSString *) requestHttpsHost platform:(int)platform homeId:(NSString *)homeId; /** 鐩存帴璺宠浆鍒拌悿鐭虫憚鍍忓ご鍒楄〃 @@ -38,14 +38,17 @@ /** 鏌ョ湅瑙嗛鐩戞帶鐩存挱 */ -+(void)Play:(NSObject*)deviceInfo; ++(void)Play:(EZDeviceInfo*)deviceInfo; +/// 鎸囧畾搴忓垪鍙� 鏌ョ湅瑙嗛鐩戞帶鐩存挱 +/// @param deviceSerial 搴忓垪鍙� ++(void)PlayWithDeviceSerial:(NSString *)deviceSerial; /** 鎵撳紑鎽勫儚澶磋缃〉闈� */ -+(void)setting:(NSObject*)deviceInfo; ++(void)setting:(EZDeviceInfo*)deviceInfo; /** 鍥炴斁鎾斁鍘嗗彶 */ -+(void)playBackVideo:(NSObject*)deviceInfo; ++(void)playBackVideo:(EZDeviceInfo*)deviceInfo; @end diff --git a/EZSDK/EZSDK/EZSDK.m b/EZSDK/EZSDK/EZSDK.m index 57ebd9c..cfb414f 100644 --- a/EZSDK/EZSDK/EZSDK.m +++ b/EZSDK/EZSDK/EZSDK.m @@ -74,9 +74,10 @@ /** 璁剧疆SDK鐨勬渤涓滄帴鍙g殑requestHttpsHost鍜屽钩鍙� 鏍囪瘑锛�1.on+(榛樿) 2.evoyo */ -+(void)setRequestHttpsHostAndPlatform:(NSString *) requestHttpsHost platform:(int) platform{ ++(void)setRequestHttpsHostAndPlatform:(NSString *) requestHttpsHost platform:(int)platform homeId:(NSString *)homeId{ [[GlobalKit shareKit] setGlobalRequestHttpsHost:requestHttpsHost]; [[GlobalKit shareKit] setHdlPlatform:platform]; + [[GlobalKit shareKit] setHdlHomeId:homeId]; } //鑾峰彇褰撳墠灞忓箷鏄剧ず鐨剉iewcontroller (杩欓噷闈㈣幏鍙栫殑鐩稿綋浜巖ootViewController) @@ -138,22 +139,40 @@ /** 鏌ョ湅瑙嗛鐩戞帶鐩存挱 */ -+(void)Play:(NSObject*)deviceInfo ++(void)Play:(EZDeviceInfo*)deviceInfo { UIStoryboard *addDeviceStoryBoard = [UIStoryboard storyboardWithName:@"EZMain" bundle:nil]; EZLivePlayViewController *rootViewController = [addDeviceStoryBoard instantiateViewControllerWithIdentifier:@"EZLivePlayViewController"]; // NSLog(@"play--iphone--rootViewController"); rootViewController.deviceInfo=(EZDeviceInfo *)deviceInfo; NSLog(@"play--iphone--deviceName -%@",rootViewController.deviceInfo.deviceName); - // rootViewController.cameraIndex=0; +// rootViewController.cameraIndex=0; [[self getCurrentVC] setNavigationBarHidden:NO]; [[self getCurrentVC] pushViewController:rootViewController animated:YES]; + + +} + +/// 鎸囧畾搴忓垪鍙锋挱鏀� +/// @param deviceSerial 搴忓垪鍙� ++(void)PlayWithDeviceSerial:(NSString *)deviceSerial{ + //鑾峰彇璁惧鍒楄〃鎺ュ彛 + [EZOpenSDK getDeviceInfo:deviceSerial completion:^(EZDeviceInfo *deviceInfo, NSError *error) { + if(error) + { + NSLog(@"EZ 鏌ヨ璁惧淇℃伅澶辫触"); + return; + } + if (deviceInfo) { + [self Play:deviceInfo]; + } + }]; } /** 鎵撳紑鎽勫儚澶磋缃〉闈� */ -+(void)setting:(NSObject*)deviceInfo ++(void)setting:(EZDeviceInfo*)deviceInfo { UIStoryboard *settingStoryBoard=[UIStoryboard storyboardWithName:@"EZMain" bundle:nil]; EZSettingViewController *settingVC=[settingStoryBoard instantiateViewControllerWithIdentifier:@"EZSettingViewController"]; @@ -165,7 +184,7 @@ /** 鍥炴斁鎾斁鍘嗗彶 */ -+(void)playBackVideo:(NSObject*)deviceInfo ++(void)playBackVideo:(EZDeviceInfo*)deviceInfo { UIStoryboard *playBackStoryBoard=[UIStoryboard storyboardWithName:@"EZMain" bundle:nil]; EZPlaybackViewController *playBackVC=[playBackStoryBoard instantiateViewControllerWithIdentifier:@"EZPlaybackViewController"]; -- Gitblit v1.8.0