表情下载、解码,发送

This commit is contained in:
chenguilong
2022-01-08 20:15:06 +08:00
committed by fengshuo
parent 446e388727
commit 4161b33930
38 changed files with 3567 additions and 63 deletions

View File

@@ -113,6 +113,9 @@
9B0086C627BA392B0032BD2B /* AnchorStageView.m in Sources */ = {isa = PBXBuildFile; fileRef = 9B0086C527BA392B0032BD2B /* AnchorStageView.m */; };
9B0086CA27BA4F570032BD2B /* AnchorMicroView.m in Sources */ = {isa = PBXBuildFile; fileRef = 9B0086C927BA4F570032BD2B /* AnchorMicroView.m */; };
9B060B5827BCAEE20001B767 /* AnchorGiftValueView.m in Sources */ = {isa = PBXBuildFile; fileRef = 9B060B5727BCAEE20001B767 /* AnchorGiftValueView.m */; };
9B04CE20278937D100434F47 /* XPFaceParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 9B04CE1F278937D100434F47 /* XPFaceParser.m */; };
9B04CE232789392E00434F47 /* FaceSendInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = 9B04CE212789392E00434F47 /* FaceSendInfo.m */; };
9B04CE26278940D700434F47 /* XPFaceProtocol.m in Sources */ = {isa = PBXBuildFile; fileRef = 9B04CE25278940D700434F47 /* XPFaceProtocol.m */; };
9B0E1C5926E77022005D4442 /* BaseNavigationController.m in Sources */ = {isa = PBXBuildFile; fileRef = 9B0E1C5826E77022005D4442 /* BaseNavigationController.m */; };
9B17F71827BD150600440843 /* SVGAParserManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 9B17F71727BD150600440843 /* SVGAParserManager.m */; };
9B7B605B27BB53060070BB72 /* XPAnchorAudienceUpMicView.m in Sources */ = {isa = PBXBuildFile; fileRef = 9B7B605A27BB53060070BB72 /* XPAnchorAudienceUpMicView.m */; };
@@ -141,6 +144,15 @@
9BE29A6B27D1BFF700446AB5 /* anchor_room_speak.svga in Resources */ = {isa = PBXBuildFile; fileRef = 9BE29A6927D1BFF700446AB5 /* anchor_room_speak.svga */; };
9BE29A6D27D210A500446AB5 /* anchor_room_bg.svga in Resources */ = {isa = PBXBuildFile; fileRef = 9BE29A6C27D210A500446AB5 /* anchor_room_bg.svga */; };
9B8585D3278837CE00D7D5C6 /* NobleLevelUpModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 9B8585D2278837CE00D7D5C6 /* NobleLevelUpModel.m */; };
9B8585D6278844B300D7D5C6 /* NSString+JsonToDic.m in Sources */ = {isa = PBXBuildFile; fileRef = 9B8585D4278844B300D7D5C6 /* NSString+JsonToDic.m */; };
9B8585EE27885B3E00D7D5C6 /* YYWebResourceDownloader.m in Sources */ = {isa = PBXBuildFile; fileRef = 9B8585ED27885B3E00D7D5C6 /* YYWebResourceDownloader.m */; };
9B8585F52788699400D7D5C6 /* FBKVOController.m in Sources */ = {isa = PBXBuildFile; fileRef = 9B8585F42788699400D7D5C6 /* FBKVOController.m */; };
9B8585F927886A1100D7D5C6 /* CommonFileUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = 9B8585F827886A1000D7D5C6 /* CommonFileUtils.m */; };
9BA9AD832789344E00C0BF8F /* FaceReceiveInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = 9BA9AD7B2789344D00C0BF8F /* FaceReceiveInfo.m */; };
9BA9AD842789344E00C0BF8F /* FaceInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = 9BA9AD7D2789344D00C0BF8F /* FaceInfo.m */; };
9BA9AD852789344E00C0BF8F /* FaceConfigInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = 9BA9AD7F2789344D00C0BF8F /* FaceConfigInfo.m */; };
9BA9AD862789344E00C0BF8F /* FaceInfoStorage.m in Sources */ = {isa = PBXBuildFile; fileRef = 9BA9AD802789344D00C0BF8F /* FaceInfoStorage.m */; };
9BA9AD872789344E00C0BF8F /* FacePlayInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = 9BA9AD812789344D00C0BF8F /* FacePlayInfo.m */; };
9BB549592782E6A30090CD26 /* XPNobleCenterPresenter.m in Sources */ = {isa = PBXBuildFile; fileRef = 9BB549582782E6A30090CD26 /* XPNobleCenterPresenter.m */; };
9BB5495C2782E79E0090CD26 /* NobleCenterModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 9BB5495B2782E79E0090CD26 /* NobleCenterModel.m */; };
9BB5495F2782E9DB0090CD26 /* NobleAuthInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = 9BB5495E2782E9DB0090CD26 /* NobleAuthInfo.m */; };
@@ -713,6 +725,12 @@
9B0086C927BA4F570032BD2B /* AnchorMicroView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AnchorMicroView.m; sourceTree = "<group>"; };
9B060B5627BCAEE20001B767 /* AnchorGiftValueView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AnchorGiftValueView.h; sourceTree = "<group>"; };
9B060B5727BCAEE20001B767 /* AnchorGiftValueView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AnchorGiftValueView.m; sourceTree = "<group>"; };
9B04CE1E278937D100434F47 /* XPFaceParser.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = XPFaceParser.h; sourceTree = "<group>"; };
9B04CE1F278937D100434F47 /* XPFaceParser.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = XPFaceParser.m; sourceTree = "<group>"; };
9B04CE212789392E00434F47 /* FaceSendInfo.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FaceSendInfo.m; sourceTree = "<group>"; };
9B04CE222789392E00434F47 /* FaceSendInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FaceSendInfo.h; sourceTree = "<group>"; };
9B04CE24278940D700434F47 /* XPFaceProtocol.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = XPFaceProtocol.h; sourceTree = "<group>"; };
9B04CE25278940D700434F47 /* XPFaceProtocol.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = XPFaceProtocol.m; sourceTree = "<group>"; };
9B0E1C5726E77022005D4442 /* BaseNavigationController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = BaseNavigationController.h; sourceTree = "<group>"; };
9B0E1C5826E77022005D4442 /* BaseNavigationController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = BaseNavigationController.m; sourceTree = "<group>"; };
9B17F71627BD150600440843 /* SVGAParserManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVGAParserManager.h; sourceTree = "<group>"; };
@@ -765,6 +783,24 @@
9BAA5FEF277A23F4007453F3 /* XPPermissionsViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = XPPermissionsViewController.m; sourceTree = "<group>"; };
9B8585D1278837CE00D7D5C6 /* NobleLevelUpModel.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = NobleLevelUpModel.h; sourceTree = "<group>"; };
9B8585D2278837CE00D7D5C6 /* NobleLevelUpModel.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = NobleLevelUpModel.m; sourceTree = "<group>"; };
9B8585D4278844B300D7D5C6 /* NSString+JsonToDic.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSString+JsonToDic.m"; sourceTree = "<group>"; };
9B8585D5278844B300D7D5C6 /* NSString+JsonToDic.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSString+JsonToDic.h"; sourceTree = "<group>"; };
9B8585EC27885B3E00D7D5C6 /* YYWebResourceDownloader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = YYWebResourceDownloader.h; sourceTree = "<group>"; };
9B8585ED27885B3E00D7D5C6 /* YYWebResourceDownloader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = YYWebResourceDownloader.m; sourceTree = "<group>"; };
9B8585F32788699400D7D5C6 /* FBKVOController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBKVOController.h; sourceTree = "<group>"; };
9B8585F42788699400D7D5C6 /* FBKVOController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBKVOController.m; sourceTree = "<group>"; };
9B8585F727886A1000D7D5C6 /* CommonFileUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CommonFileUtils.h; sourceTree = "<group>"; };
9B8585F827886A1000D7D5C6 /* CommonFileUtils.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CommonFileUtils.m; sourceTree = "<group>"; };
9BA9AD792789344D00C0BF8F /* FaceConfigInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FaceConfigInfo.h; sourceTree = "<group>"; };
9BA9AD7A2789344D00C0BF8F /* FaceInfoStorage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FaceInfoStorage.h; sourceTree = "<group>"; };
9BA9AD7B2789344D00C0BF8F /* FaceReceiveInfo.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FaceReceiveInfo.m; sourceTree = "<group>"; };
9BA9AD7C2789344D00C0BF8F /* FacePlayInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FacePlayInfo.h; sourceTree = "<group>"; };
9BA9AD7D2789344D00C0BF8F /* FaceInfo.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FaceInfo.m; sourceTree = "<group>"; };
9BA9AD7E2789344D00C0BF8F /* FaceInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FaceInfo.h; sourceTree = "<group>"; };
9BA9AD7F2789344D00C0BF8F /* FaceConfigInfo.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FaceConfigInfo.m; sourceTree = "<group>"; };
9BA9AD802789344D00C0BF8F /* FaceInfoStorage.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FaceInfoStorage.m; sourceTree = "<group>"; };
9BA9AD812789344D00C0BF8F /* FacePlayInfo.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FacePlayInfo.m; sourceTree = "<group>"; };
9BA9AD822789344E00C0BF8F /* FaceReceiveInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FaceReceiveInfo.h; sourceTree = "<group>"; };
9BB549572782E6A30090CD26 /* XPNobleCenterPresenter.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = XPNobleCenterPresenter.h; sourceTree = "<group>"; };
9BB549582782E6A30090CD26 /* XPNobleCenterPresenter.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = XPNobleCenterPresenter.m; sourceTree = "<group>"; };
9BB5495A2782E79E0090CD26 /* NobleCenterModel.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = NobleCenterModel.h; sourceTree = "<group>"; };
@@ -1926,6 +1962,9 @@
E80CBDE727D0C528001E1EC2 /* Timer */,
180116F6279E8C3100F2CBC0 /* Date */,
9B17F71527BD14FF00440843 /* SVGAParserManager */,
9B8585F627886A1000D7D5C6 /* File */,
9B8585F22788699400D7D5C6 /* KVO */,
9B8585EA27885B3D00D7D5C6 /* WebResource */,
E82D5C77276B25B000858D6D /* SpriteSheetManager */,
E865964E2701A1A900846EBD /* StatisticsService */,
E89DA6612700590A008483C1 /* IAPHelper */,
@@ -2193,10 +2232,38 @@
);
path = Model;
sourceTree = "<group>";
};
9B04CE1B2789379B00434F47 /* XPFaceParser */ = {
isa = PBXGroup;
children = (
9B04CE1E278937D100434F47 /* XPFaceParser.h */,
9B04CE1F278937D100434F47 /* XPFaceParser.m */,
);
path = XPFaceParser;
sourceTree = "<group>";
};
9B04CE1C278937B300434F47 /* Procotol */ = {
isa = PBXGroup;
children = (
9B04CE24278940D700434F47 /* XPFaceProtocol.h */,
9B04CE25278940D700434F47 /* XPFaceProtocol.m */,
);
path = Procotol;
sourceTree = "<group>";
};
9B04CE1D278937BB00434F47 /* Api */ = {
isa = PBXGroup;
children = (
);
path = Api;
sourceTree = "<group>";
};
9B208A372779C1EF00F9E54A /* FaceView */ = {
isa = PBXGroup;
children = (
9B04CE1D278937BB00434F47 /* Api */,
9B04CE1C278937B300434F47 /* Procotol */,
9B04CE1B2789379B00434F47 /* XPFaceParser */,
9BC5C8E6277AAD8B007C8719 /* Presenter */,
9B208A492779C30600F9E54A /* Model */,
9B208A382779C2CA00F9E54A /* View */,
@@ -2232,6 +2299,18 @@
9B208A492779C30600F9E54A /* Model */ = {
isa = PBXGroup;
children = (
9BA9AD792789344D00C0BF8F /* FaceConfigInfo.h */,
9BA9AD7F2789344D00C0BF8F /* FaceConfigInfo.m */,
9BA9AD7E2789344D00C0BF8F /* FaceInfo.h */,
9BA9AD7D2789344D00C0BF8F /* FaceInfo.m */,
9BA9AD7A2789344D00C0BF8F /* FaceInfoStorage.h */,
9BA9AD802789344D00C0BF8F /* FaceInfoStorage.m */,
9BA9AD7C2789344D00C0BF8F /* FacePlayInfo.h */,
9BA9AD812789344D00C0BF8F /* FacePlayInfo.m */,
9BA9AD822789344E00C0BF8F /* FaceReceiveInfo.h */,
9BA9AD7B2789344D00C0BF8F /* FaceReceiveInfo.m */,
9B04CE222789392E00434F47 /* FaceSendInfo.h */,
9B04CE212789392E00434F47 /* FaceSendInfo.m */,
9B208A4A2779C30600F9E54A /* XCGameRoomFaceViewDisplayModel.h */,
9B208A4D2779C30600F9E54A /* XCGameRoomFaceViewDisplayModel.m */,
9B208A4C2779C30600F9E54A /* XCGameRoomFaceTitleDisplayModel.h */,
@@ -2265,6 +2344,48 @@
path = NobleVIP;
sourceTree = "<group>";
};
9B8585D727884FE200D7D5C6 /* Face */ = {
isa = PBXGroup;
children = (
);
path = Face;
sourceTree = "<group>";
};
9B8585EA27885B3D00D7D5C6 /* WebResource */ = {
isa = PBXGroup;
children = (
9B8585EB27885B3E00D7D5C6 /* Downloader */,
);
path = WebResource;
sourceTree = "<group>";
};
9B8585EB27885B3E00D7D5C6 /* Downloader */ = {
isa = PBXGroup;
children = (
9B8585EC27885B3E00D7D5C6 /* YYWebResourceDownloader.h */,
9B8585ED27885B3E00D7D5C6 /* YYWebResourceDownloader.m */,
);
path = Downloader;
sourceTree = "<group>";
};
9B8585F22788699400D7D5C6 /* KVO */ = {
isa = PBXGroup;
children = (
9B8585F32788699400D7D5C6 /* FBKVOController.h */,
9B8585F42788699400D7D5C6 /* FBKVOController.m */,
);
path = KVO;
sourceTree = "<group>";
};
9B8585F627886A1000D7D5C6 /* File */ = {
isa = PBXGroup;
children = (
9B8585F727886A1000D7D5C6 /* CommonFileUtils.h */,
9B8585F827886A1000D7D5C6 /* CommonFileUtils.m */,
);
path = File;
sourceTree = "<group>";
};
9BB549632782F96F0090CD26 /* SubViews */ = {
isa = PBXGroup;
children = (
@@ -2526,6 +2647,8 @@
E81366E426F0A4820076364C /* NSString */ = {
isa = PBXGroup;
children = (
9B8585D5278844B300D7D5C6 /* NSString+JsonToDic.h */,
9B8585D4278844B300D7D5C6 /* NSString+JsonToDic.m */,
E81366E526F0A49E0076364C /* NSString+Utils.h */,
E81366E626F0A49E0076364C /* NSString+Utils.m */,
);
@@ -3516,6 +3639,7 @@
E8412F9A2779BAC2006E1101 /* Setting */,
E84150B027747A7400A7F548 /* FirstRecharge */,
E81C1B1327705EF00020D1E4 /* ArrangeMic */,
9B8585D727884FE200D7D5C6 /* Face */,
9B8585D0278835BF00D7D5C6 /* NobleVIP */,
9BC5C915277C809E007C8719 /* ReleaseRadio */,
E8A1E4462761F8EA00B294CA /* CandyTree */,
@@ -4278,6 +4402,7 @@
E8ACEFEF27C8C45100F66D1A /* XPHomeHapppyRoomTableViewCell.m in Sources */,
E84BF7DA277C72AC00EF8877 /* XPRoomRoleTableViewCell.m in Sources */,
E839532D276A030F00CF2F24 /* XPMineDressUpListViewController.m in Sources */,
9BA9AD832789344E00C0BF8F /* FaceReceiveInfo.m in Sources */,
E8B846D826FDE17300A777FE /* XPMineRechargeProtocol.h in Sources */,
E82D5C7D276B343300858D6D /* YYAnimatedImageView+ImageShow.m in Sources */,
E8B846C726FDB45000A777FE /* XPMineUserInfoAlbumProtocol.h in Sources */,
@@ -4333,11 +4458,14 @@
E84150BB27747BAF00A7F548 /* XPFirstRechargePresenter.m in Sources */,
9BEE3D1727858E5700C83219 /* XPNobleAuthorityDescView.m in Sources */,
E82325F9274E2E42003A3332 /* Api+UserCard.m in Sources */,
9B04CE20278937D100434F47 /* XPFaceParser.m in Sources */,
E82109B026F1D83500FC3319 /* LoginBindPhonePresent.m in Sources */,
E81C1B1F27705F7A0020D1E4 /* XPArrangeMicViewController.m in Sources */,
9BA9AD852789344E00C0BF8F /* FaceConfigInfo.m in Sources */,
E8B825C726EA0D9A009E8E9F /* LoginVerifCodeProtocol.h in Sources */,
E824544E26F5BC1A00BE8163 /* XPMineModifPayPwdView.m in Sources */,
E8A6C2A227CF856E00AC7442 /* HomeCollectRoomModel.m in Sources */,
9B8585F52788699400D7D5C6 /* FBKVOController.m in Sources */,
E8A03DE22762FA000098D9EA /* XPCandyTreeMoreView.m in Sources */,
E8B825CA26EA1231009E8E9F /* LoginVerifCodeViewController.m in Sources */,
189DD76226E60DDC00AB55B1 /* Api+Login.m in Sources */,
@@ -4387,6 +4515,7 @@
189DD53426DE255300AB55B1 /* TabbarViewController.m in Sources */,
E87A26F927587C62002DDC7A /* XPHomeContainerPresenter.m in Sources */,
18EE401A2754BA9F00A452BF /* NIMMessageMaker.m in Sources */,
9B8585EE27885B3E00D7D5C6 /* YYWebResourceDownloader.m in Sources */,
E8EEB91D26FC9D58007C6EBA /* XPMineUserInfoDateView.m in Sources */,
E82325E9274CE56A003A3332 /* XPShareItem.m in Sources */,
E890BC0D273D09A50007C46B /* XPGiftCountView.m in Sources */,
@@ -4506,6 +4635,8 @@
18E7B31E26F0984C0064BC9B /* UserLevelVo.m in Sources */,
E82D5C7A276B25D100858D6D /* SpriteSheetImageManager.m in Sources */,
E874B88B27215EAF003954B9 /* MicroQueueModel.m in Sources */,
9BA9AD872789344E00C0BF8F /* FacePlayInfo.m in Sources */,
9B8585D6278844B300D7D5C6 /* NSString+JsonToDic.m in Sources */,
E8EE827D272B9A2300A17217 /* XPRoomSendTextView.m in Sources */,
9BD63FAE277EE97A006EB744 /* XPReleaseRadioPresenter.m in Sources */,
E8EEB90626FC5772007C6EBA /* XPMineUserInfoEditViewController.m in Sources */,
@@ -4553,6 +4684,7 @@
186A534A26FC6ED900D67B2C /* TTActionSheetConfig.m in Sources */,
9BBC028B2786E05A0007C24B /* XPNobleCenterEntranceView.m in Sources */,
E81C279326EB394D0031E639 /* LoginForgetPasswordViewController.m in Sources */,
9BA9AD862789344E00C0BF8F /* FaceInfoStorage.m in Sources */,
E81C278D26EAFAF60031E639 /* DESEncrypt.m in Sources */,
9BC5C8E9277AB6AE007C8719 /* XPFacePresenter.m in Sources */,
E81366E726F0A49E0076364C /* NSString+Utils.m in Sources */,
@@ -4636,6 +4768,7 @@
E83DB481274649FB00D8CBD1 /* XPGiftBannerUserInfoModel.m in Sources */,
E878893F273A54F500BF1D57 /* XPGiftPresenter.m in Sources */,
E8A03DF62763367F0098D9EA /* XPCandyTreeEmptyableViewCell.m in Sources */,
9B04CE232789392E00434F47 /* FaceSendInfo.m in Sources */,
E8AEAEED27141AE20017FCE0 /* XPRoomBackContainerView.m in Sources */,
E88B5CC126FB407B00DA9178 /* XPMineUserInfoViewController.m in Sources */,
18F4043A275E20D900A6C548 /* TRTCRtcImpl.m in Sources */,
@@ -4649,9 +4782,11 @@
E8A6C28C27CF436300AC7442 /* XPHomeLikeViewController.m in Sources */,
E8E70D8F26F2F5DB00F03460 /* XPMineMenuTableViewCell.m in Sources */,
E8E5E1A927C3850400F457D8 /* XPHomeHotRoomCollectionViewCell.m in Sources */,
9B8585F927886A1100D7D5C6 /* CommonFileUtils.m in Sources */,
187EEEE126E89BFB002833B2 /* AccountModel.m in Sources */,
E896EFA92771AEEC00AD2CC1 /* XPMineAttentionTableViewCell.m in Sources */,
9BBC02912786FC570007C24B /* XPMineNobleCardTableViewCell.m in Sources */,
9B04CE26278940D700434F47 /* XPFaceProtocol.m in Sources */,
E8AC722126F47E23007D6E91 /* XPMineAboutUsViewController.m in Sources */,
18F403CB2758C66800A6C548 /* MessageContentText.m in Sources */,
E8232600274E48EA003A3332 /* XPUserCardItemCollectionViewCell.m in Sources */,
@@ -4674,6 +4809,7 @@
E84BF7E0277C869A00EF8877 /* XPRoomOnLineViewController.m in Sources */,
186A534826FC6ED900D67B2C /* TTAlertButtonConfig.m in Sources */,
E8ACEFF827C9034C00F66D1A /* XPHomeListEmptyTableViewCell.m in Sources */,
9BA9AD842789344E00C0BF8F /* FaceInfo.m in Sources */,
E89D60BA271D643A001F8895 /* Api+Room.m in Sources */,
E872308926E89BE000B90D4F /* LoginPhoneViewController.m in Sources */,
E8C6FFEA2755040B004DC9F0 /* XPHomeSearchNavView.m in Sources */,

View File

@@ -0,0 +1,91 @@
//
// CommonFileUtils.h
// Commons
//
// Created by 小城 on 14-6-5.
// Copyright (c) 2014年 YY Inc. All rights reserved.
//
#import <Foundation/Foundation.h>
@interface CommonFileUtils : NSObject
/**Some FilePaths
*/
+ (NSString *)documentsDirectory;
+ (NSString *)cachesDirectory;
/**
* File Operation
*/
/**
* 创建文件所在的目录
*
* @param path 文件的绝对路径
*
* @return 是否创建成功
*/
+ (BOOL)createDirForPath:(NSString *)path;
/**
* 创建目录
*
* @param dirPath 目录绝对路径
*
* @return 是否创建成功
*/
+ (BOOL)createDirWithDirPath:(NSString *)dirPath;
/**
* 删除文件
*
* @param path 文件所在的绝对路径
*
* @return 是否删除成功
*/
+ (BOOL)deleteFileWithFullPath:(NSString *)path;
/**
* 指定路径的文件是否存在
*
* @param filePath 文件的绝对路径
*
* @return 是否存在
*/
+ (BOOL)isFileExists:(NSString *)filePath;
/**
* 在文件的末尾追加文本内容
*
* @param content 文本内容
* @param filePath 文件绝对路径比如保证该文件是存在的返回会返回NO
*
* @return 是否追加成功
*/
+ (BOOL)appendContent:(NSString *)content toFilePath:(NSString *)filePath;
/**FileUtils In UserDefault
*/
+ (BOOL)writeObject:(id)object toUserDefaultWithKey:(NSString*)key;
+ (id)readObjectFromUserDefaultWithKey:(NSString*)key;
+ (BOOL)deleteObjectFromUserDefaultWithKey:(NSString*)key;
/**FileUtils In CachesPath
*/
+ (void)writeObject:(id)object toCachesPath:(NSString*)path;
+ (id)readObjectFromCachesPath:(NSString*)path;
+ (BOOL)deleteFileFromCachesPath:(NSString *)path;
/**FileUtils In DocumentPath
*/
+ (void)writeObject:(id)object toDocumentPath:(NSString *)path;
+ (id)readObjectFromDocumentPath:(NSString *)path;
+ (BOOL)deleteFileFromDocumentPath:(NSString *)path;
+ (BOOL)copyItem:(NSString *)destination toPath:(NSString *)toPath;
+ (NSString*)getFileMD5WithPath:(NSString*)path;
@end

View File

@@ -0,0 +1,360 @@
//
// CommonFileUtils.m
// Commons
//
// Created by on 14-6-5.
// Copyright (c) 2014 YY Inc. All rights reserved.
//
#import "CommonFileUtils.h"
#import <CommonCrypto/CommonDigest.h>
#define FileHashDefaultChunkSizeForReadingData 1024*8 // 8K
@implementation CommonFileUtils
+ (NSString *)documentsDirectory
{
static NSString *docsDir = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
docsDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
});
return docsDir;
}
+ (NSString *)cachesDirectory
{
static NSString *cachesDir = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
cachesDir = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) objectAtIndex:0];
});
return cachesDir;
}
+ (BOOL)createDirForPath:(NSString *)path
{
return [[NSFileManager defaultManager] createDirectoryAtPath:path withIntermediateDirectories:YES attributes:nil error:nil];
}
+ (BOOL)createDirWithDirPath:(NSString *)dirPath
{
return [[NSFileManager defaultManager] createDirectoryAtPath:dirPath
withIntermediateDirectories:YES
attributes:nil
error:nil];
}
+ (BOOL)deleteFileWithFullPath:(NSString *)fullPath
{
BOOL deleteSucc = NO;
if ([[NSFileManager defaultManager] isDeletableFileAtPath:fullPath]) {
deleteSucc = [[NSFileManager defaultManager] removeItemAtPath:fullPath error:NULL];
}
return deleteSucc;
}
/**UserDefault
*/
+ (BOOL)writeObject:(id)object toUserDefaultWithKey:(NSString*)key
{
if (object == nil || key == nil) return NO;
NSData *myEncodedObject = [NSKeyedArchiver archivedDataWithRootObject:object];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:myEncodedObject forKey:key];
return [defaults synchronize];
}
+ (id)readObjectFromUserDefaultWithKey:(NSString*)key
{
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSData *myEncodedObject = [defaults objectForKey:key];
if (myEncodedObject == nil) {
return nil;
}
@try {
return [NSKeyedUnarchiver unarchiveObjectWithData: myEncodedObject];
}
@catch (NSException *e){
return nil;
}
}
+ (BOOL)deleteObjectFromUserDefaultWithKey:(NSString*)key
{
if (!key) {
return NO;
}
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults removeObjectForKey:key];
return [defaults synchronize];
}
+ (BOOL)isFileExists:(NSString *)filePath
{
return [[NSFileManager defaultManager] fileExistsAtPath:filePath];
}
+ (BOOL)appendContent:(NSString *)content toFilePath:(NSString *)filePath
{
if (![CommonFileUtils isFileExists:filePath]) {
return NO;
}
BOOL appendSucc = YES;
NSFileHandle *fileHandle = [NSFileHandle fileHandleForWritingAtPath:filePath];
if (!fileHandle) {
appendSucc = NO;
} else {
[fileHandle seekToEndOfFile];
[fileHandle writeData:[content dataUsingEncoding:NSUTF8StringEncoding]];
[fileHandle closeFile];
}
return appendSucc;
}
/**CachesPath
*/
+ (void)writeObject:(id)object toCachesPath:(NSString*)path
{
if (object == nil || [path length] == 0)
return;
NSString *fullPath = [[CommonFileUtils cachesDirectory] stringByAppendingPathComponent:path];
[CommonFileUtils _writeObject:object toPath:fullPath];
}
+ (id)readObjectFromCachesPath:(NSString*)path
{
if ([path length] == 0)
return nil;
NSString *fullPath = [[CommonFileUtils cachesDirectory] stringByAppendingPathComponent:path];
return [CommonFileUtils _readObjectFromPath:fullPath];
}
+ (BOOL)deleteFileFromCachesPath:(NSString *)path
{
NSString *fullPath = [[CommonFileUtils cachesDirectory] stringByAppendingPathComponent:path];
return [CommonFileUtils deleteFileWithFullPath:fullPath];
}
/**DocumentPath
*/
+ (void)writeObject:(id)object toDocumentPath:(NSString *)path
{
if (object == nil || [path length] == 0)
return;
NSString *fullPath = [[CommonFileUtils documentsDirectory] stringByAppendingPathComponent:path];
[CommonFileUtils _writeObject:object toPath:fullPath];
}
+ (id)readObjectFromDocumentPath:(NSString *)path
{
if ([path length] == 0)
return nil;
NSString *fullPath = [[CommonFileUtils documentsDirectory] stringByAppendingPathComponent:path];
return [CommonFileUtils _readObjectFromPath:fullPath];
}
+ (BOOL)deleteFileFromDocumentPath:(NSString *)path
{
NSString *fullPath = [[CommonFileUtils documentsDirectory] stringByAppendingPathComponent:path];
return [CommonFileUtils deleteFileWithFullPath:fullPath];
}
+ (BOOL)copyItem:(NSString *)destination toPath:(NSString *)toPath
{
NSError *error = nil;
[[NSFileManager defaultManager] copyItemAtPath:destination toPath:toPath error:&error];
return error != nil;
}
#pragma mark - private
static id getSemaphore(NSString *key)
{
static NSMutableDictionary *dict = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
dict = [[NSMutableDictionary alloc] initWithCapacity:10];
});
id obj = [dict objectForKey:key];
if (!obj)
{
obj = [[NSObject alloc] init];
[dict setObject:obj forKey:key];
}
return obj;
}
static dispatch_queue_t getFileQueue()
{
static dispatch_queue_t queue = NULL;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
queue = dispatch_queue_create("FileQueue", NULL);
});
return queue;
}
+ (void)_writeObject:(id)obj toPath:(NSString *)fullPath
{
if (obj == nil || [fullPath length] == 0)
return;
id newObj = obj;
if ([obj isKindOfClass:[NSArray class]] || [obj isKindOfClass:[NSDictionary class]])
{
//线线
if ([obj isKindOfClass:[NSMutableArray class]])
newObj = [NSMutableArray arrayWithArray:obj];
else if ([obj isKindOfClass:[NSArray class]])
newObj = [NSArray arrayWithArray:obj];
else if ([obj isKindOfClass:[NSMutableDictionary class]])
newObj = [NSMutableDictionary dictionaryWithDictionary:obj];
else
newObj = [NSDictionary dictionaryWithDictionary:obj];
}
id sema = getSemaphore(fullPath);
//queue
dispatch_async(getFileQueue(), ^{
@synchronized(sema)
{
//archiveRootObject
if ([CommonFileUtils createDirForPath:fullPath])
{
[NSKeyedArchiver archiveRootObject:newObj toFile:fullPath];
}
// else
// {
// }
}
});
}
+ (id)_readObjectFromPath:(NSString *)fullPath
{
id sema = getSemaphore(fullPath);
if ([[NSFileManager defaultManager] fileExistsAtPath:fullPath])
{
@try
{
@synchronized(sema)
{
return [NSKeyedUnarchiver unarchiveObjectWithFile:fullPath];
}
}
@catch (NSException *e)
{
return nil;
}
}
else
return nil;
}
+(NSString*)getFileMD5WithPath:(NSString*)path
{
return (__bridge NSString *)FileMD5HashCreateWithPath((__bridge CFStringRef)path,FileHashDefaultChunkSizeForReadingData);
}
CFStringRef FileMD5HashCreateWithPath(CFStringRef filePath,
size_t chunkSizeForReadingData) {
// Declare needed variables
CFStringRef result = NULL;
CFReadStreamRef readStream = NULL;
// Get the file URL
CFURLRef fileURL =
CFURLCreateWithFileSystemPath(kCFAllocatorDefault,
(CFStringRef)filePath,
kCFURLPOSIXPathStyle,
(Boolean)false);
CC_MD5_CTX hashObject;
bool hasMoreData = true;
bool didSucceed;
if (!fileURL) goto done;
// Create and open the read stream
readStream = CFReadStreamCreateWithFile(kCFAllocatorDefault,
(CFURLRef)fileURL);
if (!readStream) goto done;
didSucceed = (bool)CFReadStreamOpen(readStream);
if (!didSucceed) goto done;
// Initialize the hash object
CC_MD5_Init(&hashObject);
// Make sure chunkSizeForReadingData is valid
if (!chunkSizeForReadingData) {
chunkSizeForReadingData = FileHashDefaultChunkSizeForReadingData;
}
// Feed the data to the hash object
while (hasMoreData) {
uint8_t buffer[chunkSizeForReadingData];
CFIndex readBytesCount = CFReadStreamRead(readStream,
(UInt8 *)buffer,
(CFIndex)sizeof(buffer));
if (readBytesCount == -1)break;
if (readBytesCount == 0) {
hasMoreData =false;
continue;
}
CC_MD5_Update(&hashObject,(const void *)buffer,(CC_LONG)readBytesCount);
}
// Check if the read operation succeeded
didSucceed = !hasMoreData;
// Compute the hash digest
unsigned char digest[CC_MD5_DIGEST_LENGTH];
CC_MD5_Final(digest, &hashObject);
// Abort if the read operation failed
if (!didSucceed) goto done;
// Compute the string result
char hash[2 *sizeof(digest) + 1];
for (size_t i =0; i < sizeof(digest); ++i) {
snprintf(hash + (2 * i),3, "%02x", (int)(digest[i]));
}
result = CFStringCreateWithCString(kCFAllocatorDefault,
(const char *)hash,
kCFStringEncodingUTF8);
done:
if (readStream) {
CFReadStreamClose(readStream);
CFRelease(readStream);
}
if (fileURL) {
CFRelease(fileURL);
}
return result;
}
@end

View File

@@ -0,0 +1,137 @@
/**
Copyright (c) 2014-present, Facebook, Inc.
All rights reserved.
This source code is licensed under the BSD-style license found in the
LICENSE file in the root directory of this source tree. An additional grant
of patent rights can be found in the PATENTS file in the same directory.
*/
#import <Foundation/Foundation.h>
/**
@abstract Block called on key-value change notification.
@param observer The observer of the change.
@param object The object changed.
@param change The change dictionary.
*/
typedef void (^FBKVONotificationBlock)(id observer, id object, NSDictionary *change);
/**
@abstract FBKVOController makes Key-Value Observing simpler and safer.
@discussion FBKVOController adds support for handling key-value changes with blocks and custom actions, as well as the NSKeyValueObserving callback. Notification will never message a deallocated observer. Observer removal never throws exceptions, and observers are removed implicitely on controller deallocation. FBKVOController is also thread safe. When used in a concurrent environment, it protects observers from possible ressurection and avoids ensuing crash. By default, the controller maintains a strong reference to objects observed.
*/
@interface FBKVOController : NSObject
/**
@abstract Creates and returns an initialized KVO controller instance.
@param observer The object notified on key-value change.
@return The initialized KVO controller instance.
*/
+ (instancetype)controllerWithObserver:(id)observer;
/**
@abstract The designated initializer.
@param observer The object notified on key-value change. The specified observer must support weak references.
@param retainObserved Flag indicating whether observed objects should be retained.
@return The initialized KVO controller instance.
@discussion Use retainObserved = NO when a strong reference between controller and observee would create a retain loop. When not retaining observees, special care must be taken to remove observation info prior to observee dealloc.
*/
- (instancetype)initWithObserver:(id)observer retainObserved:(BOOL)retainObserved;
/**
@abstract Convenience initializer.
@param observer The object notified on key-value change. The specified observer must support weak references.
@return The initialized KVO controller instance.
@discussion By default, KVO controller retains objects observed.
*/
- (instancetype)initWithObserver:(id)observer;
/// The observer notified on key-value change. Specified on initialization.
@property (atomic, weak, readonly) id observer;
/**
@abstract Registers observer for key-value change notification.
@param object The object to observe.
@param keyPath The key path to observe.
@param options The NSKeyValueObservingOptions to use for observation.
@param block The block to execute on notification.
@discussion On key-value change, the specified block is called. Inorder to avoid retain loops, the block must avoid referencing the KVO controller or an owner thereof. Observing an already observed object key path or nil results in no operation.
*/
- (void)observe:(id)object keyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options block:(FBKVONotificationBlock)block;
/**
@abstract Registers observer for key-value change notification.
@param object The object to observe.
@param keyPath The key path to observe.
@param options The NSKeyValueObservingOptions to use for observation.
@param action The observer selector called on key-value change.
@discussion On key-value change, the observer's action selector is called. The selector provided should take the form of -propertyDidChange, -propertyDidChange: or -propertyDidChange:object:, where optional parameters delivered will be KVO change dictionary and object observed. Observing nil or observing an already observed object's key path results in no operation.
*/
- (void)observe:(id)object keyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options action:(SEL)action;
/**
@abstract Registers observer for key-value change notification.
@param object The object to observe.
@param keyPath The key path to observe.
@param options The NSKeyValueObservingOptions to use for observation.
@param context The context specified.
@discussion On key-value change, the observer's -observeValueForKeyPath:ofObject:change:context: method is called. Observing an already observed object key path or nil results in no operation.
*/
- (void)observe:(id)object keyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options context:(void *)context;
/**
@abstract Registers observer for key-value change notification.
@param object The object to observe.
@param keyPaths The key paths to observe.
@param options The NSKeyValueObservingOptions to use for observation.
@param block The block to execute on notification.
@discussion On key-value change, the specified block is called. Inorder to avoid retain loops, the block must avoid referencing the KVO controller or an owner thereof. Observing an already observed object key path or nil results in no operation.
*/
- (void)observe:(id)object keyPaths:(NSArray *)keyPaths options:(NSKeyValueObservingOptions)options block:(FBKVONotificationBlock)block;
/**
@abstract Registers observer for key-value change notification.
@param object The object to observe.
@param keyPaths The key paths to observe.
@param options The NSKeyValueObservingOptions to use for observation.
@param action The observer selector called on key-value change.
@discussion On key-value change, the observer's action selector is called. The selector provided should take the form of -propertyDidChange, -propertyDidChange: or -propertyDidChange:object:, where optional parameters delivered will be KVO change dictionary and object observed. Observing nil or observing an already observed object's key path results in no operation.
*/
- (void)observe:(id)object keyPaths:(NSArray *)keyPaths options:(NSKeyValueObservingOptions)options action:(SEL)action;
/**
@abstract Registers observer for key-value change notification.
@param object The object to observe.
@param keyPaths The key paths to observe.
@param options The NSKeyValueObservingOptions to use for observation.
@param context The context specified.
@discussion On key-value change, the observer's -observeValueForKeyPath:ofObject:change:context: method is called. Observing an already observed object key path or nil results in no operation.
*/
- (void)observe:(id)object keyPaths:(NSArray *)keyPaths options:(NSKeyValueObservingOptions)options context:(void *)context;
/**
@abstract Unobserve object key path.
@param object The object to unobserve.
@param keyPath The key path to observe.
@discussion If not observing object key path, or unobserving nil, this method results in no operation.
*/
- (void)unobserve:(id)object keyPath:(NSString *)keyPath;
/**
@abstract Unobserve all object key paths.
@param object The object to unobserve.
@discussion If not observing object, or unobserving nil, this method results in no operation.
*/
- (void)unobserve:(id)object;
/**
@abstract Unobserve all objects.
@discussion If not observing any objects, this method results in no operation.
*/
- (void)unobserveAll;
@end

View File

@@ -0,0 +1,624 @@
/**
Copyright (c) 2014-present, Facebook, Inc.
All rights reserved.
This source code is licensed under the BSD-style license found in the
LICENSE file in the root directory of this source tree. An additional grant
of patent rights can be found in the PATENTS file in the same directory.
*/
#import "FBKVOController.h"
#import <libkern/OSAtomic.h>
#import <objc/message.h>
#if !__has_feature(objc_arc)
#error This file must be compiled with ARC. Convert your project to ARC or specify the -fobjc-arc flag.
#endif
#pragma mark Utilities -
static NSString *describe_option(NSKeyValueObservingOptions option)
{
switch (option) {
case NSKeyValueObservingOptionNew:
return @"NSKeyValueObservingOptionNew";
break;
case NSKeyValueObservingOptionOld:
return @"NSKeyValueObservingOptionOld";
break;
case NSKeyValueObservingOptionInitial:
return @"NSKeyValueObservingOptionInitial";
break;
case NSKeyValueObservingOptionPrior:
return @"NSKeyValueObservingOptionPrior";
break;
default:
NSCAssert(NO, @"unexpected option %tu", option);
break;
}
return nil;
}
static void append_option_description(NSMutableString *s, NSUInteger option)
{
if (0 == s.length) {
[s appendString:describe_option(option)];
} else {
[s appendString:@"|"];
[s appendString:describe_option(option)];
}
}
static NSUInteger enumerate_flags(NSUInteger *ptrFlags)
{
NSCAssert(ptrFlags, @"expected ptrFlags");
if (!ptrFlags) {
return 0;
}
NSUInteger flags = *ptrFlags;
if (!flags) {
return 0;
}
NSUInteger flag = 1 << __builtin_ctzl(flags);
flags &= ~flag;
*ptrFlags = flags;
return flag;
}
static NSString *describe_options(NSKeyValueObservingOptions options)
{
NSMutableString *s = [NSMutableString string];
NSUInteger option;
while (0 != (option = enumerate_flags(&options))) {
append_option_description(s, option);
}
return s;
}
#pragma mark _FBKVOInfo -
/**
@abstract The key-value observation info.
@discussion Object equality is only used within the scope of a controller instance. Safely omit controller from equality definition.
*/
@interface _FBKVOInfo : NSObject
@end
@implementation _FBKVOInfo
{
@public
__weak FBKVOController *_controller;
NSString *_keyPath;
NSKeyValueObservingOptions _options;
SEL _action;
void *_context;
FBKVONotificationBlock _block;
}
- (instancetype)initWithController:(FBKVOController *)controller keyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options block:(FBKVONotificationBlock)block action:(SEL)action context:(void *)context
{
self = [super init];
if (nil != self) {
_controller = controller;
_block = [block copy];
_keyPath = [keyPath copy];
_options = options;
_action = action;
_context = context;
}
return self;
}
- (instancetype)initWithController:(FBKVOController *)controller keyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options block:(FBKVONotificationBlock)block
{
return [self initWithController:controller keyPath:keyPath options:options block:block action:NULL context:NULL];
}
- (instancetype)initWithController:(FBKVOController *)controller keyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options action:(SEL)action
{
return [self initWithController:controller keyPath:keyPath options:options block:NULL action:action context:NULL];
}
- (instancetype)initWithController:(FBKVOController *)controller keyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options context:(void *)context
{
return [self initWithController:controller keyPath:keyPath options:options block:NULL action:NULL context:context];
}
- (instancetype)initWithController:(FBKVOController *)controller keyPath:(NSString *)keyPath
{
return [self initWithController:controller keyPath:keyPath options:0 block:NULL action:NULL context:NULL];
}
- (NSUInteger)hash
{
return [_keyPath hash];
}
- (BOOL)isEqual:(id)object
{
if (nil == object) {
return NO;
}
if (self == object) {
return YES;
}
if (![object isKindOfClass:[self class]]) {
return NO;
}
return [_keyPath isEqualToString:((_FBKVOInfo *)object)->_keyPath];
}
- (NSString *)debugDescription
{
NSMutableString *s = [NSMutableString stringWithFormat:@"<%@:%p keyPath:%@", NSStringFromClass([self class]), self, _keyPath];
if (0 != _options) {
[s appendFormat:@" options:%@", describe_options(_options)];
}
if (NULL != _action) {
[s appendFormat:@" action:%@", NSStringFromSelector(_action)];
}
if (NULL != _context) {
[s appendFormat:@" context:%p", _context];
}
if (NULL != _block) {
[s appendFormat:@" block:%p", _block];
}
[s appendString:@">"];
return s;
}
@end
#pragma mark _FBKVOSharedController -
/**
@abstract The shared KVO controller instance.
@discussion Acts as a receptionist, receiving and forwarding KVO notifications.
*/
@interface _FBKVOSharedController : NSObject
/** A shared instance that never deallocates. */
+ (instancetype)sharedController;
/** observe an object, info pair */
- (void)observe:(id)object info:(_FBKVOInfo *)info;
/** unobserve an object, info pair */
- (void)unobserve:(id)object info:(_FBKVOInfo *)info;
/** unobserve an object with a set of infos */
- (void)unobserve:(id)object infos:(NSSet *)infos;
@end
@implementation _FBKVOSharedController
{
NSHashTable *_infos;
OSSpinLock _lock;
}
+ (instancetype)sharedController
{
static _FBKVOSharedController *_controller = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_controller = [[_FBKVOSharedController alloc] init];
});
return _controller;
}
- (instancetype)init
{
self = [super init];
if (nil != self) {
NSHashTable *infos = [NSHashTable alloc];
#ifdef __IPHONE_OS_VERSION_MIN_REQUIRED
_infos = [infos initWithOptions:NSPointerFunctionsWeakMemory|NSPointerFunctionsObjectPointerPersonality capacity:0];
#elif defined(__MAC_OS_X_VERSION_MIN_REQUIRED)
if ([NSHashTable respondsToSelector:@selector(weakObjectsHashTable)]) {
_infos = [infos initWithOptions:NSPointerFunctionsWeakMemory|NSPointerFunctionsObjectPointerPersonality capacity:0];
} else {
// silence deprecated warnings
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
_infos = [infos initWithOptions:NSPointerFunctionsZeroingWeakMemory|NSPointerFunctionsObjectPointerPersonality capacity:0];
#pragma clang diagnostic pop
}
#endif
_lock = OS_SPINLOCK_INIT;
}
return self;
}
- (NSString *)debugDescription
{
NSMutableString *s = [NSMutableString stringWithFormat:@"<%@:%p", NSStringFromClass([self class]), self];
// lock
OSSpinLockLock(&_lock);
NSMutableArray *infoDescriptions = [NSMutableArray arrayWithCapacity:_infos.count];
for (_FBKVOInfo *info in _infos) {
[infoDescriptions addObject:info.debugDescription];
}
[s appendFormat:@" contexts:%@", infoDescriptions];
// unlock
OSSpinLockUnlock(&_lock);
[s appendString:@">"];
return s;
}
- (void)observe:(id)object info:(_FBKVOInfo *)info
{
if (nil == info) {
return;
}
// register info
OSSpinLockLock(&_lock);
[_infos addObject:info];
OSSpinLockUnlock(&_lock);
// add observer
[object addObserver:self forKeyPath:info->_keyPath options:info->_options context:(void *)info];
}
- (void)unobserve:(id)object info:(_FBKVOInfo *)info
{
if (nil == info) {
return;
}
// unregister info
OSSpinLockLock(&_lock);
[_infos removeObject:info];
OSSpinLockUnlock(&_lock);
// remove observer
[object removeObserver:self forKeyPath:info->_keyPath context:(void *)info];
}
- (void)unobserve:(id)object infos:(NSSet *)infos
{
if (0 == infos.count) {
return;
}
// unregister info
OSSpinLockLock(&_lock);
for (_FBKVOInfo *info in infos) {
[_infos removeObject:info];
}
OSSpinLockUnlock(&_lock);
// remove observer
for (_FBKVOInfo *info in infos) {
[object removeObserver:self forKeyPath:info->_keyPath context:(void *)info];
}
}
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
NSAssert(context, @"missing context keyPath:%@ object:%@ change:%@", keyPath, object, change);
_FBKVOInfo *info;
{
// lookup context in registered infos, taking out a strong reference only if it exists
OSSpinLockLock(&_lock);
info = [_infos member:(__bridge id)context];
OSSpinLockUnlock(&_lock);
}
if (nil != info) {
// take strong reference to controller
FBKVOController *controller = info->_controller;
if (nil != controller) {
// take strong reference to observer
id observer = controller.observer;
if (nil != observer) {
// dispatch custom block or action, fall back to default action
if (info->_block) {
info->_block(observer, object, change);
} else if (info->_action) {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
[observer performSelector:info->_action withObject:change withObject:object];
#pragma clang diagnostic pop
} else {
[observer observeValueForKeyPath:keyPath ofObject:object change:change context:info->_context];
}
}
}
}
}
@end
#pragma mark FBKVOController -
@implementation FBKVOController
{
NSMapTable *_objectInfosMap;
OSSpinLock _lock;
}
#pragma mark Lifecycle -
+ (instancetype)controllerWithObserver:(id)observer
{
return [[self alloc] initWithObserver:observer];
}
- (instancetype)initWithObserver:(id)observer retainObserved:(BOOL)retainObserved
{
self = [super init];
if (nil != self) {
_observer = observer;
NSPointerFunctionsOptions keyOptions = retainObserved ? NSPointerFunctionsStrongMemory|NSPointerFunctionsObjectPointerPersonality : NSPointerFunctionsWeakMemory|NSPointerFunctionsObjectPointerPersonality;
_objectInfosMap = [[NSMapTable alloc] initWithKeyOptions:keyOptions valueOptions:NSPointerFunctionsStrongMemory|NSPointerFunctionsObjectPersonality capacity:0];
_lock = OS_SPINLOCK_INIT;
}
return self;
}
- (instancetype)initWithObserver:(id)observer
{
return [self initWithObserver:observer retainObserved:YES];
}
- (void)dealloc
{
[self unobserveAll];
}
#pragma mark Properties -
- (NSString *)debugDescription
{
NSMutableString *s = [NSMutableString stringWithFormat:@"<%@:%p", NSStringFromClass([self class]), self];
[s appendFormat:@" observer:<%@:%p>", NSStringFromClass([_observer class]), _observer];
// lock
OSSpinLockLock(&_lock);
if (0 != _objectInfosMap.count) {
[s appendString:@"\n "];
}
for (id object in _objectInfosMap) {
NSMutableSet *infos = [_objectInfosMap objectForKey:object];
NSMutableArray *infoDescriptions = [NSMutableArray arrayWithCapacity:infos.count];
[infos enumerateObjectsUsingBlock:^(_FBKVOInfo *info, BOOL *stop) {
[infoDescriptions addObject:info.debugDescription];
}];
[s appendFormat:@"%@ -> %@", object, infoDescriptions];
}
// unlock
OSSpinLockUnlock(&_lock);
[s appendString:@">"];
return s;
}
#pragma mark Utilities -
- (void)_observe:(id)object info:(_FBKVOInfo *)info
{
// lock
OSSpinLockLock(&_lock);
NSMutableSet *infos = [_objectInfosMap objectForKey:object];
// check for info existence
_FBKVOInfo *existingInfo = [infos member:info];
if (nil != existingInfo) {
NSLog(@"observation info already exists %@", existingInfo);
// unlock and return
OSSpinLockUnlock(&_lock);
return;
}
// lazilly create set of infos
if (nil == infos) {
infos = [NSMutableSet set];
[_objectInfosMap setObject:infos forKey:object];
}
// add info and oberve
[infos addObject:info];
// unlock prior to callout
OSSpinLockUnlock(&_lock);
[[_FBKVOSharedController sharedController] observe:object info:info];
}
- (void)_unobserve:(id)object info:(_FBKVOInfo *)info
{
// lock
OSSpinLockLock(&_lock);
// get observation infos
NSMutableSet *infos = [_objectInfosMap objectForKey:object];
// lookup registered info instance
_FBKVOInfo *registeredInfo = [infos member:info];
if (nil != registeredInfo) {
[infos removeObject:registeredInfo];
// remove no longer used infos
if (0 == infos.count) {
[_objectInfosMap removeObjectForKey:object];
}
}
// unlock
OSSpinLockUnlock(&_lock);
// unobserve
[[_FBKVOSharedController sharedController] unobserve:object info:registeredInfo];
}
- (void)_unobserve:(id)object
{
// lock
OSSpinLockLock(&_lock);
NSMutableSet *infos = [_objectInfosMap objectForKey:object];
// remove infos
[_objectInfosMap removeObjectForKey:object];
// unlock
OSSpinLockUnlock(&_lock);
// unobserve
[[_FBKVOSharedController sharedController] unobserve:object infos:infos];
}
- (void)_unobserveAll
{
// lock
OSSpinLockLock(&_lock);
NSMapTable *objectInfoMaps = [_objectInfosMap copy];
// clear table and map
[_objectInfosMap removeAllObjects];
// unlock
OSSpinLockUnlock(&_lock);
_FBKVOSharedController *shareController = [_FBKVOSharedController sharedController];
for (id object in objectInfoMaps) {
// unobserve each registered object and infos
NSSet *infos = [objectInfoMaps objectForKey:object];
[shareController unobserve:object infos:infos];
}
}
#pragma mark API -
- (void)observe:(id)object keyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options block:(FBKVONotificationBlock)block
{
NSAssert(0 != keyPath.length && NULL != block, @"missing required parameters observe:%@ keyPath:%@ block:%p", object, keyPath, block);
if (nil == object || 0 == keyPath.length || NULL == block) {
return;
}
// create info
_FBKVOInfo *info = [[_FBKVOInfo alloc] initWithController:self keyPath:keyPath options:options block:block];
// observe object with info
[self _observe:object info:info];
}
- (void)observe:(id)object keyPaths:(NSArray *)keyPaths options:(NSKeyValueObservingOptions)options block:(FBKVONotificationBlock)block
{
NSAssert(0 != keyPaths.count && NULL != block, @"missing required parameters observe:%@ keyPath:%@ block:%p", object, keyPaths, block);
if (nil == object || 0 == keyPaths.count || NULL == block) {
return;
}
for (NSString *keyPath in keyPaths)
{
[self observe:object keyPath:keyPath options:options block:block];
}
}
- (void)observe:(id)object keyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options action:(SEL)action
{
NSAssert(0 != keyPath.length && NULL != action, @"missing required parameters observe:%@ keyPath:%@ action:%@", object, keyPath, NSStringFromSelector(action));
NSAssert([_observer respondsToSelector:action], @"%@ does not respond to %@", _observer, NSStringFromSelector(action));
if (nil == object || 0 == keyPath.length || NULL == action) {
return;
}
// create info
_FBKVOInfo *info = [[_FBKVOInfo alloc] initWithController:self keyPath:keyPath options:options action:action];
// observe object with info
[self _observe:object info:info];
}
- (void)observe:(id)object keyPaths:(NSArray *)keyPaths options:(NSKeyValueObservingOptions)options action:(SEL)action
{
NSAssert(0 != keyPaths.count && NULL != action, @"missing required parameters observe:%@ keyPath:%@ action:%@", object, keyPaths, NSStringFromSelector(action));
NSAssert([_observer respondsToSelector:action], @"%@ does not respond to %@", _observer, NSStringFromSelector(action));
if (nil == object || 0 == keyPaths.count || NULL == action) {
return;
}
for (NSString *keyPath in keyPaths)
{
[self observe:object keyPath:keyPath options:options action:action];
}
}
- (void)observe:(id)object keyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options context:(void *)context
{
NSAssert(0 != keyPath.length, @"missing required parameters observe:%@ keyPath:%@", object, keyPath);
if (nil == object || 0 == keyPath.length) {
return;
}
// create info
_FBKVOInfo *info = [[_FBKVOInfo alloc] initWithController:self keyPath:keyPath options:options context:context];
// observe object with info
[self _observe:object info:info];
}
- (void)observe:(id)object keyPaths:(NSArray *)keyPaths options:(NSKeyValueObservingOptions)options context:(void *)context
{
NSAssert(0 != keyPaths.count, @"missing required parameters observe:%@ keyPath:%@", object, keyPaths);
if (nil == object || 0 == keyPaths.count) {
return;
}
for (NSString *keyPath in keyPaths)
{
[self observe:object keyPath:keyPath options:options context:context];
}
}
- (void)unobserve:(id)object keyPath:(NSString *)keyPath
{
// create representative info
_FBKVOInfo *info = [[_FBKVOInfo alloc] initWithController:self keyPath:keyPath];
// unobserve object property
[self _unobserve:object info:info];
}
- (void)unobserve:(id)object
{
if (nil == object) {
return;
}
[self _unobserve:object];
}
- (void)unobserveAll
{
[self _unobserveAll];
}
@end

View File

@@ -0,0 +1,16 @@
//
// NSString+JsonToDic.h
// XChatFramework
//
// Created by 卫明何 on 2017/9/11.
// Copyright © 2017年 chenran. All rights reserved.
//
#import <Foundation/Foundation.h>
@interface NSString (JsonToDic)
+ (NSDictionary *)dictionaryWithJsonString:(NSString *)jsonString;
+ (id)idWithJsonString:(NSString *)str;
@end

View File

@@ -0,0 +1,61 @@
//
// NSString+JsonToDic.m
// XChatFramework
//
// Created by on 2017/9/11.
// Copyright © 2017 chenran. All rights reserved.
//
#import "NSString+JsonToDic.h"
@implementation NSString (JsonToDic)
+ (NSDictionary *)dictionaryWithJsonString:(NSString *)jsonString {
if (jsonString == nil) {
return nil;
}
NSData *jsonData = [jsonString dataUsingEncoding:NSUTF8StringEncoding];
NSError *err;
NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:jsonData
options:NSJSONReadingMutableContainers
error:&err];
if(err) {
NSLog(@"json解析失败%@",err);
return nil;
}
return dic;
}
+ (id)idWithJsonString:(NSString *)str {
if (!str) {
return nil;
}
NSError *error = nil;
id jsonObject = [NSJSONSerialization JSONObjectWithData:[str dataUsingEncoding:NSUTF8StringEncoding] options:NSJSONReadingAllowFragments
error:nil];
if (jsonObject != nil && error == nil){
return jsonObject;
}else{
//
return nil;
}
}
@end

View File

@@ -0,0 +1,72 @@
//
// YYWebResourceDownloader.h
// YYMobileFramework
//
// Created by wuwei on 14/6/12.
// Copyright (c) 2014年 YY Inc. All rights reserved.
//
#import <UIKit/UIKit.h>
typedef NS_OPTIONS(NSUInteger, YYWebResourceDownloaderOptions) {
YYWebResourceDownloaderProgressiveDownload = 1 << 1,
YYWebResourceDownloaderUseNSURLCache = 1 << 2,
YYWebResourceDownloaderIgnoreCachedResponse = 1 << 3,
YYWebResourceDownloaderContinueInBackground = 1 << 4,
YYWebResourceDownloaderHandleCookies = 1 << 5,
};
/**
* 下载的进度回调
*
* @param received
* @param expected
*/
typedef void(^YYWebResourceDownloaderProgressBlock)(int64_t received, int64_t expected, CGFloat progress);
/**
* 下载完成回调Block
*
* @param filePath 下载完成后文件的URL(fileURL)
* @param error 下载过程中的错误
* @param finished 是否完成
*/
typedef void(^YYWebResourceDownloaderCompletionBlock)(NSURL *filePath, NSError *error, BOOL finished);
@class YYWebResourceDownloader;
@class YYWebResourceDownloadOperation;
@interface YYWebResourceDownloadOperation : NSOperation
@end
NS_AVAILABLE_IOS(7_0) @interface YYWebResourceDownloader : NSObject
+ (instancetype)sharedDownloader;
/**
* The designated initializer
*
* @param name name of the downloader
*
* @return The initialized YYWebResourceDownloader instance
*/
- (instancetype)initWithName:(NSString *)name;
@property (nonatomic, strong, readonly) NSString *downloaderName;
// default is 15.0
@property (nonatomic, assign) NSTimeInterval downloadTimeout;
@property (nonatomic, strong) NSDictionary*(^headerFilter)(NSURL *url, NSDictionary *headers);
- (void)setValue:(NSString *)value forHTTPHeaderField:(NSString *)field;
- (NSString *)valueForHTTPHeaderField:(NSString *)field;
- (YYWebResourceDownloadOperation *)downloadWithURL:(NSURL *)url
fileName:(NSString *)fileName
options:(YYWebResourceDownloaderOptions)options
progress:(YYWebResourceDownloaderProgressBlock)progress
completion:(YYWebResourceDownloaderCompletionBlock)completion;
@end

View File

@@ -0,0 +1,415 @@
//
// YYWebResourceDownloader.m
// YYMobileFramework
//
// Created by wuwei on 14/6/12.
// Copyright (c) 2014 YY Inc. All rights reserved.
//
#import "YYWebResourceDownloader.h"
#import <AFURLSessionManager.h>
#import "FBKVOController.h"
#if TRAFFIC_DATA
#import "../../../../YYMobileCore/YYMobileCore/Cores/CoreManager.h"
#import "../../../../YYMobileCore/YYMobileCore/Cores/Carrier/ICarrierService.h"
#import "../../../../YYMobileCore/YYMobileCore/Cores/Carrier/CarrierServiceTypes.h"
#endif
#define ENABLE_UNICOM_PROXY 0
static NSString * const kProgressCallbackKey = @"progress";
static NSString * const kCompletionCallbackKey = @"completed";
#if TRAFFIC_DATA
extern NSString * const CarrierDataTrafficPackageSubscribeStateUpdateNotification;
#endif
static const NSTimeInterval kDefaultDownloadTimeout = 15.0f;
@interface YYWebResourceDownloadOperation ()
- (instancetype)initWithTask:(NSURLSessionTask *)task;
- (instancetype)initWithTask:(NSURLSessionTask *)task cancelledBlock:(dispatch_block_t)cancelBlock;
@end
@implementation YYWebResourceDownloadOperation
{
NSURLSessionTask *_task;
dispatch_block_t _cancelBlock;
}
- (instancetype)initWithTask:(NSURLSessionTask *)task {
self = [super init];
if (self) {
_task = task;
}
return self;
}
- (instancetype)initWithTask:(NSURLSessionTask *)task cancelledBlock:(dispatch_block_t)cancel
{
self = [self initWithTask:task];
if (self) {
_cancelBlock = cancel;
}
return self;
}
- (void)cancel {
[super cancel];
[_task cancel];
if (_cancelBlock) {
_cancelBlock();
}
}
@end
@interface YYWebResourceDownloader ()
@property (nonatomic, strong, readonly) AFURLSessionManager *sessionManager;
@property (nonatomic, strong) NSURLSessionConfiguration *sessionConfiguration;
@property (nonatomic, strong, readonly) dispatch_queue_t barrierQueue;
@property (nonatomic, strong, readonly) NSMutableDictionary *URLCallbacks;
@property (nonatomic, strong, readonly) NSMutableDictionary *HTTPHeaders;
@property (nonatomic, strong, readonly) NSMapTable *downloadingTasks;
@end
@implementation YYWebResourceDownloader
@synthesize barrierQueue = _barrierQueue;
@synthesize URLCallbacks = _URLCallbacks;
@synthesize HTTPHeaders =_HTTPHeaders;
@synthesize downloaderName = _downloaderName;
@synthesize sessionManager = _sessionManager;
+ (instancetype)sharedDownloader
{
static id instance;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
instance = [[self alloc] initWithName:@"default"];
});
return instance;
}
- (instancetype)initWithName:(NSString *)name
{
self = [super init];
if (self) {
_downloaderName = name;
_downloadingTasks = [NSMapTable strongToWeakObjectsMapTable];
#if TRAFFIC_DATA
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(OnCarrierDataTrafficPackageSubscribeStateUpdate:) name:CarrierDataTrafficPackageSubscribeStateUpdateNotification object:nil];
#endif
NSURLSessionConfiguration *defaultConfiguration = [NSURLSessionConfiguration defaultSessionConfiguration];
/*
defaultConfiguration.connectionProxyDictionary = @{
(NSString *)kCFStreamPropertyHTTPProxyHost: @"huanjushidai.gzproxy.10155.com",
(NSString *)kCFStreamPropertyHTTPProxyPort: @(8080)};
defaultConfiguration.HTTPAdditionalHeaders = @{@"Authorization": @"Basic MzAwMDAwNDU0NDo5OEI4NTU5MDI0ODYwQkE1NDE2MTUwNDM4NzA2NjdGMQ=="};
*/
_sessionManager = [[AFURLSessionManager alloc] initWithSessionConfiguration:defaultConfiguration];
_downloadTimeout = kDefaultDownloadTimeout;
_URLCallbacks = [NSMutableDictionary dictionary];
_HTTPHeaders = [NSMutableDictionary dictionary];
// Create a queue using the downloader name
name = name ? : @"<anonymous>";
NSString *queueName = [NSString stringWithFormat:@"com.yy.webResourceDownloader.%@.barrierQueue", name];
_barrierQueue = dispatch_queue_create([queueName UTF8String], DISPATCH_QUEUE_CONCURRENT);
static char kBarrierQueueSpecificKey;
dispatch_queue_set_specific(self.barrierQueue, &kBarrierQueueSpecificKey, (__bridge void *)self, NULL);
}
return self;
}
- (instancetype)init
{
return [self initWithName:nil];
}
- (void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
- (void)setValue:(NSString *)value forHTTPHeaderField:(NSString *)field
{
if (value) {
self.HTTPHeaders[field] = value;
}
else {
[self.HTTPHeaders removeObjectForKey:field];
}
}
- (NSString *)valueForHTTPHeaderField:(NSString *)field
{
return self.HTTPHeaders[field];
}
- (YYWebResourceDownloadOperation *)downloadWithURL:(NSURL *)url
fileName:(NSString *)fileName
options:(YYWebResourceDownloaderOptions)options
progress:(YYWebResourceDownloaderProgressBlock)progress
completion:(YYWebResourceDownloaderCompletionBlock)completion
{
#if TRAFFIC_DATA
//Session
if(!_sessionManager)
{
NSURLSessionConfiguration *defaultConfiguration = [NSURLSessionConfiguration defaultSessionConfiguration];
BOOL isDataTrafficeFree = [GetCoreI(ICarrierService) isDataTrafficFree];
if(isDataTrafficeFree)
{
CarrierProxyConfiguration* httpProxyConfiguration = [GetCoreI(ICarrierService) getProxyConfiguration];
if(httpProxyConfiguration)
{
defaultConfiguration.connectionProxyDictionary = @{ (NSString *)kCFStreamPropertyHTTPProxyHost: httpProxyConfiguration.serverAddress,
(NSString *)kCFStreamPropertyHTTPProxyPort: @(httpProxyConfiguration.serverPort)};
defaultConfiguration.HTTPAdditionalHeaders = @{@"Authorization": [NSString stringWithFormat:@"Basic %@", httpProxyConfiguration.authenticationString]};
}
self.sessionConfiguration = defaultConfiguration;
}
_sessionManager = [[AFURLSessionManager alloc] initWithSessionConfiguration:self.sessionConfiguration];
[_sessionManager setTaskWillPerformHTTPRedirectionBlock:^NSURLRequest *(NSURLSession *session, NSURLSessionTask *task, NSURLResponse *response, NSURLRequest *request) {
NSMutableURLRequest *redirectRequest = [request mutableCopy];
if(isDataTrafficeFree)
{
CarrierProxyConfiguration* httpProxyConfiguration = [GetCoreI(ICarrierService) getProxyConfiguration];
[redirectRequest addValue:[NSString stringWithFormat:@"Basic %@", httpProxyConfiguration.authenticationString] forHTTPHeaderField:@"Authorization"];
}
return redirectRequest;
}];
}
#endif
__block YYWebResourceDownloadOperation *downloadOperation = nil;
__weak YYWebResourceDownloader *wself = self;
[self _addProgressCallback:progress andCompletionBlock:completion forURL:url createCallback:^{
NSTimeInterval timeoutInterval = wself.downloadTimeout;
if (timeoutInterval == 0.0) {
timeoutInterval = kDefaultDownloadTimeout;
}
// In order to prevent from potential duplicate caching (NSURLCache + YYImageCache), we disable the cache for image requests if told otherwise
NSURLRequestCachePolicy cachePolicy = (options & YYWebResourceDownloaderUseNSURLCache) ? NSURLRequestUseProtocolCachePolicy : NSURLRequestReloadIgnoringLocalCacheData;
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url
cachePolicy:cachePolicy
timeoutInterval:timeoutInterval];
request.HTTPShouldHandleCookies = (options & YYWebResourceDownloaderHandleCookies);
request.HTTPShouldUsePipelining = YES;
if (wself.headerFilter) {
request.allHTTPHeaderFields = wself.headerFilter(url, [wself.HTTPHeaders copy]);
}
else {
request.allHTTPHeaderFields = [wself.HTTPHeaders copy];
}
__block NSProgress *progress;
__block FBKVOController *controller = [FBKVOController controllerWithObserver:wself];
__block NSURLSessionTask *sessionTask = [wself.sessionManager downloadTaskWithRequest:request progress:^(NSProgress * _Nonnull downloadProgress) {
progress = downloadProgress;
} destination:^NSURL * _Nonnull(NSURL * _Nonnull targetPath, NSURLResponse * _Nonnull response) {
// return [targetPath URLByAppendingPathExtension:@"download"];
NSString *fullPath;
if (fileName.length > 0 || fileName) {
fullPath = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:fileName];
}else {
fullPath = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:response.suggestedFilename];
}
return [NSURL fileURLWithPath:fullPath];
} completionHandler:^(NSURLResponse * _Nonnull response, NSURL * _Nullable filePath, NSError * _Nullable error) {
if (error) {
// [YYLogger debug:TAG(THTTP,TNetSend) message:@"[Task: %@] Download %@ failed with error %@", sessionTask, url, error];
} else {
// [YYLogger debug:TAG(THTTP,TNetSend) message:@"[Task: %@] Download %@ successfully, store to %@", sessionTask, url, filePath];
}
if (error.code == NSURLErrorCancelled) {
// CancelYYWebResourceOperationcancelBlock
return;
}
if (!wself) return; // return if deallocated
__strong __typeof__(wself) sself = wself;
NSArray *callbacksForURL = [sself _callbacksForURL:url];
[sself _removeCallbacksForURL:url];
for (NSDictionary *callbacks in callbacksForURL) {
YYWebResourceDownloaderCompletionBlock complete = callbacks[kCompletionCallbackKey];
if (complete) {
complete(filePath, error, YES);
}
}
//
[[NSFileManager defaultManager] removeItemAtURL:filePath error:nil];
// Remove KVO
controller = nil;
}];
// Observe the fractionCompleted property of the progress
[controller observe:progress keyPath:@"fractionCompleted" options:NSKeyValueObservingOptionNew block:^(id observer, id object, NSDictionary *change) {
if (!wself) return; // return if deallocated
__strong __typeof__(wself) sself = wself;
NSArray *callbacksForURL = [sself _callbacksForURL:url];
for (NSDictionary *callbacks in callbacksForURL) {
YYWebResourceDownloaderProgressBlock progressBlock = callbacks[kProgressCallbackKey];
if (progressBlock) {
progressBlock(progress.completedUnitCount, progress.totalUnitCount, progress.fractionCompleted);
}
}
}];
// [YYLogger debug:TAG(THTTP,TNetSend)message:@"[Task: %@] download %@ DID START!", sessionTask, url];
downloadOperation = [[YYWebResourceDownloadOperation alloc] initWithTask:sessionTask cancelledBlock:^{
__strong __typeof__(wself) sself = wself;
if (sself) {
[sself _removeCallbacksForURL:url];
}
}];
// [wself.downloadingTasks setObject:downloadOperation forKey:url];
// start the task
[sessionTask resume];
}];
return downloadOperation;
}
- (void)_addProgressCallback:(YYWebResourceDownloaderProgressBlock)progress
andCompletionBlock:(YYWebResourceDownloaderCompletionBlock)completion
forURL:(NSURL *)url
createCallback:(dispatch_block_t)createCallback
{
NSParameterAssert(createCallback);
if (url == nil) {
if (completion != nil) {
completion(nil, nil, NO);
}
return;
}
dispatch_barrier_sync(self.barrierQueue, ^{
BOOL first = NO;
if (!self.URLCallbacks[url]) {
self.URLCallbacks[url] = [NSMutableArray new];
first = YES;
}
id task = [self.downloadingTasks objectForKey:url];
// [YYLogger debug:TAG(THTTP,TNetSend) message:@"add Callbacks for url %@, existing task: %@, isFirst: %d", url, task, first];
// Handle single download of simulaneous download request for the same URL
NSMutableArray *callbacksForURL = self.URLCallbacks[url];
NSMutableDictionary *callbacks = [NSMutableDictionary new];
if (progress) {
callbacks[kProgressCallbackKey] = [progress copy];
}
if (completion) {
callbacks[kCompletionCallbackKey] = [completion copy];
}
[callbacksForURL addObject:callbacks];
self.URLCallbacks[url] = callbacksForURL;
if (first) {
createCallback();
}
});
}
- (NSArray *)_callbacksForURL:(NSURL *)url {
__block NSArray *callbacksForURL;
dispatch_sync(self.barrierQueue, ^{
callbacksForURL = self.URLCallbacks[url];
});
return [callbacksForURL copy];
}
- (void)_removeCallbacksForURL:(NSURL *)url {
dispatch_barrier_async(self.barrierQueue, ^{
[self.URLCallbacks removeObjectForKey:url];
});
}
#if TRAFFIC_DATA
-(void) OnCarrierDataTrafficPackageSubscribeStateUpdate:(NSNotification*)notification
{
CarrierProxyConfiguration* httpProxyConfiguration = [notification object];
if (httpProxyConfiguration && httpProxyConfiguration.serverAddress.length > 0)
{
NSURLSessionConfiguration *proxyConfiguration = [NSURLSessionConfiguration defaultSessionConfiguration];
proxyConfiguration.connectionProxyDictionary = @{ (NSString *)kCFStreamPropertyHTTPProxyHost: httpProxyConfiguration.serverAddress,
(NSString *)kCFStreamPropertyHTTPProxyPort: @(httpProxyConfiguration.serverPort)};
proxyConfiguration.HTTPAdditionalHeaders = @{@"Authorization": [NSString stringWithFormat:@"Basic %@", httpProxyConfiguration.authenticationString]};
self.sessionConfiguration = proxyConfiguration;
if(!_sessionManager)
{
return;
}
if([_sessionManager.tasks count] > 0)
{
[_sessionManager invalidateSessionCancelingTasks:false];
[[NSNotificationCenter defaultCenter] addObserverForName:AFURLSessionDidInvalidateNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(__unused NSNotification *note) {
[[NSNotificationCenter defaultCenter] removeObserver:self name:AFURLSessionDidInvalidateNotification object:nil];
_sessionManager = nil;
}];
}
else
{
_sessionManager = nil;
}
}
else
{
if(!self.sessionConfiguration)
return;
if([_sessionManager.tasks count] > 0)
{
[_sessionManager invalidateSessionCancelingTasks:false];
[[NSNotificationCenter defaultCenter] addObserverForName:AFURLSessionDidInvalidateNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(__unused NSNotification *note) {
[[NSNotificationCenter defaultCenter] removeObserver:self name:AFURLSessionDidInvalidateNotification object:nil];
self.sessionConfiguration = nil;
_sessionManager = nil;
}];
}
else
{
self.sessionConfiguration = nil;
_sessionManager = nil;
}
}
}
#endif
@end

View File

@@ -18,6 +18,8 @@ typedef NS_ENUM(NSUInteger, CustomMessageType) {
CustomMessageType_Account = 5,
///队列操作
CustomMessageType_Queue = 8,
///表情
CustomMessageType_Face = 9,
///全麦送
CustomMessageType_AllMicroSend = 12,
///座驾进房动画
@@ -81,6 +83,12 @@ typedef NS_ENUM(NSInteger, CustomMessageSubQueue) {
Custom_Message_Sub_Queue_Kick = 82,
};
//first = CustomMessageType_Face
typedef NS_ENUM(NSUInteger, CustomMessageSubFace) {
///发送
Custom_Message_Sub_Face_Send = 91,
};
///first = CustomMessageType_ALLMicroSend
typedef NS_ENUM(NSUInteger, CustomMessageSubAllMicroSend) {
///全麦送礼物

View File

@@ -0,0 +1,48 @@
//
// FaceConfigModel.h
// xplan-ios
//
// Created by GreenLand on 2022/1/7.
//
#import "NSObject+MJExtension.h"
#import "GiftNobleInfoModel.h"
typedef enum : NSUInteger {
XCFaceDisplayTypeOnlyOne = 0,
XCFaceDisplayTypeFlow = 1,
XCFaceDisplayTypeOverLay = 2,
XCFaceDisplayTypeOnlyOneLine = 3,
} XCFaceDisplayType;
typedef enum : NSUInteger {
XCFaceType_Face = 1,//1 正常表情,需要在表情面板显示
XCFaceType_Dragon = 2,// 2 龙珠
XCFaceType_PlayTogether = 3, //一起玩
} XCFaceType;
@interface FaceConfigInfo : NSObject
@property (nonatomic, assign) int id;
@property (nonatomic, copy) NSString *name;
@property (nonatomic, copy) NSString *pinyin;
@property (nonatomic, assign) NSInteger animDuration;
@property (nonatomic, assign) NSInteger animEndPos;
@property (nonatomic, assign) NSInteger animStartPos;
@property (nonatomic, assign) NSInteger iconPos;
@property (nonatomic, assign) NSInteger animRepeatCount;
@property (nonatomic, assign) NSInteger resultCount;
@property (nonatomic, assign) BOOL canResultRepeat;
@property (nonatomic, assign) NSInteger resultDuration;
@property (nonatomic, assign) NSInteger resultEndPos;
@property (nonatomic, assign) NSInteger resultStartPos;
@property (nonatomic, assign) NSInteger imageCount;
@property (nonatomic, assign) XCFaceDisplayType displayType;
@property (nonatomic, assign) BOOL isNobleFace; //是否贵族表情
@property (nonatomic, assign) int nobleId;//贵族等级
@property (nonatomic, assign) XCFaceType faceType;//1 正常表情,需要在表情面板显示, 2 龙珠 3.一起玩
@property (nonatomic, assign) BOOL isLuckFace;//YES 表示审核中需要隐藏的表情NO 审核中不需要隐藏的表情
///贵族表情信息
@property (nonatomic, strong) GiftNobleInfoModel *faceVipInfo;
@end

View File

@@ -0,0 +1,12 @@
//
// FaceConfigModel.m
// xplan-ios
//
// Created by GreenLand on 2022/1/7.
//
#import "FaceConfigInfo.h"
@implementation FaceConfigInfo
@end

View File

@@ -0,0 +1,23 @@
//
// FaceInfo.h
// BberryCore
//
// Created by 卫明何 on 2017/9/29.
// Copyright © 2017年 chenran. All rights reserved.
//
#import <Foundation/Foundation.h>
@interface FaceInfo : NSObject
@property (assign, nonatomic) NSInteger faceId;
@property (copy, nonatomic) NSString *faceName;
@property (assign, nonatomic) NSInteger faceParentId;
@property (copy, nonatomic) NSString *facePicUrl;
@property (assign, nonatomic) BOOL hasGifUrl;
@property (copy, nonatomic) NSString *faceGifUrl;
@property (assign, nonatomic) BOOL show;
@property (strong, nonatomic) NSArray *children;
@property (assign, nonatomic) NSInteger faceValue;
@end

View File

@@ -0,0 +1,19 @@
//
// FaceInfo.m
// BberryCore
//
// Created by on 2017/9/29.
// Copyright © 2017 chenran. All rights reserved.
//
#import "FaceInfo.h"
@implementation FaceInfo
+ (nullable NSDictionary<NSString *, id> *)modelContainerPropertyGenericClass{
return @{
@"children" : FaceInfo.class,
};
}
@end

View File

@@ -0,0 +1,16 @@
//
// FaceInfoStorage.h
// BberryCore
//
// Created by 卫明何 on 2017/9/29.
// Copyright © 2017年 chenran. All rights reserved.
//
#import <Foundation/Foundation.h>
@interface FaceInfoStorage : NSObject
+ (NSMutableArray *)getFaceInfos;
+ (void)saveFaceInfos:(NSString *)json;
@end

View File

@@ -0,0 +1,48 @@
//
// FaceInfoStorage.m
// BberryCore
//
// Created by on 2017/9/29.
// Copyright © 2017 chenran. All rights reserved.
//
#define kFileName @"FaceInfoList.data"
#define kDataKey @"faceInfos"
#define EncodeKey @"1ea53d260ecf11e7b56e00163e046a26123"
#import "FaceInfoStorage.h"
#import "FaceInfo.h"
#import "DESEncrypt.h"
#import "SSKeychain.h"
#import "FaceConfigInfo.h"
#import <MJExtension/MJExtension.h>
@implementation FaceInfoStorage
+ (NSString *)getFilePath {
NSArray *array = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *path = [[array objectAtIndex:0] stringByAppendingPathComponent:kFileName];
if (![[NSFileManager defaultManager] fileExistsAtPath:path]) {
[[NSFileManager defaultManager] createFileAtPath:path contents:nil attributes:nil];
}
return path;
}
+ (NSMutableArray *)getFaceInfos{
NSMutableArray *faceInfos = [NSMutableArray array];
NSString *encodeJson = [SSKeychain passwordForService:@"json" account:@"face"];
NSString *decodeJson = [DESEncrypt decryptUseDES:encodeJson key:EncodeKey];
if (decodeJson.length > 0) {
// faceInfos = [[NSArray yy_modelArrayWithClass:[FaceConfigModel class] json:decodeJson] mutableCopy];
faceInfos = [[FaceConfigInfo modelsWithArray:decodeJson] mutableCopy];
}
return faceInfos;
}
+ (void)saveFaceInfos:(NSString *)json {
NSString *encodeJson = [DESEncrypt encryptUseDES:json key:EncodeKey];
[SSKeychain setPassword:encodeJson forService:@"json" account:@"face"];
}
@end

View File

@@ -0,0 +1,18 @@
//
// FacePlayInfo.h
// BberryCore
//
// Created by 卫明何 on 2017/9/29.
// Copyright © 2017年 chenran. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "FaceReceiveInfo.h"
@interface FacePlayInfo : NSObject
@property (assign, nonatomic) double delay;
@property (strong, nonatomic) NIMMessage *message;
@property (strong, nonatomic) FaceReceiveInfo *faceReceiveInfo;
@end

View File

@@ -0,0 +1,13 @@
//
// FacePlayInfo.m
// BberryCore
//
// Created by on 2017/9/29.
// Copyright © 2017 chenran. All rights reserved.
//
#import "FacePlayInfo.h"
@implementation FacePlayInfo
@end

View File

@@ -0,0 +1,19 @@
//
// FaceReceiveInfo.h
// BberryCore
//
// Created by 卫明何 on 2017/9/29.
// Copyright © 2017年 chenran. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "AttachmentModel.h"
@interface FaceReceiveInfo : NSObject
@property (assign, nonatomic)long long uid;
@property (copy, nonatomic) NSString *nick;
@property (assign, nonatomic) NSInteger faceId;
@property (strong, nonatomic) UIImage *resultImage;
@property (strong, nonatomic) NSMutableArray *resultIndexes;//骰子数
@end

View File

@@ -0,0 +1,13 @@
//
// FaceReceiveInfo.m
// BberryCore
//
// Created by on 2017/9/29.
// Copyright © 2017 chenran. All rights reserved.
//
#import "FaceReceiveInfo.h"
@implementation FaceReceiveInfo
@end

View File

@@ -0,0 +1,17 @@
//
// FaceSendInfo.h
// BberryCore
//
// Created by 卫明何 on 2017/9/29.
// Copyright © 2017年 chenran. All rights reserved.
//
#import <Foundation/Foundation.h>
#import <NIMSDK/NIMSDK.h>
@interface FaceSendInfo : NSObject<NIMCustomAttachment>
@property (strong, nonatomic) NSArray *data; //faceRecieveInfos
@property (assign, nonatomic) long long uid;
@property (copy, nonatomic) NSDictionary *encodeAttachemt;
@end

View File

@@ -0,0 +1,32 @@
//
// FaceSendInfo.m
// BberryCore
//
// Created by on 2017/9/29.
// Copyright © 2017 chenran. All rights reserved.
//
#import "FaceSendInfo.h"
#import "FaceInfo.h"
#import "FaceReceiveInfo.h"
//#import "NSObject+YYModel.h"
@implementation FaceSendInfo
- (NSDictionary *)encodeAttachemt {
NSDictionary *dict = @{
@"data" : self.data,
@"uid" : @(self.uid)
};
return dict;
}
+ (nullable NSDictionary<NSString *, id> *)modelContainerPropertyGenericClass{
return @{
@"data" : [FaceReceiveInfo class],
};
}
@end

View File

@@ -5,11 +5,22 @@
// Created by GreenLand on 2021/12/28.
//
#import <Foundation/Foundation.h>
#import "BaseMvpPresenter.h"
#import <NIMSDK/NIMSDK.h>
NS_ASSUME_NONNULL_BEGIN
@interface XPFacePresenter : NSObject
@class FaceConfigInfo, UserInfoModel;
@interface XPFacePresenter : BaseMvpPresenter
/**
单独发表情
@param faceInfo 表情信息
@param roomId 房间ID
@param sendUser 发送人信息
*/
- (void)sendFace:(FaceConfigInfo *)faceInfo roomId:(long long)roomId sendUser:(UserInfoModel *)sendUser member:(NIMChatroomMember *)member;
@end

View File

@@ -6,7 +6,189 @@
//
#import "XPFacePresenter.h"
///Tool
#import "NSString+JsonToDic.h"
#import "NSObject+MJExtension.h"
#import <MJExtension/MJExtension.h>
//#import "AccountInfoStorage.h"
//#import "XPGiftStorage.h"
//#import "Api+Gift.h"
///Model
#import "FaceReceiveInfo.h"
#import "FaceConfigInfo.h"
#import "FaceSendInfo.h"
#import "UserInfoModel.h"
///P
#import "XPFaceProtocol.h"
@interface XPFacePresenter ()
///
@property (nonatomic,weak) id view;
@end
@implementation XPFacePresenter
///
- (void)attatchView:(id)view {
self.view = view;
}
- (id)getView {
return self.view;
}
//
- (void)sendFace:(FaceConfigInfo *)faceInfo roomId:(long long)roomId sendUser:(UserInfoModel *)sendUser member:(NIMChatroomMember *)member {
if (roomId) {
FaceReceiveInfo *faceRecieveInfo = [[FaceReceiveInfo alloc]init];
NSMutableArray *resultIndexs = [NSMutableArray array];
if (faceInfo.resultStartPos > 0 && faceInfo.resultEndPos > 0) {
int value;
if (faceInfo.canResultRepeat) { //
for (int i = 0; i < faceInfo.resultCount; i++) {
value = [self getRandomNumber:(short)faceInfo.resultStartPos to:(short)faceInfo.resultEndPos];
[resultIndexs addObject:@(value)];
faceRecieveInfo.resultIndexes = [resultIndexs copy];
}
}else {
faceRecieveInfo.resultIndexes = [[self randomArray:(short)faceInfo.resultStartPos to:(short)faceInfo.resultEndPos count:(short)faceInfo.resultCount] mutableCopy];
}
}
NSMutableArray *faceRecieveInfos = [NSMutableArray array];
faceRecieveInfo.nick = sendUser.nick;
faceRecieveInfo.faceId = faceInfo.id;
faceRecieveInfo.uid = sendUser.uid;
[faceRecieveInfos addObject:faceRecieveInfo];
FaceSendInfo *sendInfo = [[FaceSendInfo alloc]init];
sendInfo.data = [FaceReceiveInfo mj_keyValuesArrayWithObjectArray:faceRecieveInfos];
sendInfo.uid = sendUser.uid;
AttachmentModel *attachment = [[AttachmentModel alloc]init];
attachment.first = CustomMessageType_Face;
attachment.second = Custom_Message_Sub_Face_Send;
attachment.data = [sendInfo encodeAttachemt];
NSString *sessionID = [NSString stringWithFormat:@"%lld",roomId];
[self sendCustomMessageAttachement:attachment sessionId:sessionID type:NIMSessionTypeChatroom member:member];
}
}
///
- (void)sendCustomMessageAttachement:(AttachmentModel *)attachment sessionId:(NSString *)sessionId type:(NIMSessionType)type member:(NIMChatroomMember *)member {
NIMMessage *message = [[NIMMessage alloc]init];
//yidun
NIMAntiSpamOption *option = [NIMAntiSpamOption new];
option.yidunEnabled = NO;
NSMutableDictionary *meRoomExt = nil;
meRoomExt = [[NSString dictionaryWithJsonString:member.roomExt] mutableCopy];
NIMCustomObject *customObject = [[NIMCustomObject alloc]init];
customObject.attachment = attachment;
message.messageObject = customObject;
// NSMutableDictionary *memberExtDic = [GetCore(ImRoomCoreV2) queryOnMicroMemberExt];
NSMutableDictionary *realMeExt = meRoomExt;
[realMeExt removeObjectForKey:@"banner"];
[realMeExt removeObjectForKey:@"open_effect"];
[realMeExt removeObjectForKey:@"halo"];
[realMeExt removeObjectForKey:@"headwear"];
[realMeExt removeObjectForKey:@"recommend"];
[realMeExt removeObjectForKey:@"pic"];
[realMeExt removeObjectForKey:@"cardbg"];
[realMeExt removeObjectForKey:@"zonebg"];
// [memberExtDic setValuesForKeysWithDictionary:meRoomExt];
if (type == NIMSessionTypeChatroom) {
message.remoteExt = meRoomExt;
}
message.antiSpamOption = option;
NIMMessageSetting *setting = [[NIMMessageSetting alloc]init];
message.setting = setting;
//
NIMSession *session = [NIMSession session:sessionId type:type];
[[NIMSDK sharedSDK].chatManager sendMessage:message toSession:session error:nil];
}
- (void)sendMessageCollectionRequestWithMessage:(NIMMessage *)message firstAttachment:(int)firstAttachment {
// if (GetCore(ClientCore).reportSwitch) {
//
// int remoteDataLength;
// if (message.remoteExt) {
// NSData *remoteData = [NSJSONSerialization dataWithJSONObject:message.remoteExt options:0 error:nil];
// remoteDataLength = (int)remoteData.length;
// }else {
// remoteDataLength = 0;
// }
//
// int messageTextDataLength;
// if (message.text) {
// NSData *messageTextData = [message.text dataUsingEncoding:NSUTF8StringEncoding];
// messageTextDataLength = (int)messageTextData.length;
// }else {
// messageTextDataLength = 0;
// }
//
// int messageSize = (int)(messageTextDataLength + sizeof(message.messageObject) + remoteDataLength);
//
// self.messageCollectionDict = @{
// @"uid":@([message.from intValue]),
// @"sessionType":@(message.session.sessionType),
// @"sessionId":@([message.session.sessionId intValue]),
// @"packetSize":@(messageSize),
// @"messageType":@(message.messageType),
// @"chatroomMemberNumber":@(GetCore(ImRoomCoreV2).onlineNumber),
// @"attachementId":@(firstAttachment)
// };
// }
}
#pragma mark - private
/**
@param from
@param to
@return
*/
- (int)getRandomNumber:(int)from to:(int)to {
return (int)(from + (arc4random() % (to - from + 1)));
}
/**
@param from
@param to
@param count
@return
*/
- (NSArray *)randomArray:(int)from to:(int)to count:(int)count {
//
NSMutableArray *startArray= [NSMutableArray array];
for (int i = from; i <= to; i++) {
[startArray addObject:@(i)];
}
//
NSMutableArray *resultArray=[[NSMutableArray alloc] initWithCapacity:0];
//
NSInteger m = count;
for (int i=0; i<m; i++) {
int t = arc4random()%startArray.count;
resultArray[i]=startArray[t];
startArray[t]=[startArray lastObject]; //
[startArray removeLastObject];
}
return resultArray;
}
@end

View File

@@ -0,0 +1,16 @@
//
// XPFaceProtocol.h
// xplan-ios
//
// Created by GreenLand on 2022/1/8.
//
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface XPFaceProtocol : NSObject
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,12 @@
//
// XPFaceProtocol.m
// xplan-ios
//
// Created by GreenLand on 2022/1/8.
//
#import "XPFaceProtocol.h"
@implementation XPFaceProtocol
@end

View File

@@ -10,6 +10,13 @@
@class FaceConfigInfo;
@protocol XCGameRoomFaceContainerCellDelegate <NSObject>
///选中的表情
- (void)onSelectFace:(FaceConfigInfo *)faceInfo;
@end
@interface XCGameRoomFaceContainerCell : UICollectionViewCell
/**
@@ -22,4 +29,6 @@
*/
@property (strong, nonatomic) NSMutableArray<FaceConfigInfo *> *faceInfos;
@property (nonatomic, weak) id<XCGameRoomFaceContainerCellDelegate> delegate;
@end

View File

@@ -24,6 +24,8 @@
//tool
//#import "XCAlertControllerCenter.h"
#import "XPFaceParser.h"
#import "NSArray+Lookin.h"
@interface XCGameRoomFaceContainerCell()
@@ -79,12 +81,15 @@ UICollectionViewDelegateFlowLayout
#pragma mark - UICollectionViewDelegate
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath {
self.currentIndexPath = indexPath;
// FaceConfigInfo *info = [self.faceInfos safeObjectAtIndex:indexPath.row];
//
// if (![GetCore(FaceCore) getShowingFace]) {
FaceConfigInfo *info = [self.faceInfos lookin_safeObjectAtIndex:indexPath.row];
if (![[XPFaceParser shareParser] getShowingFace]) {
if (self.delegate && [self.delegate respondsToSelector:@selector(onSelectFace:)]) {
[self.delegate onSelectFace:info];
}
// [GetCore(FaceCore) sendFace:info];
// [[XCAlertControllerCenter defaultCenter]dismissAlertNeedBlock:NO];
// }
}
}
#pragma mark - UICollectionViewDataSource
@@ -103,9 +108,9 @@ UICollectionViewDelegateFlowLayout
FaceConfigInfo *info = self.faceInfos[indexPath.row];
//
// UIImage *face = [GetCore(FaceCore) findFaceIconImageById:info.id];
// [cell.faceImageView setImage:face];
// [cell.faceName setText:info.name];
UIImage *face = [[XPFaceParser shareParser] findFaceIconImageById:info.id];
[cell.faceImageView setImage:face];
[cell.faceName setText:info.name];
cell.nobleTagImageView.hidden = YES;
}

View File

@@ -15,18 +15,15 @@
///Third
#import <Masonry/Masonry.h>
#import "NSArray+Lookin.h"
#import <ReactiveObjC/ReactiveObjC.h>
///tool
#import "XPMacro.h"
//core
//#import "FaceCore.h"
//#import "VersionCore.h"
//client
//#import "FaceSourceClient.h"
#import "XPFaceParser.h"
///P
#import "XPFacePresenter.h"
//model
//#import "FaceInfo.h"
#import "UserInfoModel.h"
#import "RoomInfoModel.h"
//#import "FaceConfigInfo.h"
//#import "AuthCore.h"
//#import "UserCore.h"
@@ -51,7 +48,8 @@
UICollectionViewDelegate,
UICollectionViewDataSource,
UICollectionViewDelegateFlowLayout,
UIScrollViewDelegate
UIScrollViewDelegate,
XCGameRoomFaceContainerCellDelegate
>
/**
@@ -96,6 +94,10 @@
///uid
@property (nonatomic,copy) NSString *roomUid;
@property (nonatomic,strong) XPFacePresenter *facePresenter;
@property (nonatomic, strong) NIMChatroomMember *myMember;
@end
@implementation XPRoomFaceView
@@ -106,7 +108,6 @@
self.roomUid = uid;
[self initView];
// [self addCore];
[self initConstrations];
}
return self;
@@ -183,6 +184,8 @@
((XCGameRoomFaceTitleCell *)cell).displayModel = [self.displayModel.titles lookin_safeObjectAtIndex:indexPath.row];
}else if ([cell isKindOfClass:[XCGameRoomFaceContainerCell class]]) {
((XCGameRoomFaceContainerCell *)cell).faceInfos = [self.faceInfos lookin_safeObjectAtIndex:indexPath.section];
XCGameRoomFaceContainerCell *faceCell = (XCGameRoomFaceContainerCell *)cell;
faceCell.delegate = self;
}
}
@@ -218,6 +221,12 @@
self.pageControl.currentPage = intPage;
}
#pragma mark - XCGameRoomFaceContainerCellDelegate
///
- (void)onSelectFace:(FaceConfigInfo *)faceInfo {
[self.facePresenter sendFace:faceInfo roomId:[self.delegate getRoomInfo].roomId sendUser:[self.delegate getUserInfo] member:self.myMember];
}
#pragma mark - FaceSourceClient
- (void)loadFaceSourceSuccess {
@@ -248,11 +257,11 @@
[self.faceCollectionView registerClass:[XCGameRoomFaceCell class] forCellWithReuseIdentifier:@"XCGameRoomFaceCell"];
[self.faceCollectionView registerClass:[XCGameRoomFaceContainerCell class] forCellWithReuseIdentifier:@"XCGameRoomFaceContainerCell"];
// if (GetCore(FaceCore).isLoadFace) {
// [self loadFace];
// }else {
if ([XPFaceParser shareParser].isLoadFace) {
[self loadFace];
}else {
// [UIView showToastInKeyWindow:@"表情准备中" duration:3.0 position:(YYToastPosition)YYToastPositionBottomWithRecordButton];
// }
}
}
- (void)initConstrations {
@@ -314,7 +323,7 @@
// hard code =1
__block NSUInteger nobleLevel = 1;
// if (self.userInfo == nil) {
// if (self.delegate.getUserInfo == nil) {
// [[GetCore(UserCore) getUserInfoByRac:GetCore(AuthCore).getUid.userIDValue refresh:NO] subscribeNext:^(id x) {
// if ([x isKindOfClass:UserInfo.class]) {
// self.userInfo = x;
@@ -332,7 +341,7 @@
self.faceInfos = [[self nobleFaceFilterByNobleLevel:nobleLevel] mutableCopy];
}else{
// self.faceInfos = [GetCore(FaceCore) getFaceInfosType:RoomFaceTypeNormal];
self.faceInfos = [[XPFaceParser shareParser] getFaceInfosType:RoomFaceTypeNormal];
}
self.pageControl.hidden = NO;
@@ -340,7 +349,14 @@
[self.faceCollectionView reloadData];
}
- (void)getMember {
[[self rac_queryChartRoomMemberByUid:[NSString stringWithFormat:@"%zd",self.delegate.getUserInfo.uid]] subscribeNext:^(id x) {
NIMChatroomMember *roomOwner = x;
if (roomOwner.isOnline) {
self.myMember = roomOwner;
}
}];
}
/**
@@ -349,31 +365,55 @@
@return
*/
- (NSArray<FaceConfigInfo *> *)nobleFaceFilterByNobleLevel:(NSUInteger)level {
// NSArray *faces = [[[GetCore(FaceCore) getFaceInfosType:RoomFaceTypeNoble] copy] firstObject];
// if (faces.count == 0) {
// return @[];
// }
//
// //
// if (level < 1) {
// level = 1;
// }
//
// NSMutableArray *mArray = [NSMutableArray array];
// for (FaceConfigInfo *face in faces) {
// if (face.nobleId <= level) {
// [mArray addObject:face];
// }
// }
NSArray *faces = [[[[XPFaceParser shareParser] getFaceInfosType:RoomFaceTypeNoble] copy] firstObject];
if (faces.count == 0) {
return @[];
}
//
if (level < 1) {
level = 1;
}
NSMutableArray *mArray = [NSMutableArray array];
for (FaceConfigInfo *face in faces) {
if (face.nobleId <= level) {
[mArray addObject:face];
}
}
NSArray *conbineArray = @[];
// if (mArray.count > 0) {
// conbineArray = @[[mArray copy]];
// }
if (mArray.count > 0) {
conbineArray = @[[mArray copy]];
}
return conbineArray;
}
//uidchartroommember
- (RACSignal *)rac_queryChartRoomMemberByUid:(NSString *)uid {
if (uid == nil || uid.length<=0) return nil;
return [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
NIMChatroomMembersByIdsRequest *request = [[NIMChatroomMembersByIdsRequest alloc]init];
request.roomId = [NSString stringWithFormat:@"%zd", self.delegate.getRoomInfo.roomId];
request.userIds = @[uid];
[[NIMSDK sharedSDK].chatroomManager fetchChatroomMembersByIds:request completion:^(NSError * _Nullable error, NSArray<NIMChatroomMember *> * _Nullable members) {
if (error == nil) {
[subscriber sendNext:members.firstObject];
[subscriber sendCompleted];
}else {
[subscriber sendNext:nil];
}
}];
return nil;
}];
}
#pragma mark - Getter & Setter
- (void)setDelegate:(id<RoomHostDelegate>)delegate {
_delegate = delegate;
[self getMember];
}
- (UICollectionView *)titlesCollectionView {
if (!_titlesCollectionView) {
@@ -450,4 +490,12 @@
}
}
- (XPFacePresenter *)facePresenter {
if (!_facePresenter) {
_facePresenter = [[XPFacePresenter alloc] init];
[_facePresenter attatchView:self];
}
return _facePresenter;
}
@end

View File

@@ -0,0 +1,155 @@
//
// XPFaceParser.h
// xplan-ios
//
// Created by GreenLand on 2022/1/8.
//
#import <Foundation/Foundation.h>
#import "FaceInfo.h"
#import "FaceConfigInfo.h"
#import "AttachmentModel.h"
#import "XCGameRoomFaceTitleDisplayModel.h"
NS_ASSUME_NONNULL_BEGIN
@interface XPFaceParser : NSObject
+ (instancetype)shareParser;
- (void)getFaceDataSuccess:(NSArray *)array;
@property (copy, nonatomic) NSString *version;
@property (copy, nonatomic) NSString *zipMd5;
@property (strong, nonatomic) NSURL *zipUrl;
@property (assign, nonatomic) BOOL isShowingFace;
@property (copy, nonatomic) NSString *destinationUrl;
@property (assign, nonatomic) BOOL isLoadFace;
@property (nonatomic, strong) FaceConfigInfo *dragonConfigInfo;//龙族资源
@property (nonatomic, assign) BOOL isSendingDragon;//是否正在发送 龙珠 也就是是否 发送云信消息 成功
@property (nonatomic, assign) BOOL canPlayTogether; //是否可以一起玩
/**
清除表情的内存缓存(收到内存警告的时候使用)
*/
- (void)cleanFaceMemoryCache;
/**
获取表情列表
@return 表情列表
*/
- (NSMutableArray *)getFaceInfosType:(RoomFaceType)faceType;
/**
是否正在播放表情
@return return value description
*/
- (BOOL)getShowingFace;
/**
群发表情
@param faceInfo 表情信息
*/
- (void)sendAllFace:(FaceConfigInfo *)faceInfo;
/**
发送表情给cp
@param faceInfo 表情信息
*/
- (void)sendToCpFace:(FaceConfigInfo *)faceInfo;
/**
发送龙珠
@param state 龙珠状态
*/
//- (void)sendDragonWithState:(CustomNotificationDragon)state;
/**
获取一起玩表情(骰子)
@return 表情信息
*/
- (FaceConfigInfo *)getPlayTogetherFace;
/**
通过表情ID找表情
@param faceId 表情ID
@return 表情信息
*/
- (FaceConfigInfo *)findFaceInfoById:(NSInteger)faceId;
/**
通过表情ID查到图片对象
@param faceId 表情ID
@return 表情图片对象
*/
- (UIImage *)findFaceIconImageById:(NSInteger)faceId;
/**
通过表情ID与Index找图片对象
@param faceId 表情ID
@param index 表情Index
@return 表情对象
*/
- (UIImage *)findFaceImageById:(NSInteger)faceId index:(NSInteger)index;
/**
通过表情ConfigInfo查找图片
@param configInfo 表情配置
@param index 位置pos
@return 表情图片对象
*/
- (UIImage *)findFaceImageByConfig:(FaceConfigInfo *)configInfo index:(NSInteger)index;
/**
通过Config查找图片数组
@param configInfo 表情配置
@return 表情图片对象数组
*/
- (NSMutableArray<UIImage *> *)findFaceFrameArrByConfig:(FaceConfigInfo *)configInfo;
/**
通过FaceId查找图片对象数组
@param faceId 表情ID
@return 图片对象数组
*/
- (NSMutableArray<UIImage *> *)findFaceFrameArrByFaceId:(NSInteger)faceId;
/**
请求Face数据
*/
//- (void)requestFaceJson;
/**
测试使用接口,发送一起玩表情
*/
- (void)startFaceTimer;
- (void)cancelFaceTimer;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,855 @@
//
// XPFaceParser.m
// xplan-ios
//
// Created by GreenLand on 2022/1/8.
//
#import "XPFaceParser.h"
#import "FaceInfoStorage.h"
#import "FaceReceiveInfo.h"
#import "FaceSendInfo.h"
#import "FaceInfo.h"
//#import "RoomInfo.h"
#import "FacePlayInfo.h"
#import "FaceConfigInfo.h"
///tool
#import "YYWebResourceDownloader.h"
#import "CommonFileUtils.h"
#import "SSKeychain.h"
#import "SSZipArchive.h"
#import <ReactiveObjC/ReactiveObjC.h>
#import "GCDHelper.h"
///third
#import "NSObject+MJExtension.h"
#import <MJExtension/MJExtension.h>
// model
#import "AttachmentModel.h"
//#import "NSObject+YYModel.h"
//#import "VersionCore.h"
//#import "ImRoomCoreV2.h"
//#import "RoomCoreV2.h"
//#import "UserCore.h"
//#import "AuthCore.h"
//#import "ImMessageCore.h"
//#import "ImMessageCoreClient.h"
//#import "FaceCoreClient.h"
//#import "FaceSourceClient.h"
//#import "AuthCoreClient.h"
//#import "AppInitClient.h"
@interface XPFaceParser()
<
SSZipArchiveDelegate
>
#define RETRYCOUNT 5;
@property(nonatomic, strong)NSMutableArray *faceInfos; //FaceConfigInfo
@property(nonatomic, strong)NSMutableArray *tempFaceInfos; //zipfaceInfos
@property (nonatomic ,strong)dispatch_source_t timer;
@property (nonatomic ,strong)dispatch_source_t testTimer; //
@property(atomic, strong)NSMutableArray *receiveFace;
@property (strong, nonatomic) NSCache *faceCache;
@property (nonatomic, assign) NSInteger *requestJsonCount; //json
@property (nonatomic,assign) NSInteger retryDelay;
@end
@implementation XPFaceParser
{
dispatch_queue_t zipQueue;
}
+ (instancetype)shareParser {
static dispatch_once_t onceToken;
static XPFaceParser * parser;
dispatch_once(&onceToken, ^{
parser = [[XPFaceParser alloc] init];
});
return parser;
}
- (instancetype)init {
self = [super init];
if (self) {
// AddCoreClient(ImMessageCoreClient, self);
// AddCoreClient(AuthCoreClient, self);
// AddCoreClient(AppInitClient, self);
zipQueue = dispatch_queue_create("com.yy.face.xcface.unzipFace", DISPATCH_QUEUE_SERIAL);
_faceInfos = [FaceInfoStorage getFaceInfos];
}
return self;
}
//- (void)dealloc {
// RemoveCoreClientAll(self);
//}
- (void)cleanFaceMemoryCache {
[self.faceCache removeAllObjects];
}
- (void)faceDownloadManager {
NSString *version = [[NSUserDefaults standardUserDefaults]objectForKey:@"faceJsonVersion"];
if (version) {
if ([version integerValue] < [self.version integerValue]) {
[self downloadZipForFace];
return;
}else {
self.isLoadFace = YES;
[self syncTheTmpJsonToNormalJson];//save
self.destinationUrl = [self getDestinationUrlStr];
// NotifyCoreClient(FaceSourceClient, @selector(loadFaceSourceSuccess), loadFaceSourceSuccess);
}
}else {
[self downloadZipForFace];
}
}
- (void)syncTheTmpJsonToNormalJson {
self.faceInfos = [self.tempFaceInfos mutableCopy];
// [[self.faceInfos model2dictionary] toJSONString]
// NSData *data = [NSJSONSerialization dataWithJSONObject:self.faceInfos options:NSJSONWritingPrettyPrinted error:nil];
// NSString *str = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSArray *array = [FaceConfigInfo mj_keyValuesArrayWithObjectArray:self.faceInfos];
[FaceInfoStorage saveFaceInfos:[array toJSONString]];
}
- (void)downloadZipForFace {
if ([self.zipUrl absoluteString].length > 0 && [[self.zipUrl absoluteString] containsString:@"http"]) {
@weakify(self);
[[YYWebResourceDownloader sharedDownloader]downloadWithURL:self.zipUrl fileName:@"face.zip" options:(YYWebResourceDownloaderOptions)YYWebResourceDownloaderProgressiveDownload progress:^(int64_t received, int64_t expected, CGFloat progress) {
} completion:^(NSURL *filePath, NSError *error, BOOL finished) {
@strongify(self);
if (error == nil) {
NSString *desPath = [self getFaceImagePath];
[CommonFileUtils createDirForPath:desPath];
NSString *filePathStr = [filePath path];
NSString *fileMD5Str = [CommonFileUtils getFileMD5WithPath:filePathStr];
fileMD5Str = [fileMD5Str uppercaseString];
if (![self.zipMd5 isEqualToString:fileMD5Str]) { //MD5
[self performSelector:@selector(downloadZipForFace) withObject:nil afterDelay:3];
}else {
dispatch_async(self->zipQueue, ^{ //线
[SSZipArchive unzipFileAtPath:filePathStr toDestination:desPath overwrite:YES password:nil progressHandler:^(NSString * _Nonnull entry, unz_file_info zipInfo, long entryNumber, long total) {
} completionHandler:^(NSString * _Nonnull path, BOOL succeeded, NSError * _Nullable error) {
dispatch_main_sync_safe(^{
if (succeeded) {
self.isLoadFace = YES;
[self syncTheTmpJsonToNormalJson];
self.destinationUrl = [self getDestinationUrlStr];
[[NSUserDefaults standardUserDefaults]setObject:self.version forKey:@"faceJsonVersion"];
// NotifyCoreClient(FaceSourceClient, @selector(loadFaceSourceSuccess), loadFaceSourceSuccess);
}else {
[self performSelector:@selector(downloadZipForFace) withObject:nil afterDelay:3];
}
});
}];
});
}
}else {
[self performSelector:@selector(downloadZipForFace) withObject:nil afterDelay:3];
}
}];
}else {
self.isLoadFace = NO;
}
}
- (NSString *)getFaceImagePath {
NSString *path = @"Documents/Face/";
NSString *savePath = [NSHomeDirectory() stringByAppendingPathComponent:path];
return savePath;
}
- (NSString *)getDestinationUrlStr {
NSString *path = @"Documents/Face/";
NSString *savePath = [NSHomeDirectory() stringByAppendingPathComponent:path];
NSFileManager *fm = [NSFileManager defaultManager];
NSArray *arr = [fm contentsOfDirectoryAtPath:savePath error:nil];
NSMutableArray *tempArr = [NSMutableArray array];
for (NSString *item in arr) {
if (![item containsString:@"."]) {
[tempArr addObject:item];
}
}
while(tempArr.count < 5 && tempArr){
if (tempArr.count > 0) {
for (NSString *item in arr) {
if (![item containsString:@"."]) {
savePath = [savePath stringByAppendingString:[NSString stringWithFormat:@"/%@",tempArr[0]]];
}
}
}
tempArr = [[fm contentsOfDirectoryAtPath:savePath error:nil] mutableCopy];
}
return savePath;
}
- (FaceConfigInfo *)findFaceInfoById:(NSInteger)faceId{
if (self.faceInfos != nil) {
for (int i = 0; i < self.faceInfos.count; i++) {
FaceConfigInfo *faceInfo = self.faceInfos[i];
if (faceInfo.id == faceId) {
return faceInfo;
}
}
}
return nil;
}
//idiCON
- (UIImage *)findFaceIconImageById:(NSInteger)faceId {
FaceConfigInfo *configInfo = [self findFaceInfoById:faceId];
NSString *faceName = [NSString stringWithFormat:@"%@_%d_%ld",configInfo.pinyin,configInfo.id,configInfo.iconPos];
UIImage *face;
face = [self.faceCache objectForKey:faceName];
if (face) {
return face;
}else {
NSString *dirName = [NSString stringWithFormat:@"%@_%d",configInfo.pinyin,configInfo.id];
NSString *targetPath = [NSString stringWithFormat:@"%@/%@/%@",self.destinationUrl,dirName,faceName];
face = [UIImage imageWithContentsOfFile:targetPath];
if (face) {
[self.faceCache setObject:face forKey:faceName];
}
return face;
}
}
//
- (NSMutableArray<UIImage *> *)findFaceFrameArrByFaceId:(NSInteger)faceId {
FaceConfigInfo *configInfo = [self findFaceInfoById:faceId];
return [self findFaceFrameArrByConfig:configInfo];
}
//
- (NSMutableArray<UIImage *> *)findFaceFrameArrByConfig:(FaceConfigInfo *)configInfo {
NSMutableArray *faceArr = [NSMutableArray array];
for (int i = (short)configInfo.animStartPos; i <= (short)configInfo.animEndPos; i++) {
[faceArr addObject:[self findFaceImageByConfig:configInfo index:i]];
}
return faceArr;
}
//
- (UIImage *)findFaceImageById:(NSInteger)faceId index:(NSInteger)index {
FaceConfigInfo *configInfo = [self findFaceInfoById:faceId];
return [self findFaceImageByConfig:configInfo index:index];
}
//
- (UIImage *)findFaceImageByConfig:(FaceConfigInfo *)configInfo index:(NSInteger)index {
NSString *faceName = [NSString stringWithFormat:@"%@_%d_%ld",configInfo.pinyin,configInfo.id,(long)index];
UIImage *face;
face = [self.faceCache objectForKey:faceName];
if (face) {
return face;
}else {
NSString *dirName = [NSString stringWithFormat:@"%@_%d",configInfo.pinyin,configInfo.id];
NSString *targetPath = [NSString stringWithFormat:@"%@/%@/%@",self.destinationUrl,dirName,faceName];
face = [UIImage imageWithContentsOfFile:targetPath];
if (face) {
[self.faceCache setObject:face forKey:faceName];
}
return face;
}
}
- (NSMutableArray *)sortFaceInfosWithfaceInfoArr:(NSMutableArray *)faceInfoArr {
NSMutableArray *temp = [NSMutableArray array];
NSMutableArray *temp2 = [NSMutableArray array]; //
for (FaceConfigInfo *item in faceInfoArr) {
if (item.resultCount <= 0) {
[temp addObject:item];
}else {
[temp2 addObject:item];
}
}
[temp addObjectsFromArray:temp2];
return temp;
}
- (NSMutableArray *)getFaceInfosType:(RoomFaceType)faceType {
NSMutableArray *arr = [NSMutableArray array];
NSMutableArray *resultArr = [NSMutableArray array];
for (int i = 0; i < self.faceInfos.count; i++) {
FaceConfigInfo *item = self.faceInfos[i];
if (faceType == RoomFaceTypeNormal && !item.faceVipInfo) {
// if (GetCore(VersionCore).loadingData) {
if (!item.isLuckFace && item.faceType == XCFaceType_Face) {
[arr addObject:item];
}
// }else{
// if (item.faceType == XCFaceType_Face) {
// [arr addObject:item];
// }
// }
}else if(faceType == RoomFaceTypeNoble && item.faceVipInfo){///
// UserInfo *myInfo = [GetCore(UserCore) getUserInfoInDB:GetCore(AuthCore).getUid.userIDValue];
if (item.nobleId<=1) {
[arr addObject:item];
}
}
if (arr.count == 15) {
[resultArr addObject:arr];
arr = [NSMutableArray array];
}
if ( i%15 != 0 && i == self.faceInfos.count - 1) {
if (arr.count) {
[resultArr addObject:arr];
}
}
}
return resultArr;
}
//
- (void)sendAllFace:(FaceConfigInfo *)faceInfo {
if (faceInfo) {
// if (GetCore(ImRoomCoreV2).isInRoom) {
// NSMutableArray *chatroomMembers = GetCore(ImRoomCoreV2).micMembers;
// NSMutableArray *faceRecieveInfos = [NSMutableArray array];
// // FaceConfigInfo *child = [[FaceConfigInfo alloc]init];
// //
// if (chatroomMembers != nil && chatroomMembers.count > 0) {
// for (int i = 0; i < chatroomMembers.count; i++) {
// FaceReceiveInfo *faceRecieveInfo = [[FaceReceiveInfo alloc]init];
// if (faceInfo.resultStartPos > 0 && faceInfo.resultEndPos > 0) {
// int value = [self getRandomNumber:(short)faceInfo.resultStartPos to:(short)faceInfo.resultEndPos];
// //
// faceRecieveInfo.resultIndexes = [@[@(value)]mutableCopy];
// }
// NIMChatroomMember *chatRoomMember = chatroomMembers[i];
//
// faceRecieveInfo.nick = chatRoomMember.roomNickname;
// faceRecieveInfo.uid = chatRoomMember.userId.userIDValue;
// faceRecieveInfo.faceId = faceInfo.id;
// // if (child != nil) {
// // faceRecieveInfo.faceId = child.faceId;
// // }else {
// // faceRecieveInfo.faceId = faceInfo.faceId;
// // }
//
// [faceRecieveInfos addObject:faceRecieveInfo];
//
// }
// }
//
// FaceSendInfo *sendInfo = [[FaceSendInfo alloc]init];
// sendInfo.data = faceRecieveInfos;
// // sendInfo.uid = info.uid;
// sendInfo.uid = [GetCore(AuthCore)getUid].userIDValue;
//
// Attachment *attachment = [[Attachment alloc]init];
// attachment.first = Custom_Noti_Header_Face;
// attachment.second = Custom_Noti_Sub_Face_Send;
// attachment.data = sendInfo.encodeAttachemt;
//
// NSString *sessionID = [NSString stringWithFormat:@"%ld",GetCore(ImRoomCoreV2).currentRoomInfo.roomId];
// [GetCore(ImMessageCore)sendCustomMessageAttachement:attachment sessionId:sessionID type:NIMSessionTypeChatroom];
// }
}
}
- (void)sendFace:(FaceConfigInfo *)faceInfo {
// RoomInfo *info = GetCore(ImRoomCoreV2).currentRoomInfo;
// if (info != nil) {
// FaceReceiveInfo *faceRecieveInfo = [[FaceReceiveInfo alloc]init];
// NSMutableArray *resultIndexs = [NSMutableArray array];
// if (faceInfo.resultStartPos > 0 && faceInfo.resultEndPos > 0) {
// int value;
// if (faceInfo.canResultRepeat) { //
// for (int i = 0; i < faceInfo.resultCount; i++) {
// value = [self getRandomNumber:(short)faceInfo.resultStartPos to:(short)faceInfo.resultEndPos];
// [resultIndexs addObject:@(value)];
// faceRecieveInfo.resultIndexes = [resultIndexs copy];
// }
//
// }else {
// faceRecieveInfo.resultIndexes = [[self randomArray:(short)faceInfo.resultStartPos to:(short)faceInfo.resultEndPos count:(short)faceInfo.resultCount] mutableCopy];
// }
//
// }
//
// // UserInfo *info = [GetCore(UserCore)getUserInfo:[GetCore(AuthCore)getUid].userIDValue refresh:NO];
// UserInfo *info = [GetCore(UserCore) getUserInfoInDB:[GetCore(AuthCore)getUid].userIDValue];
// NSMutableArray *faceRecieveInfos = [NSMutableArray array];
//
// faceRecieveInfo.nick = info.nick;
// faceRecieveInfo.faceId = faceInfo.id;
// faceRecieveInfo.uid = info.uid;
// [faceRecieveInfos addObject:faceRecieveInfo];
//
// FaceSendInfo *sendInfo = [[FaceSendInfo alloc]init];
// sendInfo.data = faceRecieveInfos;
// sendInfo.uid = info.uid;
//
// Attachment *attachment = [[Attachment alloc]init];
// attachment.first = Custom_Noti_Header_Face;
// attachment.second = Custom_Noti_Sub_Face_Send;
// attachment.data = sendInfo.encodeAttachemt;
// NSString *sessionID = [NSString stringWithFormat:@"%ld",GetCore(ImRoomCoreV2).currentRoomInfo.roomId];
// [GetCore(ImMessageCore)sendCustomMessageAttachement:attachment sessionId:sessionID type:NIMSessionTypeChatroom];
//
// }
}
- (void)sendToCpFace:(FaceConfigInfo *)faceInfo {
// GetCore(ImRoomCoreV2).myMember.roomExt = @"";
// if ( GetCore(ImRoomCoreV2).p2pUid > 0) {
// FaceReceiveInfo *faceRecieveInfo = [[FaceReceiveInfo alloc]init];
// NSMutableArray *resultIndexs = [NSMutableArray array];
// if (faceInfo.resultStartPos > 0 && faceInfo.resultEndPos > 0) {
// int value;
// if (faceInfo.canResultRepeat) { //
// for (int i = 0; i < faceInfo.resultCount; i++) {
// value = [self getRandomNumber:(short)faceInfo.resultStartPos to:(short)faceInfo.resultEndPos];
// [resultIndexs addObject:@(value)];
// faceRecieveInfo.resultIndexes = [resultIndexs copy];
// }
//
// }else {
// faceRecieveInfo.resultIndexes = [[self randomArray:(short)faceInfo.resultStartPos to:(short)faceInfo.resultEndPos count:(short)faceInfo.resultCount] mutableCopy];
// }
//
// }
//
// // UserInfo *info = [GetCore(UserCore)getUserInfo:[GetCore(AuthCore)getUid].userIDValue refresh:NO];
// UserInfo *info = [GetCore(UserCore) getUserInfoInDB:[GetCore(AuthCore)getUid].userIDValue];
// NSMutableArray *faceRecieveInfos = [NSMutableArray array];
//
// faceRecieveInfo.nick = info.nick;
// faceRecieveInfo.faceId = faceInfo.id;
// faceRecieveInfo.uid = info.uid;
// [faceRecieveInfos addObject:faceRecieveInfo];
//
// FaceSendInfo *sendInfo = [[FaceSendInfo alloc]init];
// sendInfo.data = faceRecieveInfos;
// sendInfo.uid = info.uid;
//
// Attachment *attachment = [[Attachment alloc]init];
// attachment.first = Custom_Noti_Header_Face;
// attachment.second = Custom_Noti_Sub_Face_Send;
// attachment.data = sendInfo.encodeAttachemt;
// NSString *sessionID = [NSString stringWithFormat:@"%ld",GetCore(ImRoomCoreV2).p2pUid];
// [GetCore(ImMessageCore)sendCustomMessageAttachement:attachment sessionId:sessionID type:NIMSessionTypeP2P];
//
// }
}
//
//- (void)sendDragonWithState:(CustomNotificationDragon)state {
// if (state == Custom_Noti_Sub_Dragon_Start) {
// RoomInfo *info = GetCore(ImRoomCoreV2).currentRoomInfo;
// UserID uid = GetCore(AuthCore).getUid.longLongValue;
// @weakify(self);
// [GetCore(RoomCoreV2) getDragonWithRoomUid:info.uid uid:uid success:^(NSArray *ballList,BOOL isNew) {
// @strongify(self);
// FaceConfigInfo *dragonInfo = self.dragonConfigInfo;
// if (info != nil) {
// FaceReceiveInfo *faceRecieveInfo = [[FaceReceiveInfo alloc]init];
// NSMutableArray *resultIndexs = [NSMutableArray array];
// if (dragonInfo.resultStartPos > 0 && dragonInfo.resultEndPos > 0) {
// for (NSString *number in ballList) {
// [resultIndexs addObject:@(number.intValue+dragonInfo.resultStartPos)];
// }
// faceRecieveInfo.resultIndexes = [resultIndexs copy];
//
// }
// UserInfo *info = [GetCore(UserCore) getUserInfoInDB:[GetCore(AuthCore)getUid].userIDValue];
// NSMutableArray *faceRecieveInfos = [NSMutableArray array];
//
// faceRecieveInfo.nick = info.nick;
// faceRecieveInfo.faceId = dragonInfo.id;
// faceRecieveInfo.uid = info.uid;
// [faceRecieveInfos addObject:faceRecieveInfo];
//
//
//
// // 17,34,40
// FaceSendInfo *sendInfo = [[FaceSendInfo alloc]init];
// sendInfo.data = faceRecieveInfos;
// sendInfo.uid = info.uid;
//
// //
//
// GetCore(RoomCoreV2).currenDragonFaceSendInfo = sendInfo;
// Attachment *attachment = [[Attachment alloc]init];
// attachment.first = Custom_Noti_Header_Dragon;
// if (isNew) {
// attachment.second = Custom_Noti_Sub_Dragon_Start;
// }else {
// attachment.second = Custom_Noti_Sub_Dragon_Continue;
// }
// attachment.data = sendInfo.encodeAttachemt;
// NSString *sessionID = [NSString stringWithFormat:@"%ld",GetCore(ImRoomCoreV2).currentRoomInfo.roomId];
// [GetCore(ImMessageCore)sendCustomMessageAttachement:attachment sessionId:sessionID type:NIMSessionTypeChatroom];
// }
// } failure:^(NSNumber *code, NSString *msg) {
//
//
//
// }];
//
//
//
//
// }else {
// //
// if (!GetCore(RoomCoreV2).currenDragonFaceSendInfo) {
// return;
// }
// Attachment *attachment = [[Attachment alloc]init];
// attachment.first = Custom_Noti_Header_Dragon;
// attachment.second = state;
// attachment.data = GetCore(RoomCoreV2).currenDragonFaceSendInfo.encodeAttachemt;
// NSString *sessionID = [NSString stringWithFormat:@"%ld",GetCore(ImRoomCoreV2).currentRoomInfo.roomId];
// [GetCore(ImMessageCore)sendCustomMessageAttachement:attachment sessionId:sessionID type:NIMSessionTypeChatroom];
// }
//
//
//}
#pragma mark - ImMessageCoreClient
- (void)onSendMessageSuccess:(NIMMessage *)msg {
if (msg.messageType == NIMMessageTypeCustom) {
NIMCustomObject *obj = (NIMCustomObject *)msg.messageObject;
// if (obj.attachment != nil && [obj.attachment isKindOfClass:[Attachment class]]) {
// Attachment *attachment = (Attachment *)obj.attachment;
// if (attachment.first == Custom_Noti_Header_Face) {
// if (attachment.second == Custom_Noti_Sub_Face_Send) {
// FaceSendInfo *faceattachement = [FaceSendInfo yy_modelWithJSON:attachment.data];
// NSMutableArray *arr = [faceattachement.data mutableCopy];
// NotifyCoreClient(FaceCoreClient, @selector(onReceiveFace:), onReceiveFace:arr);
// if (arr.count > 0) {
// FaceReceiveInfo *faceRecieveInfo = arr.firstObject;
// FaceConfigInfo *faceInfo = [self findFaceInfoById:faceRecieveInfo.faceId];
// if (faceInfo.id > 1 && faceInfo != nil && faceRecieveInfo.resultIndexes.count > 0) {
// FacePlayInfo *playInfo = [[FacePlayInfo alloc]init];
// playInfo.delay = 3;
// playInfo.faceReceiveInfo = arr.firstObject;
// playInfo.message = msg;
// for (FaceReceiveInfo *item in arr) {
// if (item.uid == [GetCore(AuthCore) getUid].userIDValue) {
// self.isShowingFace = YES;
// }
// }
//
// [self handleFaceMessage:playInfo];
// }
// }
// }
// }else if (attachment.first == Custom_Noti_Header_Dragon){
// //
// NotifyCoreClient(RoomCoreClient, @selector(onRecvChatRoomDragonMsg:), onRecvChatRoomDragonMsg:msg);
//
// }
// }
}
}
- (void)onRecvChatRoomCustomMsg:(NIMMessage *)msg {
if (msg.messageType == NIMMessageTypeCustom) {
NIMCustomObject *obj = (NIMCustomObject *)msg.messageObject;
// if (obj.attachment != nil && [obj.attachment isKindOfClass:[Attachment class]]) {
// Attachment *attachment = (Attachment *)obj.attachment;
// if (attachment.first == Custom_Noti_Header_Face) {
// if (attachment.second == Custom_Noti_Sub_Face_Send) {
// FaceSendInfo *faceattachement = [FaceSendInfo yy_modelWithJSON:attachment.data];
//
// NSMutableArray *arr = [faceattachement.data mutableCopy];
// NotifyCoreClient(FaceCoreClient, @selector(onReceiveFace:), onReceiveFace:arr);
// if (arr.count > 0) {
// FaceReceiveInfo *faceRecieveInfo = arr.firstObject;
// FaceConfigInfo *faceInfo = [self findFaceInfoById:faceRecieveInfo.faceId];
// if (faceInfo.id > 1 && faceInfo != nil && faceRecieveInfo.resultIndexes.count > 0) {
// FacePlayInfo *playInfo = [[FacePlayInfo alloc]init];
// playInfo.delay = 3;
// playInfo.faceReceiveInfo = arr.firstObject;
// playInfo.message = msg;
// for (FaceReceiveInfo *item in arr) {
// if (item.uid == [GetCore(AuthCore) getUid].userIDValue) {
// self.isShowingFace = YES;
// }
// }
//
// [self handleFaceMessage:playInfo];
// }
//
// }
// }
// }else if (attachment.first == Custom_Noti_Header_Dragon) {
// //
//
// }
// }
}
}
//
- (void)onSendDragonMessageFailthWithMsg:(NIMMessage *)msg error:(NSError *)error {
NSString *errormsg = [NSString stringWithFormat:@"错误码%ld,%@",(long)error.code,error.description];
// NotifyCoreClient(FaceCoreClient, @selector(onDragonSendFailth:), onDragonSendFailth:errormsg);
}
#pragma mark - AppInitClient
- (void)getFaceDataSuccess:(NSArray *)faceArr {
self.tempFaceInfos = [self sortFaceInfosWithfaceInfoArr:[faceArr mutableCopy]]; //
[self faceDownloadManager];
// NotifyCoreClient(FaceCoreClient, @selector(onGetFaceJsonSuccess), onGetFaceJsonSuccess);
}
#pragma mark - Face Play Method
- (void)handleFaceMessage:(FacePlayInfo *)facePlayInfo {
[self.receiveFace addObject:facePlayInfo];
if (self.timer== nil) {
[self startTheFaceQueueScanner];
}
}
- (void)startTheFaceQueueScanner {
NSTimeInterval period = 1; //
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); dispatch_source_t _timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);
dispatch_source_set_timer(_timer, dispatch_walltime(NULL, 0), period * NSEC_PER_SEC, 0); //1
@weakify(self);
dispatch_source_set_event_handler(_timer, ^{
@strongify(self);
if (self.receiveFace.count > 0) {
NSMutableArray *tempArr = [NSMutableArray array];
NSMutableArray *temp = [self.receiveFace mutableCopy];
for (FacePlayInfo *item in temp) {
item.delay = item.delay - 1;
if (item.delay == 0) {
self.isShowingFace = NO;
if ([NSThread isMainThread])
{
// NotifyCoreClient(FaceCoreClient, @selector(onFaceIsResult:), onFaceIsResult:item);
}
else
{
dispatch_sync(dispatch_get_main_queue(), ^{
//Update UI in UI thread here
// NotifyCoreClient(FaceCoreClient, @selector(onFaceIsResult:), onFaceIsResult:item);
});
}
}else {
[tempArr addObject:item];
}
}
self.receiveFace = tempArr;
} else {
dispatch_source_cancel(_timer);
self.timer = nil;
}
});
dispatch_resume(_timer);
self.timer = _timer;
}
#pragma mark - Private
/**
@param from
@param to
@param count
@return
*/
- (NSArray *)randomArray:(int)from to:(int)to count:(int)count {
//
NSMutableArray *startArray= [NSMutableArray array];
for (int i = from; i <= to; i++) {
[startArray addObject:@(i)];
}
//
NSMutableArray *resultArray=[[NSMutableArray alloc] initWithCapacity:0];
//
NSInteger m = count;
for (int i=0; i<m; i++) {
int t = arc4random()%startArray.count;
resultArray[i]=startArray[t];
startArray[t]=[startArray lastObject]; //
[startArray removeLastObject];
}
return resultArray;
}
/**
@param from
@param to
@return
*/
- (int)getRandomNumber:(int)from to:(int)to {
return (int)(from + (arc4random() % (to - from + 1)));
}
- (BOOL)isEnableFace:(FaceConfigInfo *)info {
if (info.displayType != XCFaceDisplayTypeOnlyOne && info.displayType != XCFaceDisplayTypeFlow && info.displayType != XCFaceDisplayTypeOverLay) {
return NO;
}else {
return YES;
}
}
#pragma mark - Getter
- (FaceConfigInfo *)dragonConfigInfo {
if (_dragonConfigInfo) {
return _dragonConfigInfo;
}
__block FaceConfigInfo *find;
[self.faceInfos enumerateObjectsUsingBlock:^(FaceConfigInfo* _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
//
if (obj.id == 40) {
find = obj;
*stop = YES;
}
}];
_dragonConfigInfo = find;
return _dragonConfigInfo;
}
- (NSMutableArray *)receiveFace {
if (_receiveFace == nil) {
_receiveFace = [NSMutableArray array];
}
return _receiveFace;
}
- (BOOL)getShowingFace {
return self.isShowingFace;
}
- (NSCache *)faceCache {
if (_faceCache == nil) {
_faceCache = [[NSCache alloc]init];
}
return _faceCache;
}
- (FaceConfigInfo *)getPlayTogetherFace {
//
if (self.faceInfos != nil && self.faceInfos.count > 0) {
for (int i = 0; i < self.faceInfos.count; i++) {
FaceConfigInfo *faceInfo = self.faceInfos[i];
if (faceInfo.id == 17) {
return faceInfo;
}
}
}else {
[self requestFaceJson];
}
return nil;
}
- (void)requestFaceJson {
@weakify(self);
self.isLoadFace = NO;
self.requestJsonCount += 1;
// [HttpRequestHelper getTheFaceJson:^(NSArray *faceJsonList) {
// @strongify(self);
// self.tempFaceInfos = [self sortFaceInfosWithfaceInfoArr:[faceJsonList mutableCopy]]; //
//
// [self faceDownloadManager];
// NotifyCoreClient(FaceCoreClient, @selector(onGetFaceJsonSuccess), onGetFaceJsonSuccess);
// } failure:^(NSNumber *resCode, NSString *message) {
// @strongify(self);
// if ((int)self.requestJsonCount < 3) {
// if (self.retryDelay == 0) {
// self.retryDelay = 1;
// }
// [self performSelector:@selector(requestFaceJson) withObject:nil afterDelay:self.retryDelay * 4];
// }
// }];
}
#pragma mark - Test //使
- (void)cancelFaceTimer {
self.timer = nil;
}
- (void)startFaceTimer {
//
dispatch_queue_t queue = dispatch_get_main_queue();
// (dispatch_source_tOC)
self.testTimer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);
//
// GCD1 == 109
//
// dispatch_time(DISPATCH_TIME_NOW, 1.0 * NSEC_PER_SEC) 3
dispatch_time_t start = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(8 * NSEC_PER_SEC));
uint64_t interval = (uint64_t)(60.0 * NSEC_PER_SEC);
dispatch_source_set_timer(self.testTimer, start, interval, 0);
//
@weakify(self);
dispatch_source_set_event_handler(self.testTimer, ^{
@strongify(self);
[self sendAllFace:[self getPlayTogetherFace]];
});
//
dispatch_resume(self.testTimer);
}
@end

View File

@@ -18,7 +18,7 @@
#import "XPCandyTreeAnimationManager.h"
///Model
#import "RoomInfoModel.h"
#import "AttachMentModel.h"
#import "AttachmentModel.h"
#import "CandyTreeInfoModel.h"
#import "CandyTreeResultModel.h"
///View

View File

@@ -17,7 +17,7 @@
#import "XPGiftStorage.h"
///Model
#import "XPMessageRemoteExtModel.h"
#import "AttachMentModel.h"
#import "AttachmentModel.h"
#import "GiftReceiveInfoModel.h"
#import "XPKickUserModel.h"
#import "MicroQueueModel.h"

View File

@@ -19,7 +19,7 @@
#import "XPRoomMiniManager.h"
///Model
#import "RoomInfoModel.h"
#import "AttachMentModel.h"
#import "AttachmentModel.h"
///View
#import "XPRoomMessageTableViewCell.h"
#import "XPRoomMessageHeaderView.h"

View File

@@ -27,7 +27,7 @@
///Model
#import "RoomInfoModel.h"
#import "UserInfoModel.h"
#import "AttachMentModel.h"
#import "AttachmentModel.h"
///View
#import "XPShareView.h"
///VC

View File

@@ -393,6 +393,8 @@
[self giftValueUpdate:attachment.data];
}else if(attachment.first == CustomMessageType_AllMicroSend && (attachment.second == Custom_Message_Sub_AllMicroSend || attachment.second == Custom_Message_Sub_AllBatchSend || attachment.second == Custom_Message_Sub_AllMicroLuckySend || attachment.second == Custom_Message_Sub_AllBatchMicroLuckySend)) {
[self giftValueUpdate:attachment.data];
} else if (attachment.first == CustomMessageType_Face && attachment.second == Custom_Message_Sub_Face_Send) {
}
}
}

View File

@@ -22,6 +22,11 @@ NS_ASSUME_NONNULL_BEGIN
@property (nonatomic,strong) ClientDataModel *configInfo;
///开箱子 大于等级 展示
@property (nonatomic, assign) NSInteger openCandyTreeLimitLevel;
///表情---
@property (nonatomic, copy) NSString *version;
@property (nonatomic, copy) NSString *zipMd5;
@property (nonatomic, strong) NSURL *zipUrl;
@end
NS_ASSUME_NONNULL_END

View File

@@ -10,6 +10,11 @@
/// tool
#import "DESEncrypt.h"
#import "XPConstant.h"
#import "NSString+JsonToDic.h"
#import <MJExtension/MJExtension.h>
#import "XPFaceParser.h"
///Model
#import "FaceConfigInfo.h"
@interface ClientConfig ()
/// 10
@@ -40,18 +45,19 @@
self.configInfo = model;
/* */
NSString *json = initData[@"faceJson"][@"json"];
// NSString *deJson = [DESEncrypt decryptUseDES:json key:keyWithType(KeyType_FAcePwdEncode, NO)];
// NSDictionary *faceInitData = [NSString dictionaryWithJsonString:deJson];
// if (faceInitData) {
// NSArray *arr = [NSArray yy_modelArrayWithClass:[FaceConfigInfo class] json:faceInitData[@"faces"]];
// GetCore(FaceCore).version = [NSString stringWithFormat:@"%@",faceInitData[@"version"]];
// GetCore(FaceCore).zipMd5 = [[NSString stringWithFormat:@"%@",faceInitData[@"zipMd5"]] uppercaseString];
// GetCore(FaceCore).zipUrl = [NSURL URLWithString:[NSString stringWithFormat:@"%@",faceInitData[@"zipUrl"]]];
//
NSString *deJson = [DESEncrypt decryptUseDES:json key:KeyWithType(KeyType_FacePwdEncode)];
NSDictionary *faceInitData = [NSString dictionaryWithJsonString:deJson];
if (faceInitData) {
NSArray *arr = [FaceConfigInfo modelsWithArray:faceInitData[@"faces"]];
NSArray *nobleArray = [FaceConfigInfo modelsWithArray:faceInitData[@"vipFaces"]];
NSMutableArray *array = [NSMutableArray arrayWithArray:arr];
[array addObjectsFromArray:nobleArray];
[XPFaceParser shareParser].version = [NSString stringWithFormat:@"%@",faceInitData[@"version"]];
[XPFaceParser shareParser].zipMd5 = [[NSString stringWithFormat:@"%@",faceInitData[@"zipMd5"]] uppercaseString];
[XPFaceParser shareParser].zipUrl = [NSURL URLWithString:[NSString stringWithFormat:@"%@",faceInitData[@"zipUrl"]]];
[[XPFaceParser shareParser] getFaceDataSuccess:array];
// NotifyCoreClient(AppInitClient, @selector(onGetFaceDataSuccess:), onGetFaceDataSuccess:arr);
//
// }
}
} else {
if (self.retryCount < 10) {
[self clientInit];