331个文件已添加
60个文件已修改
6 文件已重命名
311个文件已删除
| | |
| | | 188175201DC05C51004A2540 /* liveOnLineView.m in Sources */ = {isa = PBXBuildFile; fileRef = 1881751F1DC05C51004A2540 /* liveOnLineView.m */; }; |
| | | 188322391F74B62400CCD0B4 /* HXEasyCustomShareView.m in Sources */ = {isa = PBXBuildFile; fileRef = 188322361F74AFFD00CCD0B4 /* HXEasyCustomShareView.m */; }; |
| | | 1883223A1F74B62400CCD0B4 /* HXShareScrollView.m in Sources */ = {isa = PBXBuildFile; fileRef = 188322381F74AFFD00CCD0B4 /* HXShareScrollView.m */; }; |
| | | 1883223E1F75058500CCD0B4 /* RooterController.m in Sources */ = {isa = PBXBuildFile; fileRef = 1883223C1F75058500CCD0B4 /* RooterController.m */; }; |
| | | 1884A6021E545D4900548480 /* PopoverAction.m in Sources */ = {isa = PBXBuildFile; fileRef = 1884A5FD1E545D4900548480 /* PopoverAction.m */; }; |
| | | 1884A6031E545D4900548480 /* PopoverViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 1884A5FF1E545D4900548480 /* PopoverViewCell.m */; }; |
| | | 1884A6041E545D4900548480 /* PopoverViews.m in Sources */ = {isa = PBXBuildFile; fileRef = 1884A6011E545D4900548480 /* PopoverViews.m */; }; |
| | |
| | | 189787861D925B5D006245B9 /* GoogleAdTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 189787841D925B5D006245B9 /* GoogleAdTableViewCell.m */; }; |
| | | 189787871D925B5D006245B9 /* GoogleAdTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 189787851D925B5D006245B9 /* GoogleAdTableViewCell.xib */; }; |
| | | 189EFECB1EF1465D00C59CAB /* yw_1222.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 189EFECA1EF1465D00C59CAB /* yw_1222.jpg */; }; |
| | | 18A0604E2060EEE700BACA54 /* libGDTMobSDK.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 18A060472060EEE500BACA54 /* libGDTMobSDK.a */; }; |
| | | 18ABF6E31DDD9B4600C9257E /* YTHNetdata.m in Sources */ = {isa = PBXBuildFile; fileRef = 18ABF6E01DDD9B4600C9257E /* YTHNetdata.m */; }; |
| | | 18ABF6E41DDD9B4600C9257E /* YTHNetInterface.m in Sources */ = {isa = PBXBuildFile; fileRef = 18ABF6E21DDD9B4600C9257E /* YTHNetInterface.m */; }; |
| | | 18B1C25A1DB5B26B00AB709B /* HMSegmentedControl.m in Sources */ = {isa = PBXBuildFile; fileRef = 18B1C23C1DB5B26B00AB709B /* HMSegmentedControl.m */; }; |
| | |
| | | 18ED606D1E1632E300AF8252 /* StartCollectionViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 18ED606B1E1632E300AF8252 /* StartCollectionViewCell.xib */; }; |
| | | 18ED60711E165CE000AF8252 /* findGoodsTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 18ED606F1E165CE000AF8252 /* findGoodsTableViewCell.m */; }; |
| | | 18ED60721E165CE000AF8252 /* findGoodsTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 18ED60701E165CE000AF8252 /* findGoodsTableViewCell.xib */; }; |
| | | 18EF91DB1D8E42DA0078C8BD /* NJKWebViewProgress.m in Sources */ = {isa = PBXBuildFile; fileRef = 18EF91D81D8E42DA0078C8BD /* NJKWebViewProgress.m */; }; |
| | | 18EF91DC1D8E42DA0078C8BD /* NJKWebViewProgressView.m in Sources */ = {isa = PBXBuildFile; fileRef = 18EF91DA1D8E42DA0078C8BD /* NJKWebViewProgressView.m */; }; |
| | | 18EF91E31D8E47610078C8BD /* WEBViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 18EF91E11D8E47610078C8BD /* WEBViewController.m */; }; |
| | | 18F2541F1DF0090900826AD0 /* FuLiSheViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 18F2541D1DF0090900826AD0 /* FuLiSheViewController.m */; }; |
| | | 18F254201DF0090900826AD0 /* FuLiSheViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 18F2541E1DF0090900826AD0 /* FuLiSheViewController.xib */; }; |
| | |
| | | 2DECF92D22325172002FF49F /* GuessLikeViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 2DECF92C22325172002FF49F /* GuessLikeViewController.m */; }; |
| | | 2DECF93122325854002FF49F /* GuessLTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 2DECF92F22325854002FF49F /* GuessLTableViewCell.m */; }; |
| | | 2DECF93222325854002FF49F /* GuessLTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 2DECF93022325854002FF49F /* GuessLTableViewCell.xib */; }; |
| | | 7042C94E2515A4FE0017F5D8 /* BUAdSDK.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7042C94B2515A4FE0017F5D8 /* BUAdSDK.framework */; }; |
| | | 7042C94F2515A4FE0017F5D8 /* BUFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7042C94C2515A4FE0017F5D8 /* BUFoundation.framework */; }; |
| | | 7042C9502515A4FE0017F5D8 /* BUAdSDK.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 7042C94D2515A4FE0017F5D8 /* BUAdSDK.bundle */; }; |
| | | 70452819250E2C610006C95E /* libGDTMobSDK.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 7045280E250E2C5F0006C95E /* libGDTMobSDK.a */; }; |
| | | 705951F425161153008E0CDF /* SearchTitleView.m in Sources */ = {isa = PBXBuildFile; fileRef = 705951F325161153008E0CDF /* SearchTitleView.m */; }; |
| | | 705951F7251633E9008E0CDF /* SearchDetailListCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 705951F6251633E9008E0CDF /* SearchDetailListCell.m */; }; |
| | | 705F1E84251F085D0065350E /* Share.m in Sources */ = {isa = PBXBuildFile; fileRef = 705F1E82251F085D0065350E /* Share.m */; }; |
| | | 705F1F6E251F1CA80065350E /* UIScrollView+MJRefresh.m in Sources */ = {isa = PBXBuildFile; fileRef = 705F1F37251F1CA70065350E /* UIScrollView+MJRefresh.m */; }; |
| | | 705F1F6F251F1CA80065350E /* MJRefreshConst.m in Sources */ = {isa = PBXBuildFile; fileRef = 705F1F38251F1CA70065350E /* MJRefreshConst.m */; }; |
| | | 705F1F70251F1CA80065350E /* MJRefreshConfig.m in Sources */ = {isa = PBXBuildFile; fileRef = 705F1F39251F1CA70065350E /* MJRefreshConfig.m */; }; |
| | | 705F1F71251F1CA80065350E /* MJRefresh.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 705F1F3D251F1CA70065350E /* MJRefresh.bundle */; }; |
| | | 705F1F72251F1CA80065350E /* UIScrollView+MJExtension.m in Sources */ = {isa = PBXBuildFile; fileRef = 705F1F3F251F1CA70065350E /* UIScrollView+MJExtension.m */; }; |
| | | 705F1F73251F1CA80065350E /* NSBundle+MJRefresh.m in Sources */ = {isa = PBXBuildFile; fileRef = 705F1F43251F1CA70065350E /* NSBundle+MJRefresh.m */; }; |
| | | 705F1F74251F1CA80065350E /* UIView+MJExtension.m in Sources */ = {isa = PBXBuildFile; fileRef = 705F1F44251F1CA70065350E /* UIView+MJExtension.m */; }; |
| | | 705F1F75251F1CA80065350E /* MJRefreshBackGifFooter.m in Sources */ = {isa = PBXBuildFile; fileRef = 705F1F4B251F1CA70065350E /* MJRefreshBackGifFooter.m */; }; |
| | | 705F1F76251F1CA80065350E /* MJRefreshBackStateFooter.m in Sources */ = {isa = PBXBuildFile; fileRef = 705F1F4C251F1CA70065350E /* MJRefreshBackStateFooter.m */; }; |
| | | 705F1F77251F1CA80065350E /* MJRefreshBackNormalFooter.m in Sources */ = {isa = PBXBuildFile; fileRef = 705F1F4D251F1CA70065350E /* MJRefreshBackNormalFooter.m */; }; |
| | | 705F1F78251F1CA80065350E /* MJRefreshAutoStateFooter.m in Sources */ = {isa = PBXBuildFile; fileRef = 705F1F52251F1CA70065350E /* MJRefreshAutoStateFooter.m */; }; |
| | | 705F1F79251F1CA80065350E /* MJRefreshAutoGifFooter.m in Sources */ = {isa = PBXBuildFile; fileRef = 705F1F53251F1CA70065350E /* MJRefreshAutoGifFooter.m */; }; |
| | | 705F1F7A251F1CA80065350E /* MJRefreshAutoNormalFooter.m in Sources */ = {isa = PBXBuildFile; fileRef = 705F1F54251F1CA70065350E /* MJRefreshAutoNormalFooter.m */; }; |
| | | 705F1F7B251F1CA80065350E /* MJRefreshStateTrailer.m in Sources */ = {isa = PBXBuildFile; fileRef = 705F1F57251F1CA70065350E /* MJRefreshStateTrailer.m */; }; |
| | | 705F1F7C251F1CA80065350E /* MJRefreshNormalTrailer.m in Sources */ = {isa = PBXBuildFile; fileRef = 705F1F58251F1CA70065350E /* MJRefreshNormalTrailer.m */; }; |
| | | 705F1F7D251F1CA80065350E /* MJRefreshNormalHeader.m in Sources */ = {isa = PBXBuildFile; fileRef = 705F1F5B251F1CA70065350E /* MJRefreshNormalHeader.m */; }; |
| | | 705F1F7E251F1CA80065350E /* MJRefreshStateHeader.m in Sources */ = {isa = PBXBuildFile; fileRef = 705F1F5F251F1CA70065350E /* MJRefreshStateHeader.m */; }; |
| | | 705F1F7F251F1CA80065350E /* MJRefreshGifHeader.m in Sources */ = {isa = PBXBuildFile; fileRef = 705F1F60251F1CA70065350E /* MJRefreshGifHeader.m */; }; |
| | | 705F1F80251F1CA80065350E /* MJRefreshFooter.m in Sources */ = {isa = PBXBuildFile; fileRef = 705F1F62251F1CA70065350E /* MJRefreshFooter.m */; }; |
| | | 705F1F81251F1CA80065350E /* MJRefreshHeader.m in Sources */ = {isa = PBXBuildFile; fileRef = 705F1F64251F1CA70065350E /* MJRefreshHeader.m */; }; |
| | | 705F1F82251F1CA80065350E /* MJRefreshBackFooter.m in Sources */ = {isa = PBXBuildFile; fileRef = 705F1F67251F1CA70065350E /* MJRefreshBackFooter.m */; }; |
| | | 705F1F83251F1CA80065350E /* MJRefreshAutoFooter.m in Sources */ = {isa = PBXBuildFile; fileRef = 705F1F68251F1CA70065350E /* MJRefreshAutoFooter.m */; }; |
| | | 705F1F84251F1CA80065350E /* MJRefreshComponent.m in Sources */ = {isa = PBXBuildFile; fileRef = 705F1F6A251F1CA70065350E /* MJRefreshComponent.m */; }; |
| | | 705F1F85251F1CA80065350E /* MJRefreshTrailer.m in Sources */ = {isa = PBXBuildFile; fileRef = 705F1F6D251F1CA70065350E /* MJRefreshTrailer.m */; }; |
| | | 7B0D3B2C1D59BCAB003E74A8 /* AnimationTool.m in Sources */ = {isa = PBXBuildFile; fileRef = 7B0D3B271D59BCAB003E74A8 /* AnimationTool.m */; }; |
| | | 7B0D3B2D1D59BCAB003E74A8 /* CMuneBar.m in Sources */ = {isa = PBXBuildFile; fileRef = 7B0D3B291D59BCAB003E74A8 /* CMuneBar.m */; }; |
| | | 7B0D3B2E1D59BCAB003E74A8 /* CMuneItem.m in Sources */ = {isa = PBXBuildFile; fileRef = 7B0D3B2B1D59BCAB003E74A8 /* CMuneItem.m */; }; |
| | |
| | | 7B1FF0DD1D670B8800E6C207 /* attentionView.m in Sources */ = {isa = PBXBuildFile; fileRef = 7B1FF0DC1D670B8800E6C207 /* attentionView.m */; }; |
| | | 7B1FF0DF1D6711CF00E6C207 /* libiconv.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 7B1FF0DE1D6711CF00E6C207 /* libiconv.tbd */; }; |
| | | 7B1FF0E11D67121700E6C207 /* libstdc++.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 7B1FF0E01D67121700E6C207 /* libstdc++.tbd */; }; |
| | | 7B1FF0E51D67169E00E6C207 /* Share.m in Sources */ = {isa = PBXBuildFile; fileRef = 7B1FF0E41D67169E00E6C207 /* Share.m */; }; |
| | | 7B32BD321D4F26F500E96E75 /* subregionView.m in Sources */ = {isa = PBXBuildFile; fileRef = 7B32BD311D4F26F500E96E75 /* subregionView.m */; }; |
| | | 7B32BD3D1D4F410F00E96E75 /* recommentCollectionViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 7B32BD3B1D4F410F00E96E75 /* recommentCollectionViewCell.m */; }; |
| | | 7B32BD3E1D4F410F00E96E75 /* recommentCollectionViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 7B32BD3C1D4F410F00E96E75 /* recommentCollectionViewCell.xib */; }; |
| | |
| | | 188322361F74AFFD00CCD0B4 /* HXEasyCustomShareView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = HXEasyCustomShareView.m; sourceTree = "<group>"; }; |
| | | 188322371F74AFFD00CCD0B4 /* HXShareScrollView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = HXShareScrollView.h; sourceTree = "<group>"; }; |
| | | 188322381F74AFFD00CCD0B4 /* HXShareScrollView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = HXShareScrollView.m; sourceTree = "<group>"; }; |
| | | 1883223B1F75058500CCD0B4 /* RooterController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RooterController.h; sourceTree = "<group>"; }; |
| | | 1883223C1F75058500CCD0B4 /* RooterController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RooterController.m; sourceTree = "<group>"; }; |
| | | 1884A5FC1E545D4900548480 /* PopoverAction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PopoverAction.h; sourceTree = "<group>"; }; |
| | | 1884A5FD1E545D4900548480 /* PopoverAction.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PopoverAction.m; sourceTree = "<group>"; }; |
| | | 1884A5FE1E545D4900548480 /* PopoverViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PopoverViewCell.h; sourceTree = "<group>"; }; |
| | |
| | | 189787841D925B5D006245B9 /* GoogleAdTableViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GoogleAdTableViewCell.m; sourceTree = "<group>"; }; |
| | | 189787851D925B5D006245B9 /* GoogleAdTableViewCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = GoogleAdTableViewCell.xib; sourceTree = "<group>"; }; |
| | | 189EFECA1EF1465D00C59CAB /* yw_1222.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = yw_1222.jpg; sourceTree = "<group>"; }; |
| | | 18A060462060EEE400BACA54 /* GDTTrack.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GDTTrack.h; sourceTree = "<group>"; }; |
| | | 18A060472060EEE500BACA54 /* libGDTMobSDK.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libGDTMobSDK.a; sourceTree = "<group>"; }; |
| | | 18A060482060EEE500BACA54 /* GDTNativeExpressAdView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GDTNativeExpressAdView.h; sourceTree = "<group>"; }; |
| | | 18A060492060EEE600BACA54 /* GDTMobBannerView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GDTMobBannerView.h; sourceTree = "<group>"; }; |
| | | 18A0604A2060EEE600BACA54 /* GDTNativeAd.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GDTNativeAd.h; sourceTree = "<group>"; }; |
| | | 18A0604B2060EEE600BACA54 /* GDTSplashAd.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GDTSplashAd.h; sourceTree = "<group>"; }; |
| | | 18A0604C2060EEE700BACA54 /* GDTMobInterstitial.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GDTMobInterstitial.h; sourceTree = "<group>"; }; |
| | | 18A0604D2060EEE700BACA54 /* GDTNativeExpressAd.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GDTNativeExpressAd.h; sourceTree = "<group>"; }; |
| | | 18ABF6DE1DDD9B4600C9257E /* Nethader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Nethader.h; sourceTree = "<group>"; }; |
| | | 18ABF6DF1DDD9B4600C9257E /* YTHNetdata.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = YTHNetdata.h; sourceTree = "<group>"; }; |
| | | 18ABF6E01DDD9B4600C9257E /* YTHNetdata.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = YTHNetdata.m; sourceTree = "<group>"; }; |
| | |
| | | 18ED606E1E165CE000AF8252 /* findGoodsTableViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = findGoodsTableViewCell.h; sourceTree = "<group>"; }; |
| | | 18ED606F1E165CE000AF8252 /* findGoodsTableViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = findGoodsTableViewCell.m; sourceTree = "<group>"; }; |
| | | 18ED60701E165CE000AF8252 /* findGoodsTableViewCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = findGoodsTableViewCell.xib; sourceTree = "<group>"; }; |
| | | 18EF91D71D8E42DA0078C8BD /* NJKWebViewProgress.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NJKWebViewProgress.h; sourceTree = "<group>"; }; |
| | | 18EF91D81D8E42DA0078C8BD /* NJKWebViewProgress.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NJKWebViewProgress.m; sourceTree = "<group>"; }; |
| | | 18EF91D91D8E42DA0078C8BD /* NJKWebViewProgressView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NJKWebViewProgressView.h; sourceTree = "<group>"; }; |
| | | 18EF91DA1D8E42DA0078C8BD /* NJKWebViewProgressView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NJKWebViewProgressView.m; sourceTree = "<group>"; }; |
| | | 18EF91E01D8E47610078C8BD /* WEBViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WEBViewController.h; sourceTree = "<group>"; }; |
| | | 18EF91E11D8E47610078C8BD /* WEBViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WEBViewController.m; sourceTree = "<group>"; }; |
| | | 18F2541C1DF0090900826AD0 /* FuLiSheViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FuLiSheViewController.h; sourceTree = "<group>"; }; |
| | |
| | | 2DBB90CC22320D2900E70439 /* DisCoverADView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DisCoverADView.h; sourceTree = "<group>"; }; |
| | | 2DBB90CD22320D2900E70439 /* DisCoverADView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = DisCoverADView.m; sourceTree = "<group>"; }; |
| | | 2DBB90CF22320D3D00E70439 /* DisCoverADView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = DisCoverADView.xib; sourceTree = "<group>"; }; |
| | | 2DD6078821AD3ABB0036A759 /* GDTRewardVideoAd.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GDTRewardVideoAd.h; sourceTree = "<group>"; }; |
| | | 2DD6078921AD3ABC0036A759 /* GDTSDKDefines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GDTSDKDefines.h; sourceTree = "<group>"; }; |
| | | 2DD6078A21AD3ABC0036A759 /* GDTSDKConfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GDTSDKConfig.h; sourceTree = "<group>"; }; |
| | | 2DEC6E5A22017DC5009B06D4 /* UITabBar+mainTab.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "UITabBar+mainTab.h"; sourceTree = "<group>"; }; |
| | | 2DEC6E5B22017DC5009B06D4 /* UITabBar+mainTab.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "UITabBar+mainTab.m"; sourceTree = "<group>"; }; |
| | | 2DECF92B22325172002FF49F /* GuessLikeViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GuessLikeViewController.h; sourceTree = "<group>"; }; |
| | |
| | | 2DECF92F22325854002FF49F /* GuessLTableViewCell.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = GuessLTableViewCell.m; sourceTree = "<group>"; }; |
| | | 2DECF93022325854002FF49F /* GuessLTableViewCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = GuessLTableViewCell.xib; sourceTree = "<group>"; }; |
| | | 5326AC3933907F23F3929227 /* Pods-BuWanVideo2.0.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-BuWanVideo2.0.release.xcconfig"; path = "Pods/Target Support Files/Pods-BuWanVideo2.0/Pods-BuWanVideo2.0.release.xcconfig"; sourceTree = "<group>"; }; |
| | | 7042C94B2515A4FE0017F5D8 /* BUAdSDK.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = BUAdSDK.framework; sourceTree = "<group>"; }; |
| | | 7042C94C2515A4FE0017F5D8 /* BUFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = BUFoundation.framework; sourceTree = "<group>"; }; |
| | | 7042C94D2515A4FE0017F5D8 /* BUAdSDK.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; path = BUAdSDK.bundle; sourceTree = "<group>"; }; |
| | | 70452801250E2C5C0006C95E /* GDTSDKDefines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GDTSDKDefines.h; sourceTree = "<group>"; }; |
| | | 70452802250E2C5C0006C95E /* GDTRewardVideoAdNetworkConnectorProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GDTRewardVideoAdNetworkConnectorProtocol.h; sourceTree = "<group>"; }; |
| | | 70452803250E2C5C0006C95E /* GDTMediaView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GDTMediaView.h; sourceTree = "<group>"; }; |
| | | 70452804250E2C5C0006C95E /* GDTAdTestSetting.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GDTAdTestSetting.h; sourceTree = "<group>"; }; |
| | | 70452805250E2C5D0006C95E /* GDTNativeExpressAdView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GDTNativeExpressAdView.h; sourceTree = "<group>"; }; |
| | | 70452806250E2C5D0006C95E /* GDTHybridAd.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GDTHybridAd.h; sourceTree = "<group>"; }; |
| | | 70452807250E2C5D0006C95E /* GDTRewardVideoAd.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GDTRewardVideoAd.h; sourceTree = "<group>"; }; |
| | | 70452808250E2C5D0006C95E /* GDTNativeExpressProAdView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GDTNativeExpressProAdView.h; sourceTree = "<group>"; }; |
| | | 70452809250E2C5D0006C95E /* GDTVideoConfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GDTVideoConfig.h; sourceTree = "<group>"; }; |
| | | 7045280A250E2C5D0006C95E /* GDTLoadAdParams.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GDTLoadAdParams.h; sourceTree = "<group>"; }; |
| | | 7045280B250E2C5D0006C95E /* GDTAdParams.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GDTAdParams.h; sourceTree = "<group>"; }; |
| | | 7045280C250E2C5D0006C95E /* GDTUnifiedNativeAdDataObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GDTUnifiedNativeAdDataObject.h; sourceTree = "<group>"; }; |
| | | 7045280D250E2C5E0006C95E /* GDTSplashAd.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GDTSplashAd.h; sourceTree = "<group>"; }; |
| | | 7045280E250E2C5F0006C95E /* libGDTMobSDK.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libGDTMobSDK.a; sourceTree = "<group>"; }; |
| | | 7045280F250E2C600006C95E /* GDTNativeExpressProAdManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GDTNativeExpressProAdManager.h; sourceTree = "<group>"; }; |
| | | 70452810250E2C600006C95E /* GDTLogoView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GDTLogoView.h; sourceTree = "<group>"; }; |
| | | 70452811250E2C600006C95E /* GDTNativeExpressAd.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GDTNativeExpressAd.h; sourceTree = "<group>"; }; |
| | | 70452812250E2C600006C95E /* GDTSDKConfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GDTSDKConfig.h; sourceTree = "<group>"; }; |
| | | 70452813250E2C600006C95E /* GDTBaseAdNetworkAdapterProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GDTBaseAdNetworkAdapterProtocol.h; sourceTree = "<group>"; }; |
| | | 70452814250E2C600006C95E /* GDTUnifiedBannerView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GDTUnifiedBannerView.h; sourceTree = "<group>"; }; |
| | | 70452815250E2C600006C95E /* GDTUnifiedInterstitialAd.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GDTUnifiedInterstitialAd.h; sourceTree = "<group>"; }; |
| | | 70452816250E2C600006C95E /* GDTRewardVideoAdNetworkAdapterProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GDTRewardVideoAdNetworkAdapterProtocol.h; sourceTree = "<group>"; }; |
| | | 70452817250E2C600006C95E /* GDTUnifiedNativeAd.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GDTUnifiedNativeAd.h; sourceTree = "<group>"; }; |
| | | 70452818250E2C610006C95E /* GDTUnifiedNativeAdView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GDTUnifiedNativeAdView.h; sourceTree = "<group>"; }; |
| | | 705951F225161153008E0CDF /* SearchTitleView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SearchTitleView.h; sourceTree = "<group>"; }; |
| | | 705951F325161153008E0CDF /* SearchTitleView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SearchTitleView.m; sourceTree = "<group>"; }; |
| | | 705951F5251633E9008E0CDF /* SearchDetailListCell.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SearchDetailListCell.h; sourceTree = "<group>"; }; |
| | | 705951F6251633E9008E0CDF /* SearchDetailListCell.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SearchDetailListCell.m; sourceTree = "<group>"; }; |
| | | 705F1E82251F085D0065350E /* Share.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Share.m; sourceTree = "<group>"; }; |
| | | 705F1E83251F085D0065350E /* Share.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Share.h; sourceTree = "<group>"; }; |
| | | 705F1F37251F1CA70065350E /* UIScrollView+MJRefresh.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIScrollView+MJRefresh.m"; sourceTree = "<group>"; }; |
| | | 705F1F38251F1CA70065350E /* MJRefreshConst.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MJRefreshConst.m; sourceTree = "<group>"; }; |
| | | 705F1F39251F1CA70065350E /* MJRefreshConfig.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MJRefreshConfig.m; sourceTree = "<group>"; }; |
| | | 705F1F3A251F1CA70065350E /* UIScrollView+MJExtension.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIScrollView+MJExtension.h"; sourceTree = "<group>"; }; |
| | | 705F1F3B251F1CA70065350E /* MJRefresh.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MJRefresh.h; sourceTree = "<group>"; }; |
| | | 705F1F3C251F1CA70065350E /* NSBundle+MJRefresh.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSBundle+MJRefresh.h"; sourceTree = "<group>"; }; |
| | | 705F1F3D251F1CA70065350E /* MJRefresh.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; path = MJRefresh.bundle; sourceTree = "<group>"; }; |
| | | 705F1F3E251F1CA70065350E /* UIView+MJExtension.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIView+MJExtension.h"; sourceTree = "<group>"; }; |
| | | 705F1F3F251F1CA70065350E /* UIScrollView+MJExtension.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIScrollView+MJExtension.m"; sourceTree = "<group>"; }; |
| | | 705F1F40251F1CA70065350E /* MJRefreshConfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MJRefreshConfig.h; sourceTree = "<group>"; }; |
| | | 705F1F41251F1CA70065350E /* MJRefreshConst.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MJRefreshConst.h; sourceTree = "<group>"; }; |
| | | 705F1F42251F1CA70065350E /* UIScrollView+MJRefresh.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIScrollView+MJRefresh.h"; sourceTree = "<group>"; }; |
| | | 705F1F43251F1CA70065350E /* NSBundle+MJRefresh.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSBundle+MJRefresh.m"; sourceTree = "<group>"; }; |
| | | 705F1F44251F1CA70065350E /* UIView+MJExtension.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIView+MJExtension.m"; sourceTree = "<group>"; }; |
| | | 705F1F48251F1CA70065350E /* MJRefreshBackGifFooter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MJRefreshBackGifFooter.h; sourceTree = "<group>"; }; |
| | | 705F1F49251F1CA70065350E /* MJRefreshBackStateFooter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MJRefreshBackStateFooter.h; sourceTree = "<group>"; }; |
| | | 705F1F4A251F1CA70065350E /* MJRefreshBackNormalFooter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MJRefreshBackNormalFooter.h; sourceTree = "<group>"; }; |
| | | 705F1F4B251F1CA70065350E /* MJRefreshBackGifFooter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MJRefreshBackGifFooter.m; sourceTree = "<group>"; }; |
| | | 705F1F4C251F1CA70065350E /* MJRefreshBackStateFooter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MJRefreshBackStateFooter.m; sourceTree = "<group>"; }; |
| | | 705F1F4D251F1CA70065350E /* MJRefreshBackNormalFooter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MJRefreshBackNormalFooter.m; sourceTree = "<group>"; }; |
| | | 705F1F4F251F1CA70065350E /* MJRefreshAutoStateFooter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MJRefreshAutoStateFooter.h; sourceTree = "<group>"; }; |
| | | 705F1F50251F1CA70065350E /* MJRefreshAutoNormalFooter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MJRefreshAutoNormalFooter.h; sourceTree = "<group>"; }; |
| | | 705F1F51251F1CA70065350E /* MJRefreshAutoGifFooter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MJRefreshAutoGifFooter.h; sourceTree = "<group>"; }; |
| | | 705F1F52251F1CA70065350E /* MJRefreshAutoStateFooter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MJRefreshAutoStateFooter.m; sourceTree = "<group>"; }; |
| | | 705F1F53251F1CA70065350E /* MJRefreshAutoGifFooter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MJRefreshAutoGifFooter.m; sourceTree = "<group>"; }; |
| | | 705F1F54251F1CA70065350E /* MJRefreshAutoNormalFooter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MJRefreshAutoNormalFooter.m; sourceTree = "<group>"; }; |
| | | 705F1F56251F1CA70065350E /* MJRefreshNormalTrailer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MJRefreshNormalTrailer.h; sourceTree = "<group>"; }; |
| | | 705F1F57251F1CA70065350E /* MJRefreshStateTrailer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MJRefreshStateTrailer.m; sourceTree = "<group>"; }; |
| | | 705F1F58251F1CA70065350E /* MJRefreshNormalTrailer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MJRefreshNormalTrailer.m; sourceTree = "<group>"; }; |
| | | 705F1F59251F1CA70065350E /* MJRefreshStateTrailer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MJRefreshStateTrailer.h; sourceTree = "<group>"; }; |
| | | 705F1F5B251F1CA70065350E /* MJRefreshNormalHeader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MJRefreshNormalHeader.m; sourceTree = "<group>"; }; |
| | | 705F1F5C251F1CA70065350E /* MJRefreshStateHeader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MJRefreshStateHeader.h; sourceTree = "<group>"; }; |
| | | 705F1F5D251F1CA70065350E /* MJRefreshGifHeader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MJRefreshGifHeader.h; sourceTree = "<group>"; }; |
| | | 705F1F5E251F1CA70065350E /* MJRefreshNormalHeader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MJRefreshNormalHeader.h; sourceTree = "<group>"; }; |
| | | 705F1F5F251F1CA70065350E /* MJRefreshStateHeader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MJRefreshStateHeader.m; sourceTree = "<group>"; }; |
| | | 705F1F60251F1CA70065350E /* MJRefreshGifHeader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MJRefreshGifHeader.m; sourceTree = "<group>"; }; |
| | | 705F1F62251F1CA70065350E /* MJRefreshFooter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MJRefreshFooter.m; sourceTree = "<group>"; }; |
| | | 705F1F63251F1CA70065350E /* MJRefreshComponent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MJRefreshComponent.h; sourceTree = "<group>"; }; |
| | | 705F1F64251F1CA70065350E /* MJRefreshHeader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MJRefreshHeader.m; sourceTree = "<group>"; }; |
| | | 705F1F65251F1CA70065350E /* MJRefreshAutoFooter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MJRefreshAutoFooter.h; sourceTree = "<group>"; }; |
| | | 705F1F66251F1CA70065350E /* MJRefreshTrailer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MJRefreshTrailer.h; sourceTree = "<group>"; }; |
| | | 705F1F67251F1CA70065350E /* MJRefreshBackFooter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MJRefreshBackFooter.m; sourceTree = "<group>"; }; |
| | | 705F1F68251F1CA70065350E /* MJRefreshAutoFooter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MJRefreshAutoFooter.m; sourceTree = "<group>"; }; |
| | | 705F1F69251F1CA70065350E /* MJRefreshHeader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MJRefreshHeader.h; sourceTree = "<group>"; }; |
| | | 705F1F6A251F1CA70065350E /* MJRefreshComponent.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MJRefreshComponent.m; sourceTree = "<group>"; }; |
| | | 705F1F6B251F1CA70065350E /* MJRefreshFooter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MJRefreshFooter.h; sourceTree = "<group>"; }; |
| | | 705F1F6C251F1CA70065350E /* MJRefreshBackFooter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MJRefreshBackFooter.h; sourceTree = "<group>"; }; |
| | | 705F1F6D251F1CA70065350E /* MJRefreshTrailer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MJRefreshTrailer.m; sourceTree = "<group>"; }; |
| | | 7B0D3B261D59BCAB003E74A8 /* AnimationTool.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AnimationTool.h; sourceTree = "<group>"; }; |
| | | 7B0D3B271D59BCAB003E74A8 /* AnimationTool.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AnimationTool.m; sourceTree = "<group>"; }; |
| | | 7B0D3B281D59BCAB003E74A8 /* CMuneBar.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CMuneBar.h; sourceTree = "<group>"; }; |
| | |
| | | 7B1FF0DC1D670B8800E6C207 /* attentionView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = attentionView.m; sourceTree = "<group>"; }; |
| | | 7B1FF0DE1D6711CF00E6C207 /* libiconv.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libiconv.tbd; path = usr/lib/libiconv.tbd; sourceTree = SDKROOT; }; |
| | | 7B1FF0E01D67121700E6C207 /* libstdc++.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = "libstdc++.tbd"; path = "usr/lib/libstdc++.tbd"; sourceTree = SDKROOT; }; |
| | | 7B1FF0E31D67169E00E6C207 /* Share.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Share.h; sourceTree = "<group>"; }; |
| | | 7B1FF0E41D67169E00E6C207 /* Share.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Share.m; sourceTree = "<group>"; }; |
| | | 7B32BD2D1D4F259300E96E75 /* recommendView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = recommendView.h; sourceTree = "<group>"; }; |
| | | 7B32BD2E1D4F259300E96E75 /* recommendView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = recommendView.m; sourceTree = "<group>"; wrapsLines = 1; }; |
| | | 7B32BD301D4F26F500E96E75 /* subregionView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = subregionView.h; sourceTree = "<group>"; }; |
| | |
| | | 2D732550212D6B5200E09821 /* WebP.framework in Frameworks */, |
| | | 2D73254E212D626B00E09821 /* YYWebImage.framework in Frameworks */, |
| | | 2D73254C212D626600E09821 /* YYCache.framework in Frameworks */, |
| | | 7042C94F2515A4FE0017F5D8 /* BUFoundation.framework in Frameworks */, |
| | | 2D73254A212D626000E09821 /* YYImage.framework in Frameworks */, |
| | | 7B8AC4F01D5D802200450285 /* CFNetwork.framework in Frameworks */, |
| | | 7B8AC5221D5D822F00450285 /* CoreMotion.framework in Frameworks */, |
| | |
| | | 7B389BE01D61B2EF0043A2F2 /* libsqlite3.tbd in Frameworks */, |
| | | 7B8AC5321D5D82B100450285 /* OpenGLES.framework in Frameworks */, |
| | | 7B8AC4FA1D5D805900450285 /* CoreText.framework in Frameworks */, |
| | | 70452819250E2C610006C95E /* libGDTMobSDK.a in Frameworks */, |
| | | 7B8AC4FD1D5D806A00450285 /* EventKit.framework in Frameworks */, |
| | | 7B8AC5361D5D82D500450285 /* Social.framework in Frameworks */, |
| | | 7B8AC5301D5D82AA00450285 /* MobileCoreServices.framework in Frameworks */, |
| | |
| | | 7B389BDC1D61B1D10043A2F2 /* ModelIO.framework in Frameworks */, |
| | | 1845BB4B209BF212009C639B /* PassKit.framework in Frameworks */, |
| | | 7B8AC52C1D5D828000450285 /* libz.1.2.5.tbd in Frameworks */, |
| | | 7042C94E2515A4FE0017F5D8 /* BUAdSDK.framework in Frameworks */, |
| | | 7B1FF0DF1D6711CF00E6C207 /* libiconv.tbd in Frameworks */, |
| | | 1877D1791DCAE119000CEC83 /* JavaScriptCore.framework in Frameworks */, |
| | | 1877D1771DCAE100000CEC83 /* CoreData.framework in Frameworks */, |
| | |
| | | 7B8AC5261D5D825200450285 /* GameKit.framework in Frameworks */, |
| | | 7B8AC5241D5D824100450285 /* CoreVideo.framework in Frameworks */, |
| | | 7B8AC5201D5D821100450285 /* CoreImage.framework in Frameworks */, |
| | | 18A0604E2060EEE700BACA54 /* libGDTMobSDK.a in Frameworks */, |
| | | 7B8AC51E1D5D820000450285 /* CoreFoundation.framework in Frameworks */, |
| | | 7B8AC51C1D5D81EF00450285 /* CoreBluetooth.framework in Frameworks */, |
| | | 7B8AC51A1D5D817C00450285 /* CoreAudio.framework in Frameworks */, |
| | |
| | | 1896FB811F7360D300720355 /* GDT_iOS_SDK */ = { |
| | | isa = PBXGroup; |
| | | children = ( |
| | | 2DD6078821AD3ABB0036A759 /* GDTRewardVideoAd.h */, |
| | | 2DD6078A21AD3ABC0036A759 /* GDTSDKConfig.h */, |
| | | 2DD6078921AD3ABC0036A759 /* GDTSDKDefines.h */, |
| | | 18A060492060EEE600BACA54 /* GDTMobBannerView.h */, |
| | | 18A0604C2060EEE700BACA54 /* GDTMobInterstitial.h */, |
| | | 18A0604A2060EEE600BACA54 /* GDTNativeAd.h */, |
| | | 18A0604D2060EEE700BACA54 /* GDTNativeExpressAd.h */, |
| | | 18A060482060EEE500BACA54 /* GDTNativeExpressAdView.h */, |
| | | 18A0604B2060EEE600BACA54 /* GDTSplashAd.h */, |
| | | 18A060462060EEE400BACA54 /* GDTTrack.h */, |
| | | 18A060472060EEE500BACA54 /* libGDTMobSDK.a */, |
| | | 7045280B250E2C5D0006C95E /* GDTAdParams.h */, |
| | | 70452804250E2C5C0006C95E /* GDTAdTestSetting.h */, |
| | | 70452813250E2C600006C95E /* GDTBaseAdNetworkAdapterProtocol.h */, |
| | | 70452806250E2C5D0006C95E /* GDTHybridAd.h */, |
| | | 7045280A250E2C5D0006C95E /* GDTLoadAdParams.h */, |
| | | 70452810250E2C600006C95E /* GDTLogoView.h */, |
| | | 70452803250E2C5C0006C95E /* GDTMediaView.h */, |
| | | 70452811250E2C600006C95E /* GDTNativeExpressAd.h */, |
| | | 70452805250E2C5D0006C95E /* GDTNativeExpressAdView.h */, |
| | | 7045280F250E2C600006C95E /* GDTNativeExpressProAdManager.h */, |
| | | 70452808250E2C5D0006C95E /* GDTNativeExpressProAdView.h */, |
| | | 70452807250E2C5D0006C95E /* GDTRewardVideoAd.h */, |
| | | 70452816250E2C600006C95E /* GDTRewardVideoAdNetworkAdapterProtocol.h */, |
| | | 70452802250E2C5C0006C95E /* GDTRewardVideoAdNetworkConnectorProtocol.h */, |
| | | 70452812250E2C600006C95E /* GDTSDKConfig.h */, |
| | | 70452801250E2C5C0006C95E /* GDTSDKDefines.h */, |
| | | 7045280D250E2C5E0006C95E /* GDTSplashAd.h */, |
| | | 70452814250E2C600006C95E /* GDTUnifiedBannerView.h */, |
| | | 70452815250E2C600006C95E /* GDTUnifiedInterstitialAd.h */, |
| | | 70452817250E2C600006C95E /* GDTUnifiedNativeAd.h */, |
| | | 7045280C250E2C5D0006C95E /* GDTUnifiedNativeAdDataObject.h */, |
| | | 70452818250E2C610006C95E /* GDTUnifiedNativeAdView.h */, |
| | | 70452809250E2C5D0006C95E /* GDTVideoConfig.h */, |
| | | 7045280E250E2C5F0006C95E /* libGDTMobSDK.a */, |
| | | ); |
| | | path = GDT_iOS_SDK; |
| | | sourceTree = "<group>"; |
| | |
| | | children = ( |
| | | 18E943F0205774D50019FD04 /* BaseViewController.h */, |
| | | 18E943F1205774D50019FD04 /* BaseViewController.m */, |
| | | 1883223B1F75058500CCD0B4 /* RooterController.h */, |
| | | 1883223C1F75058500CCD0B4 /* RooterController.m */, |
| | | 7BB429001D4B463000AA2D11 /* MainViewController.h */, |
| | | 7BB429011D4B463000AA2D11 /* MainViewController.m */, |
| | | 7B8ADA371D585D43007A3FFD /* XYRVideoInfoModel.h */, |
| | |
| | | path = detailCell; |
| | | sourceTree = "<group>"; |
| | | }; |
| | | 18EF91D61D8E42B60078C8BD /* NJKWebViewPress */ = { |
| | | isa = PBXGroup; |
| | | children = ( |
| | | 18EF91D71D8E42DA0078C8BD /* NJKWebViewProgress.h */, |
| | | 18EF91D81D8E42DA0078C8BD /* NJKWebViewProgress.m */, |
| | | 18EF91D91D8E42DA0078C8BD /* NJKWebViewProgressView.h */, |
| | | 18EF91DA1D8E42DA0078C8BD /* NJKWebViewProgressView.m */, |
| | | ); |
| | | name = NJKWebViewPress; |
| | | sourceTree = "<group>"; |
| | | }; |
| | | 18F2541B1DF008AA00826AD0 /* 福利社(专用) */ = { |
| | | isa = PBXGroup; |
| | | children = ( |
| | |
| | | 2DECF93022325854002FF49F /* GuessLTableViewCell.xib */, |
| | | ); |
| | | path = "猜你喜欢"; |
| | | sourceTree = "<group>"; |
| | | }; |
| | | 7042C94A2515A4FE0017F5D8 /* CSJ */ = { |
| | | isa = PBXGroup; |
| | | children = ( |
| | | 7042C94B2515A4FE0017F5D8 /* BUAdSDK.framework */, |
| | | 7042C94C2515A4FE0017F5D8 /* BUFoundation.framework */, |
| | | 7042C94D2515A4FE0017F5D8 /* BUAdSDK.bundle */, |
| | | ); |
| | | path = CSJ; |
| | | sourceTree = "<group>"; |
| | | }; |
| | | 705951F12516112D008E0CDF /* View */ = { |
| | | isa = PBXGroup; |
| | | children = ( |
| | | 705951F225161153008E0CDF /* SearchTitleView.h */, |
| | | 705951F325161153008E0CDF /* SearchTitleView.m */, |
| | | 705951F5251633E9008E0CDF /* SearchDetailListCell.h */, |
| | | 705951F6251633E9008E0CDF /* SearchDetailListCell.m */, |
| | | ); |
| | | name = View; |
| | | sourceTree = "<group>"; |
| | | }; |
| | | 705F1F36251F1CA70065350E /* MJRefresh */ = { |
| | | isa = PBXGroup; |
| | | children = ( |
| | | 705F1F37251F1CA70065350E /* UIScrollView+MJRefresh.m */, |
| | | 705F1F38251F1CA70065350E /* MJRefreshConst.m */, |
| | | 705F1F39251F1CA70065350E /* MJRefreshConfig.m */, |
| | | 705F1F3A251F1CA70065350E /* UIScrollView+MJExtension.h */, |
| | | 705F1F3B251F1CA70065350E /* MJRefresh.h */, |
| | | 705F1F3C251F1CA70065350E /* NSBundle+MJRefresh.h */, |
| | | 705F1F3D251F1CA70065350E /* MJRefresh.bundle */, |
| | | 705F1F3E251F1CA70065350E /* UIView+MJExtension.h */, |
| | | 705F1F3F251F1CA70065350E /* UIScrollView+MJExtension.m */, |
| | | 705F1F40251F1CA70065350E /* MJRefreshConfig.h */, |
| | | 705F1F41251F1CA70065350E /* MJRefreshConst.h */, |
| | | 705F1F42251F1CA70065350E /* UIScrollView+MJRefresh.h */, |
| | | 705F1F43251F1CA70065350E /* NSBundle+MJRefresh.m */, |
| | | 705F1F44251F1CA70065350E /* UIView+MJExtension.m */, |
| | | 705F1F45251F1CA70065350E /* Custom */, |
| | | 705F1F61251F1CA70065350E /* Base */, |
| | | ); |
| | | path = MJRefresh; |
| | | sourceTree = "<group>"; |
| | | }; |
| | | 705F1F45251F1CA70065350E /* Custom */ = { |
| | | isa = PBXGroup; |
| | | children = ( |
| | | 705F1F46251F1CA70065350E /* Footer */, |
| | | 705F1F55251F1CA70065350E /* Trailer */, |
| | | 705F1F5A251F1CA70065350E /* Header */, |
| | | ); |
| | | path = Custom; |
| | | sourceTree = "<group>"; |
| | | }; |
| | | 705F1F46251F1CA70065350E /* Footer */ = { |
| | | isa = PBXGroup; |
| | | children = ( |
| | | 705F1F47251F1CA70065350E /* Back */, |
| | | 705F1F4E251F1CA70065350E /* Auto */, |
| | | ); |
| | | path = Footer; |
| | | sourceTree = "<group>"; |
| | | }; |
| | | 705F1F47251F1CA70065350E /* Back */ = { |
| | | isa = PBXGroup; |
| | | children = ( |
| | | 705F1F48251F1CA70065350E /* MJRefreshBackGifFooter.h */, |
| | | 705F1F49251F1CA70065350E /* MJRefreshBackStateFooter.h */, |
| | | 705F1F4A251F1CA70065350E /* MJRefreshBackNormalFooter.h */, |
| | | 705F1F4B251F1CA70065350E /* MJRefreshBackGifFooter.m */, |
| | | 705F1F4C251F1CA70065350E /* MJRefreshBackStateFooter.m */, |
| | | 705F1F4D251F1CA70065350E /* MJRefreshBackNormalFooter.m */, |
| | | ); |
| | | path = Back; |
| | | sourceTree = "<group>"; |
| | | }; |
| | | 705F1F4E251F1CA70065350E /* Auto */ = { |
| | | isa = PBXGroup; |
| | | children = ( |
| | | 705F1F4F251F1CA70065350E /* MJRefreshAutoStateFooter.h */, |
| | | 705F1F50251F1CA70065350E /* MJRefreshAutoNormalFooter.h */, |
| | | 705F1F51251F1CA70065350E /* MJRefreshAutoGifFooter.h */, |
| | | 705F1F52251F1CA70065350E /* MJRefreshAutoStateFooter.m */, |
| | | 705F1F53251F1CA70065350E /* MJRefreshAutoGifFooter.m */, |
| | | 705F1F54251F1CA70065350E /* MJRefreshAutoNormalFooter.m */, |
| | | ); |
| | | path = Auto; |
| | | sourceTree = "<group>"; |
| | | }; |
| | | 705F1F55251F1CA70065350E /* Trailer */ = { |
| | | isa = PBXGroup; |
| | | children = ( |
| | | 705F1F56251F1CA70065350E /* MJRefreshNormalTrailer.h */, |
| | | 705F1F57251F1CA70065350E /* MJRefreshStateTrailer.m */, |
| | | 705F1F58251F1CA70065350E /* MJRefreshNormalTrailer.m */, |
| | | 705F1F59251F1CA70065350E /* MJRefreshStateTrailer.h */, |
| | | ); |
| | | path = Trailer; |
| | | sourceTree = "<group>"; |
| | | }; |
| | | 705F1F5A251F1CA70065350E /* Header */ = { |
| | | isa = PBXGroup; |
| | | children = ( |
| | | 705F1F5B251F1CA70065350E /* MJRefreshNormalHeader.m */, |
| | | 705F1F5C251F1CA70065350E /* MJRefreshStateHeader.h */, |
| | | 705F1F5D251F1CA70065350E /* MJRefreshGifHeader.h */, |
| | | 705F1F5E251F1CA70065350E /* MJRefreshNormalHeader.h */, |
| | | 705F1F5F251F1CA70065350E /* MJRefreshStateHeader.m */, |
| | | 705F1F60251F1CA70065350E /* MJRefreshGifHeader.m */, |
| | | ); |
| | | path = Header; |
| | | sourceTree = "<group>"; |
| | | }; |
| | | 705F1F61251F1CA70065350E /* Base */ = { |
| | | isa = PBXGroup; |
| | | children = ( |
| | | 705F1F62251F1CA70065350E /* MJRefreshFooter.m */, |
| | | 705F1F63251F1CA70065350E /* MJRefreshComponent.h */, |
| | | 705F1F64251F1CA70065350E /* MJRefreshHeader.m */, |
| | | 705F1F65251F1CA70065350E /* MJRefreshAutoFooter.h */, |
| | | 705F1F66251F1CA70065350E /* MJRefreshTrailer.h */, |
| | | 705F1F67251F1CA70065350E /* MJRefreshBackFooter.m */, |
| | | 705F1F68251F1CA70065350E /* MJRefreshAutoFooter.m */, |
| | | 705F1F69251F1CA70065350E /* MJRefreshHeader.h */, |
| | | 705F1F6A251F1CA70065350E /* MJRefreshComponent.m */, |
| | | 705F1F6B251F1CA70065350E /* MJRefreshFooter.h */, |
| | | 705F1F6C251F1CA70065350E /* MJRefreshBackFooter.h */, |
| | | 705F1F6D251F1CA70065350E /* MJRefreshTrailer.m */, |
| | | ); |
| | | path = Base; |
| | | sourceTree = "<group>"; |
| | | }; |
| | | 7B0A1E1F1D4B1437000518FA /* cell */ = { |
| | |
| | | 7B1FF0E21D67166C00E6C207 /* Share(公共) */ = { |
| | | isa = PBXGroup; |
| | | children = ( |
| | | 7B1FF0E31D67169E00E6C207 /* Share.h */, |
| | | 7B1FF0E41D67169E00E6C207 /* Share.m */, |
| | | 705F1E83251F085D0065350E /* Share.h */, |
| | | 705F1E82251F085D0065350E /* Share.m */, |
| | | 7BC24A501D50282200F6D2D9 /* YTHsharedManger.h */, |
| | | 7BC24A511D50282200F6D2D9 /* YTHsharedManger.m */, |
| | | 18BBB9021E23977E00793EAB /* LSPageScrollView.h */, |
| | |
| | | 7BC600A01D63F134005CE8FD /* searchView(搜索) */ = { |
| | | isa = PBXGroup; |
| | | children = ( |
| | | 705951F12516112D008E0CDF /* View */, |
| | | 7BC600A31D63F187005CE8FD /* viewController */, |
| | | 7BC600A11D63F167005CE8FD /* view */, |
| | | ); |
| | |
| | | AD73C5ED1D4DDBAE0060437E /* lib(第三方库) */ = { |
| | | isa = PBXGroup; |
| | | children = ( |
| | | 705F1F36251F1CA70065350E /* MJRefresh */, |
| | | 7042C94A2515A4FE0017F5D8 /* CSJ */, |
| | | 188322341F74AFFD00CCD0B4 /* HXEasyCustomShare */, |
| | | 1896FB811F7360D300720355 /* GDT_iOS_SDK */, |
| | | 1884A6051E54630300548480 /* LGLAlertView */, |
| | |
| | | 187A74521DF79DDF001E856F /* LXAlertView */, |
| | | 18B1C2391DB5B26B00AB709B /* HMSegmentedControl */, |
| | | 18B1C2541DB5B26B00AB709B /* SlideMenuControllerOC */, |
| | | 18EF91D61D8E42B60078C8BD /* NJKWebViewPress */, |
| | | 7BF5265F1D742C65004B9DBB /* weikouAD */, |
| | | 7B8ADA3A1D588C6C007A3FFD /* MuneBar */, |
| | | AD73C5F11D4DE72E0060437E /* GTMBase64 */, |
| | |
| | | 7B41E9971D4A04AE00F05CE2 /* Resources */, |
| | | 18FEC7C31DCC7958001C4F51 /* Embed Frameworks */, |
| | | FE8605A55E7B8A38B0D237D5 /* [CP] Embed Pods Frameworks */, |
| | | 833E2D4951B9E9642185698D /* [CP] Copy Pods Resources */, |
| | | ); |
| | | buildRules = ( |
| | | ); |
| | |
| | | 18B6BE6E1DADDB4700DA4F63 /* InfoTableViewCell.xib in Resources */, |
| | | 7B4220FA1D6D7DDE007345E6 /* OnlySpecialOne.xib in Resources */, |
| | | 18BC12A81EDEA7AD001E2FB0 /* HotLiveTableViewCell.xib in Resources */, |
| | | 7042C9502515A4FE0017F5D8 /* BUAdSDK.bundle in Resources */, |
| | | 7B9D31CD1D54481000EDED00 /* XYRDetailViewController.xib in Resources */, |
| | | 7B59CC001D5B15A3000B357F /* GroupCollectionViewCell.xib in Resources */, |
| | | 7B4220FC1D6D7DDE007345E6 /* OnlySpecialThere.xib in Resources */, |
| | |
| | | 18ED60721E165CE000AF8252 /* findGoodsTableViewCell.xib in Resources */, |
| | | 18B6BE621DADC64A00DA4F63 /* Personal_informationViewController.xib in Resources */, |
| | | 7B59CC0F1D5B16B7000B357F /* GroupSmallSection.xib in Resources */, |
| | | 705F1F71251F1CA80065350E /* MJRefresh.bundle in Resources */, |
| | | 7B893F471D7043030028A556 /* AttentionCollectionReusableView.xib in Resources */, |
| | | 7B59CC0A1D5B162A000B357F /* GuessYouLikeCollectionViewCell.xib in Resources */, |
| | | 187A745E1DF7B1C6001E856F /* titleImage2.png in Resources */, |
| | |
| | | shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; |
| | | showEnvVarsInLog = 0; |
| | | }; |
| | | 833E2D4951B9E9642185698D /* [CP] Copy Pods Resources */ = { |
| | | isa = PBXShellScriptBuildPhase; |
| | | buildActionMask = 2147483647; |
| | | files = ( |
| | | ); |
| | | inputPaths = ( |
| | | "${SRCROOT}/Pods/Target Support Files/Pods-BuWanVideo2.0/Pods-BuWanVideo2.0-resources.sh", |
| | | "${PODS_ROOT}/UMengUShare/UShareSDK/UMSocialSDK/UMSocialSDKPromptResources.bundle", |
| | | "${PODS_ROOT}/UMengUShare/UShareSDK/SocialLibraries/QQ/QQSDK/TencentOpenApi_IOS_Bundle.bundle", |
| | | "${PODS_ROOT}/UMengUShare/UShareSDK/UMSocialUI/UMSocialSDKResources.bundle", |
| | | ); |
| | | name = "[CP] Copy Pods Resources"; |
| | | outputPaths = ( |
| | | "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/UMSocialSDKPromptResources.bundle", |
| | | "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/TencentOpenApi_IOS_Bundle.bundle", |
| | | "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/UMSocialSDKResources.bundle", |
| | | ); |
| | | runOnlyForDeploymentPostprocessing = 0; |
| | | shellPath = /bin/sh; |
| | | shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-BuWanVideo2.0/Pods-BuWanVideo2.0-resources.sh\"\n"; |
| | | showEnvVarsInLog = 0; |
| | | }; |
| | | FE8605A55E7B8A38B0D237D5 /* [CP] Embed Pods Frameworks */ = { |
| | | isa = PBXShellScriptBuildPhase; |
| | | buildActionMask = 2147483647; |
| | | files = ( |
| | | ); |
| | | inputPaths = ( |
| | | "${SRCROOT}/Pods/Target Support Files/Pods-BuWanVideo2.0/Pods-BuWanVideo2.0-frameworks.sh", |
| | | "${PODS_ROOT}/Target Support Files/Pods-BuWanVideo2.0/Pods-BuWanVideo2.0-frameworks.sh", |
| | | "${BUILT_PRODUCTS_DIR}/AFNetworking/AFNetworking.framework", |
| | | "${BUILT_PRODUCTS_DIR}/GoogleToolboxForMac/GoogleToolboxForMac.framework", |
| | | "${BUILT_PRODUCTS_DIR}/MJRefresh/MJRefresh.framework", |
| | | "${BUILT_PRODUCTS_DIR}/SDWebImage/SDWebImage.framework", |
| | | "${BUILT_PRODUCTS_DIR}/SVProgressHUD/SVProgressHUD.framework", |
| | | "${BUILT_PRODUCTS_DIR}/YYCache/YYCache.framework", |
| | | "${BUILT_PRODUCTS_DIR}/YYImage/YYImage.framework", |
| | | "${BUILT_PRODUCTS_DIR}/YYModel/YYModel.framework", |
| | | "${BUILT_PRODUCTS_DIR}/YYWebImage/YYWebImage.framework", |
| | | "${BUILT_PRODUCTS_DIR}/nanopb/nanopb.framework", |
| | | ); |
| | | name = "[CP] Embed Pods Frameworks"; |
| | | outputPaths = ( |
| | | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/AFNetworking.framework", |
| | | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/GoogleToolboxForMac.framework", |
| | | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/MJRefresh.framework", |
| | | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SDWebImage.framework", |
| | | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SVProgressHUD.framework", |
| | | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/YYCache.framework", |
| | | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/YYImage.framework", |
| | | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/YYModel.framework", |
| | | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/YYWebImage.framework", |
| | | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/nanopb.framework", |
| | | ); |
| | | runOnlyForDeploymentPostprocessing = 0; |
| | | shellPath = /bin/sh; |
| | | shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-BuWanVideo2.0/Pods-BuWanVideo2.0-frameworks.sh\"\n"; |
| | | shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-BuWanVideo2.0/Pods-BuWanVideo2.0-frameworks.sh\"\n"; |
| | | showEnvVarsInLog = 0; |
| | | }; |
| | | /* End PBXShellScriptBuildPhase section */ |
| | |
| | | isa = PBXSourcesBuildPhase; |
| | | buildActionMask = 2147483647; |
| | | files = ( |
| | | 705F1F74251F1CA80065350E /* UIView+MJExtension.m in Sources */, |
| | | 705F1F79251F1CA80065350E /* MJRefreshAutoGifFooter.m in Sources */, |
| | | 18678ED920BE96D5000F5D54 /* recommendView.m in Sources */, |
| | | 188322391F74B62400CCD0B4 /* HXEasyCustomShareView.m in Sources */, |
| | | 2DEC6E5C22017DC5009B06D4 /* UITabBar+mainTab.m in Sources */, |
| | |
| | | 7BB429151D4B5FC900AA2D11 /* UIImageView+YTH.m in Sources */, |
| | | 7B59CC181D5B16DC000B357F /* ADCollectionReusableView.m in Sources */, |
| | | 183080E01E29D0E60017DDD7 /* XYRChildTableViewCell.m in Sources */, |
| | | 705F1F7A251F1CA80065350E /* MJRefreshAutoNormalFooter.m in Sources */, |
| | | 705F1F84251F1CA80065350E /* MJRefreshComponent.m in Sources */, |
| | | 7B41E9A11D4A04AE00F05CE2 /* AppDelegate.m in Sources */, |
| | | 18F5CAA51E1CD25E001F526F /* allCommentsViewController.m in Sources */, |
| | | 18E943EC2057667D0019FD04 /* MineViewController.m in Sources */, |
| | | 7BC24A601D50754600F6D2D9 /* FooterCollectionReusableView.m in Sources */, |
| | | 7B4220FD1D6D7DDE007345E6 /* OnlySpecialTwo.m in Sources */, |
| | | 7B4220ED1D6D7D34007345E6 /* AllSpecialCell.m in Sources */, |
| | | 705F1F77251F1CA80065350E /* MJRefreshBackNormalFooter.m in Sources */, |
| | | 183080D91E29CD2F0017DDD7 /* childCollectionViewCell.m in Sources */, |
| | | 2D1E3DB82134FF4C0021C50A /* BSKImagesPageView.m in Sources */, |
| | | 7B59CBFA1D5B1447000B357F /* GroupSection.m in Sources */, |
| | | 7BFBC6831D6705AB0058FFEB /* SettingWebView.m in Sources */, |
| | | 7B59CC0E1D5B16B7000B357F /* GroupSmallSection.m in Sources */, |
| | | 7B0D3B2C1D59BCAB003E74A8 /* AnimationTool.m in Sources */, |
| | | 705951F425161153008E0CDF /* SearchTitleView.m in Sources */, |
| | | 7B59CC041D5B15C4000B357F /* IntroductionCollectionViewCell.m in Sources */, |
| | | 7B1FF0C21D670A3B00E6C207 /* Starview.m in Sources */, |
| | | 7BFBC6621D6704EF0058FFEB /* LookNoteController.m in Sources */, |
| | | 2D3F513821AE716F00C50FA5 /* AdCollectionViewCell.m in Sources */, |
| | | 18B1C25C1DB5B26B00AB709B /* README.md in Sources */, |
| | | 18B1C2681DB5B26B00AB709B /* SlideMenuController.m in Sources */, |
| | | 705F1F78251F1CA80065350E /* MJRefreshAutoStateFooter.m in Sources */, |
| | | 18E943E9205766510019FD04 /* subregionViewController.m in Sources */, |
| | | 7B0D3B2E1D59BCAB003E74A8 /* CMuneItem.m in Sources */, |
| | | 18E943F52057C5720019FD04 /* JYNetWorking.m in Sources */, |
| | | 181D3A091E1DFD5300CDBDE9 /* XYRUITextField.m in Sources */, |
| | | 705F1F83251F1CA80065350E /* MJRefreshAutoFooter.m in Sources */, |
| | | 705F1F85251F1CA80065350E /* MJRefreshTrailer.m in Sources */, |
| | | 18F5CAA01E1C8E79001F526F /* discoverGoodsDetailViewController.m in Sources */, |
| | | 7B59CBFF1D5B15A3000B357F /* GroupCollectionViewCell.m in Sources */, |
| | | 18B1C25A1DB5B26B00AB709B /* HMSegmentedControl.m in Sources */, |
| | | 18ABF6E41DDD9B4600C9257E /* YTHNetInterface.m in Sources */, |
| | | 2D433C162236684100083427 /* FaxianCReusableView.m in Sources */, |
| | | 18D94EAB1ECD7B6E00B6FA54 /* newADCollectionViewCell.m in Sources */, |
| | | 705F1F73251F1CA80065350E /* NSBundle+MJRefresh.m in Sources */, |
| | | 7BFBC66D1D6705280058FFEB /* ComentCell.m in Sources */, |
| | | 7B1FF0D01D670AA900E6C207 /* TWScell.m in Sources */, |
| | | 18E943F2205774D50019FD04 /* BaseViewController.m in Sources */, |
| | | 1884A6081E54630300548480 /* LGLAlertView.m in Sources */, |
| | | 7BF526591D7408A0004B9DBB /* CollectionController.m in Sources */, |
| | | 18C5F6401E1B8B0A00537707 /* findTitleTableViewCell.m in Sources */, |
| | | 705F1F6F251F1CA80065350E /* MJRefreshConst.m in Sources */, |
| | | 7BF5266B1D742C80004B9DBB /* adModel.m in Sources */, |
| | | 187A74571DF79DDF001E856F /* LXAlertView.m in Sources */, |
| | | 7BF526691D742C80004B9DBB /* WeiKouNetWorkRequest.m in Sources */, |
| | |
| | | 7B1FF0CB1D670A7F00E6C207 /* StarsController.m in Sources */, |
| | | 7B1FF0D41D670AB200E6C207 /* TWScontroller.m in Sources */, |
| | | 18BC12C01EDEAB8D001E2FB0 /* LiveListCollectionViewCell.m in Sources */, |
| | | 705F1F72251F1CA80065350E /* UIScrollView+MJExtension.m in Sources */, |
| | | 705F1F76251F1CA80065350E /* MJRefreshBackStateFooter.m in Sources */, |
| | | 18BC12AC1EDEA838001E2FB0 /* AllLiveTypeTableViewCell.m in Sources */, |
| | | 18ABF6E31DDD9B4600C9257E /* YTHNetdata.m in Sources */, |
| | | 7B1FF0A61D67094500E6C207 /* CellOne.m in Sources */, |
| | |
| | | 7B4220F91D6D7DDE007345E6 /* OnlySpecialOne.m in Sources */, |
| | | 2DBB90CE22320D2900E70439 /* DisCoverADView.m in Sources */, |
| | | 7BF5266A1D742C80004B9DBB /* WeiKouAdView.m in Sources */, |
| | | 705F1F7C251F1CA80065350E /* MJRefreshNormalTrailer.m in Sources */, |
| | | 1845BB48209BF13D009C639B /* DisCoverTableViewCell.m in Sources */, |
| | | 18F5CAAB1E1CFE8C001F526F /* PublishGoodsViewController.m in Sources */, |
| | | 18FB20DE1EE7E5330008AFD9 /* liveTopicViewController.m in Sources */, |
| | |
| | | 7BFBC65E1D6704E20058FFEB /* NoteCell.m in Sources */, |
| | | 182F49632092D0E200FEAAF7 /* UINavigationBar+SJNav.m in Sources */, |
| | | 7B893F461D7043030028A556 /* AttentionCollectionReusableView.m in Sources */, |
| | | 705951F7251633E9008E0CDF /* SearchDetailListCell.m in Sources */, |
| | | 705F1F7E251F1CA80065350E /* MJRefreshStateHeader.m in Sources */, |
| | | 18EF91E31D8E47610078C8BD /* WEBViewController.m in Sources */, |
| | | 2D1E3DBB213536700021C50A /* NoNetworkView.m in Sources */, |
| | | 7B32BD3D1D4F410F00E96E75 /* recommentCollectionViewCell.m in Sources */, |
| | | 18EF91DB1D8E42DA0078C8BD /* NJKWebViewProgress.m in Sources */, |
| | | 18BC12BB1EDEAB68001E2FB0 /* AllLiveTypeCollectionViewCell.m in Sources */, |
| | | 7B8ADA391D585D43007A3FFD /* XYRVideoInfoModel.m in Sources */, |
| | | ADF5E0A51D4E33C1005F8A9E /* LeftTableViewCell.m in Sources */, |
| | | 705F1F75251F1CA80065350E /* MJRefreshBackGifFooter.m in Sources */, |
| | | 7B9D31C31D5421E000EDED00 /* SubregionViewCollectionViewCell.m in Sources */, |
| | | 705F1F82251F1CA80065350E /* MJRefreshBackFooter.m in Sources */, |
| | | 189787861D925B5D006245B9 /* GoogleAdTableViewCell.m in Sources */, |
| | | 705F1F70251F1CA80065350E /* MJRefreshConfig.m in Sources */, |
| | | 188175201DC05C51004A2540 /* liveOnLineView.m in Sources */, |
| | | 7BB429171D4B5FC900AA2D11 /* NSString+YTH.m in Sources */, |
| | | 7BF5266C1D742C80004B9DBB /* NSString+WeiKouAd.m in Sources */, |
| | | 7B1FF0E51D67169E00E6C207 /* Share.m in Sources */, |
| | | 18ED60711E165CE000AF8252 /* findGoodsTableViewCell.m in Sources */, |
| | | 7B9D31CC1D54481000EDED00 /* XYRDetailViewController.m in Sources */, |
| | | 18B6BE681DADDB2C00DA4F63 /* IconTableViewCell.m in Sources */, |
| | | 7B1FF0951D6708FD00E6C207 /* discoverView.m in Sources */, |
| | | 705F1F81251F1CA80065350E /* MJRefreshHeader.m in Sources */, |
| | | 7BFBC6861D6705AB0058FFEB /* SettingController.m in Sources */, |
| | | 7B32BD321D4F26F500E96E75 /* subregionView.m in Sources */, |
| | | 7BC600AC1D63F560005CE8FD /* searchDetailViewController.m in Sources */, |
| | |
| | | 7B1FF0D91D670B7E00E6C207 /* AttentionCell.m in Sources */, |
| | | 7BCE16701D640A75004EAD5A /* YTHSearchTextField.m in Sources */, |
| | | AD73C5F51D4DE7DD0060437E /* GTMBase64.m in Sources */, |
| | | 18EF91DC1D8E42DA0078C8BD /* NJKWebViewProgressView.m in Sources */, |
| | | 7B41E99E1D4A04AE00F05CE2 /* main.m in Sources */, |
| | | 705F1E84251F085D0065350E /* Share.m in Sources */, |
| | | 7BC600A71D63F1B9005CE8FD /* searchViewController.m in Sources */, |
| | | 2DECF93122325854002FF49F /* GuessLTableViewCell.m in Sources */, |
| | | 7BC24A5B1D50752B00F6D2D9 /* HeaderCollectionReusableView.m in Sources */, |
| | |
| | | 18FC90F71D9144320041D298 /* GoogleAdCollectionReusableView.m in Sources */, |
| | | 2D1198E5212E93CD0043EA39 /* UIViewController+Tools.m in Sources */, |
| | | 7B7BB82F1D65558500066939 /* SearchCollectionReusableView.m in Sources */, |
| | | 705F1F80251F1CA80065350E /* MJRefreshFooter.m in Sources */, |
| | | 7BFBC6901D6705DD0058FFEB /* StorageSpaceTableViewCell.m in Sources */, |
| | | 7B1FF0BA1D670A1F00E6C207 /* AllSpecialController.m in Sources */, |
| | | 7BC24A521D50282200F6D2D9 /* YTHsharedManger.m in Sources */, |
| | |
| | | 7BCE16771D644EB8004EAD5A /* SearchCollectionViewCell.m in Sources */, |
| | | 7B8ADA461D589448007A3FFD /* XYRVideoDetailModel.m in Sources */, |
| | | 18E943EF205767120019FD04 /* discoverViewController.m in Sources */, |
| | | 705F1F7B251F1CA80065350E /* MJRefreshStateTrailer.m in Sources */, |
| | | 705F1F7D251F1CA80065350E /* MJRefreshNormalHeader.m in Sources */, |
| | | 705F1F7F251F1CA80065350E /* MJRefreshGifHeader.m in Sources */, |
| | | 18E943E62057656C0019FD04 /* recommendViewController.m in Sources */, |
| | | 7BB429141D4B5FC900AA2D11 /* UIImage+YTH.m in Sources */, |
| | | 7B1FF0DD1D670B8800E6C207 /* attentionView.m in Sources */, |
| | |
| | | 7BFBC6461D6703E40058FFEB /* WebControllerView.m in Sources */, |
| | | 18BC12B11EDEA87D001E2FB0 /* LiveListTableViewCell.m in Sources */, |
| | | 7B1FF0AE1D67094500E6C207 /* CellHead.m in Sources */, |
| | | 705F1F6E251F1CA80065350E /* UIScrollView+MJRefresh.m in Sources */, |
| | | 18BC12A71EDEA7AD001E2FB0 /* HotLiveTableViewCell.m in Sources */, |
| | | 7B59CC131D5B16CC000B357F /* GroupfootSection.m in Sources */, |
| | | 1883223E1F75058500CCD0B4 /* RooterController.m in Sources */, |
| | | 18ED606C1E1632E300AF8252 /* StartCollectionViewCell.m in Sources */, |
| | | ); |
| | | runOnlyForDeploymentPostprocessing = 0; |
| | |
| | | CODE_SIGN_IDENTITY = "iPhone Developer"; |
| | | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; |
| | | CODE_SIGN_STYLE = Automatic; |
| | | CURRENT_PROJECT_VERSION = 75; |
| | | DEVELOPMENT_TEAM = 98HSDT7AP4; |
| | | ENABLE_BITCODE = NO; |
| | | FRAMEWORK_SEARCH_PATHS = ( |
| | |
| | | "$(PROJECT_DIR)/BuWanVideo2.0", |
| | | "$(PROJECT_DIR)/BuWanVideo2.0/ALiTrade\\ -\\ 3.0.3", |
| | | "$(PROJECT_DIR)/Pods/YYImage/Vendor", |
| | | "$(PROJECT_DIR)/BuWanVideo2.0/CSJ", |
| | | ); |
| | | GCC_PREFIX_HEADER = "$(SRCROOT)/PrefixHeader.pch"; |
| | | GCC_PREPROCESSOR_DEFINITIONS = ( |
| | |
| | | "$(PROJECT_DIR)/BuWanVideo2.0/DKADSet_iOS_SDK_1.2.0_iphoneOS", |
| | | "$(PROJECT_DIR)/BuWanVideo2.0/GDT_iOS_SDK", |
| | | ); |
| | | MARKETING_VERSION = 3.1.0; |
| | | ONLY_ACTIVE_ARCH = YES; |
| | | OTHER_LDFLAGS = ( |
| | | "$(inherited)", |
| | | "-ObjC", |
| | | "-l\"SocialQQ\"", |
| | | "-l\"c++\"", |
| | | "-l\"iconv\"", |
| | | "-l\"sqlite3\"", |
| | |
| | | "-framework", |
| | | "\"CoreVideo\"", |
| | | "-framework", |
| | | "\"FirebaseAnalytics\"", |
| | | "-framework", |
| | | "\"FirebaseCore\"", |
| | | "-framework", |
| | | "\"FirebaseInstanceID\"", |
| | | "-framework", |
| | | "\"GLKit\"", |
| | | "-framework", |
| | | "\"GoogleMobileAds\"", |
| | | "-framework", |
| | | "\"ImageIO\"", |
| | | "-framework", |
| | | "\"MJRefresh\"", |
| | | "-framework", |
| | | "\"MediaPlayer\"", |
| | | "-framework", |
| | |
| | | "\"StoreKit\"", |
| | | "-framework", |
| | | "\"SystemConfiguration\"", |
| | | "-framework", |
| | | "\"TencentOpenAPI\"", |
| | | "-framework", |
| | | "\"UMMobClick\"", |
| | | "-framework", |
| | | "\"YYCache\"", |
| | | "-framework", |
| | |
| | | CODE_SIGN_IDENTITY = "iPhone Developer"; |
| | | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; |
| | | CODE_SIGN_STYLE = Automatic; |
| | | CURRENT_PROJECT_VERSION = 75; |
| | | DEVELOPMENT_TEAM = 98HSDT7AP4; |
| | | ENABLE_BITCODE = NO; |
| | | FRAMEWORK_SEARCH_PATHS = ( |
| | |
| | | "$(PROJECT_DIR)/BuWanVideo2.0", |
| | | "$(PROJECT_DIR)/BuWanVideo2.0/ALiTrade\\ -\\ 3.0.3", |
| | | "$(PROJECT_DIR)/Pods/YYImage/Vendor", |
| | | "$(PROJECT_DIR)/BuWanVideo2.0/CSJ", |
| | | ); |
| | | GCC_PREFIX_HEADER = "$(SRCROOT)/PrefixHeader.pch"; |
| | | GCC_PREPROCESSOR_DEFINITIONS = ( |
| | |
| | | "$(PROJECT_DIR)/BuWanVideo2.0/DKADSet_iOS_SDK_1.2.0_iphoneOS", |
| | | "$(PROJECT_DIR)/BuWanVideo2.0/GDT_iOS_SDK", |
| | | ); |
| | | MARKETING_VERSION = 3.1.0; |
| | | ONLY_ACTIVE_ARCH = NO; |
| | | OTHER_LDFLAGS = ( |
| | | "$(inherited)", |
| | | "-ObjC", |
| | | "-l\"SocialQQ\"", |
| | | "-l\"c++\"", |
| | | "-l\"iconv\"", |
| | | "-l\"sqlite3\"", |
| | |
| | | "-framework", |
| | | "\"CoreVideo\"", |
| | | "-framework", |
| | | "\"FirebaseAnalytics\"", |
| | | "-framework", |
| | | "\"FirebaseCore\"", |
| | | "-framework", |
| | | "\"FirebaseInstanceID\"", |
| | | "-framework", |
| | | "\"GLKit\"", |
| | | "-framework", |
| | | "\"GoogleMobileAds\"", |
| | | "-framework", |
| | | "\"ImageIO\"", |
| | | "-framework", |
| | | "\"MJRefresh\"", |
| | | "-framework", |
| | | "\"MediaPlayer\"", |
| | | "-framework", |
| | |
| | | "\"StoreKit\"", |
| | | "-framework", |
| | | "\"SystemConfiguration\"", |
| | | "-framework", |
| | | "\"TencentOpenAPI\"", |
| | | "-framework", |
| | | "\"UMMobClick\"", |
| | | "-framework", |
| | | "\"YYCache\"", |
| | | "-framework", |
New file |
| | |
| | | <?xml version="1.0" encoding="UTF-8"?> |
| | | <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> |
| | | <plist version="1.0"> |
| | | <dict> |
| | | <key>IDEDidComputeMac32BitWarning</key> |
| | | <true/> |
| | | </dict> |
| | | </plist> |
| | |
| | | selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" |
| | | selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" |
| | | shouldUseLaunchSchemeArgsEnv = "YES"> |
| | | <Testables> |
| | | </Testables> |
| | | <MacroExpansion> |
| | | <BuildableReference |
| | | BuildableIdentifier = "primary" |
| | |
| | | ReferencedContainer = "container:BuWanVideo2.0.xcodeproj"> |
| | | </BuildableReference> |
| | | </MacroExpansion> |
| | | <AdditionalOptions> |
| | | </AdditionalOptions> |
| | | <Testables> |
| | | </Testables> |
| | | </TestAction> |
| | | <LaunchAction |
| | | buildConfiguration = "Debug" |
| | |
| | | isEnabled = "YES"> |
| | | </EnvironmentVariable> |
| | | </EnvironmentVariables> |
| | | <AdditionalOptions> |
| | | </AdditionalOptions> |
| | | </LaunchAction> |
| | | <ProfileAction |
| | | buildConfiguration = "Debug" |
New file |
| | |
| | | <?xml version="1.0" encoding="UTF-8"?> |
| | | <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> |
| | | <plist version="1.0"> |
| | | <dict> |
| | | <key>SchemeUserState</key> |
| | | <dict> |
| | | <key>BuWanVideo2.0.xcscheme_^#shared#^_</key> |
| | | <dict> |
| | | <key>orderHint</key> |
| | | <integer>0</integer> |
| | | </dict> |
| | | </dict> |
| | | </dict> |
| | | </plist> |
New file |
| | |
| | | <?xml version="1.0" encoding="UTF-8"?> |
| | | <Bucket |
| | | uuid = "902FA679-A2C2-4138-A6FF-894D766FEE56" |
| | | type = "0" |
| | | version = "2.0"> |
| | | <Breakpoints> |
| | | <BreakpointProxy |
| | | BreakpointExtensionID = "Xcode.Breakpoint.ExceptionBreakpoint"> |
| | | <BreakpointContent |
| | | uuid = "F0981AB1-3E30-46EC-988D-1F87F755BD25" |
| | | shouldBeEnabled = "Yes" |
| | | ignoreCount = "0" |
| | | continueAfterRunningActions = "No" |
| | | breakpointStackSelectionBehavior = "1" |
| | | scope = "1" |
| | | stopOnStyle = "0"> |
| | | </BreakpointContent> |
| | | </BreakpointProxy> |
| | | <BreakpointProxy |
| | | BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint"> |
| | | <BreakpointContent |
| | | uuid = "254119EF-F0E8-4C8D-8232-F32063752158" |
| | | shouldBeEnabled = "Yes" |
| | | ignoreCount = "0" |
| | | continueAfterRunningActions = "No" |
| | | filePath = "BuWanVideo2.0/MineViewController.m" |
| | | startingColumnNumber = "9223372036854775807" |
| | | endingColumnNumber = "9223372036854775807" |
| | | startingLineNumber = "27" |
| | | endingLineNumber = "27" |
| | | landmarkName = "-viewDidLoad" |
| | | landmarkType = "7"> |
| | | </BreakpointContent> |
| | | </BreakpointProxy> |
| | | <BreakpointProxy |
| | | BreakpointExtensionID = "Xcode.Breakpoint.ExceptionBreakpoint"> |
| | | <BreakpointContent |
| | | uuid = "127EF0C5-FD11-4574-9E06-D3CEDC1FD45E" |
| | | shouldBeEnabled = "Yes" |
| | | ignoreCount = "0" |
| | | continueAfterRunningActions = "No" |
| | | breakpointStackSelectionBehavior = "1" |
| | | scope = "1" |
| | | stopOnStyle = "0"> |
| | | </BreakpointContent> |
| | | </BreakpointProxy> |
| | | <BreakpointProxy |
| | | BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint"> |
| | | <BreakpointContent |
| | | uuid = "CF15CBC7-720A-4BBC-B215-CFCC21985B8D" |
| | | shouldBeEnabled = "No" |
| | | ignoreCount = "0" |
| | | continueAfterRunningActions = "No" |
| | | filePath = "BuWanVideo2.0/LeftViewController.m" |
| | | startingColumnNumber = "9223372036854775807" |
| | | endingColumnNumber = "9223372036854775807" |
| | | startingLineNumber = "64" |
| | | endingLineNumber = "64" |
| | | landmarkName = "-viewDidLoad" |
| | | landmarkType = "7"> |
| | | </BreakpointContent> |
| | | </BreakpointProxy> |
| | | <BreakpointProxy |
| | | BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint"> |
| | | <BreakpointContent |
| | | uuid = "168E34C7-0749-406A-A855-BFD021A08E0A" |
| | | shouldBeEnabled = "Yes" |
| | | ignoreCount = "0" |
| | | continueAfterRunningActions = "No" |
| | | filePath = "BuWanVideo2.0/MineViewController.m" |
| | | startingColumnNumber = "9223372036854775807" |
| | | endingColumnNumber = "9223372036854775807" |
| | | startingLineNumber = "21" |
| | | endingLineNumber = "21" |
| | | landmarkName = "-init" |
| | | landmarkType = "7"> |
| | | </BreakpointContent> |
| | | </BreakpointProxy> |
| | | </Breakpoints> |
| | | </Bucket> |
| | |
| | | |
| | | - (void)viewDidLoad { |
| | | [super viewDidLoad]; |
| | | [MobClick beginLogPageView:@"进入专题合集"]; |
| | | //[MobClick beginLogPageView:@"进入专题合集"]; |
| | | |
| | | [self initScene]; |
| | | } |
| | | |
| | | -(void)dealloc{ |
| | | [MobClick beginLogPageView:@"退出专题合集"]; |
| | | //[MobClick beginLogPageView:@"退出专题合集"]; |
| | | } |
| | | |
| | | -(void)initScene{ |
| | |
| | | #import "LeftViewController.h" |
| | | |
| | | #import "GDTSplashAd.h" |
| | | #import "GDTSDKConfig.h" |
| | | //#import "GDTTrack.h" |
| | | #import "AFNetworkReachabilityManager.h" |
| | | |
| | |
| | | //#import "XGSetting.h" |
| | | |
| | | //#import <AlibcTradeSDK/AlibcTradeSDK.h> |
| | | #import "RooterController.h" |
| | | |
| | | #import "recommendViewController.h" |
| | | #import "subregionViewController.h" |
| | |
| | | #import "UITabBar+mainTab.h" |
| | | #import "GuessLikeViewController.h" |
| | | |
| | | #import <UMCommon/UMCommon.h> |
| | | //#import <UMShare/UMShare.h> |
| | | |
| | | #import <BUAdSDK/BUAdSDK.h> |
| | | |
| | | #define LECUsedBundleID @"com.yeshi.buwanshequ.ios" |
| | | |
| | | #define TICK NSDate *startTime = [NSDate date] |
| | | #define TOCK NSLog(@"Time: %f", -[startTime timeIntervalSinceNow]) |
| | | @import Firebase; |
| | | |
| | | @interface AppDelegate ()<GDTSplashAdDelegate> |
| | | @interface AppDelegate ()<GDTSplashAdDelegate, BUSplashAdDelegate> |
| | | |
| | | @property (strong,nonatomic) GDTSplashAd *splash; |
| | | |
| | | @property (nonatomic, strong) BUSplashAdView *splashAdView; |
| | | |
| | | @property (strong,nonatomic) UIView *bottomView; |
| | | @end |
| | |
| | | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { |
| | | TICK; |
| | | //清空角标 |
| | | [UIApplication sharedApplication].applicationIconBadgeNumber=0; |
| | | [UIApplication sharedApplication].applicationIconBadgeNumber = 0; |
| | | //设置状态栏的字体颜色 |
| | | [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent]; |
| | | //添加网络监测 |
| | | [self NetworkMonitoring]; |
| | | |
| | | |
| | | [self fetchCommenConfig]; |
| | | |
| | | //集成友盟 |
| | | [self setUmeng]; |
| | | [MobClick setLogEnabled:YES]; |
| | | //[MobClick setLogEnabled:YES]; |
| | | |
| | | |
| | | |
| | | //设置提示框的样式 |
| | | [SVProgressHUD setDefaultStyle:SVProgressHUDStyleCustom]; |
| | | [SVProgressHUD setMinimumDismissTimeInterval:3.0]; |
| | | //谷歌广告的初始化 |
| | | [FIRApp configure]; |
| | | |
| | | if(iOS8){ |
| | | [self registerPushForIOS8]; |
| | | }else{ |
| | |
| | | [YTHsharedManger startManger].Uid = [[NSUserDefaults standardUserDefaults] objectForKey:@"uid"]; |
| | | //加载主视图 |
| | | [self loadMainView]; |
| | | }else{ |
| | | |
| | | } else { |
| | | //获取Uid |
| | | [self getUid]; |
| | | } |
| | | |
| | | |
| | | |
| | | TOCK; |
| | | return YES; |
| | | } |
| | | |
| | | - (void)fetchCommenConfig { |
| | | NSMutableDictionary *parms = [[NSMutableDictionary alloc] init]; |
| | | [parms setObject:@"getConfig" forKey:@"Method"]; |
| | | [[YTHNetInterface startInterface] fetchCommenConfig:parms WithBlock:^(BOOL isSuccessful, id result, NSString *error) { |
| | | if ([result[@"IsPost"] boolValue]) { |
| | | [YTHsharedManger startManger].ad = result[@"Data"][@"ad"]; |
| | | } |
| | | }]; |
| | | } |
| | | |
| | | - (void)applicationWillResignActive:(UIApplication *)application { |
| | |
| | | } |
| | | //状态栏重现 |
| | | [[UIApplication sharedApplication] setStatusBarHidden:NO]; |
| | | // [GDTTrack activateApp]; |
| | | // [GDTTrack activateApp]; |
| | | } |
| | | |
| | | - (void)applicationWillTerminate:(UIApplication *)application { |
| | |
| | | } |
| | | |
| | | - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation{ |
| | | if (![[UMSocialManager defaultManager] handleOpenURL:url]) { |
| | | BOOL result = [[UMSocialManager defaultManager] handleOpenURL:url]; |
| | | return result; |
| | | } |
| | | |
| | | // if (![[UMSocialManager defaultManager] handleOpenURL:url]) { |
| | | // BOOL result = [[UMSocialManager defaultManager] handleOpenURL:url]; |
| | | // return result; |
| | | // } |
| | | |
| | | return YES; |
| | | |
| | | } |
| | |
| | | //IOS9.0 系统新的处理openURL 的API |
| | | - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url options:(NSDictionary<NSString *,id> *)options { |
| | | // 新接口写法 |
| | | if (![[UMSocialManager defaultManager] handleOpenURL:url]) { |
| | | BOOL result = [[UMSocialManager defaultManager] handleOpenURL:url]; |
| | | return result; |
| | | } |
| | | // if (![[UMSocialManager defaultManager] handleOpenURL:url]) { |
| | | // BOOL result = [[UMSocialManager defaultManager] handleOpenURL:url]; |
| | | // return result; |
| | | // } |
| | | return YES; |
| | | } |
| | | |
| | | - (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken { |
| | | |
| | | |
| | | } |
| | | |
| | | - (void)application:(UIApplication*)application didReceiveRemoteNotification:(NSDictionary*)userInfo |
| | | { |
| | | |
| | | |
| | | } |
| | | |
| | | - (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notifications{ |
| | | |
| | | |
| | | } |
| | | |
| | | #pragma mark 获取Uid |
| | |
| | | [self loadMainView]; |
| | | }else{ |
| | | //判断当前用户是否还保存有Uid,如果没有,要提醒用户暂时不能使用 |
| | | if ([YTHsharedManger startManger].Uid==nil) { |
| | | if ([YTHsharedManger startManger].Uid == nil) { |
| | | //提醒用户暂不能使用,请检查网络 |
| | | //还是允许用户进入 |
| | | [self loadMainView]; |
| | |
| | | return UIInterfaceOrientationMaskPortrait; |
| | | } |
| | | |
| | | -(void)loadAd{ |
| | | // _splash=[[GDTSplashAd alloc] initWithAppkey:GDTADkey placementId:GDTFullADid]; |
| | | _splash = [[GDTSplashAd alloc] initWithAppId:GDTADkey placementId:GDTFullADid]; |
| | | - (void)setupBUAdSDK { |
| | | //optional |
| | | //GDPR 0 close privacy protection, 1 open privacy protection |
| | | [BUAdSDKManager setGDPR:0]; |
| | | //optional |
| | | //Coppa 0 adult, 1 child |
| | | [BUAdSDKManager setCoppa:0]; |
| | | |
| | | #if DEBUG |
| | | // Whether to open log. default is none. |
| | | [BUAdSDKManager setLoglevel:BUAdSDKLogLevelDebug]; |
| | | // [BUAdSDKManager setDisableSKAdNetwork:YES]; |
| | | #endif |
| | | //BUAdSDK requires iOS 9 and up |
| | | // |
| | | [BUAdSDKManager setAppID:@"5096047"]; |
| | | |
| | | [BUAdSDKManager setIsPaidApp:NO]; |
| | | // splash AD demo |
| | | [self addSplashAD]; |
| | | } |
| | | |
| | | _splash.delegate=self;//设置代理 |
| | | #pragma mark - Splash |
| | | - (void)addSplashAD { |
| | | CGRect frame = CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height - 100); |
| | | |
| | | self.splashAdView = [[BUSplashAdView alloc] initWithSlotID:@"887379201" frame:frame]; |
| | | |
| | | self.splashAdView.tolerateTimeout = 10; |
| | | self.splashAdView.delegate = self; |
| | | //optional |
| | | self.splashAdView.needSplashZoomOutAd = YES; |
| | | |
| | | float width = [UIScreen mainScreen].bounds.size.width; |
| | | float height = [UIScreen mainScreen].bounds.size.height; |
| | | UIImageView *imageview = [[UIImageView alloc] init]; |
| | | |
| | | CGFloat viewHeight = 0.0; |
| | | if (width == 320.0f && height<=480.0f) { |
| | | // iphone4 iphone4s 上的default图片 |
| | | _splash.backgroundColor=[UIColor colorWithPatternImage:[UIImage imageNamed:@"320x480"]]; |
| | | imageview.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"320"]]; |
| | | viewHeight = 55; |
| | | |
| | | }else if (width ==320.0f && height==568.0f) { |
| | | // iphone5 上的default图片 |
| | | _splash.backgroundColor=[UIColor colorWithPatternImage:[UIImage imageNamed:@"320x568"]]; |
| | | imageview.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"320"]]; |
| | | viewHeight = 55; |
| | | |
| | | }else if (width ==375.0f) { |
| | | // iphone6 上的default图片 |
| | | _splash.backgroundColor=[UIColor colorWithPatternImage:[UIImage imageNamed:@"375x667"]]; |
| | | imageview.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"375"]]; |
| | | viewHeight = 63; |
| | | |
| | | }else{ |
| | | // iphone6 plus 上的default图片 |
| | | _splash.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"414x736"]]; |
| | | imageview.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"414"]]; |
| | | viewHeight = 69; |
| | | } |
| | | if (KIsiPhoneX) { |
| | | _splash.backgroundColor=[UIColor colorWithPatternImage:[UIImage imageNamed:@"1125x2436"]]; |
| | | } |
| | | |
| | | UIWindow *keyWindow = self.window; |
| | | //self.startTime = CACurrentMediaTime(); |
| | | [self.splashAdView loadAdData]; |
| | | [keyWindow.rootViewController.view addSubview:self.splashAdView]; |
| | | |
| | | self.splashAdView.frame = CGRectMake(0, 0, KScreenW, KScreenH - viewHeight); |
| | | |
| | | _bottomView = [[UIView alloc] initWithFrame:CGRectMake(0, KScreenH - viewHeight, KScreenW, viewHeight)]; |
| | | imageview.frame = CGRectMake(0, 12, _bottomView.frame.size.width, _bottomView.frame.size.height - 6); |
| | | |
| | | [_bottomView addSubview:imageview]; |
| | | _bottomView.backgroundColor = [UIColor whiteColor]; |
| | | |
| | | [keyWindow addSubview:self.bottomView]; |
| | | |
| | | self.splashAdView.rootViewController = keyWindow.rootViewController; |
| | | } |
| | | |
| | | |
| | | - (void)loadAd { |
| | | BOOL res = [GDTSDKConfig registerAppId:GDTADkey]; |
| | | if (res) { |
| | | |
| | | } |
| | | self.splash = [[GDTSplashAd alloc] initWithPlacementId:GDTFullADid]; |
| | | |
| | | _splash.delegate = self;//设置代理 |
| | | |
| | | //根据iPhone设备不同设置不同的背景图 |
| | | float width = [UIScreen mainScreen].bounds.size.width; |
| | |
| | | |
| | | }else{ |
| | | // iphone6 plus 上的default图片 |
| | | _splash.backgroundColor=[UIColor colorWithPatternImage:[UIImage imageNamed:@"414x736"]]; |
| | | _splash.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"414x736"]]; |
| | | imageview.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"414"]]; |
| | | viewHeight = 69; |
| | | } |
| | |
| | | // [_splash loadAdAndShowInWindow:self.window];//拉起并展示全屏广告 |
| | | |
| | | // [_splash loadAdAndShowInWindow:self.window withBottomView:[UIView new]]; |
| | | _bottomView = [[UIView alloc]initWithFrame:CGRectMake(0, KScreenH - viewHeight, KScreenW, viewHeight)]; |
| | | _bottomView = [[UIView alloc] initWithFrame:CGRectMake(0, KScreenH - viewHeight, KScreenW, viewHeight)]; |
| | | imageview.frame = CGRectMake(0, 12, _bottomView.frame.size.width, _bottomView.frame.size.height - 6); |
| | | |
| | | [_bottomView addSubview:imageview]; |
| | |
| | | |
| | | |
| | | -(void)loadMainView{ |
| | | //首页视图 |
| | | // MainViewController *MainVC=[[MainViewController alloc] init]; |
| | | // RooterController *NVC=[[RooterController alloc] initWithRootViewController:MainVC]; |
| | | // |
| | | // 添加到 navigationBar 上 |
| | | //侧滑栏视图 |
| | | // LeftViewController *leftMenuViewController=[[LeftViewController alloc] init]; |
| | | // |
| | | // SlideMenuController *slideMenuController = [[SlideMenuController alloc] initWithMainViewController:NVC leftMenuViewController:leftMenuViewController rightMenuViewController:nil]; |
| | | // |
| | | // slideMenuController.option.leftViewWitdth = KScreenW*3/4; |
| | | // slideMenuController.option.simultaneousGestureRecognizers=NO; |
| | | |
| | | self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; |
| | | self.window.backgroundColor=[UIColor whiteColor]; |
| | | [self.window makeKeyAndVisible]; |
| | |
| | | subregionViewController *subVC = [[subregionViewController alloc]init]; |
| | | subVC.tabBarItem.image = [[UIImage imageNamed:@"Camera-拷贝"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal]; |
| | | subVC.tabBarItem.selectedImage = [[UIImage imageNamed:@"Camera"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal]; |
| | | |
| | | |
| | | UINavigationController *nsubVC = [[UINavigationController alloc]initWithRootViewController:subVC]; |
| | | |
| | | discoverViewController *disVC = [[discoverViewController alloc]init]; |
| | |
| | | guessVC.tabBarItem.image = [[UIImage imageNamed:@"HEART2"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal]; |
| | | guessVC.tabBarItem.selectedImage = [[UIImage imageNamed:@"HEART"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal]; |
| | | UINavigationController *nguessVC = [[UINavigationController alloc]initWithRootViewController:guessVC]; |
| | | |
| | | |
| | | SJTabbarViewController *tabBarController = [[SJTabbarViewController alloc]init]; |
| | | tabBarController.viewControllers = @[nrecommendVC,ndisVC,nguessVC,nsubVC,nmineVC]; |
| | | tabBarController.tabBar.tintColor = YTHColor(248, 89, 69); |
| | | [tabBarController.tabBar setClipsToBounds:YES]; |
| | | tabBarController.tabBar.opaque = YES; |
| | | |
| | | |
| | | NSMutableDictionary *attr3=[NSMutableDictionary dictionary]; |
| | | attr3[NSFontAttributeName]=[UIFont systemFontOfSize:10]; |
| | | [[UITabBarItem appearance]setTitleTextAttributes:attr3 forState:UIControlStateNormal]; |
| | | // tabBarController.tabBar.itemPositioning = UITabBarItemPositioningFill; |
| | | |
| | | self.window.rootViewController = tabBarController; |
| | | //添加开屏广告 |
| | | [self loadAd]; |
| | | // tabBarController.tabBar.itemPositioning = UITabBarItemPositioningFill; |
| | | |
| | | self.window.rootViewController = tabBarController; |
| | | |
| | | [self setupBUAdSDK]; |
| | | |
| | | //添加开屏广告 |
| | | NSLog(@""); |
| | | |
| | | } |
| | | |
| | | #pragma mark 友盟集成 |
| | | - (void)setUmeng{ |
| | | //友盟分享 |
| | | [[UMSocialManager defaultManager] setPlaform:UMSocialPlatformType_WechatSession appKey:YMWXKEY appSecret:YMWXSENT redirectURL:nil];//微信 |
| | | |
| | | [[UMSocialManager defaultManager] setPlaform:UMSocialPlatformType_QQ appKey:YMQQKEY appSecret:YMQQSENT redirectURL:@"http://mobile.umeng.com/social"];//QQ |
| | | [UMConfigure initWithAppkey:UmengKey channel:@"App Store"]; |
| | | [UMConfigure setLogEnabled:YES]; |
| | | |
| | | [[UMSocialManager defaultManager] setPlaform:UMSocialPlatformType_Sina appKey:YMSinaKEY appSecret:YMSinaSecret redirectURL:@"https://sns.whalecloud.com/sina2/callback"];//新浪 |
| | | |
| | | //友盟数据分析 |
| | | UMConfigInstance.appKey = UmengKey; |
| | | UMConfigInstance.channelId = nil; |
| | | UMConfigInstance.ePolicy=BATCH; |
| | | [MobClick startWithConfigure:UMConfigInstance]; |
| | | // //友盟分享 |
| | | // [[UMSocialManager defaultManager] setPlaform:UMSocialPlatformType_WechatSession appKey:YMWXKEY appSecret:YMWXSENT redirectURL:nil];//微信 |
| | | // |
| | | // [[UMSocialManager defaultManager] setPlaform:UMSocialPlatformType_QQ appKey:YMQQKEY appSecret:YMQQSENT redirectURL:@"http://mobile.umeng.com/social"];//QQ |
| | | // |
| | | // [[UMSocialManager defaultManager] setPlaform:UMSocialPlatformType_Sina appKey:YMSinaKEY appSecret:YMSinaSecret redirectURL:@"https://sns.whalecloud.com/sina2/callback"];//新浪 |
| | | } |
| | | |
| | | #pragma mark 阿里百川 |
| | |
| | | break; |
| | | } |
| | | } |
| | | #pragma mark BUSplashAdDelegate |
| | | //- (void)splashAdDidLoad:(BUSplashAdView *)splashAd { |
| | | // if (splashAd.zoomOutView) { |
| | | // UIViewController *parentVC = [UIApplication sharedApplication].keyWindow.rootViewController; |
| | | // [parentVC.view addSubview:splashAd.zoomOutView]; |
| | | // [parentVC.view bringSubviewToFront:splashAd]; |
| | | // //Add this view to your container |
| | | // [parentVC.view insertSubview:splashAd.zoomOutView belowSubview:splashAd]; |
| | | // splashAd.zoomOutView.rootViewController = parentVC; |
| | | // } |
| | | //} |
| | | |
| | | /// 当splash广告关闭时调用此方法。 |
| | | - (void)splashAdDidClose:(BUSplashAdView *)splashAd { |
| | | [splashAd removeFromSuperview]; |
| | | [self.bottomView removeFromSuperview]; |
| | | [self pbu_logWithSEL:_cmd msg:@""]; |
| | | } |
| | | |
| | | - (void)splashAdDidClick:(BUSplashAdView *)splashAd { |
| | | [splashAd removeFromSuperview]; |
| | | [self.bottomView removeFromSuperview]; |
| | | [self pbu_logWithSEL:_cmd msg:@""]; |
| | | } |
| | | |
| | | - (void)splashAdDidClickSkip:(BUSplashAdView *)splashAd { |
| | | if (splashAd.zoomOutView) { |
| | | [splashAd.zoomOutView removeFromSuperview]; |
| | | } |
| | | } |
| | | |
| | | - (void)splashAd:(BUSplashAdView *)splashAd didFailWithError:(NSError *)error { |
| | | [splashAd removeFromSuperview]; |
| | | [self.bottomView removeFromSuperview]; |
| | | self.bottomView = nil; |
| | | [self loadAd]; |
| | | [self pbu_logWithSEL:_cmd msg:@""]; |
| | | } |
| | | |
| | | - (void)splashAdWillVisible:(BUSplashAdView *)splashAd { |
| | | [self pbu_logWithSEL:_cmd msg:@""]; |
| | | } |
| | | |
| | | - (void)splashAdWillClose:(BUSplashAdView *)splashAd { |
| | | [self pbu_logWithSEL:_cmd msg:@""]; |
| | | } |
| | | |
| | | - (void)splashAdDidCloseOtherController:(BUSplashAdView *)splashAd interactionType:(BUInteractionType)interactionType { |
| | | [self pbu_logWithSEL:_cmd msg:@""]; |
| | | } |
| | | |
| | | - (void)splashAdCountdownToZero:(BUSplashAdView *)splashAd { |
| | | [self pbu_logWithSEL:_cmd msg:@""]; |
| | | } |
| | | |
| | | - (void)pbu_logWithSEL:(SEL)sel msg:(NSString *)msg { |
| | | |
| | | } |
| | | |
| | | |
| | | #pragma mark -GDTSplashAdDelegate |
| | | -(void)splashAdSuccessPresentScreen:(GDTSplashAd *)splashAd |
| | |
| | | { |
| | | self.bottomView.hidden = YES; |
| | | [self.bottomView removeFromSuperview]; |
| | | |
| | | |
| | | NSLog(@"%s",__FUNCTION__); |
| | | |
| | | } |
New file |
| | |
| | | /* |
| | | BULanguage.strings |
| | | BUAdSDK |
| | | |
| | | Created by wangyanlin on 2020/4/10. |
| | | Copyright © 2020 bytedance. All rights reserved. |
| | | */ |
| | | |
| | | // String |
| | | |
| | | "Click" = "انقر فوق"; |
| | | "AD" = "الإعلان"; |
| | | "PlayConsumed" = "سيؤدي تشغيل هذا إلى استخدام بيانات تبلغ %.2f ميجابايت"; |
| | | "Evaluation" = "التقييم"; |
| | | "Score" = "تصنيف (تصنيفات) %@"; |
| | | "Select" = "اختر"; |
| | | "Back" = "رجوع"; |
| | | "Replay" = "انقر لإعادة التشغيل"; |
| | | "Continue" = "المتابعة للتشغيل"; |
| | | "Skip" = "تخطي"; |
| | | "Feedback" = "التعليقات"; |
| | | "FeedbackStr1" = "شكرًا لك على تعليقك."; |
| | | "FeedbackStr2" = "سنبذل قصارى جهدنا لمنحك تجربة إعلانية أفضل"; |
| | | "FeedbackStr3" = "لقد أرسلت تعليق بالفعل."; |
| | | "FeedbackStr4" = "يرجى عدم الإرسال أكثر من مرة!"; |
| | | "ViewNow" = "عرض الآن"; |
| | | "Download" = "تنزيل"; |
| | | "LoadFailure" = "تعذر التحميل. يرجى المحاولة مرة أخرى."; |
| | | "GetRewardAfterWatching" = "قم بإستكمال مشاهدة الفيديو بالكامل للحصول على مكافآت"; |
| | | "GiveUpReward" = "تخطي المكافآت"; |
| | | "ContinueWatching" = "متابعة المشاهدة"; |
| | | "CanbeTurnedOffAfter" = "s %d تخطي بعد"; |
| | | "Get" = "تنزيل"; |
| | | "View" = "عرض"; |
| | | "ContinuePlaying" = "متابعة التشغيل"; |
| | | "GetRewardAfterPlaying" = "قم بإستكمال التشغيل للحصول على المكافآت"; |
| | | "Wan" = "10 ألف"; |
New file |
| | |
| | | /* |
| | | BULanguage.strings |
| | | BUAdSDK |
| | | |
| | | Created by wangyanlin on 2020/4/10. |
| | | Copyright © 2020 bytedance. All rights reserved. |
| | | */ |
| | | |
| | | // String |
| | | |
| | | "Click" = "Klick"; |
| | | "AD" = "Anzeige"; |
| | | "PlayConsumed" = "Bei der Wiedergabe werden %.2f MB Daten verbraucht"; |
| | | "Evaluation" = "Bewertung"; |
| | | "Score" = "%@ Rating(s)"; |
| | | "Select" = "Auswählen"; |
| | | "Back" = "Zurück"; |
| | | "Replay" = "Zum erneuten Wiedergeben klicken"; |
| | | "Continue" = "Weiter wiedergeben"; |
| | | "Skip" = "Überspringen"; |
| | | "Feedback" = "Feedback"; |
| | | "FeedbackStr1" = "Vielen Dank für Ihr Feedback."; |
| | | "FeedbackStr2" = "Wir sind bemüht, Ihre Werbeerfahrung weiter zu verbessern."; |
| | | "FeedbackStr3" = "Sie haben bereits Feedback übermittelt."; |
| | | "FeedbackStr4" = "Bitte senden Sie Ihr Feedback nicht mehrfach!"; |
| | | "ViewNow" = "Jetzt ansehen"; |
| | | "Download" = "Abrufen"; |
| | | "LoadFailure" = "Ladefehler. Bitte versuchen Sie es erneut."; |
| | | "GetRewardAfterWatching" = "Sehen Sie sich das Video vollständig an, um Prämien zu erhalten."; |
| | | "GiveUpReward" = "Auf Prämien verzichten"; |
| | | "ContinueWatching" = "Weiter ansehen"; |
| | | "CanbeTurnedOffAfter" = "Nach %d s überspringen"; |
| | | "Get" = "Herunterladen"; |
| | | "View" = "Ansehen"; |
| | | "ContinuePlaying" = "Weiter wiedergeben"; |
| | | "GetRewardAfterPlaying" = "Bis zum Ende wiedergeben, um Prämien zu erhalten"; |
| | | "Wan" = "Zehntausend"; |
| | | // Icon |
New file |
| | |
| | | /* |
| | | BULanguage.strings |
| | | BUAdSDK |
| | | |
| | | Created by 李盛 on 2019/1/7. |
| | | Copyright © 2019 bytedance. All rights reserved. |
| | | */ |
| | | |
| | | // String |
| | | |
| | | "Click" = "Click"; |
| | | "AD" = "AD"; |
| | | "PlayConsumed" = "%.2fMB traffic will be consumed if you play it"; |
| | | "Evaluation" = "Evaluation"; |
| | | "Score" = "%@ score"; |
| | | "Select" = "Select"; |
| | | "Wan" = "";//英文逻辑不一样,为空就好 |
| | | "Back" = "Back"; |
| | | "Replay" = "Click to replay"; |
| | | "Continue" = "Continue to play"; |
| | | "Skip" = "Skip"; |
| | | "Feedback" = "Feedback"; |
| | | "FeedbackStr1" = "Thank you for your feedback."; |
| | | "FeedbackStr2" = "We will try to do better."; |
| | | "FeedbackStr3" = "You have submitted feedback."; |
| | | "FeedbackStr4" = "please don’t submit it again!"; |
| | | "ViewNow" = "View now"; |
| | | "Download" = "Download"; |
| | | "LoadFailure" = "Failed to load, and click to try again"; |
| | | "GetRewardAfterWatching" = "Get reward after watching the full video"; |
| | | "GiveUpReward" = "Abandon"; |
| | | "ContinueWatching" = "Continue watching"; |
| | | "CanbeTurnedOffAfter" = "Skip after %ds"; |
| | | "Get" = "Get"; |
| | | "View" = "View"; |
| | | "ContinuePlaying" = "Keep on"; |
| | | "GetRewardAfterPlaying" = "Finish playing to get rewards!"; |
| | | // Icon |
New file |
| | |
| | | /* |
| | | BULanguage.strings |
| | | BUAdSDK |
| | | |
| | | Created by wangyanlin on 2020/4/10. |
| | | Copyright © 2020 bytedance. All rights reserved. |
| | | */ |
| | | |
| | | // String |
| | | |
| | | "Click" = "Clic"; |
| | | "AD" = "Anuncio"; |
| | | "PlayConsumed" = "Reproducir esto usará %.2f MB de datos"; |
| | | "Evaluation" = "Evaluación"; |
| | | "Score" = "%@ valoración(es)"; |
| | | "Select" = "Seleccionar"; |
| | | "Back" = "Volver"; |
| | | "Replay" = "Haga clic para volver a reproducir"; |
| | | "Continue" = "Seguir con la reproducción"; |
| | | "Skip" = "Omitir"; |
| | | "Feedback" = "Comentarios"; |
| | | "FeedbackStr1" = "Gracias por sus comentarios."; |
| | | "FeedbackStr2" = "Seguiremos esforzándonos por ofrecerle una mejor experiencia publicitaria."; |
| | | "FeedbackStr3" = "Ya ha enviado sus comentarios."; |
| | | "FeedbackStr4" = "No lo envíe más de una vez."; |
| | | "ViewNow" = "Ver ahora"; |
| | | "Download" = "Obtener"; |
| | | "LoadFailure" = "Error en la carga. Inténtelo de nuevo."; |
| | | "GetRewardAfterWatching" = "Termine de ver el vídeo por completo para recibir recompensas"; |
| | | "GiveUpReward" = "Renunciar a las recompensas"; |
| | | "ContinueWatching" = "Seguir viendo"; |
| | | "CanbeTurnedOffAfter" = "Omitir después de %d s"; |
| | | "Get" = "Descargar"; |
| | | "View" = "Ver"; |
| | | "ContinuePlaying" = "Seguir con la reproducción"; |
| | | "GetRewardAfterPlaying" = "Terminar la reproducción para reclamar recompensas"; |
| | | "Wan" = "10"; |
| | | // Icon |
New file |
| | |
| | | /* |
| | | BULanguage.strings |
| | | BUAdSDK |
| | | |
| | | Created by wangyanlin on 2020/4/10. |
| | | Copyright © 2020 bytedance. All rights reserved. |
| | | */ |
| | | |
| | | // String |
| | | |
| | | "Click" = "Clic"; |
| | | "AD" = "ANNONCE"; |
| | | "PlayConsumed" = "%.2f Mo de données seront utilisés pour la lecture"; |
| | | "Evaluation" = "Évaluation"; |
| | | "Score" = "%@ cote(s)"; |
| | | "Select" = "Sélectionner"; |
| | | "Back" = "Retour"; |
| | | "Replay" = "Cliquer pour relancer la lecture"; |
| | | "Continue" = "Continuer pour lancer la lecture"; |
| | | "Skip" = "Passer"; |
| | | "Feedback" = "Commentaire"; |
| | | "FeedbackStr1" = "Merci pour votre commentaire."; |
| | | "FeedbackStr2" = "Nous continuerons à mettre tout en œuvre pour vous offrir une meilleure expérience publicitaire."; |
| | | "FeedbackStr3" = "Vous avez déjà envoyé un commentaire."; |
| | | "FeedbackStr4" = "Merci de ne pas envoyer un commentaire plusieurs fois !"; |
| | | "ViewNow" = "Regarder"; |
| | | "Download" = "Obtenir"; |
| | | "LoadFailure" = "Téléchargement impossible. Veuillez réessayer."; |
| | | "GetRewardAfterWatching" = "Regardez la vidéo jusqu'à la fin pour obtenir vos récompenses"; |
| | | "GiveUpReward" = "Renoncer aux récompenses"; |
| | | "ContinueWatching" = "Continuer à regarder"; |
| | | "CanbeTurnedOffAfter" = "Passer après %d s"; |
| | | "Get" = "Télécharger"; |
| | | "View" = "Voir"; |
| | | "ContinuePlaying" = "Poursuivre la lecture"; |
| | | "GetRewardAfterPlaying" = "Terminez la lecture pour obtenir vos récompenses"; |
| | | "Wan" = "10 000"; |
| | | // Icon |
New file |
| | |
| | | /* |
| | | BULanguage.strings |
| | | BUAdSDK |
| | | |
| | | Created by wangyanlin on 2020/4/10. |
| | | Copyright © 2020 bytedance. All rights reserved. |
| | | */ |
| | | |
| | | // String |
| | | |
| | | "Click" = "क्लिक करें"; |
| | | "AD" = "विज्ञापन"; |
| | | "PlayConsumed" = "इसको चलाने पर %.2f MB डेटा का इस्तेमाल होगा"; |
| | | "Evaluation" = "मूल्यांकन"; |
| | | "Score" = "%@ रेटिंग"; |
| | | "Select" = "चुनें"; |
| | | "Back" = "वापस जाएँ"; |
| | | "Replay" = "रीप्ले करने के लिए क्लिक करें"; |
| | | "Continue" = "चलाना जारी रखें"; |
| | | "Skip" = "छोड़ें"; |
| | | "Feedback" = "फ़ीडबैक"; |
| | | "FeedbackStr1" = "आपके फ़ीडबैक के लिए धन्यवाद."; |
| | | "FeedbackStr2" = "हम आपको बेहतर विज्ञापन अनुभव देने की कोशिश करते रहेंगे."; |
| | | "FeedbackStr3" = "आप पहले ही फ़ीडबैक सबमिट कर चुके हैं."; |
| | | "FeedbackStr4" = "कृपया एक से अधिक बार न सबमिट करें!"; |
| | | "ViewNow" = "अभी देखें"; |
| | | "Download" = "पाएँ"; |
| | | "LoadFailure" = "लोड नहीं किया जा सका. कृपया फिर से कोशिश करें."; |
| | | "GetRewardAfterWatching" = "रिवॉर्ड्स पाने के लिए पूरा वीडियो देखें"; |
| | | "GiveUpReward" = "रिवॉर्ड्स छोड़ें"; |
| | | "ContinueWatching" = "देखते रहें"; |
| | | "CanbeTurnedOffAfter" = "%d सेकंड के बाद छोड़ दें"; |
| | | "Get" = "डाउनलोड करें"; |
| | | "View" = "देखें"; |
| | | "ContinuePlaying" = "देखना जारी रखें"; |
| | | "GetRewardAfterPlaying" = "रिवॉर्ड्स का दावा करने के लिए पूरा देखें"; |
| | | "Wan" = "10 हज़ार"; |
| | | // Icon |
New file |
| | |
| | | /* |
| | | BULanguage.strings |
| | | BUAdSDK |
| | | |
| | | Created by wangyanlin on 2020/4/10. |
| | | Copyright © 2020 bytedance. All rights reserved. |
| | | */ |
| | | |
| | | // String |
| | | |
| | | "Click" = "Klik"; |
| | | "AD" = "IKLAN"; |
| | | "PlayConsumed" = "Memutar ini akan menghabiskan data %.2f MB"; |
| | | "Evaluation" = "Evaluasi"; |
| | | "Score" = "%@ peringkat"; |
| | | "Select" = "Pilih"; |
| | | "Back" = "Kembali"; |
| | | "Replay" = "Klik untuk memutar ulang"; |
| | | "Continue" = "Lanjut memutar"; |
| | | "Skip" = "Lewati"; |
| | | "Feedback" = "Umpan balik"; |
| | | "FeedbackStr1" = "Terima kasih atas umpan balik Anda."; |
| | | "FeedbackStr2" = "Kami akan terus berusaha meningkatkan pengalaman beriklan Anda."; |
| | | "FeedbackStr3" = "Anda telah mengirimkan umpan balik."; |
| | | "FeedbackStr4" = "Mohon tidak mengirim lebih dari satu!"; |
| | | "ViewNow" = "Lihat sekarang"; |
| | | "Download" = "Dapatkan"; |
| | | "LoadFailure" = "Gagal memuat. Silakan coba lagi."; |
| | | "GetRewardAfterWatching" = "Selesaikan menonton video lengkap untuk mendapatkan reward"; |
| | | "GiveUpReward" = "Abaikan reward"; |
| | | "ContinueWatching" = "Lanjut menonton"; |
| | | "CanbeTurnedOffAfter" = "Lewati setelah %d detik"; |
| | | "Get" = "Unduh"; |
| | | "View" = "Lihat"; |
| | | "ContinuePlaying" = "Lanjut memutar"; |
| | | "GetRewardAfterPlaying" = "Selesaikan pemutaran untuk mendapatkan reward"; |
| | | "Wan" = "10 ribu"; |
| | | // Icon |
New file |
| | |
| | | /* |
| | | BULanguage.strings |
| | | BUAdSDK |
| | | |
| | | Created by wangyanlin on 2020/4/10. |
| | | Copyright © 2020 bytedance. All rights reserved. |
| | | */ |
| | | |
| | | // String |
| | | |
| | | "Click" = "Clic"; |
| | | "AD" = "Annuncio"; |
| | | "PlayConsumed" = "La riproduzione utilizzerà %.2f MB di dati"; |
| | | "Evaluation" = "Valutazione"; |
| | | "Score" = "Valutazione(i) %@"; |
| | | "Select" = "Seleziona"; |
| | | "Back" = "Indietro"; |
| | | "Replay" = "Clic per caricare"; |
| | | "Continue" = "Continua per riprodurre"; |
| | | "Skip" = "Ignora"; |
| | | "Feedback" = "Feedback"; |
| | | "FeedbackStr1" = "Grazie per il tuo feedback"; |
| | | "FeedbackStr2" = "Continueremo a impegnarci per fornirti un'esperienza pubblicitaria migliore."; |
| | | "FeedbackStr3" = "Hai già inviato il tuo feedback."; |
| | | "FeedbackStr4" = "Non inviarne più di uno!"; |
| | | "ViewNow" = "Visualizza ora"; |
| | | "Download" = "Ottieni"; |
| | | "LoadFailure" = "Caricamento non riuscito. Riprova."; |
| | | "GetRewardAfterWatching" = "Finisci di guardare il video per ottenere le ricompense"; |
| | | "GiveUpReward" = "Rinuncia a ricompense"; |
| | | "ContinueWatching" = "Continua a guardare"; |
| | | "CanbeTurnedOffAfter" = "Ignora dopo %ds"; |
| | | "Get" = "Scarica"; |
| | | "View" = "Visualizza"; |
| | | "ContinuePlaying" = "Continua a riprodurre"; |
| | | "GetRewardAfterPlaying" = "Riproduci tutto per richiedere le ricompense"; |
| | | "Wan" = "10 mila"; |
New file |
| | |
| | | /* |
| | | BULanguage.strings |
| | | BUAdSDK |
| | | |
| | | Created by 李盛 on 2019/1/7. |
| | | Copyright © 2019 bytedance. All rights reserved. |
| | | */ |
| | | |
| | | // String |
| | | |
| | | "Click" = "クリック"; |
| | | "AD" = "広告"; |
| | | "PlayConsumed" = "再生すると%.2fMBの通信量が消費されます"; |
| | | "Evaluation" = "評価"; |
| | | "Score" = "評価数:%@"; |
| | | "Select" = "選択"; |
| | | "Wan" = "万"; |
| | | "Back" = "戻る"; |
| | | "Replay" = "リプレイ"; |
| | | "Continue" = "再生し続ける"; |
| | | "Skip" = "skip"; |
| | | "Feedback" = "Feedback"; |
| | | "FeedbackStr1" = "Thank you for your feedback."; |
| | | "FeedbackStr2" = "We will try to do better."; |
| | | "FeedbackStr3" = "You have submitted feedback."; |
| | | "FeedbackStr4" = "please don’t submit it again!"; |
| | | "ViewNow" = "詳細を見る"; |
| | | "Download" = "download"; |
| | | "LoadFailure" = "ロードに失敗しました。クリックして再度お試しください"; |
| | | "GetRewardAfterWatching" = "動画を最後まで視聴いただけるとリワードを付与されます"; |
| | | "GiveUpReward" = "やらない"; |
| | | "ContinueWatching" = "視聴し続ける"; |
| | | "CanbeTurnedOffAfter" = "%ds後に閉じられます"; |
| | | "Get" = "Get"; |
| | | "View" = "View"; |
| | | "ContinuePlaying" = "つづける"; |
| | | "GetRewardAfterPlaying" = "遊んで報酬をゲット!"; |
| | | // Icon |
New file |
| | |
| | | /* |
| | | BULanguage.strings |
| | | BUAdSDK |
| | | |
| | | Created by iCuiCui on 2020/2/12. |
| | | Copyright © 2019 bytedance. All rights reserved. |
| | | */ |
| | | |
| | | // String |
| | | |
| | | "Click" = "클릭"; |
| | | "AD" = "광고"; |
| | | "PlayConsumed" = "재생하면 %.2fMB 트래픽이 소비하다"; |
| | | "Evaluation" = "평가"; |
| | | "Score" = "%@ 평점"; |
| | | "Select" = "선택"; |
| | | "Wan" = "만"; |
| | | "Back" = "뒤로"; |
| | | "Replay" = "재생하다"; |
| | | "Continue" = "계속하다"; |
| | | "Skip" = "건너뛰다"; |
| | | "Feedback" = "피드백"; |
| | | "FeedbackStr1" = "피드백을 주셔서 감사합니다!"; |
| | | "FeedbackStr2" = "더 양질의 광고 체험을 드리 겠습니다!"; |
| | | "FeedbackStr3" = "피드백을 제출 완료 됐었습니다!"; |
| | | "FeedbackStr4" = "반복하게 제출하지 마십시오"; |
| | | "ViewNow" = "즉시 보기"; |
| | | "Download" = "즉시 다운로드"; |
| | | "LoadFailure" = "적재 실패, 재시도 클릭"; |
| | | "GetRewardAfterWatching" = "전체 비디오를 본 후 보상을 받으십시오."; |
| | | "GiveUpReward" = "포상을 포기하다"; |
| | | "ContinueWatching" = "계속보기"; |
| | | "CanbeTurnedOffAfter" = "%ds후에 닫을 수 있다"; |
| | | "Get" = "다운로드"; |
| | | "View" = "체크"; |
| | | "ContinuePlaying" = "계속하다"; |
| | | "GetRewardAfterPlaying" = "리워드는 게임 플레이 이후에 지급됩니다."; |
| | | // Icon |
New file |
| | |
| | | /* |
| | | BULanguage.strings |
| | | BUAdSDK |
| | | |
| | | Created by wangyanlin on 2020/4/10. |
| | | Copyright © 2020 bytedance. All rights reserved. |
| | | */ |
| | | |
| | | // String |
| | | |
| | | "Click" = "Clicar"; |
| | | "AD" = "Anúncio"; |
| | | "PlayConsumed" = "Ao executar este, você usará %.2f MB dos dados"; |
| | | "Evaluation" = "Avaliação"; |
| | | "Score" = "%@ classificação(ões)"; |
| | | "Select" = "Selecionar"; |
| | | "Back" = "Voltar"; |
| | | "Replay" = "Clique para reproduzir"; |
| | | "Continue" = "Continue para executar"; |
| | | "Skip" = "Pular"; |
| | | "Feedback" = "Feedback"; |
| | | "FeedbackStr1" = "Obrigado por seu feedback."; |
| | | "FeedbackStr2" = "Continuaremos nos empenhando para fornecer a você a melhor experiência em publicidade."; |
| | | "FeedbackStr3" = "Você já enviou seu feedback."; |
| | | "FeedbackStr4" = "Não envie mais de um!"; |
| | | "ViewNow" = "Visualizar agora"; |
| | | "Download" = "Obter"; |
| | | "LoadFailure" = "Falha ao carregar. Tente novamente."; |
| | | "GetRewardAfterWatching" = "Assista ao vídeo completo para ganhar premiações"; |
| | | "GiveUpReward" = "Desistir das premiações"; |
| | | "ContinueWatching" = "Continuar assistindo"; |
| | | "CanbeTurnedOffAfter" = "Pular depois de %ds"; |
| | | "Get" = "Fazer download"; |
| | | "View" = "Visualizar"; |
| | | "ContinuePlaying" = "Continuar executando"; |
| | | "GetRewardAfterPlaying" = "Finalizar a execução para solicitar as premiações"; |
| | | "Wan" = "10 mil"; |
| | | // Icon |
New file |
| | |
| | | /* |
| | | BULanguage.strings |
| | | BUAdSDK |
| | | |
| | | Created by wangyanlin on 2020/4/10. |
| | | Copyright © 2020 bytedance. All rights reserved. |
| | | */ |
| | | |
| | | // String |
| | | |
| | | "Click" = "Нажмите"; |
| | | "AD" = "Рекламное объявление"; |
| | | "PlayConsumed" = "На воспроизведение будет потрачено %.2f МБ трафика"; |
| | | "Evaluation" = "Оценка"; |
| | | "Score" = "Оценки: %@"; |
| | | "Select" = "Выбрать"; |
| | | "Back" = "Назад"; |
| | | "Replay" = "Нажмите, чтобы воспроизвести еще раз"; |
| | | "Continue" = "Продолжить воспроизведение"; |
| | | "Skip" = "Пропустить"; |
| | | "Feedback" = "Отзыв"; |
| | | "FeedbackStr1" = "Благодарим за ваш отзыв."; |
| | | "FeedbackStr2" = "Мы постоянно работаем над улучшением качества рекламы."; |
| | | "FeedbackStr3" = "Вы уже оставили отзыв."; |
| | | "FeedbackStr4" = "Желательно оставлять отзыв только один раз!"; |
| | | "ViewNow" = "Смотреть"; |
| | | "Download" = "Получить"; |
| | | "LoadFailure" = "Ошибка загрузки. Попробуйте снова."; |
| | | "GetRewardAfterWatching" = "Завершите просмотр полного видео, чтобы получить награду"; |
| | | "GiveUpReward" = "Отказаться от награды"; |
| | | "ContinueWatching" = "Продолжить просмотр"; |
| | | "CanbeTurnedOffAfter" = "Можно пропустить через %d с"; |
| | | "Get" = "Скачать"; |
| | | "View" = "Вид"; |
| | | "ContinuePlaying" = "Продолжить просмотр"; |
| | | "GetRewardAfterPlaying" = "Завершите просмотр, чтобы получить награду"; |
| | | "Wan" = "10 тысяч"; |
New file |
| | |
| | | /* |
| | | BULanguage.strings |
| | | BUAdSDK |
| | | |
| | | Created by wangyanlin on 2020/4/10. |
| | | Copyright © 2020 bytedance. All rights reserved. |
| | | */ |
| | | |
| | | // String |
| | | |
| | | "Click" = "คลิก"; |
| | | "AD" = "โฆษณา"; |
| | | "PlayConsumed" = "การเล่นรายการนี้จะใช้อินเทอร์เน็ต %.2f MB"; |
| | | "Evaluation" = "การประเมินผล"; |
| | | "Score" = "%@ คะแนน"; |
| | | "Select" = "เลือก"; |
| | | "Back" = "กลับ"; |
| | | "Replay" = "คลิกเพื่อเล่นซ้ำ"; |
| | | "Continue" = "ดำเนินการต่อเพื่อเล่น"; |
| | | "Skip" = "ข้าม"; |
| | | "Feedback" = "ผลตอบรับ"; |
| | | "FeedbackStr1" = "ขอบคุณสำหรับผลตอบรับของคุณ"; |
| | | "FeedbackStr2" = "เราจะพยายามอย่างต่อเนื่องเพื่อมอบประสบการณ์การโฆษณาที่ดียิ่งขึ้น"; |
| | | "FeedbackStr3" = "คุณได้ส่งผลตอบรับแล้ว"; |
| | | "FeedbackStr4" = "โปรดอย่าส่งมากกว่าหนึ่งครั้ง"; |
| | | "ViewNow" = "ดูตอนนี้"; |
| | | "Download" = "รับ"; |
| | | "LoadFailure" = "การโหลดล้มเหลว โปรดลองอีกครั้ง"; |
| | | "GetRewardAfterWatching" = "ดูวิดีโอแบบเต็มจนจบเพื่อรับรางวัล"; |
| | | "GiveUpReward" = "รางวัลการยอมแพ้"; |
| | | "ContinueWatching" = "ดูต่อ"; |
| | | "CanbeTurnedOffAfter" = "ข้ามหลังจาก %d วิ"; |
| | | "Get" = "ดาวน์โหลด"; |
| | | "View" = "ดู"; |
| | | "ContinuePlaying" = "เล่นต่อ"; |
| | | "GetRewardAfterPlaying" = "เล่นจนจบเพื่อรับรางวัล"; |
| | | "Wan" = "1 หมื่น"; |
New file |
| | |
| | | /* |
| | | BULanguage.strings |
| | | BUAdSDK |
| | | |
| | | Created by wangyanlin on 2020/4/10. |
| | | Copyright © 2020 bytedance. All rights reserved. |
| | | */ |
| | | |
| | | // String |
| | | |
| | | "Click" = "Nhấp"; |
| | | "AD" = "QUẢNG CÁO"; |
| | | "PlayConsumed" = "Bạn sẽ mất %.2f MB dữ liệu để phát mục này"; |
| | | "Evaluation" = "Đánh giá"; |
| | | "Score" = "%@ xếp hạng"; |
| | | "Select" = "Chọn"; |
| | | "Back" = "Quay lại"; |
| | | "Replay" = "Nhấp để phát lại"; |
| | | "Continue" = "Tiếp tục phát"; |
| | | "Skip" = "Bỏ qua"; |
| | | "Feedback" = "Phản hồi"; |
| | | "FeedbackStr1" = "Cảm ơn bạn đã phản hồi."; |
| | | "FeedbackStr2" = "Chúng tôi sẽ tiếp tục nỗ lực để mang đến cho bạn trải nghiệm quảng cáo tốt hơn."; |
| | | "FeedbackStr3" = "Bạn đã gửi phản hồi."; |
| | | "FeedbackStr4" = "Vui lòng không gửi nhiều lần!"; |
| | | "ViewNow" = "Xem ngay"; |
| | | "Download" = "Lấy"; |
| | | "LoadFailure" = "Không tải được. Vui lòng thử lại."; |
| | | "GetRewardAfterWatching" = "Xem hết video để nhận phần thưởng"; |
| | | "GiveUpReward" = "Bỏ phần thưởng"; |
| | | "ContinueWatching" = "Tiếp tục xem"; |
| | | "CanbeTurnedOffAfter" = "Bỏ qua sau %d s"; |
| | | "Get" = "Tải"; |
| | | "View" = "Xem"; |
| | | "ContinuePlaying" = "Tiếp tục chơi"; |
| | | "GetRewardAfterPlaying" = "Chơi hết để giành phần thưởng"; |
| | | "Wan" = "10 nghìn"; |
New file |
| | |
| | | /* |
| | | BULanguage.strings |
| | | BUAdSDK |
| | | |
| | | Created by 李盛 on 2019/1/7. |
| | | Copyright © 2019 bytedance. All rights reserved. |
| | | */ |
| | | |
| | | // String |
| | | |
| | | "Click" = "点击"; |
| | | "AD" = "广告"; |
| | | "PlayConsumed" = "播放将消耗%.2fMB流量"; |
| | | "Evaluation" = "评价"; |
| | | "Score" = "%@个评分"; |
| | | "Select" = "选择"; |
| | | "Wan" = "万"; |
| | | "Back" = "返回"; |
| | | "Replay" = "点击重播"; |
| | | "Continue" = "继续播放"; |
| | | "Skip" = "跳过"; |
| | | "Feedback" = "反馈"; |
| | | "FeedbackStr1" = "感谢您的反馈!"; |
| | | "FeedbackStr2" = "我们将为您带来更优质的广告体验"; |
| | | "FeedbackStr3" = "您已提交过反馈!"; |
| | | "FeedbackStr4" = "请勿反复提交"; |
| | | "ViewNow" = "立即查看"; |
| | | "Download" = "立即下载"; |
| | | "LoadFailure" = "加载失败,点击重试"; |
| | | "GetRewardAfterWatching" = "观看完整视频才能获得奖励"; |
| | | "GiveUpReward" = "放弃奖励"; |
| | | "ContinueWatching" = "继续观看"; |
| | | "CanbeTurnedOffAfter" = "%ds后可关闭"; |
| | | "Get" = "下载"; |
| | | "View" = "查看"; |
| | | "ContinuePlaying" = "继续试玩"; |
| | | "GetRewardAfterPlaying" = "试玩后才可领取奖励"; |
| | | // Icon |
New file |
| | |
| | | /* |
| | | BULanguage.strings |
| | | BUAdSDK |
| | | |
| | | Created by wangyanlin on 2020/4/10. |
| | | Copyright © 2020 bytedance. All rights reserved. |
| | | */ |
| | | |
| | | // String |
| | | |
| | | "Click" = "點擊"; |
| | | "AD" = "廣告"; |
| | | "PlayConsumed" = "播放將消耗%.2fMB流量"; |
| | | "Evaluation" = "評估"; |
| | | "Score" = "%@個評分"; |
| | | "Select" = "選擇"; |
| | | "Back" = "返回"; |
| | | "Replay" = "點擊重播"; |
| | | "Continue" = "繼續播放"; |
| | | "Skip" = "跳過"; |
| | | "Feedback" = "迴響"; |
| | | "FeedbackStr1" = "感謝您的迴響!"; |
| | | "FeedbackStr2" = "我們將為您帶來更優質的廣告體驗"; |
| | | "FeedbackStr3" = "您已提交過迴響!"; |
| | | "FeedbackStr4" = "請勿反復提交"; |
| | | "ViewNow" = "立即查看"; |
| | | "Download" = "立即下載"; |
| | | "LoadFailure" = "加載失敗,點擊重試"; |
| | | "GetRewardAfterWatching" = "觀看完整視頻才能獲得獎勵"; |
| | | "GiveUpReward" = "放弃獎勵"; |
| | | "ContinueWatching" = "繼續觀看"; |
| | | "CanbeTurnedOffAfter" = "%ds後可關閉"; |
| | | "Get" = "下載"; |
| | | "View" = "查看"; |
| | | "ContinuePlaying" = "繼續試玩"; |
| | | "GetRewardAfterPlaying" = "試玩後才可領取獎勵"; |
| | | "Wan" = "萬"; |
New file |
| | |
| | | // |
| | | // BUAdSDK.h |
| | | // BUAdSDK |
| | | // |
| | | // Copyright © 2017年 bytedance. All rights reserved. |
| | | // |
| | | |
| | | #import <UIKit/UIKit.h> |
| | | // In this header, you should import all the public headers of your framework using statements like #import <BUAdSDK/PublicHeader.h> |
| | | |
| | | #import <BUAdSDK/BUAdSDKDefines.h> |
| | | #import <BUAdSDK/BUAdSDKManager.h> |
| | | #import <BUAdSDK/BUAdSDKError.h> |
| | | #import <BUAdSDK/BUAdSlot.h> |
| | | #import <BUAdSDK/BUImage.h> |
| | | #import <BUAdSDK/BUSize.h> |
| | | #import <BUAdSDK/BUMaterialMeta.h> |
| | | #import <BUAdSDK/BUPlayerPublicDefine.h> |
| | | #import <BUAdSDK/BUVideoAdView.h> |
| | | |
| | | ///customize dislike style |
| | | #import <BUAdSDK/BUDislike.h> |
| | | #import <BUAdSDK/BUDislikeWords.h> |
| | | |
| | | /// native ads |
| | | #import <BUAdSDK/BUNativeAd.h> |
| | | #import <BUAdSDK/BUNativeAdRelatedView.h> |
| | | #import <BUAdSDK/BUNativeAdsManager.h> |
| | | |
| | | /// native express ads |
| | | #import <BUAdSDK/BUNativeExpressAdManager.h> |
| | | #import <BUAdSDK/BUNativeExpressAdView.h> |
| | | #import <BUAdSDK/BUNativeExpressBannerView.h> |
| | | #import <BUAdSDK/BUNativeExpressInterstitialAd.h> |
| | | #import <BUAdSDK/BUNativeExpressRewardedVideoAd.h> |
| | | #import <BUAdSDK/BUNativeExpressFullscreenVideoAd.h> |
| | | #import <BUAdSDK/BUNativeExpressSplashView.h> |
| | | |
| | | /// banner ads |
| | | #import <BUAdSDK/BUBannerAdView.h> |
| | | |
| | | /// splash ads |
| | | #import <BUAdSDK/BUSplashAdView.h> |
| | | |
| | | /// interstitial ads |
| | | #import <BUAdSDK/BUInterstitialAd.h> |
| | | |
| | | /// rewarded video ads |
| | | #import <BUAdSDK/BURewardedVideoModel.h> |
| | | #import <BUAdSDK/BURewardedVideoAd.h> |
| | | |
| | | /// full-screen video ads |
| | | #import <BUAdSDK/BUFullscreenVideoAd.h> |
| | | |
| | | /// playable tool |
| | | #import <BUAdSDK/BUAdSDKPlayableToolManager.h> |
| | | |
| | | // smartlook |
| | | #import <BUAdSDK/BUAdSmartlookManager.h> |
| | | |
| | | /// test tools |
| | | #import <BUAdSDK/BUAdSDKTestToolManager.h> |
| | | |
| | | /// pangle view |
| | | #import <BUAdSDK/PangleNativeBannerView.h> |
| | | #import <BUAdSDK/PangleNativeInterstitialView.h> |
New file |
| | |
| | | // |
| | | // BUAdSDKDefines.h |
| | | // BUAdSDK |
| | | // |
| | | // Copyright © 2017年 bytedance. All rights reserved. |
| | | // |
| | | |
| | | #ifndef BUAdSDK_DEFINES_h |
| | | #define BUAdSDK_DEFINES_h |
| | | |
| | | #import <Foundation/Foundation.h> |
| | | |
| | | typedef NS_ENUM(NSInteger, BUOfflineType) { |
| | | BUOfflineTypeNone, // Do not set offline |
| | | BUOfflineTypeProtocol, // Offline dependence NSURLProtcol |
| | | BUOfflineTypeWebview, // Offline dependence WKWebview |
| | | }; |
| | | |
| | | typedef NS_ENUM(NSInteger, BUAdSDKLogLevel) { |
| | | BUAdSDKLogLevelNone, |
| | | BUAdSDKLogLevelError, |
| | | BUAdSDKLogLevelDebug |
| | | }; |
| | | |
| | | typedef NS_ENUM(NSInteger, BURitSceneType) { |
| | | BURitSceneType_custom = 0,//custom |
| | | BURitSceneType_home_open_bonus = 1,//Login/open rewards (login, sign-in, offline rewards doubling, etc.) |
| | | BURitSceneType_home_svip_bonus = 2,//Special privileges (VIP privileges, daily rewards, etc.) |
| | | BURitSceneType_home_get_props = 3,//Watch rewarded video ad to gain skin, props, levels, skills, etc |
| | | BURitSceneType_home_try_props = 4,//Watch rewarded video ad to try out skins, props, levels, skills, etc |
| | | BURitSceneType_home_get_bonus = 5,//Watch rewarded video ad to get gold COINS, diamonds, etc |
| | | BURitSceneType_home_gift_bonus = 6,//Sweepstakes, turntables, gift boxes, etc |
| | | BURitSceneType_game_start_bonus = 7,//Before the opening to obtain physical strength, opening to strengthen, opening buff, task props |
| | | BURitSceneType_game_reduce_waiting = 8,//Reduce wait and cooldown on skill CD, building CD, quest CD, etc |
| | | BURitSceneType_game_more_opportunities = 9,//More chances (resurrect death, extra game time, decrypt tips, etc.) |
| | | BURitSceneType_game_finish_rewards = 10,//Settlement multiple times/extra bonus (completion of chapter, victory over boss, first place, etc.) |
| | | BURitSceneType_game_gift_bonus = 11//The game dropped treasure box, treasures and so on |
| | | }; |
| | | |
| | | @protocol BUToDictionary <NSObject> |
| | | - (NSDictionary *)dictionaryValue; |
| | | @end |
| | | |
| | | #endif |
New file |
| | |
| | | // |
| | | // BUAdSDKError.h |
| | | // BUAdSDK |
| | | // |
| | | // Copyright © 2017年 bytedance. All rights reserved. |
| | | // |
| | | |
| | | #import <Foundation/Foundation.h> |
| | | |
| | | extern NSErrorDomain BUErrorDomain ; |
| | | |
| | | typedef NS_ENUM(NSInteger, BUErrorCode) { |
| | | BUErrorCodeTempError = -6, // native template is invalid |
| | | BUErrorCodeTempAddationError= -5, // native template addation is invalid |
| | | BUErrorCodeOpenAPPStoreFail = -4, // failed to open appstore |
| | | BUErrorCodeNOAdError = -3, // parsed data has no ads |
| | | BUErrorCodeNetError = -2, // network request failed |
| | | BUErrorCodeParseError = -1, // parsing failed |
| | | |
| | | BUErrorCodeSDKInitConfigUnfinished = -100, // sdk init config is unfinished |
| | | |
| | | BUErrorCodePlayableError_ERR_HAS_CACHE = -702, // has cache |
| | | BUErrorCodePlayableError_ERR_UNZIP = -704, // unzip error |
| | | |
| | | BUErrorCodeNERenderResultError= 101, // native Express ad, render result parse fail |
| | | BUErrorCodeNETempError = 102, // native Express ad, template is invalid |
| | | BUErrorCodeNETempPluginError = 103, // native Express ad, template plugin is invalid |
| | | BUErrorCodeNEDataError = 104, // native Express ad, data is invalid |
| | | BUErrorCodeNEParseError = 105, // native Express ad, parse fail |
| | | BUErrorCodeNERenderError = 106, // native Express ad, render fail |
| | | BUErrorCodeNERenderTimoutError= 107, // native Express ad, render timeout |
| | | BUErrorCodeTempLoadError = 109, // native Express ad, template load fail |
| | | |
| | | BUErrorCodeSDKStop = 1000, // SDK stop forcely |
| | | |
| | | BUErrorCodeParamError = 10001, // parameter error |
| | | BUErrorCodeTimeout = 10002, |
| | | |
| | | BUErrorCodeSuccess = 20000, |
| | | BUErrorCodeNOAD = 20001, // no ads |
| | | |
| | | BUErrorCodeContentType = 40000, // http conent_type error |
| | | BUErrorCodeRequestPBError = 40001, // http request pb error |
| | | BUErrorCodeAppEmpty = 40002, // request app can't be empty |
| | | BUErrorCodeWapEMpty = 40003, // request wap can't be empty |
| | | BUErrorCodeAdSlotEmpty = 40004, // missing ad slot description |
| | | BUErrorCodeAdSlotSizeEmpty = 40005, // the ad slot size is invalid |
| | | BUErrorCodeAdSlotIDError = 40006, // the ad slot ID is invalid |
| | | BUErrorCodeAdCountError = 40007, // request the wrong number of ads |
| | | BUUnionAdImageSizeError = 40008, // wrong image size |
| | | BUUnionAdSiteIdError = 40009, // Media ID is illegal |
| | | BUUnionAdSiteMeiaTypeError = 40010, // Media type is illegal |
| | | BUUnionAdSiteAdTypeError = 40011, // Ad type is illegal |
| | | BUUnionAdSiteAccessMethodError = 40012,// Media access type is illegal and has been deprecated |
| | | BUUnionSplashAdTypeError = 40013, // Code bit id is less than 900 million, but adType is not splash ad |
| | | BUUnionRedirectError = 40014, // The redirect parameter is incorrect |
| | | BUUnionRequestInvalidError = 40015, // Media rectification exceeds deadline, request illegal |
| | | BUUnionAppSiteRelError = 40016, // The relationship between slot_id and app_id is invalid. |
| | | BUUnionAccessMethodError = 40017, // Media access type is not legal API/SDK |
| | | BUUnionPackageNameError = 40018, // Media package name is inconsistent with entry |
| | | BUUnionConfigurationError = 40019, // Media configuration ad type is inconsistent with request |
| | | BUUnionRequestLimitError = 40020, // The ad space registered by developers exceeds daily request limit |
| | | BUUnionSignatureError = 40021, // Apk signature sha1 value is inconsistent with media platform entry |
| | | BUUnionIncompleteError = 40022, // Whether the media request material is inconsistent with the media platform entry |
| | | BUUnionOSError = 40023, // The OS field is incorrectly filled |
| | | BUUnionLowVersion = 40024, // The SDK version is too low to return ads |
| | | BUErrorCodeAdPackageIncomplete = 40025,// the SDK package is incomplete. It is recommended to verify the integrity of SDK package or contact technical support. |
| | | BUUnionMedialCheckError = 40026, // Non-international account request for overseas delivery system |
| | | BUUnionSlotIDRenderMthodNoMatch = 40029,// The rendering method for slot ID does not match. |
| | | |
| | | BUErrorCodeSysError = 50001 // ad server error |
| | | }; |
New file |
| | |
| | | // |
| | | // BUAdSDKManager.h |
| | | // BUAdSDK |
| | | // |
| | | // Copyright © 2017 bytedance. All rights reserved. |
| | | // |
| | | |
| | | #import <Foundation/Foundation.h> |
| | | #import <UIKit/UIKit.h> |
| | | #import "BUAdSDKDefines.h" |
| | | #import "BUMopubAdMarkUpDelegate.h" |
| | | |
| | | typedef void (^BUConfirmGDPR)(BOOL isAgreed); |
| | | |
| | | @interface BUAdSDKManager : NSObject |
| | | |
| | | @property (nonatomic, copy, readonly, class) NSString *SDKVersion; |
| | | |
| | | /** |
| | | Register the App key that’s already been applied before requesting an ad from TikTok Audience Network. |
| | | @param appID : the unique identifier of the App |
| | | */ |
| | | + (void)setAppID:(NSString *)appID; |
| | | /** |
| | | Configure development mode. |
| | | @param level : default BUAdSDKLogLevelNone |
| | | */ |
| | | + (void)setLoglevel:(BUAdSDKLogLevel)level; |
| | | |
| | | /* Set the COPPA of the user, COPPA is the short of Children's Online Privacy Protection Rule, the interface only works in the United States. |
| | | * @params Coppa 0 adult, 1 child |
| | | */ |
| | | + (void)setCoppa:(NSUInteger)Coppa; |
| | | |
| | | /// Set the user's keywords, such as interests and hobbies, etc. |
| | | /// Must obtain the consent of the user before incoming. |
| | | + (void)setUserKeywords:(NSString *)keywords; |
| | | |
| | | /// set additional user information. |
| | | + (void)setUserExtData:(NSString *)data; |
| | | |
| | | /// Set whether the app is a paid app, the default is a non-paid app. |
| | | /// Must obtain the consent of the user before incoming |
| | | + (void)setIsPaidApp:(BOOL)isPaidApp; |
| | | |
| | | /// Solve the problem when your WKWebview post message empty,default is BUOfflineTypeWebview |
| | | + (void)setOfflineType:(BUOfflineType)type; |
| | | |
| | | /// Custom set the GDPR of the user,GDPR is the short of General Data Protection Regulation,the interface only works in The European. |
| | | /// @params GDPR 0 close privacy protection, 1 open privacy protection |
| | | + (void)setGDPR:(NSInteger)GDPR; |
| | | |
| | | /// Custom set the AB vid of the user. Array element type is NSNumber |
| | | + (void)setABVidArray:(NSArray<NSNumber *> *)abvids; |
| | | |
| | | /// Custom set the tob ab sdk version of the user. |
| | | + (void)setABSDKVersion:(NSString *)abSDKVersion; |
| | | |
| | | /// Custom set disable sdadnetwork. if won't need skadnetwork to record conversion set disable to YES, default is enable |
| | | + (void)setDisableSKAdNetwork:(BOOL)disable; |
| | | |
| | | /// Open GDPR Privacy for the user to choose before setAppID. |
| | | + (void)openGDPRPrivacyFromRootViewController:(UIViewController *)rootViewController confirm:(BUConfirmGDPR)confirm; |
| | | |
| | | /// get appID |
| | | + (NSString *)appID; |
| | | |
| | | /// get isPaidApp |
| | | + (BOOL)isPaidApp; |
| | | |
| | | /// get GDPR |
| | | + (NSInteger)GDPR; |
| | | |
| | | @end |
| | | |
| | | |
| | | @interface BUAdSDKManager (MopubAdaptor) <BUMopubAdMarkUpDelegate> |
| | | |
| | | @end |
New file |
| | |
| | | // |
| | | // BUAdSDKPlayableToolManager.h |
| | | // BUAdSDK |
| | | // |
| | | // Copyright © 2019 bytedance. All rights reserved. |
| | | // |
| | | |
| | | #import <Foundation/Foundation.h> |
| | | |
| | | @interface BUAdSDKPlayableToolManager : NSObject |
| | | |
| | | + (instancetype)sharedInstance; |
| | | |
| | | + (void)setPlayableURL:(NSString *)url; |
| | | |
| | | + (void)setDownloadUrl:(NSString *)url; |
| | | |
| | | + (void)setDeeplinkUrl:(NSString *)url; |
| | | |
| | | + (void)setIsLandScape:(BOOL)isLandScape; |
| | | |
| | | + (void)clearAll; |
| | | |
| | | @end |
| | | |
New file |
| | |
| | | // |
| | | // BUAdSDKTestToolManager.h |
| | | // BUAdSDK |
| | | // |
| | | // Created by wangyanlin on 2020/4/14. |
| | | // Copyright © 2020 bytedance. All rights reserved. |
| | | // |
| | | |
| | | #import <Foundation/Foundation.h> |
| | | |
| | | |
| | | @interface BUAdSDKTestToolManager : NSObject |
| | | |
| | | + (instancetype)sharedInstance; |
| | | |
| | | + (void)setHostIP:(NSString *)hostIP; |
| | | |
| | | + (void)setHostPort:(NSString *)hostPort; |
| | | |
| | | + (void)setInputOneContent:(NSString *)oneContent; |
| | | |
| | | + (void)setInputTwoContent:(NSString *)twoContent; |
| | | |
| | | + (void)clearIPAddress; |
| | | |
| | | + (void)clearInputContent; |
| | | |
| | | @end |
| | | |
| | | |
New file |
| | |
| | | // |
| | | // BUAdSlot.h |
| | | // BUAdSDK |
| | | // |
| | | // Copyright © 2017 bytedance. All rights reserved. |
| | | // |
| | | |
| | | #import <Foundation/Foundation.h> |
| | | #import "BUSize.h" |
| | | |
| | | typedef NS_ENUM(NSInteger, BUAdSlotAdType) { |
| | | BUAdSlotAdTypeUnknown = 0, |
| | | BUAdSlotAdTypeBanner = 1, // banner ads |
| | | BUAdSlotAdTypeInterstitial = 2, // interstitial ads |
| | | BUAdSlotAdTypeSplash = 3, // splash ads |
| | | BUAdSlotAdTypeSplash_Cache = 4, // cache splash ads |
| | | BUAdSlotAdTypeFeed = 5, // feed ads |
| | | BUAdSlotAdTypePaster = 6, // paster ads |
| | | BUAdSlotAdTypeRewardVideo = 7, // rewarded video ads |
| | | BUAdSlotAdTypeFullscreenVideo = 8, // full-screen video ads |
| | | BUAdSlotAdTypeDrawVideo = 9, // vertical (immersive) video ads |
| | | }; |
| | | |
| | | typedef NS_ENUM(NSInteger, BUAdSlotPosition) { |
| | | BUAdSlotPositionTop = 1, |
| | | BUAdSlotPositionBottom = 2, |
| | | BUAdSlotPositionFeed = 3, |
| | | BUAdSlotPositionMiddle = 4, // for interstitial ad only |
| | | BUAdSlotPositionFullscreen = 5, |
| | | }; |
| | | |
| | | @interface BUAdSlot : NSObject |
| | | |
| | | /// required. The unique identifier of a native ad. |
| | | @property (nonatomic, copy) NSString *ID; |
| | | |
| | | /// required. Ad type. |
| | | @property (nonatomic, assign) BUAdSlotAdType AdType; |
| | | |
| | | /// required. Ad display location. |
| | | @property (nonatomic, assign) BUAdSlotPosition position; |
| | | |
| | | /// Accept a set of image sizes, please pass in the BUSize object. |
| | | @property (nonatomic, strong) NSMutableArray<BUSize *> *imgSizeArray; |
| | | |
| | | /// required. Image size. |
| | | @property (nonatomic, strong) BUSize *imgSize; |
| | | |
| | | /// Icon size. |
| | | @property (nonatomic, strong) BUSize *iconSize; |
| | | |
| | | /// Maximum length of the title. |
| | | @property (nonatomic, assign) NSInteger titleLengthLimit; |
| | | |
| | | /// Maximum length of description. |
| | | @property (nonatomic, assign) NSInteger descLengthLimit; |
| | | |
| | | /// Whether to support deeplink. |
| | | @property (nonatomic, assign) BOOL isSupportDeepLink; |
| | | |
| | | /// Native banner ads and native interstitial ads are set to 1, other ad types are 0, the default is 0. |
| | | @property (nonatomic, assign) BOOL isOriginAd; |
| | | |
| | | |
| | | //adload_seq:(针对聚合广告位)传递本次请求是为“自然日内某设备某广告位置第N次展示机会”发出的广告请求,同物理位置在自然日从1开始计数,不同物理位置独立计数;example:某原生广告位置,当天第5次产生展示机会,这次展示机向穿山甲发送了4次广告请求,则这4次广告请求的"adload_seq"的值应为5。第二天重新开始计数。 |
| | | @property (nonatomic, assign) NSInteger adloadSeq; |
| | | |
| | | //prime_rit:(针对聚合广告位)广告物理位置对应的固定穿山甲广告位id,可以使用第一层的广告位id也可以为某一层的广告位id,但要求同一物理位置在该字段固定上报同一广告位id,不频繁更换;example:某原生广告位,当天共发出了1000个请求,这1000个请求中使用了5个不同target的穿山甲rit,用某X rit来作为该位置的标记rit,则这1000次请求的prime_rit都需要上报X rit的rit id。 |
| | | @property (nonatomic, copy) NSString *primeRit; |
| | | |
| | | - (NSDictionary *)dictionaryValue; |
| | | |
| | | @end |
| | | |
New file |
| | |
| | | // |
| | | // BUAdSmartlookManager.h |
| | | // BUAdSDK |
| | | // |
| | | // Created by wangchao on 2020/3/30. |
| | | // Copyright © 2020 bytedance. All rights reserved. |
| | | // |
| | | |
| | | #import <Foundation/Foundation.h> |
| | | |
| | | NS_ASSUME_NONNULL_BEGIN |
| | | |
| | | @interface BUAdSmartlookManager : NSObject |
| | | |
| | | |
| | | + (instancetype)sharedInstance; |
| | | |
| | | + (void)setupSmartlookConfig:(NSString *)config; |
| | | + (void)resetConfig; |
| | | |
| | | @end |
| | | |
| | | NS_ASSUME_NONNULL_END |
New file |
| | |
| | | // |
| | | // BUBannerAdView.h |
| | | // BUAdSDK |
| | | // |
| | | // Copyright © 2017年 bytedance. All rights reserved. |
| | | // |
| | | |
| | | #import <UIKit/UIKit.h> |
| | | #import "BUNativeAd.h" |
| | | |
| | | @class BUDislikeWords, BUAdSlot; |
| | | @protocol BUBannerAdViewDelegate; |
| | | |
| | | |
| | | NS_ASSUME_NONNULL_BEGIN |
| | | |
| | | @interface BUBannerAdView : UIView |
| | | |
| | | @property (nonatomic, weak, nullable) id<BUBannerAdViewDelegate> delegate; |
| | | |
| | | /** |
| | | The carousel interval, in seconds, is set in the range of 30~120s, and is passed during initialization. If it does not meet the requirements, it will not be in carousel ad. |
| | | */ |
| | | @property (nonatomic, assign, readonly) NSInteger interval; |
| | | |
| | | /** |
| | | The dislikeButton has been added to the upper right corner of the BannerView by default, it will respond to dislike reasons. |
| | | */ |
| | | @property (nonatomic, strong, readonly, nonnull) UIButton *dislikeButton; |
| | | |
| | | /// media configuration parameters. |
| | | @property (nonatomic, copy, readonly) NSDictionary *mediaExt; |
| | | |
| | | - (instancetype)initWithIdentifier:(NSString *)slotID |
| | | rootViewController:(UIViewController *)rootViewController |
| | | adSize:(CGSize)adSize |
| | | withShowPosition:(BUAdSlotPosition)showPosition |
| | | WithIsSupportDeepLink:(BOOL)isSupportDeepLink; |
| | | |
| | | - (instancetype)initWithIdentifier:(NSString *)slotID |
| | | rootViewController:(UIViewController *)rootViewController |
| | | adSize:(CGSize)adSize |
| | | withShowPosition:(BUAdSlotPosition)showPosition |
| | | WithIsSupportDeepLink:(BOOL)isSupportDeepLink |
| | | interval:(NSInteger)interval; |
| | | |
| | | - (instancetype)initWithSlotID:(NSString *)slotID |
| | | size:(BUSize *)adSize |
| | | rootViewController:(UIViewController *)rootViewController; |
| | | |
| | | - (instancetype)initWithSlotID:(NSString *)slotID |
| | | size:(BUSize *)adSize |
| | | rootViewController:(UIViewController *)rootViewController |
| | | interval:(NSInteger)interval; |
| | | |
| | | /** |
| | | adload_seq:(针对聚合广告位)传递本次请求是为“自然日内某设备某广告位置第N次展示机会”发出的广告请求,同物理位置在自然日从1开始计数,不同物理位置独立计数;example:某原生广告位置,当天第5次产生展示机会,这次展示机向穿山甲发送了4次广告请求,则这4次广告请求的"adload_seq"的值应为5。第二天重新开始计数。 |
| | | |
| | | prime_rit:(针对聚合广告位)广告物理位置对应的固定穿山甲广告位id,可以使用第一层的广告位id也可以为某一层的广告位id,但要求同一物理位置在该字段固定上报同一广告位id,不频繁更换;example:某原生广告位,当天共发出了1000个请求,这1000个请求中使用了5个不同target的穿山甲rit,用某X rit来作为该位置的标记rit,则这1000次请求的prime_rit都需要上报X rit的rit id。 |
| | | */ |
| | | |
| | | - (instancetype)initWithSlotID:(NSString *)slotID |
| | | adloadSeq:(NSInteger)adloadSeq |
| | | primeRit:(NSString *)primeRit |
| | | rootViewController:(UIViewController *)rootViewController |
| | | adSize:(CGSize)adSize |
| | | withShowPosition:(BUAdSlotPosition)showPosition |
| | | WithIsSupportDeepLink:(BOOL)isSupportDeepLink; |
| | | |
| | | - (void)loadAdData; |
| | | |
| | | - (IBAction)dislikeAction:(id)sender; |
| | | @end |
| | | |
| | | @protocol BUBannerAdViewDelegate <NSObject> |
| | | |
| | | @optional |
| | | |
| | | /** |
| | | This method is called when bannerAdView ad slot loaded successfully. |
| | | @param bannerAdView : view for bannerAdView |
| | | @param nativeAd : nativeAd for bannerAdView |
| | | */ |
| | | - (void)bannerAdViewDidLoad:(BUBannerAdView *)bannerAdView WithAdmodel:(BUNativeAd *_Nullable)nativeAd; |
| | | |
| | | /** |
| | | This method is called when bannerAdView ad slot failed to load. |
| | | @param error : the reason of error |
| | | */ |
| | | - (void)bannerAdView:(BUBannerAdView *)bannerAdView didLoadFailWithError:(NSError *_Nullable)error; |
| | | |
| | | /** |
| | | This method is called when bannerAdView ad slot showed new ad. |
| | | */ |
| | | - (void)bannerAdViewDidBecomVisible:(BUBannerAdView *)bannerAdView WithAdmodel:(BUNativeAd *_Nullable)nativeAd; |
| | | |
| | | /** |
| | | This method is called when bannerAdView is clicked. |
| | | */ |
| | | - (void)bannerAdViewDidClick:(BUBannerAdView *)bannerAdView WithAdmodel:(BUNativeAd *_Nullable)nativeAd; |
| | | |
| | | /** |
| | | This method is called when the user clicked dislike button and chose dislike reasons. |
| | | @param filterwords : the array of reasons for dislike. |
| | | */ |
| | | - (void)bannerAdView:(BUBannerAdView *)bannerAdView dislikeWithReason:(NSArray<BUDislikeWords *> *_Nullable)filterwords; |
| | | |
| | | /** |
| | | This method is called when another controller has been closed. |
| | | @param interactionType : open appstore in app or open the webpage or view video ad details page. |
| | | */ |
| | | - (void)bannerAdViewDidCloseOtherController:(BUBannerAdView *)bannerAdView interactionType:(BUInteractionType)interactionType; |
| | | |
| | | @end |
| | | |
| | | NS_ASSUME_NONNULL_END |
| | | |
New file |
| | |
| | | // |
| | | // BUDislike.h |
| | | // BUAdSDK |
| | | // |
| | | // Copyright © 2018年 bytedance. All rights reserved. |
| | | // |
| | | |
| | | #import <Foundation/Foundation.h> |
| | | @class BUNativeAd; |
| | | @class BUDislikeWords; |
| | | |
| | | /** |
| | | !!! important : |
| | | Please report to the sdk the user’s selection, inaccurate model will result in poor ad performance. |
| | | */ |
| | | @interface BUDislike : NSObject |
| | | /** |
| | | The array of BUDislikeWords which have reasons for dislike. |
| | | The application can show the secondary page for dislike if '[filterWords.options count] > 0'. |
| | | */ |
| | | @property (nonatomic, copy, readonly) NSArray<BUDislikeWords *> *filterWords; |
| | | |
| | | /** |
| | | Initialize with nativeAd to get filterWords. |
| | | return BUDislike |
| | | */ |
| | | - (instancetype)initWithNativeAd:(BUNativeAd *)nativeAd; |
| | | |
| | | /** |
| | | Call this method after the user chose dislike reasons. |
| | | (Only for object which uses 'BUDislike.filterWords') |
| | | @param filterWord : reasons for dislike |
| | | @note : don't need to call this method if '[filterWords.options count] > 0'. |
| | | @note :please dont't change 'BUDislike.filterWords'. |
| | | 'filterWord' must be one of 'BUDislike.filterWords', otherwise it will be filtered. |
| | | */ |
| | | - (void)didSelectedFilterWordWithReason:(BUDislikeWords *)filterWord; |
| | | |
| | | @end |
| | | |
New file |
| | |
| | | // |
| | | // BUDislikeWords.h |
| | | // BUAdSDK |
| | | // |
| | | // Copyright © 2017年 bytedance. All rights reserved. |
| | | // |
| | | |
| | | #import <Foundation/Foundation.h> |
| | | |
| | | @interface BUDislikeWords : NSObject <NSCoding> |
| | | @property (nonatomic, copy, readonly) NSString *dislikeID; |
| | | @property (nonatomic, copy, readonly) NSString *name; |
| | | @property (nonatomic, assign, readonly) BOOL isSelected; |
| | | @property (nonatomic, copy,readonly) NSArray<BUDislikeWords *> *options; |
| | | |
| | | - (instancetype)initWithDictionary:(NSDictionary *)dict error:(NSError **)error; |
| | | @end |
New file |
| | |
| | | // |
| | | // BUFullscreenVideoAd.h |
| | | // BUAdSDK |
| | | // |
| | | // Copyright © 2018年 bytedance. All rights reserved. |
| | | // |
| | | |
| | | #import <Foundation/Foundation.h> |
| | | #import <UIKit/UIKit.h> |
| | | #import "BUAdSlot.h" |
| | | #import "BUMopubAdMarkUpDelegate.h" |
| | | |
| | | typedef NS_ENUM(NSUInteger, BUFullScreenVideoAdType) { |
| | | BUFullScreenAdTypeEndcard = 0, // video + endcard |
| | | BUFullScreenAdTypeVideoPlayable = 1, // video + playable |
| | | BUFullScreenAdTypePurePlayable = 2 // pure playable |
| | | }; |
| | | |
| | | NS_ASSUME_NONNULL_BEGIN |
| | | |
| | | @class BUFullscreenVideoAd; |
| | | |
| | | @protocol BUFullscreenVideoAdDelegate <NSObject> |
| | | |
| | | @optional |
| | | |
| | | /** |
| | | This method is called when video ad material loaded successfully. |
| | | */ |
| | | - (void)fullscreenVideoMaterialMetaAdDidLoad:(BUFullscreenVideoAd *)fullscreenVideoAd; |
| | | |
| | | /** |
| | | This method is called when video ad materia failed to load. |
| | | @param error : the reason of error |
| | | */ |
| | | - (void)fullscreenVideoAd:(BUFullscreenVideoAd *)fullscreenVideoAd didFailWithError:(NSError *_Nullable)error; |
| | | |
| | | /** |
| | | This method is called when video cached successfully. |
| | | */ |
| | | - (void)fullscreenVideoAdVideoDataDidLoad:(BUFullscreenVideoAd *)fullscreenVideoAd; |
| | | |
| | | /** |
| | | This method is called when video ad slot will be showing. |
| | | */ |
| | | - (void)fullscreenVideoAdWillVisible:(BUFullscreenVideoAd *)fullscreenVideoAd; |
| | | |
| | | /** |
| | | This method is called when video ad slot has been shown. |
| | | */ |
| | | - (void)fullscreenVideoAdDidVisible:(BUFullscreenVideoAd *)fullscreenVideoAd; |
| | | |
| | | /** |
| | | This method is called when video ad is clicked. |
| | | */ |
| | | - (void)fullscreenVideoAdDidClick:(BUFullscreenVideoAd *)fullscreenVideoAd; |
| | | |
| | | /** |
| | | This method is called when video ad is about to close. |
| | | */ |
| | | - (void)fullscreenVideoAdWillClose:(BUFullscreenVideoAd *)fullscreenVideoAd; |
| | | |
| | | /** |
| | | This method is called when video ad is closed. |
| | | */ |
| | | - (void)fullscreenVideoAdDidClose:(BUFullscreenVideoAd *)fullscreenVideoAd; |
| | | |
| | | |
| | | /** |
| | | This method is called when video ad play completed or an error occurred. |
| | | @param error : the reason of error |
| | | */ |
| | | - (void)fullscreenVideoAdDidPlayFinish:(BUFullscreenVideoAd *)fullscreenVideoAd didFailWithError:(NSError *_Nullable)error; |
| | | |
| | | /** |
| | | This method is called when the user clicked skip button. |
| | | */ |
| | | - (void)fullscreenVideoAdDidClickSkip:(BUFullscreenVideoAd *)fullscreenVideoAd; |
| | | |
| | | /** |
| | | this method is used to get the type of fullscreen video ad |
| | | */ |
| | | - (void)fullscreenVideoAdCallback:(BUFullscreenVideoAd *)fullscreenVideoAd withType:(BUFullScreenVideoAdType)fullscreenVideoAdType; |
| | | |
| | | @end |
| | | |
| | | @interface BUFullscreenVideoAd : NSObject <BUMopubAdMarkUpDelegate> |
| | | |
| | | @property (nonatomic, weak, nullable) id<BUFullscreenVideoAdDelegate> delegate; |
| | | @property (nonatomic, getter=isAdValid, readonly) BOOL adValid; |
| | | |
| | | /// media configuration parameters. |
| | | @property (nonatomic, copy, readonly) NSDictionary *mediaExt; |
| | | |
| | | /** |
| | | Initializes video ad with slot id. |
| | | @param slotID : the unique identifier of video ad. |
| | | @return BUFullscreenVideoAd |
| | | */ |
| | | - (instancetype)initWithSlotID:(NSString *)slotID; |
| | | |
| | | /** |
| | | adload_seq:(针对聚合广告位)传递本次请求是为“自然日内某设备某广告位置第N次展示机会”发出的广告请求,同物理位置在自然日从1开始计数,不同物理位置独立计数;example:某原生广告位置,当天第5次产生展示机会,这次展示机向穿山甲发送了4次广告请求,则这4次广告请求的"adload_seq"的值应为5。第二天重新开始计数。 |
| | | |
| | | prime_rit:(针对聚合广告位)广告物理位置对应的固定穿山甲广告位id,可以使用第一层的广告位id也可以为某一层的广告位id,但要求同一物理位置在该字段固定上报同一广告位id,不频繁更换;example:某原生广告位,当天共发出了1000个请求,这1000个请求中使用了5个不同target的穿山甲rit,用某X rit来作为该位置的标记rit,则这1000次请求的prime_rit都需要上报X rit的rit id。 |
| | | */ |
| | | |
| | | - (instancetype)initWithSlotID:(NSString *)slotID adloadSeq:(NSInteger)adloadSeq primeRit:(NSString * __nullable)primeRit; |
| | | /** |
| | | Load video ad datas. |
| | | */ |
| | | - (void)loadAdData; |
| | | |
| | | /** |
| | | Display video ad. |
| | | @param rootViewController : root view controller for displaying ad. |
| | | @return : whether it is successfully displayed. |
| | | */ |
| | | - (BOOL)showAdFromRootViewController:(UIViewController *)rootViewController; |
| | | |
| | | /** |
| | | Display video ad. |
| | | @param rootViewController : root view controller for displaying ad. |
| | | @param sceneDescirbe : optional. Identifies a custom description of the presentation scenario. |
| | | @return : whether it is successfully displayed. |
| | | */ |
| | | - (BOOL)showAdFromRootViewController:(UIViewController *)rootViewController ritSceneDescribe:(NSString *_Nullable)sceneDescirbe; |
| | | |
| | | @end |
| | | |
| | | NS_ASSUME_NONNULL_END |
New file |
| | |
| | | // |
| | | // BUImage.h |
| | | // BUAdSDK |
| | | // |
| | | // Copyright © 2017 bytedance. All rights reserved. |
| | | // |
| | | |
| | | #import <Foundation/Foundation.h> |
| | | |
| | | @interface BUImage : NSObject <NSCoding> |
| | | |
| | | // image address URL |
| | | @property (nonatomic, copy) NSString *imageURL; |
| | | |
| | | // image width |
| | | @property (nonatomic, assign) float width; |
| | | |
| | | // image height |
| | | @property (nonatomic, assign) float height; |
| | | |
| | | - (instancetype)initWithDictionary:(NSDictionary *)dic; |
| | | |
| | | - (NSDictionary *)dictionaryValue; |
| | | |
| | | @end |
| | | |
New file |
| | |
| | | // |
| | | // BUInterstitialAd.h |
| | | // BUAdSDK |
| | | // |
| | | // Copyright © 2017年 bytedance. All rights reserved. |
| | | // |
| | | |
| | | #import <UIKit/UIKit.h> |
| | | #import "BUAdSDKDefines.h" |
| | | #import "BUMaterialMeta.h" |
| | | |
| | | NS_ASSUME_NONNULL_BEGIN |
| | | |
| | | @class BUSize; |
| | | @protocol BUInterstitialAdDelegate; |
| | | |
| | | @interface BUInterstitialAd : NSObject |
| | | @property (nonatomic, weak, nullable) id<BUInterstitialAdDelegate> delegate; |
| | | @property (nonatomic, getter=isAdValid, readonly) BOOL adValid; |
| | | |
| | | /// media configuration parameters. |
| | | @property (nonatomic, copy, readonly) NSDictionary *mediaExt; |
| | | |
| | | /** |
| | | Initializes interstitial ad. |
| | | @param slotID : The unique identifier of interstitial ad. |
| | | @param expectSize : custom size, default 600px * 400px |
| | | @return BUInterstitialAd |
| | | */ |
| | | - (instancetype)initWithSlotID:(NSString *)slotID size:(BUSize *)expectSize ; |
| | | |
| | | /** |
| | | adload_seq:(针对聚合广告位)传递本次请求是为“自然日内某设备某广告位置第N次展示机会”发出的广告请求,同物理位置在自然日从1开始计数,不同物理位置独立计数;example:某原生广告位置,当天第5次产生展示机会,这次展示机向穿山甲发送了4次广告请求,则这4次广告请求的"adload_seq"的值应为5。第二天重新开始计数。 |
| | | |
| | | prime_rit:(针对聚合广告位)广告物理位置对应的固定穿山甲广告位id,可以使用第一层的广告位id也可以为某一层的广告位id,但要求同一物理位置在该字段固定上报同一广告位id,不频繁更换;example:某原生广告位,当天共发出了1000个请求,这1000个请求中使用了5个不同target的穿山甲rit,用某X rit来作为该位置的标记rit,则这1000次请求的prime_rit都需要上报X rit的rit id。 |
| | | */ |
| | | |
| | | - (instancetype)initWithSlotID:(NSString *)slotID adloadSeq:(NSInteger)adloadSeq primeRit:(NSString * __nullable)primeRit size:(BUSize *)expectSize ; |
| | | /** |
| | | Load interstitial ad datas. |
| | | */ |
| | | - (void)loadAdData; |
| | | /** |
| | | Display interstitial ad. |
| | | @param rootViewController : root view controller for displaying ad. |
| | | @return : whether it is successfully displayed. |
| | | */ |
| | | - (BOOL)showAdFromRootViewController:(UIViewController *)rootViewController; |
| | | |
| | | @end |
| | | |
| | | @protocol BUInterstitialAdDelegate <NSObject> |
| | | |
| | | @optional |
| | | /** |
| | | This method is called when interstitial ad material loaded successfully. |
| | | */ |
| | | - (void)interstitialAdDidLoad:(BUInterstitialAd *)interstitialAd; |
| | | |
| | | /** |
| | | This method is called when interstitial ad material failed to load. |
| | | @param error : the reason of error |
| | | */ |
| | | - (void)interstitialAd:(BUInterstitialAd *)interstitialAd didFailWithError:(NSError * _Nullable)error; |
| | | |
| | | /** |
| | | This method is called when interstitial ad slot will be showing. |
| | | */ |
| | | - (void)interstitialAdWillVisible:(BUInterstitialAd *)interstitialAd; |
| | | |
| | | /** |
| | | This method is called when interstitial ad is clicked. |
| | | */ |
| | | - (void)interstitialAdDidClick:(BUInterstitialAd *)interstitialAd; |
| | | |
| | | /** |
| | | This method is called when interstitial ad is about to close. |
| | | */ |
| | | - (void)interstitialAdWillClose:(BUInterstitialAd *)interstitialAd; |
| | | |
| | | /** |
| | | This method is called when interstitial ad is closed. |
| | | */ |
| | | - (void)interstitialAdDidClose:(BUInterstitialAd *)interstitialAd; |
| | | |
| | | /** |
| | | This method is called when another controller has been closed. |
| | | @param interactionType : open appstore in app or open the webpage or view video ad details page. |
| | | */ |
| | | - (void)interstitialAdDidCloseOtherController:(BUInterstitialAd *)interstitialAd interactionType:(BUInteractionType)interactionType; |
| | | @end |
| | | |
| | | NS_ASSUME_NONNULL_END |
New file |
| | |
| | | // |
| | | // BUMaterialMeta.h |
| | | // BUAdSDK |
| | | // |
| | | // Copyright © 2017 bytedance. All rights reserved. |
| | | // |
| | | |
| | | #import <Foundation/Foundation.h> |
| | | #import "BUDislikeWords.h" |
| | | #import "BUImage.h" |
| | | |
| | | typedef NS_ENUM(NSInteger, BUInteractionType) { |
| | | BUInteractionTypeCustorm = 0, |
| | | BUInteractionTypeNO_INTERACTION = 1, // pure ad display |
| | | BUInteractionTypeURL = 2, // open the webpage using a browser |
| | | BUInteractionTypePage = 3, // open the webpage within the app |
| | | BUInteractionTypeDownload = 4, // download the app |
| | | BUInteractionTypePhone = 5, // make a call |
| | | BUInteractionTypeMessage = 6, // send messages |
| | | BUInteractionTypeEmail = 7, // send email |
| | | BUInteractionTypeVideoAdDetail = 8 // video ad details page |
| | | }; |
| | | |
| | | typedef NS_ENUM(NSInteger, BUFeedADMode) { |
| | | BUFeedADModeSmallImage = 2, |
| | | BUFeedADModeLargeImage = 3, |
| | | BUFeedADModeGroupImage = 4, |
| | | BUFeedVideoAdModeImage = 5, // video ad || rewarded video ad horizontal screen |
| | | BUFeedVideoAdModePortrait = 15, // rewarded video ad vertical screen |
| | | BUFeedADModeImagePortrait = 16, |
| | | BUFeedADModeSquareImage = 33, //SquareImage Currently it exists only in the oversea now. V3200 add |
| | | BUFeedADModeSquareVideo = 50, //SquareVideo Currently it exists only in the oversea now. V3200 add |
| | | }; |
| | | |
| | | @interface BUMaterialMeta : NSObject <NSCoding> |
| | | |
| | | /// interaction types supported by ads. |
| | | @property (nonatomic, assign) BUInteractionType interactionType; |
| | | |
| | | /// material pictures. |
| | | @property (nonatomic, strong) NSArray<BUImage *> *imageAry; |
| | | |
| | | /// ad logo icon. |
| | | @property (nonatomic, strong) BUImage *icon; |
| | | |
| | | /// ad headline. |
| | | @property (nonatomic, copy) NSString *AdTitle; |
| | | |
| | | /// ad description. |
| | | @property (nonatomic, copy) NSString *AdDescription; |
| | | |
| | | /// ad source. |
| | | @property (nonatomic, copy) NSString *source; |
| | | |
| | | /// text displayed on the creative button. |
| | | @property (nonatomic, copy) NSString *buttonText; |
| | | |
| | | /// display format of the in-feed ad, other ads ignores it. |
| | | @property (nonatomic, assign) BUFeedADMode imageMode; |
| | | |
| | | /// Star rating, range from 1 to 5. |
| | | @property (nonatomic, assign) NSInteger score; |
| | | |
| | | /// Number of comments. |
| | | @property (nonatomic, assign) NSInteger commentNum; |
| | | |
| | | /// ad installation package size, unit byte. |
| | | @property (nonatomic, assign) NSInteger appSize; |
| | | |
| | | /// video duration |
| | | @property (nonatomic, assign) NSInteger videoDuration; |
| | | |
| | | /// media configuration parameters. |
| | | @property (nonatomic, copy) NSDictionary *mediaExt; |
| | | |
| | | |
| | | - (instancetype)initWithDictionary:(NSDictionary *)dict error:(NSError * __autoreleasing *)error; |
| | | |
| | | @end |
| | | |
New file |
| | |
| | | // |
| | | // BUMopubAdMarkUpDelegate.h |
| | | // BUAdSDK |
| | | // |
| | | // Created by Siwant on 2020/4/24. |
| | | // Copyright © 2020 bytedance. All rights reserved. |
| | | // |
| | | |
| | | #import <Foundation/Foundation.h> |
| | | |
| | | NS_ASSUME_NONNULL_BEGIN |
| | | |
| | | @protocol BUMopubAdMarkUpDelegate <NSObject> |
| | | @optional |
| | | |
| | | /** Mopub AdMarkUp |
| | | */ |
| | | - (void)setMopubAdMarkUp:(NSString *)adm; |
| | | |
| | | /** Mopub Adaptor get AD type from rit |
| | | * @return @{@"adSlotType": @(1), @"renderType": @(1)} |
| | | * adSlotType refer from BUAdSlotAdType in "BUAdSlot.h" |
| | | * showType: @"1" express AD @"2" native AD |
| | | */ |
| | | + (NSDictionary *)AdTypeWithRit:(NSString *)rit error:(NSError **)error; |
| | | |
| | | /** Mopub bidding Adaptor get AD type from adm |
| | | * @return @{@"adSlotType": @(1), @"renderType": @(1)} |
| | | * adSlotType refer from BUAdSlotAdType in "BUAdSlot.h" |
| | | * showType: @"1" express AD @"2" native AD |
| | | */ |
| | | + (NSDictionary *)AdTypeWithAdMarkUp:(NSString *)adm; |
| | | |
| | | |
| | | /// Mopub Bidding Token |
| | | + (NSString *)mopubBiddingToken; |
| | | @end |
| | | |
| | | NS_ASSUME_NONNULL_END |
New file |
| | |
| | | // |
| | | // BUNativeAd.h |
| | | // BUAdSDK |
| | | // |
| | | // Copyright © 2017 bytedance. All rights reserved. |
| | | // |
| | | |
| | | #import <Foundation/Foundation.h> |
| | | #import <UIKit/UIKit.h> |
| | | #import "BUAdSlot.h" |
| | | #import "BUMaterialMeta.h" |
| | | #import "BUVideoAdView.h" |
| | | #import "BUMopubAdMarkUpDelegate.h" |
| | | |
| | | @protocol BUNativeAdDelegate; |
| | | |
| | | NS_ASSUME_NONNULL_BEGIN |
| | | |
| | | |
| | | /** |
| | | Abstract ad slot containing ad data loading, response callbacks. |
| | | BUNativeAd currently supports native ads. |
| | | Native ads include in-feed ad (multiple ads, image + video), general native ad (single ad, image + video), native banner ad, and native interstitial ad. |
| | | Support interstitial ad, banner ad, splash ad, rewarded video ad, full-screen video ad. |
| | | */ |
| | | @interface BUNativeAd : NSObject <BUMopubAdMarkUpDelegate> |
| | | |
| | | /** |
| | | Ad slot description. |
| | | */ |
| | | @property (nonatomic, strong, readwrite, nullable) BUAdSlot *adslot; |
| | | |
| | | /** |
| | | Ad slot material. |
| | | */ |
| | | @property (atomic, strong, readonly, nullable) BUMaterialMeta *data; |
| | | |
| | | /** |
| | | The delegate for receiving state change messages. |
| | | The delegate is not limited to viewcontroller. |
| | | The delegate can be set to any object which conforming to <BUNativeAdDelegate>. |
| | | */ |
| | | @property (nonatomic, weak, readwrite, nullable) id<BUNativeAdDelegate> delegate; |
| | | |
| | | /** |
| | | required. |
| | | Root view controller for handling ad actions. |
| | | Action method includes is 'presentViewController'. |
| | | */ |
| | | @property (nonatomic, weak, readwrite) UIViewController *rootViewController; |
| | | |
| | | /** |
| | | Initializes native ad with ad slot. |
| | | @param slot : ad slot description. |
| | | including slotID,adType,adPosition,etc. |
| | | @return BUNativeAd |
| | | */ |
| | | - (instancetype)initWithSlot:(BUAdSlot *)slot; |
| | | |
| | | /** |
| | | Register clickable views in native ads view. |
| | | Interaction types can be configured on TikTok Audience Network. |
| | | Interaction types include view video ad details page, make a call, send email, download the app, open the webpage using a browser,open the webpage within the app, etc. |
| | | @param containerView : required. |
| | | container view of the native ad. |
| | | @param clickableViews : optional. |
| | | Array of views that are clickable. |
| | | */ |
| | | - (void)registerContainer:(__kindof UIView *)containerView |
| | | withClickableViews:(NSArray<__kindof UIView *> *_Nullable)clickableViews; |
| | | |
| | | /** |
| | | Unregister ad view from the native ad. |
| | | */ |
| | | - (void)unregisterView; |
| | | |
| | | /** |
| | | Actively request nativeAd datas. |
| | | */ |
| | | - (void)loadAdData; |
| | | |
| | | @end |
| | | |
| | | |
| | | @protocol BUNativeAdDelegate <NSObject> |
| | | |
| | | @optional |
| | | |
| | | /** |
| | | This method is called when native ad material loaded successfully. |
| | | */ |
| | | - (void)nativeAdDidLoad:(BUNativeAd *)nativeAd; |
| | | |
| | | /** |
| | | This method is called when native ad materia failed to load. |
| | | @param error : the reason of error |
| | | */ |
| | | - (void)nativeAd:(BUNativeAd *)nativeAd didFailWithError:(NSError *_Nullable)error; |
| | | |
| | | /** |
| | | This method is called when native ad slot has been shown. |
| | | */ |
| | | - (void)nativeAdDidBecomeVisible:(BUNativeAd *)nativeAd; |
| | | |
| | | /** |
| | | This method is called when another controller has been closed. |
| | | @param interactionType : open appstore in app or open the webpage or view video ad details page. |
| | | */ |
| | | - (void)nativeAdDidCloseOtherController:(BUNativeAd *)nativeAd interactionType:(BUInteractionType)interactionType; |
| | | |
| | | /** |
| | | This method is called when native ad is clicked. |
| | | */ |
| | | - (void)nativeAdDidClick:(BUNativeAd *)nativeAd withView:(UIView *_Nullable)view; |
| | | |
| | | /** |
| | | This method is called when the user clicked dislike reasons. |
| | | Only used for dislikeButton in BUNativeAdRelatedView.h |
| | | @param filterWords : reasons for dislike |
| | | */ |
| | | - (void)nativeAd:(BUNativeAd *_Nullable)nativeAd dislikeWithReason:(NSArray<BUDislikeWords *> *_Nullable)filterWords; |
| | | @end |
| | | |
| | | NS_ASSUME_NONNULL_END |
New file |
| | |
| | | // |
| | | // BUNativeAdRelatedView.h |
| | | // BUAdSDK |
| | | // |
| | | // Copyright © 2018年 bytedance. All rights reserved. |
| | | // |
| | | |
| | | #import <UIKit/UIKit.h> |
| | | #import "BUVideoAdView.h" |
| | | #import "BUNativeAd.h" |
| | | |
| | | NS_ASSUME_NONNULL_BEGIN |
| | | |
| | | @interface BUNativeAdRelatedView : NSObject |
| | | |
| | | /** |
| | | Need to actively add to the view in order to deal with the feedback and improve the accuracy of ad. |
| | | */ |
| | | @property (nonatomic, strong, readonly, nullable) UIButton *dislikeButton; |
| | | |
| | | /** |
| | | Promotion label.Need to actively add to the view. |
| | | */ |
| | | @property (nonatomic, strong, readonly, nullable) UILabel *adLabel; |
| | | |
| | | /** |
| | | Ad logo.Need to actively add to the view. |
| | | */ |
| | | @property (nonatomic, strong, readonly, nullable) UIImageView *logoImageView; |
| | | /** |
| | | Ad logo + Promotion label.Need to actively add to the view. |
| | | */ |
| | | @property (nonatomic, strong, readonly, nullable) UIImageView *logoADImageView; |
| | | |
| | | /** |
| | | Video ad view. Need to actively add to the view. |
| | | */ |
| | | @property (nonatomic, strong, readonly, nullable) BUVideoAdView *videoAdView; |
| | | |
| | | /** |
| | | Refresh the data every time you get new datas in order to show ad perfectly. |
| | | */ |
| | | - (void)refreshData:(BUNativeAd *)nativeAd; |
| | | |
| | | @end |
| | | |
| | | NS_ASSUME_NONNULL_END |
New file |
| | |
| | | // |
| | | // BUNativeAdsManager.h |
| | | // BUAdSDK |
| | | // |
| | | // Copyright © 2017 bytedance. All rights reserved. |
| | | // |
| | | |
| | | /** |
| | | BUNativeAdsManager : for multiple requests at the same time. |
| | | */ |
| | | |
| | | #import <Foundation/Foundation.h> |
| | | #import <UIKit/UIKit.h> |
| | | #import "BUAdSlot.h" |
| | | #import "BUMaterialMeta.h" |
| | | #import "BUNativeAd.h" |
| | | |
| | | @protocol BUNativeAdsManagerDelegate; |
| | | |
| | | NS_ASSUME_NONNULL_BEGIN |
| | | /// Bunativeadsmanager class can request multiple ad data per time. |
| | | @interface BUNativeAdsManager : NSObject <BUMopubAdMarkUpDelegate> |
| | | |
| | | @property (nonatomic, strong, nullable) BUAdSlot *adslot; |
| | | @property (nonatomic, strong, nullable) NSArray<BUNativeAd *> *data; |
| | | /// The delegate for receiving state change messages such as requests succeeding/failing. |
| | | /// The delegate can be set to any object which conforming to <BUNativeAdsManagerDelegate>. |
| | | @property (nonatomic, weak, nullable) id<BUNativeAdsManagerDelegate> delegate; |
| | | |
| | | - (instancetype)initWithSlot:(BUAdSlot * _Nullable) slot; |
| | | |
| | | /** |
| | | It is recommended to request no more than 3 ads. |
| | | The maximum is 10. |
| | | */ |
| | | - (void)loadAdDataWithCount:(NSInteger)count; |
| | | |
| | | @end |
| | | |
| | | @protocol BUNativeAdsManagerDelegate <NSObject> |
| | | |
| | | @optional |
| | | |
| | | - (void)nativeAdsManagerSuccessToLoad:(BUNativeAdsManager *)adsManager nativeAds:(NSArray<BUNativeAd *> *_Nullable)nativeAdDataArray; |
| | | |
| | | - (void)nativeAdsManager:(BUNativeAdsManager *)adsManager didFailWithError:(NSError *_Nullable)error; |
| | | |
| | | @end |
| | | |
| | | NS_ASSUME_NONNULL_END |
New file |
| | |
| | | // |
| | | // BUNativeExpressAdManager.h |
| | | // BUAdSDK |
| | | // |
| | | // Created by bytedance on 2019/1/20. |
| | | // Copyright © 2019年 bytedance. All rights reserved. |
| | | // |
| | | |
| | | #import <Foundation/Foundation.h> |
| | | #import <UIKit/UIKit.h> |
| | | #import "BUAdSlot.h" |
| | | #import "BUMaterialMeta.h" |
| | | #import "BUNativeExpressAdView.h" |
| | | #import "BUDislikeWords.h" |
| | | #import "BUPlayerPublicDefine.h" |
| | | #import "BUMopubAdMarkUpDelegate.h" |
| | | |
| | | NS_ASSUME_NONNULL_BEGIN |
| | | |
| | | @class BUNativeExpressAdManager; |
| | | |
| | | @protocol BUNativeExpressAdViewDelegate <NSObject> |
| | | |
| | | @optional |
| | | /** |
| | | * Sent when views successfully load ad |
| | | */ |
| | | - (void)nativeExpressAdSuccessToLoad:(BUNativeExpressAdManager *)nativeExpressAd views:(NSArray<__kindof BUNativeExpressAdView *> *)views; |
| | | |
| | | /** |
| | | * Sent when views fail to load ad |
| | | */ |
| | | - (void)nativeExpressAdFailToLoad:(BUNativeExpressAdManager *)nativeExpressAd error:(NSError *_Nullable)error; |
| | | |
| | | /** |
| | | * This method is called when rendering a nativeExpressAdView successed, and nativeExpressAdView.size.height has been updated |
| | | */ |
| | | - (void)nativeExpressAdViewRenderSuccess:(BUNativeExpressAdView *)nativeExpressAdView; |
| | | |
| | | /** |
| | | * This method is called when a nativeExpressAdView failed to render |
| | | */ |
| | | - (void)nativeExpressAdViewRenderFail:(BUNativeExpressAdView *)nativeExpressAdView error:(NSError *_Nullable)error; |
| | | |
| | | /** |
| | | * Sent when an ad view is about to present modal content |
| | | */ |
| | | - (void)nativeExpressAdViewWillShow:(BUNativeExpressAdView *)nativeExpressAdView; |
| | | |
| | | /** |
| | | * Sent when an ad view is clicked |
| | | */ |
| | | - (void)nativeExpressAdViewDidClick:(BUNativeExpressAdView *)nativeExpressAdView; |
| | | |
| | | /** |
| | | Sent when a playerw playback status changed. |
| | | @param playerState : player state after changed |
| | | */ |
| | | - (void)nativeExpressAdView:(BUNativeExpressAdView *)nativeExpressAdView stateDidChanged:(BUPlayerPlayState)playerState; |
| | | |
| | | /** |
| | | * Sent when a player finished |
| | | * @param error : error of player |
| | | */ |
| | | - (void)nativeExpressAdViewPlayerDidPlayFinish:(BUNativeExpressAdView *)nativeExpressAdView error:(NSError *)error; |
| | | |
| | | /** |
| | | * Sent when a user clicked dislike reasons. |
| | | * @param filterWords : the array of reasons why the user dislikes the ad |
| | | */ |
| | | - (void)nativeExpressAdView:(BUNativeExpressAdView *)nativeExpressAdView dislikeWithReason:(NSArray<BUDislikeWords *> *)filterWords; |
| | | |
| | | /** |
| | | * Sent after an ad view is clicked, a ad landscape view will present modal content |
| | | */ |
| | | - (void)nativeExpressAdViewWillPresentScreen:(BUNativeExpressAdView *)nativeExpressAdView; |
| | | |
| | | /** |
| | | This method is called when another controller has been closed. |
| | | @param interactionType : open appstore in app or open the webpage or view video ad details page. |
| | | */ |
| | | - (void)nativeExpressAdViewDidCloseOtherController:(BUNativeExpressAdView *)nativeExpressAdView interactionType:(BUInteractionType)interactionType; |
| | | |
| | | @end |
| | | |
| | | |
| | | @interface BUNativeExpressAdManager : NSObject <BUMopubAdMarkUpDelegate> |
| | | |
| | | @property (nonatomic, strong, nullable) BUAdSlot *adslot; |
| | | |
| | | @property (nonatomic, assign, readwrite) CGSize adSize; |
| | | |
| | | /** |
| | | The delegate for receiving state change messages from a BUNativeExpressAdManager |
| | | */ |
| | | @property (nonatomic, weak, nullable) id<BUNativeExpressAdViewDelegate> delegate; |
| | | |
| | | |
| | | /** |
| | | @param size expected ad view size,when size.height is zero, acture height will match size.width |
| | | */ |
| | | - (instancetype)initWithSlot:(BUAdSlot * _Nullable)slot adSize:(CGSize)size; |
| | | |
| | | /** |
| | | The number of ads requested,The maximum is 3 |
| | | */ |
| | | - (void)loadAd:(NSInteger)count; |
| | | @end |
| | | |
| | | NS_ASSUME_NONNULL_END |
New file |
| | |
| | | // |
| | | // BUNativeExpressAdView.h |
| | | // BUAdSDK |
| | | // |
| | | // Created by bytedance on 2019/1/20. |
| | | // Copyright © 2019年 bytedance. All rights reserved. |
| | | // |
| | | |
| | | #import <UIKit/UIKit.h> |
| | | |
| | | NS_ASSUME_NONNULL_BEGIN |
| | | |
| | | @interface BUNativeExpressAdView : UIView |
| | | /** |
| | | * Whether render is ready |
| | | */ |
| | | @property (nonatomic, assign, readonly) BOOL isReady; |
| | | |
| | | /// media configuration parameters. |
| | | @property (nonatomic, copy, readonly) NSDictionary *mediaExt; |
| | | |
| | | /// video duration. |
| | | @property (nonatomic,assign, readonly) NSInteger videoDuration; |
| | | |
| | | /// Get the already played time. |
| | | @property (nonatomic,assign, readonly) CGFloat currentPlayedTime; |
| | | |
| | | /* |
| | | required. |
| | | Root view controller for handling ad actions. |
| | | */ |
| | | @property (nonatomic, weak) UIViewController *rootViewController; |
| | | |
| | | /** |
| | | required |
| | | */ |
| | | - (void)render; |
| | | |
| | | @end |
| | | |
| | | NS_ASSUME_NONNULL_END |
New file |
| | |
| | | // |
| | | // BUNativeExpressBannerView.h |
| | | // BUAdSDK |
| | | // |
| | | // Created by xxx on 2019/5/17. |
| | | // Copyright © 2019 bytedance. All rights reserved. |
| | | // |
| | | |
| | | #import <UIKit/UIKit.h> |
| | | #import "BUMaterialMeta.h" |
| | | #import "BUMopubAdMarkUpDelegate.h" |
| | | |
| | | NS_ASSUME_NONNULL_BEGIN |
| | | |
| | | @class BUNativeExpressBannerView; |
| | | @class BUDislikeWords; |
| | | @class BUSize; |
| | | |
| | | @protocol BUNativeExpressBannerViewDelegate <NSObject> |
| | | |
| | | @optional |
| | | /** |
| | | This method is called when bannerAdView ad slot loaded successfully. |
| | | @param bannerAdView : view for bannerAdView |
| | | */ |
| | | - (void)nativeExpressBannerAdViewDidLoad:(BUNativeExpressBannerView *)bannerAdView; |
| | | |
| | | /** |
| | | This method is called when bannerAdView ad slot failed to load. |
| | | @param error : the reason of error |
| | | */ |
| | | - (void)nativeExpressBannerAdView:(BUNativeExpressBannerView *)bannerAdView didLoadFailWithError:(NSError *_Nullable)error; |
| | | |
| | | /** |
| | | This method is called when rendering a nativeExpressAdView successed. |
| | | */ |
| | | - (void)nativeExpressBannerAdViewRenderSuccess:(BUNativeExpressBannerView *)bannerAdView; |
| | | |
| | | /** |
| | | This method is called when a nativeExpressAdView failed to render. |
| | | @param error : the reason of error |
| | | */ |
| | | - (void)nativeExpressBannerAdViewRenderFail:(BUNativeExpressBannerView *)bannerAdView error:(NSError * __nullable)error; |
| | | |
| | | /** |
| | | This method is called when bannerAdView ad slot showed new ad. |
| | | */ |
| | | - (void)nativeExpressBannerAdViewWillBecomVisible:(BUNativeExpressBannerView *)bannerAdView; |
| | | |
| | | /** |
| | | This method is called when bannerAdView is clicked. |
| | | */ |
| | | - (void)nativeExpressBannerAdViewDidClick:(BUNativeExpressBannerView *)bannerAdView; |
| | | |
| | | /** |
| | | This method is called when the user clicked dislike button and chose dislike reasons. |
| | | @param filterwords : the array of reasons for dislike. |
| | | */ |
| | | - (void)nativeExpressBannerAdView:(BUNativeExpressBannerView *)bannerAdView dislikeWithReason:(NSArray<BUDislikeWords *> *_Nullable)filterwords; |
| | | |
| | | /** |
| | | This method is called when another controller has been closed. |
| | | @param interactionType : open appstore in app or open the webpage or view video ad details page. |
| | | */ |
| | | - (void)nativeExpressBannerAdViewDidCloseOtherController:(BUNativeExpressBannerView *)bannerAdView interactionType:(BUInteractionType)interactionType; |
| | | |
| | | @end |
| | | |
| | | @interface BUNativeExpressBannerView : UIView <BUMopubAdMarkUpDelegate> |
| | | |
| | | @property (nonatomic, weak, nullable) id<BUNativeExpressBannerViewDelegate> delegate; |
| | | |
| | | /** |
| | | The carousel interval, in seconds, is set in the range of 30~120s, and is passed during initialization. If it does not meet the requirements, it will not be in carousel ad. |
| | | */ |
| | | @property (nonatomic, assign, readonly) NSInteger interval; |
| | | |
| | | /// media configuration parameters. |
| | | @property (nonatomic, copy, readonly) NSDictionary *mediaExt; |
| | | |
| | | - (instancetype)initWithSlotID:(NSString *)slotID |
| | | rootViewController:(UIViewController *)rootViewController |
| | | adSize:(CGSize)adsize |
| | | IsSupportDeepLink:(BOOL)isSupportDeepLink; |
| | | |
| | | - (instancetype)initWithSlotID:(NSString *)slotID |
| | | rootViewController:(UIViewController *)rootViewController |
| | | adSize:(CGSize)adsize |
| | | IsSupportDeepLink:(BOOL)isSupportDeepLink |
| | | interval:(NSInteger)interval; |
| | | |
| | | /** |
| | | adload_seq:(针对聚合广告位)传递本次请求是为“自然日内某设备某广告位置第N次展示机会”发出的广告请求,同物理位置在自然日从1开始计数,不同物理位置独立计数;example:某原生广告位置,当天第5次产生展示机会,这次展示机向穿山甲发送了4次广告请求,则这4次广告请求的"adload_seq"的值应为5。第二天重新开始计数。 |
| | | |
| | | prime_rit:(针对聚合广告位)广告物理位置对应的固定穿山甲广告位id,可以使用第一层的广告位id也可以为某一层的广告位id,但要求同一物理位置在该字段固定上报同一广告位id,不频繁更换;example:某原生广告位,当天共发出了1000个请求,这1000个请求中使用了5个不同target的穿山甲rit,用某X rit来作为该位置的标记rit,则这1000次请求的prime_rit都需要上报X rit的rit id。 |
| | | */ |
| | | |
| | | - (instancetype)initWithSlotID:(NSString *)slotID |
| | | adloadSeq:(NSInteger)adloadSeq |
| | | primeRit:(NSString *)primeRit |
| | | rootViewController:(UIViewController *)rootViewController |
| | | adSize:(CGSize)adsize |
| | | IsSupportDeepLink:(BOOL)isSupportDeepLink; |
| | | |
| | | |
| | | - (instancetype)initWithSlotID:(NSString *)slotID |
| | | adloadSeq:(NSInteger)adloadSeq |
| | | primeRit:(NSString *)primeRit |
| | | rootViewController:(UIViewController *)rootViewController |
| | | adSize:(CGSize)adsize |
| | | IsSupportDeepLink:(BOOL)isSupportDeepLink |
| | | interval:(NSInteger)interval; |
| | | |
| | | - (void)loadAdData; |
| | | |
| | | @end |
| | | |
| | | NS_ASSUME_NONNULL_END |
New file |
| | |
| | | // |
| | | // BUNativeExpressFullscreenVideoAd.h |
| | | // BUAdSDK |
| | | // |
| | | // Copyright © 2019 bytedance. All rights reserved. |
| | | // |
| | | |
| | | #import <UIKit/UIKit.h> |
| | | #import "BUMaterialMeta.h" |
| | | |
| | | @class BUNativeExpressFullscreenVideoAd; |
| | | |
| | | //define the type of native express video ad |
| | | typedef NS_ENUM(NSUInteger, BUNativeExpressFullScreenAdType) { |
| | | BUNativeExpressFullScreenAdTypeEndcard = 0, // video + endcard |
| | | BUNativeExpressFullScreenAdTypeVideoPlayable = 1, // video + playable |
| | | BUNativeExpressFullScreenAdTypePurePlayable = 2 // pure playable |
| | | }; |
| | | |
| | | NS_ASSUME_NONNULL_BEGIN |
| | | @protocol BUNativeExpressFullscreenVideoAdDelegate <NSObject> |
| | | |
| | | @optional |
| | | /** |
| | | This method is called when video ad material loaded successfully. |
| | | And you can call [BUNativeExpressFullscreenVideoAd showAdFromRootViewController:]. |
| | | */ |
| | | - (void)nativeExpressFullscreenVideoAdDidLoad:(BUNativeExpressFullscreenVideoAd *)fullscreenVideoAd; |
| | | |
| | | /** |
| | | This method is called when video ad materia failed to load. |
| | | @param error : the reason of error |
| | | */ |
| | | - (void)nativeExpressFullscreenVideoAd:(BUNativeExpressFullscreenVideoAd *)fullscreenVideoAd didFailWithError:(NSError *_Nullable)error; |
| | | |
| | | /** |
| | | This method is called when rendering a nativeExpressAdView successed. |
| | | It will happen when ad is show. |
| | | */ |
| | | - (void)nativeExpressFullscreenVideoAdViewRenderSuccess:(BUNativeExpressFullscreenVideoAd *)rewardedVideoAd; |
| | | |
| | | /** |
| | | This method is called when a nativeExpressAdView failed to render. |
| | | @param error : the reason of error |
| | | */ |
| | | - (void)nativeExpressFullscreenVideoAdViewRenderFail:(BUNativeExpressFullscreenVideoAd *)rewardedVideoAd error:(NSError *_Nullable)error; |
| | | |
| | | /** |
| | | This method is called when video cached successfully. |
| | | For a better user experience, it is recommended to display video ads at this time. |
| | | */ |
| | | - (void)nativeExpressFullscreenVideoAdDidDownLoadVideo:(BUNativeExpressFullscreenVideoAd *)fullscreenVideoAd; |
| | | |
| | | /** |
| | | This method is called when video ad slot will be showing. |
| | | */ |
| | | - (void)nativeExpressFullscreenVideoAdWillVisible:(BUNativeExpressFullscreenVideoAd *)fullscreenVideoAd; |
| | | |
| | | /** |
| | | This method is called when video ad slot has been shown. |
| | | */ |
| | | - (void)nativeExpressFullscreenVideoAdDidVisible:(BUNativeExpressFullscreenVideoAd *)fullscreenVideoAd; |
| | | |
| | | /** |
| | | This method is called when video ad is clicked. |
| | | */ |
| | | - (void)nativeExpressFullscreenVideoAdDidClick:(BUNativeExpressFullscreenVideoAd *)fullscreenVideoAd; |
| | | |
| | | /** |
| | | This method is called when the user clicked skip button. |
| | | */ |
| | | - (void)nativeExpressFullscreenVideoAdDidClickSkip:(BUNativeExpressFullscreenVideoAd *)fullscreenVideoAd; |
| | | |
| | | /** |
| | | This method is called when video ad is about to close. |
| | | */ |
| | | - (void)nativeExpressFullscreenVideoAdWillClose:(BUNativeExpressFullscreenVideoAd *)fullscreenVideoAd; |
| | | |
| | | /** |
| | | This method is called when video ad is closed. |
| | | */ |
| | | - (void)nativeExpressFullscreenVideoAdDidClose:(BUNativeExpressFullscreenVideoAd *)fullscreenVideoAd; |
| | | |
| | | /** |
| | | This method is called when video ad play completed or an error occurred. |
| | | @param error : the reason of error |
| | | */ |
| | | - (void)nativeExpressFullscreenVideoAdDidPlayFinish:(BUNativeExpressFullscreenVideoAd *)fullscreenVideoAd didFailWithError:(NSError *_Nullable)error; |
| | | |
| | | /** |
| | | This method is used to get the type of nativeExpressFullScreenVideo ad |
| | | */ |
| | | - (void)nativeExpressFullscreenVideoAdCallback:(BUNativeExpressFullscreenVideoAd *)fullscreenVideoAd withType:(BUNativeExpressFullScreenAdType) nativeExpressVideoAdType; |
| | | |
| | | /** |
| | | This method is called when another controller has been closed. |
| | | @param interactionType : open appstore in app or open the webpage or view video ad details page. |
| | | */ |
| | | - (void)nativeExpressFullscreenVideoAdDidCloseOtherController:(BUNativeExpressFullscreenVideoAd *)fullscreenVideoAd interactionType:(BUInteractionType)interactionType; |
| | | |
| | | @end |
| | | |
| | | |
| | | @interface BUNativeExpressFullscreenVideoAd : NSObject |
| | | |
| | | @property (nonatomic, weak, nullable) id<BUNativeExpressFullscreenVideoAdDelegate> delegate; |
| | | @property (nonatomic, getter=isAdValid, readonly) BOOL adValid; |
| | | |
| | | /// media configuration parameters. |
| | | @property (nonatomic, copy, readonly) NSDictionary *mediaExt; |
| | | |
| | | /** |
| | | Initializes video ad with slot id. |
| | | @param slotID : the unique identifier of video ad. |
| | | @return BUFullscreenVideoAd |
| | | */ |
| | | - (instancetype)initWithSlotID:(NSString *)slotID; |
| | | |
| | | /** |
| | | adload_seq:(针对聚合广告位)传递本次请求是为“自然日内某设备某广告位置第N次展示机会”发出的广告请求,同物理位置在自然日从1开始计数,不同物理位置独立计数;example:某原生广告位置,当天第5次产生展示机会,这次展示机向穿山甲发送了4次广告请求,则这4次广告请求的"adload_seq"的值应为5。第二天重新开始计数。 |
| | | |
| | | prime_rit:(针对聚合广告位)广告物理位置对应的固定穿山甲广告位id,可以使用第一层的广告位id也可以为某一层的广告位id,但要求同一物理位置在该字段固定上报同一广告位id,不频繁更换;example:某原生广告位,当天共发出了1000个请求,这1000个请求中使用了5个不同target的穿山甲rit,用某X rit来作为该位置的标记rit,则这1000次请求的prime_rit都需要上报X rit的rit id。 |
| | | */ |
| | | |
| | | - (instancetype)initWithSlotID:(NSString *)slotID adloadSeq:(NSInteger)adloadSeq primeRit:(NSString * __nullable)primeRit; |
| | | |
| | | /** |
| | | Load video ad datas. |
| | | */ |
| | | - (void)loadAdData; |
| | | |
| | | /** |
| | | Display video ad. |
| | | @param rootViewController : root view controller for displaying ad. |
| | | @return : whether it is successfully displayed. |
| | | */ |
| | | - (BOOL)showAdFromRootViewController:(UIViewController *)rootViewController; |
| | | |
| | | /** |
| | | Display video ad. |
| | | @param rootViewController : root view controller for displaying ad. |
| | | @param sceneDescirbe : optional. Identifies a custom description of the presentation scenario. |
| | | @return : whether it is successfully displayed. |
| | | */ |
| | | - (BOOL)showAdFromRootViewController:(UIViewController *)rootViewController ritSceneDescribe:(NSString *_Nullable)sceneDescirbe; |
| | | |
| | | @end |
| | | |
| | | NS_ASSUME_NONNULL_END |
New file |
| | |
| | | // |
| | | // BUNativeExpressInterstitialAd.h |
| | | // BUAdSDK |
| | | // |
| | | // Created by xxx on 2019/5/16. |
| | | // Copyright © 2019 bytedance. All rights reserved. |
| | | // |
| | | |
| | | #import <UIKit/UIKit.h> |
| | | #import "BUMaterialMeta.h" |
| | | #import "BUMopubAdMarkUpDelegate.h" |
| | | NS_ASSUME_NONNULL_BEGIN |
| | | |
| | | @class BUSize; |
| | | @class BUNativeExpressInterstitialAd; |
| | | |
| | | @protocol BUNativeExpresInterstitialAdDelegate <NSObject> |
| | | |
| | | @optional |
| | | /** |
| | | This method is called when interstitial ad material loaded successfully. |
| | | */ |
| | | - (void)nativeExpresInterstitialAdDidLoad:(BUNativeExpressInterstitialAd *)interstitialAd; |
| | | |
| | | /** |
| | | This method is called when interstitial ad material failed to load. |
| | | @param error : the reason of error |
| | | */ |
| | | - (void)nativeExpresInterstitialAd:(BUNativeExpressInterstitialAd *)interstitialAd didFailWithError:(NSError * __nullable)error; |
| | | |
| | | /** |
| | | This method is called when rendering a nativeExpressAdView successed. |
| | | */ |
| | | - (void)nativeExpresInterstitialAdRenderSuccess:(BUNativeExpressInterstitialAd *)interstitialAd; |
| | | |
| | | /** |
| | | This method is called when a nativeExpressAdView failed to render. |
| | | @param error : the reason of error |
| | | */ |
| | | - (void)nativeExpresInterstitialAdRenderFail:(BUNativeExpressInterstitialAd *)interstitialAd error:(NSError * __nullable)error; |
| | | |
| | | /** |
| | | This method is called when interstitial ad slot will be showing. |
| | | */ |
| | | - (void)nativeExpresInterstitialAdWillVisible:(BUNativeExpressInterstitialAd *)interstitialAd; |
| | | |
| | | /** |
| | | This method is called when interstitial ad is clicked. |
| | | */ |
| | | - (void)nativeExpresInterstitialAdDidClick:(BUNativeExpressInterstitialAd *)interstitialAd; |
| | | |
| | | /** |
| | | This method is called when interstitial ad is about to close. |
| | | */ |
| | | - (void)nativeExpresInterstitialAdWillClose:(BUNativeExpressInterstitialAd *)interstitialAd; |
| | | |
| | | /** |
| | | This method is called when interstitial ad is closed. |
| | | */ |
| | | - (void)nativeExpresInterstitialAdDidClose:(BUNativeExpressInterstitialAd *)interstitialAd; |
| | | |
| | | /** |
| | | This method is called when another controller has been closed. |
| | | @param interactionType : open appstore in app or open the webpage or view video ad details page. |
| | | */ |
| | | - (void)nativeExpresInterstitialAdDidCloseOtherController:(BUNativeExpressInterstitialAd *)interstitialAd interactionType:(BUInteractionType)interactionType; |
| | | |
| | | @end |
| | | |
| | | @interface BUNativeExpressInterstitialAd : NSObject <BUMopubAdMarkUpDelegate> |
| | | |
| | | @property (nonatomic, weak, nullable) id<BUNativeExpresInterstitialAdDelegate> delegate; |
| | | |
| | | @property (nonatomic, getter=isAdValid, readonly) BOOL adValid; |
| | | |
| | | /// media configuration parameters. |
| | | @property (nonatomic, copy, readonly) NSDictionary *mediaExt; |
| | | |
| | | /** |
| | | Initializes interstitial ad. |
| | | @param slotID : The unique identifier of interstitial ad. |
| | | @param adsize : custom size of ad view. |
| | | @return BUInterstitialAd |
| | | */ |
| | | - (instancetype)initWithSlotID:(NSString *)slotID adSize:(CGSize)adsize; |
| | | |
| | | /** |
| | | adload_seq:(针对聚合广告位)传递本次请求是为“自然日内某设备某广告位置第N次展示机会”发出的广告请求,同物理位置在自然日从1开始计数,不同物理位置独立计数;example:某原生广告位置,当天第5次产生展示机会,这次展示机向穿山甲发送了4次广告请求,则这4次广告请求的"adload_seq"的值应为5。第二天重新开始计数。 |
| | | |
| | | prime_rit:(针对聚合广告位)广告物理位置对应的固定穿山甲广告位id,可以使用第一层的广告位id也可以为某一层的广告位id,但要求同一物理位置在该字段固定上报同一广告位id,不频繁更换;example:某原生广告位,当天共发出了1000个请求,这1000个请求中使用了5个不同target的穿山甲rit,用某X rit来作为该位置的标记rit,则这1000次请求的prime_rit都需要上报X rit的rit id。 |
| | | */ |
| | | |
| | | - (instancetype)initWithSlotID:(NSString *)slotID adloadSeq:(NSInteger)adloadSeq primeRit:(NSString * __nullable)primeRit adSize:(CGSize)adsize; |
| | | |
| | | /** |
| | | Load interstitial ad datas. |
| | | */ |
| | | - (void)loadAdData; |
| | | |
| | | /** |
| | | Display interstitial ad. |
| | | @param rootViewController : root view controller for displaying ad. |
| | | @return : whether it is successfully displayed. |
| | | */ |
| | | - (BOOL)showAdFromRootViewController:(UIViewController *)rootViewController; |
| | | |
| | | @end |
| | | |
| | | NS_ASSUME_NONNULL_END |
New file |
| | |
| | | // |
| | | // BUNativeExpressRewardedVideoAd.h |
| | | // BUAdSDK |
| | | // |
| | | // Copyright © 2019 bytedance. All rights reserved. |
| | | // |
| | | |
| | | #import <UIKit/UIKit.h> |
| | | #import "BUAdSDKDefines.h" |
| | | #import "BUMaterialMeta.h" |
| | | |
| | | @class BUNativeExpressRewardedVideoAd; |
| | | @class BURewardedVideoModel; |
| | | |
| | | NS_ASSUME_NONNULL_BEGIN |
| | | |
| | | /// define the type of native express rewarded video Ad |
| | | typedef NS_ENUM(NSUInteger, BUNativeExpressRewardedVideoAdType) { |
| | | BUNativeExpressRewardedVideoAdTypeEndcard = 0, // video + endcard |
| | | BUNativeExpressRewardedVideoAdTypeVideoPlayable = 1, // video + playable |
| | | BUNativeExpressRewardedVideoAdTypePurePlayable = 2, // pure playable |
| | | }; |
| | | |
| | | @protocol BUNativeExpressRewardedVideoAdDelegate <NSObject> |
| | | |
| | | @optional |
| | | /** |
| | | This method is called when video ad material loaded successfully. |
| | | And you can call [BUNativeExpressRewardedVideoAd showAdFromRootViewController:]. |
| | | */ |
| | | - (void)nativeExpressRewardedVideoAdDidLoad:(BUNativeExpressRewardedVideoAd *)rewardedVideoAd; |
| | | |
| | | /** |
| | | This method is called when video ad materia failed to load. |
| | | @param error : the reason of error |
| | | */ |
| | | - (void)nativeExpressRewardedVideoAd:(BUNativeExpressRewardedVideoAd *)rewardedVideoAd didFailWithError:(NSError *_Nullable)error; |
| | | /** |
| | | this methods is to tell delegate the type of native express rewarded video Ad |
| | | */ |
| | | - (void)nativeExpressRewardedVideoAdCallback:(BUNativeExpressRewardedVideoAd *)rewardedVideoAd withType:(BUNativeExpressRewardedVideoAdType)nativeExpressVideoType; |
| | | |
| | | /** |
| | | This method is called when cached successfully. |
| | | For a better user experience, it is recommended to display video ads at this time. |
| | | */ |
| | | - (void)nativeExpressRewardedVideoAdDidDownLoadVideo:(BUNativeExpressRewardedVideoAd *)rewardedVideoAd; |
| | | |
| | | /** |
| | | This method is called when rendering a nativeExpressAdView successed. |
| | | It will happen when ad is show. |
| | | */ |
| | | - (void)nativeExpressRewardedVideoAdViewRenderSuccess:(BUNativeExpressRewardedVideoAd *)rewardedVideoAd; |
| | | |
| | | /** |
| | | This method is called when a nativeExpressAdView failed to render. |
| | | @param error : the reason of error |
| | | */ |
| | | - (void)nativeExpressRewardedVideoAdViewRenderFail:(BUNativeExpressRewardedVideoAd *)rewardedVideoAd error:(NSError *_Nullable)error; |
| | | |
| | | /** |
| | | This method is called when video ad slot will be showing. |
| | | */ |
| | | - (void)nativeExpressRewardedVideoAdWillVisible:(BUNativeExpressRewardedVideoAd *)rewardedVideoAd; |
| | | |
| | | /** |
| | | This method is called when video ad slot has been shown. |
| | | */ |
| | | - (void)nativeExpressRewardedVideoAdDidVisible:(BUNativeExpressRewardedVideoAd *)rewardedVideoAd; |
| | | |
| | | /** |
| | | This method is called when video ad is about to close. |
| | | */ |
| | | - (void)nativeExpressRewardedVideoAdWillClose:(BUNativeExpressRewardedVideoAd *)rewardedVideoAd; |
| | | |
| | | /** |
| | | This method is called when video ad is closed. |
| | | */ |
| | | - (void)nativeExpressRewardedVideoAdDidClose:(BUNativeExpressRewardedVideoAd *)rewardedVideoAd; |
| | | |
| | | /** |
| | | This method is called when video ad is clicked. |
| | | */ |
| | | - (void)nativeExpressRewardedVideoAdDidClick:(BUNativeExpressRewardedVideoAd *)rewardedVideoAd; |
| | | |
| | | /** |
| | | This method is called when the user clicked skip button. |
| | | */ |
| | | - (void)nativeExpressRewardedVideoAdDidClickSkip:(BUNativeExpressRewardedVideoAd *)rewardedVideoAd; |
| | | |
| | | /** |
| | | This method is called when video ad play completed or an error occurred. |
| | | @param error : the reason of error |
| | | */ |
| | | - (void)nativeExpressRewardedVideoAdDidPlayFinish:(BUNativeExpressRewardedVideoAd *)rewardedVideoAd didFailWithError:(NSError *_Nullable)error; |
| | | |
| | | /** |
| | | Server verification which is requested asynchronously is succeeded. now include two v erify methods: |
| | | 1. C2C need server verify 2. S2S don't need server verify |
| | | @param verify :return YES when return value is 2000. |
| | | */ |
| | | - (void)nativeExpressRewardedVideoAdServerRewardDidSucceed:(BUNativeExpressRewardedVideoAd *)rewardedVideoAd verify:(BOOL)verify; |
| | | |
| | | /** |
| | | Server verification which is requested asynchronously is failed. |
| | | Return value is not 2000. |
| | | */ |
| | | - (void)nativeExpressRewardedVideoAdServerRewardDidFail:(BUNativeExpressRewardedVideoAd *)rewardedVideoAd __attribute__((deprecated("Use nativeExpressRewardedVideoAdServerRewardDidFail: error: instead."))); |
| | | |
| | | /** |
| | | Server verification which is requested asynchronously is failed. |
| | | @param rewardedVideoAd express rewardVideo Ad |
| | | @param error request error info |
| | | */ |
| | | - (void)nativeExpressRewardedVideoAdServerRewardDidFail:(BUNativeExpressRewardedVideoAd *)rewardedVideoAd error:(NSError *_Nullable)error; |
| | | |
| | | /** |
| | | This method is called when another controller has been closed. |
| | | @param interactionType : open appstore in app or open the webpage or view video ad details page. |
| | | */ |
| | | - (void)nativeExpressRewardedVideoAdDidCloseOtherController:(BUNativeExpressRewardedVideoAd *)rewardedVideoAd interactionType:(BUInteractionType)interactionType; |
| | | |
| | | @end |
| | | |
| | | |
| | | @interface BUNativeExpressRewardedVideoAd : NSObject |
| | | @property (nonatomic, strong) BURewardedVideoModel *rewardedVideoModel; |
| | | @property (nonatomic, weak, nullable) id<BUNativeExpressRewardedVideoAdDelegate> delegate; |
| | | /// media configuration parameters. |
| | | @property (nonatomic, copy, readonly) NSDictionary *mediaExt; |
| | | |
| | | /** |
| | | Whether material is effective. |
| | | Setted to YES when data is not empty and has not been displayed. |
| | | Repeated display is not billed. |
| | | */ |
| | | @property (nonatomic, getter=isAdValid, readonly) BOOL adValid; |
| | | |
| | | - (instancetype)initWithSlotID:(NSString *)slotID rewardedVideoModel:(BURewardedVideoModel *)model; |
| | | - (void)loadAdData; |
| | | |
| | | /** |
| | | Display video ad. |
| | | @param rootViewController : root view controller for displaying ad. |
| | | @return : whether it is successfully displayed. |
| | | */ |
| | | - (BOOL)showAdFromRootViewController:(UIViewController *)rootViewController; |
| | | |
| | | /** |
| | | If ritSceneType is custom, you need to pass in the values for sceneDescirbe. |
| | | @param ritSceneType : optional. Identifies a custom description of the presentation scenario. |
| | | @param sceneDescirbe : optional. Identify the scene of presentation. |
| | | */ |
| | | - (BOOL)showAdFromRootViewController:(UIViewController *)rootViewController ritScene:(BURitSceneType)ritSceneType ritSceneDescribe:(NSString *_Nullable)sceneDescirbe; |
| | | |
| | | @end |
| | | |
| | | NS_ASSUME_NONNULL_END |
New file |
| | |
| | | // |
| | | // BUNativeExpressSplashView.h |
| | | // BUAdSDK |
| | | // |
| | | // Copyright © 2019 bytedance. All rights reserved. |
| | | // |
| | | |
| | | #import <UIKit/UIKit.h> |
| | | #import "BUMaterialMeta.h" |
| | | |
| | | @class BUNativeExpressSplashView; |
| | | |
| | | NS_ASSUME_NONNULL_BEGIN |
| | | @protocol BUNativeExpressSplashViewDelegate <NSObject> |
| | | /** |
| | | This method is called when splash ad material loaded successfully. |
| | | */ |
| | | - (void)nativeExpressSplashViewDidLoad:(BUNativeExpressSplashView *)splashAdView; |
| | | |
| | | /** |
| | | This method is called when splash ad material failed to load. |
| | | @param error : the reason of error |
| | | */ |
| | | - (void)nativeExpressSplashView:(BUNativeExpressSplashView *)splashAdView didFailWithError:(NSError * _Nullable)error; |
| | | |
| | | /** |
| | | This method is called when rendering a nativeExpressAdView successed. |
| | | */ |
| | | - (void)nativeExpressSplashViewRenderSuccess:(BUNativeExpressSplashView *)splashAdView; |
| | | |
| | | /** |
| | | This method is called when a nativeExpressAdView failed to render. |
| | | @param error : the reason of error |
| | | */ |
| | | - (void)nativeExpressSplashViewRenderFail:(BUNativeExpressSplashView *)splashAdView error:(NSError * __nullable)error; |
| | | |
| | | /** |
| | | This method is called when nativeExpressSplashAdView will be showing. |
| | | */ |
| | | - (void)nativeExpressSplashViewWillVisible:(BUNativeExpressSplashView *)splashAdView; |
| | | |
| | | /** |
| | | This method is called when nativeExpressSplashAdView is clicked. |
| | | */ |
| | | - (void)nativeExpressSplashViewDidClick:(BUNativeExpressSplashView *)splashAdView; |
| | | |
| | | /** |
| | | This method is called when nativeExpressSplashAdView's skip button is clicked. |
| | | */ |
| | | - (void)nativeExpressSplashViewDidClickSkip:(BUNativeExpressSplashView *)splashAdView; |
| | | /** |
| | | This method is called when nativeExpressSplashAdView countdown equals to zero |
| | | */ |
| | | - (void)nativeExpressSplashViewCountdownToZero:(BUNativeExpressSplashView *)splashAdView; |
| | | |
| | | /** |
| | | This method is called when nativeExpressSplashAdView closed. |
| | | */ |
| | | - (void)nativeExpressSplashViewDidClose:(BUNativeExpressSplashView *)splashAdView; |
| | | |
| | | /** |
| | | This method is called when when video ad play completed or an error occurred. |
| | | */ |
| | | - (void)nativeExpressSplashViewFinishPlayDidPlayFinish:(BUNativeExpressSplashView *)splashView didFailWithError:(NSError *)error; |
| | | |
| | | /** |
| | | This method is called when another controller has been closed. |
| | | @param interactionType : open appstore in app or open the webpage or view video ad details page. |
| | | */ |
| | | - (void)nativeExpressSplashViewDidCloseOtherController:(BUNativeExpressSplashView *)splashView interactionType:(BUInteractionType)interactionType; |
| | | |
| | | @end |
| | | |
| | | |
| | | |
| | | @interface BUNativeExpressSplashView : UIView |
| | | /** |
| | | The delegate for receiving state change messages. |
| | | */ |
| | | @property (nonatomic, weak, nullable) id<BUNativeExpressSplashViewDelegate> delegate; |
| | | |
| | | /** |
| | | Maximum allowable load timeout, default 3s, unit s. |
| | | */ |
| | | @property (nonatomic, assign) NSTimeInterval tolerateTimeout; |
| | | |
| | | /** |
| | | Whether hide skip button, default NO. |
| | | If you hide the skip button, you need to customize the countdown. |
| | | */ |
| | | @property (nonatomic, assign) BOOL hideSkipButton; |
| | | |
| | | /** |
| | | Whether the splash ad data has been loaded. |
| | | */ |
| | | @property (nonatomic, getter=isAdValid, readonly) BOOL adValid; |
| | | |
| | | /// media configuration parameters. |
| | | @property (nonatomic, copy, readonly) NSDictionary *mediaExt; |
| | | |
| | | /** |
| | | Initializes native express splash ad with slot id and frame. |
| | | @param slotID : the unique identifier of splash ad |
| | | @param adSize : the adSize of native express splashAd view. It is recommended for the mobile phone screen. |
| | | @return BUNativeExpressSplashView |
| | | */ |
| | | - (instancetype)initWithSlotID:(NSString *)slotID adSize:(CGSize)adSize rootViewController:(UIViewController *)rootViewController; |
| | | |
| | | /** |
| | | adload_seq:(针对聚合广告位)传递本次请求是为“自然日内某设备某广告位置第N次展示机会”发出的广告请求,同物理位置在自然日从1开始计数,不同物理位置独立计数;example:某原生广告位置,当天第5次产生展示机会,这次展示机向穿山甲发送了4次广告请求,则这4次广告请求的"adload_seq"的值应为5。第二天重新开始计数。 |
| | | |
| | | prime_rit:(针对聚合广告位)广告物理位置对应的固定穿山甲广告位id,可以使用第一层的广告位id也可以为某一层的广告位id,但要求同一物理位置在该字段固定上报同一广告位id,不频繁更换;example:某原生广告位,当天共发出了1000个请求,这1000个请求中使用了5个不同target的穿山甲rit,用某X rit来作为该位置的标记rit,则这1000次请求的prime_rit都需要上报X rit的rit id。 |
| | | */ |
| | | - (instancetype)initWithSlotID:(NSString *)slotID adloadSeq:(NSInteger)adloadSeq primeRit:(NSString * __nullable)primeRit adSize:(CGSize)adSize rootViewController:(UIViewController *)rootViewController; |
| | | |
| | | /** |
| | | Load splash ad datas. |
| | | Start the countdown(@tolerateTimeout) as soon as you request datas. |
| | | */ |
| | | - (void)loadAdData; |
| | | |
| | | /** |
| | | Remove splash view. |
| | | Stop the countdown as soon as you call this method. |
| | | 移除开屏视图 |
| | | 一旦调用这个方法,倒计时将自动停止 |
| | | */ |
| | | - (void)removeSplashView; |
| | | |
| | | @end |
| | | |
| | | NS_ASSUME_NONNULL_END |
New file |
| | |
| | | // |
| | | // BUPlayerPublicDefine.h |
| | | // BUAdSDK |
| | | // |
| | | // Copyright © 2018年 bytedance. All rights reserved. |
| | | // |
| | | |
| | | #ifndef BUPlayerPublicDefine_h |
| | | #define BUPlayerPublicDefine_h |
| | | |
| | | typedef NS_ENUM(NSInteger, BUPlayerPlayState) { |
| | | BUPlayerStateFailed = 0, |
| | | BUPlayerStateBuffering = 1, |
| | | BUPlayerStatePlaying = 2, |
| | | BUPlayerStateStopped = 3, |
| | | BUPlayerStatePause = 4, |
| | | BUPlayerStateDefalt = 5 |
| | | }; |
| | | |
| | | @class BUPlayer; |
| | | |
| | | @protocol BUPlayerDelegate <NSObject> |
| | | |
| | | @optional |
| | | /** |
| | | This method is called when the player status changes. |
| | | */ |
| | | - (void)player:(BUPlayer *)player stateDidChanged:(BUPlayerPlayState)playerState; |
| | | /** |
| | | This method is called when the player is ready. |
| | | */ |
| | | - (void)playerReadyToPlay:(BUPlayer *)player; |
| | | /** |
| | | This method is called when the player plays completion or occurrs error. |
| | | */ |
| | | - (void)playerDidPlayFinish:(BUPlayer *)player error:(NSError *)error; |
| | | |
| | | /** |
| | | This method is called when the player is clicked. |
| | | */ |
| | | - (void)player:(BUPlayer *)player recognizeTapGesture:(UITapGestureRecognizer *)gesture; |
| | | |
| | | |
| | | /** |
| | | This method is called when the view is clicked during ad play. |
| | | */ |
| | | - (void)playerTouchesBegan:(BUPlayer *)player; |
| | | |
| | | @end |
| | | |
| | | #endif /* BUPlayerPublicDefine_h */ |
New file |
| | |
| | | // |
| | | // BURewardedVideoAd.h |
| | | // BUAdSDK |
| | | // |
| | | // Copyright © 2018年 bytedance. All rights reserved. |
| | | // |
| | | |
| | | #import <UIKit/UIKit.h> |
| | | #import "BUAdSDKDefines.h" |
| | | #import "BUMopubAdMarkUpDelegate.h" |
| | | |
| | | NS_ASSUME_NONNULL_BEGIN |
| | | |
| | | /// define the type of rewarded video ad |
| | | typedef NS_ENUM(NSUInteger, BURewardedVideoAdType) { |
| | | BURewardedVideoAdTypeEndcard = 0, // video + endcard |
| | | BURewardedVideoAdTypeVideoPlayable = 1, // video + playable |
| | | BURewardedVideoAdTypePurePlayable = 2 // pure playable |
| | | }; |
| | | |
| | | @protocol BURewardedVideoAdDelegate; |
| | | @class BURewardedVideoModel; |
| | | |
| | | @interface BURewardedVideoAd : NSObject <BUMopubAdMarkUpDelegate> |
| | | @property (nonatomic, strong) BURewardedVideoModel *rewardedVideoModel; |
| | | @property (nonatomic, weak, nullable) id<BURewardedVideoAdDelegate> delegate; |
| | | |
| | | /** |
| | | Whether material is effective. |
| | | Setted to YES when data is not empty and has not been displayed. |
| | | Repeated display is not billed. |
| | | */ |
| | | @property (nonatomic, getter=isAdValid, readonly) BOOL adValid; |
| | | |
| | | /// media configuration parameters. |
| | | @property (nonatomic, copy, readonly) NSDictionary *mediaExt; |
| | | |
| | | - (instancetype)initWithSlotID:(NSString *)slotID rewardedVideoModel:(BURewardedVideoModel *)model; |
| | | /** |
| | | adload_seq:(针对聚合广告位)传递本次请求是为“自然日内某设备某广告位置第N次展示机会”发出的广告请求,同物理位置在自然日从1开始计数,不同物理位置独立计数;example:某原生广告位置,当天第5次产生展示机会,这次展示机向穿山甲发送了4次广告请求,则这4次广告请求的"adload_seq"的值应为5。第二天重新开始计数。 |
| | | |
| | | prime_rit:(针对聚合广告位)广告物理位置对应的固定穿山甲广告位id,可以使用第一层的广告位id也可以为某一层的广告位id,但要求同一物理位置在该字段固定上报同一广告位id,不频繁更换;example:某原生广告位,当天共发出了1000个请求,这1000个请求中使用了5个不同target的穿山甲rit,用某X rit来作为该位置的标记rit,则这1000次请求的prime_rit都需要上报X rit的rit id。 |
| | | */ |
| | | |
| | | - (instancetype)initWithSlotID:(NSString *)slotID adloadSeq:(NSInteger)adloadSeq primeRit:(NSString * __nullable)primeRit rewardedVideoModel:(nonnull BURewardedVideoModel *)model; |
| | | |
| | | - (void)loadAdData; |
| | | |
| | | /** |
| | | Display video ad. |
| | | @param rootViewController : root view controller for displaying ad. |
| | | @return : whether it is successfully displayed. |
| | | */ |
| | | - (BOOL)showAdFromRootViewController:(UIViewController *)rootViewController; |
| | | /** |
| | | If ritSceneType is custom, you need to pass in the values for sceneDescirbe. |
| | | @param ritSceneType : optional. Identifies a custom description of the presentation scenario. |
| | | @param sceneDescirbe : optional. Identify the scene of presentation. |
| | | */ |
| | | - (BOOL)showAdFromRootViewController:(UIViewController *)rootViewController ritScene:(BURitSceneType)ritSceneType ritSceneDescribe:(NSString *_Nullable)sceneDescirbe; |
| | | |
| | | @end |
| | | |
| | | @protocol BURewardedVideoAdDelegate <NSObject> |
| | | |
| | | @optional |
| | | |
| | | /** |
| | | This method is called when video ad material loaded successfully. |
| | | */ |
| | | - (void)rewardedVideoAdDidLoad:(BURewardedVideoAd *)rewardedVideoAd; |
| | | |
| | | /** |
| | | This method is called when video ad materia failed to load. |
| | | @param error : the reason of error |
| | | */ |
| | | - (void)rewardedVideoAd:(BURewardedVideoAd *)rewardedVideoAd didFailWithError:(NSError *_Nullable)error; |
| | | |
| | | /** |
| | | This method is called when cached successfully. |
| | | */ |
| | | - (void)rewardedVideoAdVideoDidLoad:(BURewardedVideoAd *)rewardedVideoAd; |
| | | |
| | | /** |
| | | This method is called when video ad slot will be showing. |
| | | */ |
| | | - (void)rewardedVideoAdWillVisible:(BURewardedVideoAd *)rewardedVideoAd; |
| | | |
| | | /** |
| | | This method is called when video ad slot has been shown. |
| | | */ |
| | | - (void)rewardedVideoAdDidVisible:(BURewardedVideoAd *)rewardedVideoAd; |
| | | |
| | | /** |
| | | This method is called when video ad is about to close. |
| | | */ |
| | | - (void)rewardedVideoAdWillClose:(BURewardedVideoAd *)rewardedVideoAd; |
| | | |
| | | /** |
| | | This method is called when video ad is closed. |
| | | */ |
| | | - (void)rewardedVideoAdDidClose:(BURewardedVideoAd *)rewardedVideoAd; |
| | | |
| | | /** |
| | | This method is called when video ad is clicked. |
| | | */ |
| | | - (void)rewardedVideoAdDidClick:(BURewardedVideoAd *)rewardedVideoAd; |
| | | |
| | | |
| | | /** |
| | | This method is called when video ad play completed or an error occurred. |
| | | @param error : the reason of error |
| | | */ |
| | | - (void)rewardedVideoAdDidPlayFinish:(BURewardedVideoAd *)rewardedVideoAd didFailWithError:(NSError *_Nullable)error; |
| | | |
| | | /** |
| | | Server verification which is requested asynchronously is succeeded. |
| | | @param verify :return YES when return value is 2000. |
| | | */ |
| | | - (void)rewardedVideoAdServerRewardDidSucceed:(BURewardedVideoAd *)rewardedVideoAd verify:(BOOL)verify; |
| | | |
| | | /** |
| | | Server verification which is requested asynchronously is failed. |
| | | Return value is not 2000. |
| | | */ |
| | | - (void)rewardedVideoAdServerRewardDidFail:(BURewardedVideoAd *)rewardedVideoAd __attribute__((deprecated("Use rewardedVideoAdServerRewardDidFail: error: instead."))); |
| | | |
| | | /** |
| | | Server verification which is requested asynchronously is failed. |
| | | @param rewardedVideoAd rewarded Video ad |
| | | @param error request error info |
| | | */ |
| | | - (void)rewardedVideoAdServerRewardDidFail:(BURewardedVideoAd *)rewardedVideoAd error:(NSError *)error; |
| | | |
| | | /** |
| | | This method is called when the user clicked skip button. |
| | | */ |
| | | - (void)rewardedVideoAdDidClickSkip:(BURewardedVideoAd *)rewardedVideoAd; |
| | | |
| | | /** |
| | | this method is used to get type of rewarded video Ad |
| | | */ |
| | | - (void)rewardedVideoAdCallback:(BURewardedVideoAd *)rewardedVideoAd withType:(BURewardedVideoAdType)rewardedVideoAdType; |
| | | |
| | | @end |
| | | |
| | | NS_ASSUME_NONNULL_END |
New file |
| | |
| | | // |
| | | // BURewardedVideoModel.h |
| | | // BUAdSDK |
| | | // |
| | | // Copyright © 2018年 bytedance. All rights reserved. |
| | | // |
| | | |
| | | #import <Foundation/Foundation.h> |
| | | |
| | | @interface BURewardedVideoModel : NSObject |
| | | |
| | | /** |
| | | required. |
| | | Third-party game user_id identity. |
| | | Mainly used in the reward issuance, it is the callback pass-through parameter from server-to-server. |
| | | It is the unique identifier of each user. |
| | | In the non-server callback mode, it will also be pass-through when the video is finished playing. |
| | | Only the string can be passed in this case, not nil. |
| | | */ |
| | | @property (nonatomic, copy) NSString *userId; |
| | | |
| | | //optional. reward name. |
| | | @property (nonatomic, copy) NSString *rewardName; |
| | | |
| | | //optional. number of rewards. |
| | | @property (nonatomic, assign) NSInteger rewardAmount; |
| | | |
| | | //optional. serialized string. |
| | | @property (nonatomic, copy) NSString *extra; |
| | | |
| | | @end |
New file |
| | |
| | | // |
| | | // BUSize.h |
| | | // BUAdSDK |
| | | // |
| | | // Copyright © 2017 bytedance. All rights reserved. |
| | | // |
| | | |
| | | #import <Foundation/Foundation.h> |
| | | |
| | | /** |
| | | Get the view with the best results by using the predefined size in pixels. |
| | | When it comes to view display, it is recommended to use the same scaling. |
| | | */ |
| | | typedef NS_ENUM(NSInteger, BUProposalSize) { |
| | | BUProposalSize_Banner600_90, |
| | | BUProposalSize_Banner640_100, |
| | | BUProposalSize_Banner600_150, |
| | | BUProposalSize_Banner600_260, |
| | | BUProposalSize_Banner600_286, |
| | | BUProposalSize_Banner600_300, |
| | | BUProposalSize_Banner690_388, |
| | | BUProposalSize_Banner600_400, |
| | | BUProposalSize_Banner600_500, |
| | | BUProposalSize_Feed228_150, |
| | | BUProposalSize_Feed690_388, |
| | | BUProposalSize_Interstitial600_400, |
| | | BUProposalSize_Interstitial600_600, |
| | | BUProposalSize_Interstitial600_900, |
| | | BUProposalSize_DrawFullScreen |
| | | }; |
| | | |
| | | @interface BUSize : NSObject |
| | | |
| | | // width unit pixel. |
| | | @property (nonatomic, assign) NSInteger width; |
| | | |
| | | // height unit pixel. |
| | | @property (nonatomic, assign) NSInteger height; |
| | | |
| | | - (NSDictionary *)dictionaryValue; |
| | | |
| | | @end |
| | | |
| | | @interface BUSize (BU_SizeFactory) |
| | | + (instancetype)sizeBy:(BUProposalSize)proposalSize; |
| | | @end |
New file |
| | |
| | | // |
| | | // BUSplashAdView.h |
| | | // BUAdSDK |
| | | // |
| | | // Copyright © 2017年 bytedance. All rights reserved. |
| | | // |
| | | |
| | | #import <UIKit/UIKit.h> |
| | | #import "BUMaterialMeta.h" |
| | | #import "BUSplashZoomOutView.h" |
| | | |
| | | NS_ASSUME_NONNULL_BEGIN |
| | | |
| | | @protocol BUSplashAdDelegate; |
| | | |
| | | @interface BUSplashAdView : UIView |
| | | /** |
| | | The unique identifier of splash ad. |
| | | */ |
| | | @property (nonatomic, copy, readonly, nonnull) NSString *slotID; |
| | | |
| | | /** |
| | | Maximum allowable load timeout, default 3s, unit s. |
| | | */ |
| | | @property (nonatomic, assign) NSTimeInterval tolerateTimeout; |
| | | |
| | | |
| | | /** |
| | | Whether hide skip button, default NO. |
| | | If you hide the skip button, you need to customize the countdown. |
| | | */ |
| | | @property (nonatomic, assign) BOOL hideSkipButton; |
| | | |
| | | ///optional: Whether need splashZoomOutAd, default NO. |
| | | @property (nonatomic, assign) BOOL needSplashZoomOutAd; |
| | | |
| | | /** |
| | | The delegate for receiving state change messages. |
| | | */ |
| | | @property (nonatomic, weak, nullable) id<BUSplashAdDelegate> delegate; |
| | | |
| | | /* |
| | | required. |
| | | Root view controller for handling ad actions. |
| | | */ |
| | | @property (nonatomic, weak) UIViewController *rootViewController; |
| | | |
| | | /** |
| | | Whether the splash ad data has been loaded. |
| | | */ |
| | | @property (nonatomic, getter=isAdValid, readonly) BOOL adValid; |
| | | |
| | | /// media configuration parameters. |
| | | @property (nonatomic, copy, readonly) NSDictionary *mediaExt; |
| | | |
| | | /// When it is a zoom out advertisement, it has value. |
| | | @property (nonatomic, strong, readonly) BUSplashZoomOutView *zoomOutView; |
| | | |
| | | /** |
| | | Initializes splash ad with slot id and frame. |
| | | @param slotID : the unique identifier of splash ad |
| | | @param frame : the frame of splashAd view. It is recommended for the mobile phone screen. |
| | | @return BUSplashAdView |
| | | */ |
| | | - (instancetype)initWithSlotID:(NSString *)slotID frame:(CGRect)frame; |
| | | |
| | | /** |
| | | adload_seq:(针对聚合广告位)传递本次请求是为“自然日内某设备某广告位置第N次展示机会”发出的广告请求,同物理位置在自然日从1开始计数,不同物理位置独立计数;example:某原生广告位置,当天第5次产生展示机会,这次展示机向穿山甲发送了4次广告请求,则这4次广告请求的"adload_seq"的值应为5。第二天重新开始计数。 |
| | | |
| | | prime_rit:(针对聚合广告位)广告物理位置对应的固定穿山甲广告位id,可以使用第一层的广告位id也可以为某一层的广告位id,但要求同一物理位置在该字段固定上报同一广告位id,不频繁更换;example:某原生广告位,当天共发出了1000个请求,这1000个请求中使用了5个不同target的穿山甲rit,用某X rit来作为该位置的标记rit,则这1000次请求的prime_rit都需要上报X rit的rit id。 |
| | | */ |
| | | |
| | | - (instancetype)initWithSlotID:(NSString *)slotID adloadSeq:(NSInteger)adloadSeq primeRit:(NSString * __nullable)primeRit frame:(CGRect)frame; |
| | | /** |
| | | Load splash ad datas. |
| | | Start the countdown(@tolerateTimeout) as soon as you request datas. |
| | | */ |
| | | - (void)loadAdData; |
| | | |
| | | @end |
| | | |
| | | |
| | | @protocol BUSplashAdDelegate <NSObject> |
| | | |
| | | @optional |
| | | /** |
| | | This method is called when splash ad material loaded successfully. |
| | | */ |
| | | - (void)splashAdDidLoad:(BUSplashAdView *)splashAd; |
| | | |
| | | /** |
| | | This method is called when splash ad material failed to load. |
| | | @param error : the reason of error |
| | | */ |
| | | - (void)splashAd:(BUSplashAdView *)splashAd didFailWithError:(NSError * _Nullable)error; |
| | | |
| | | /** |
| | | This method is called when splash ad slot will be showing. |
| | | */ |
| | | - (void)splashAdWillVisible:(BUSplashAdView *)splashAd; |
| | | |
| | | /** |
| | | This method is called when splash ad is clicked. |
| | | */ |
| | | - (void)splashAdDidClick:(BUSplashAdView *)splashAd; |
| | | |
| | | /** |
| | | This method is called when splash ad is closed. |
| | | */ |
| | | - (void)splashAdDidClose:(BUSplashAdView *)splashAd; |
| | | |
| | | /** |
| | | This method is called when splash ad is about to close. |
| | | */ |
| | | - (void)splashAdWillClose:(BUSplashAdView *)splashAd; |
| | | |
| | | /** |
| | | This method is called when another controller has been closed. |
| | | @param interactionType : open appstore in app or open the webpage or view video ad details page. |
| | | */ |
| | | - (void)splashAdDidCloseOtherController:(BUSplashAdView *)splashAd interactionType:(BUInteractionType)interactionType; |
| | | |
| | | /** |
| | | This method is called when spalashAd skip button is clicked. |
| | | */ |
| | | - (void)splashAdDidClickSkip:(BUSplashAdView *)splashAd; |
| | | |
| | | /** |
| | | This method is called when spalashAd countdown equals to zero |
| | | */ |
| | | - (void)splashAdCountdownToZero:(BUSplashAdView *)splashAd; |
| | | |
| | | @end |
| | | |
| | | NS_ASSUME_NONNULL_END |
| | | |
New file |
| | |
| | | // |
| | | // BUSplashZoomOutView.h |
| | | // BUAdSDK |
| | | // |
| | | // Created by wangyanlin on 2020/6/17. |
| | | // Copyright © 2020 bytedance. All rights reserved. |
| | | // |
| | | |
| | | #import <UIKit/UIKit.h> |
| | | #import "BUMaterialMeta.h" |
| | | |
| | | NS_ASSUME_NONNULL_BEGIN |
| | | |
| | | @protocol BUSplashZoomOutViewDelegate; |
| | | |
| | | @interface BUSplashZoomOutView : UIView |
| | | /* |
| | | required. |
| | | Root view controller for handling ad actions. |
| | | */ |
| | | @property (nonatomic, weak) UIViewController *rootViewController; |
| | | |
| | | /** |
| | | Suggested size for show. |
| | | */ |
| | | @property (nonatomic, assign, readonly) CGSize showSize; |
| | | |
| | | /** |
| | | The delegate for receiving state change messages. |
| | | */ |
| | | @property (nonatomic, weak) id<BUSplashZoomOutViewDelegate> delegate; |
| | | @end |
| | | |
| | | @protocol BUSplashZoomOutViewDelegate <NSObject> |
| | | /** |
| | | This method is called when splash ad is clicked. |
| | | */ |
| | | - (void)splashZoomOutViewAdDidClick:(BUSplashZoomOutView *)splashAd; |
| | | |
| | | /** |
| | | This method is called when splash ad is closed. |
| | | */ |
| | | - (void)splashZoomOutViewAdDidClose:(BUSplashZoomOutView *)splashAd; |
| | | |
| | | /** |
| | | This method is called when another controller has been closed. |
| | | @param interactionType : open appstore in app or open the webpage or view video ad details page. |
| | | */ |
| | | - (void)splashZoomOutViewAdDidCloseOtherController:(BUSplashZoomOutView *)splashAd interactionType:(BUInteractionType)interactionType; |
| | | |
| | | @end |
| | | NS_ASSUME_NONNULL_END |
New file |
| | |
| | | // |
| | | // BUVideoAdView.h |
| | | // BUAdSDK |
| | | // |
| | | // Copyright © 2017年 bytedance. All rights reserved. |
| | | // |
| | | |
| | | #import <UIKit/UIKit.h> |
| | | #import "BUPlayerPublicDefine.h" |
| | | #import "BUMaterialMeta.h" |
| | | |
| | | @class BUMaterialMeta; |
| | | |
| | | NS_ASSUME_NONNULL_BEGIN |
| | | |
| | | /** |
| | | Control TikTok Audience Network video player. |
| | | */ |
| | | @protocol BUVideoEngine <NSObject> |
| | | |
| | | /** |
| | | Get the already played time. |
| | | */ |
| | | - (CGFloat)currentPlayTime; |
| | | |
| | | /** |
| | | Set video play when you support CustomMode |
| | | **/ |
| | | - (void)play; |
| | | |
| | | /** |
| | | Set video pause when you support CustomMode |
| | | **/ |
| | | - (void)pause; |
| | | |
| | | @end |
| | | |
| | | @protocol BUVideoAdViewDelegate; |
| | | |
| | | |
| | | @interface BUVideoAdView : UIView<BUPlayerDelegate, BUVideoEngine> |
| | | |
| | | @property (nonatomic, weak, nullable) id<BUVideoAdViewDelegate> delegate; |
| | | /** |
| | | required. Root view controller for handling ad actions. |
| | | **/ |
| | | @property (nonatomic, weak, readwrite) UIViewController *rootViewController; |
| | | |
| | | /** |
| | | Whether to allow pausing the video by clicking, default NO. Only for draw video(vertical video ads). |
| | | **/ |
| | | @property (nonatomic, assign) BOOL drawVideoClickEnable; |
| | | |
| | | /** |
| | | material information. |
| | | */ |
| | | @property (nonatomic, strong, readwrite, nullable) BUMaterialMeta *materialMeta; |
| | | |
| | | /** |
| | | Set your Video autoPlayMode when you support CustomMode |
| | | if support CustomMode , default autoplay Video |
| | | **/ |
| | | @property (nonatomic, assign) BOOL supportAutoPlay; |
| | | |
| | | |
| | | - (instancetype)initWithMaterial:(BUMaterialMeta *)materialMeta; |
| | | |
| | | /** |
| | | Resume to the corresponding time. |
| | | */ |
| | | - (void)playerSeekToTime:(CGFloat)time; |
| | | |
| | | /** |
| | | Support configuration for pause button. |
| | | @param playImg : the image of the button |
| | | @param playSize : the size of the button. Set as cgsizezero to use default icon size. |
| | | */ |
| | | - (void)playerPlayIncon:(UIImage *)playImg playInconSize:(CGSize)playSize; |
| | | |
| | | @end |
| | | |
| | | @protocol BUVideoAdViewDelegate <NSObject> |
| | | |
| | | @optional |
| | | |
| | | /** |
| | | This method is called when videoadview failed to play. |
| | | @param error : the reason of error |
| | | */ |
| | | - (void)videoAdView:(BUVideoAdView *)videoAdView didLoadFailWithError:(NSError *_Nullable)error; |
| | | |
| | | /** |
| | | This method is called when videoadview playback status changed. |
| | | @param playerState : player state after changed |
| | | */ |
| | | - (void)videoAdView:(BUVideoAdView *)videoAdView stateDidChanged:(BUPlayerPlayState)playerState; |
| | | |
| | | /** |
| | | This method is called when videoadview end of play. |
| | | */ |
| | | - (void)playerDidPlayFinish:(BUVideoAdView *)videoAdView; |
| | | |
| | | /** |
| | | This method is called when videoadview is clicked. |
| | | */ |
| | | - (void)videoAdViewDidClick:(BUVideoAdView *)videoAdView; |
| | | |
| | | /** |
| | | This method is called when videoadview's finish view is clicked. |
| | | */ |
| | | - (void)videoAdViewFinishViewDidClick:(BUVideoAdView *)videoAdView; |
| | | |
| | | /** |
| | | This method is called when another controller has been closed. |
| | | @param interactionType : open appstore in app or open the webpage or view video ad details page. |
| | | */ |
| | | - (void)videoAdViewDidCloseOtherController:(BUVideoAdView *)videoAdView interactionType:(BUInteractionType)interactionType; |
| | | |
| | | @end |
| | | |
| | | NS_ASSUME_NONNULL_END |
New file |
| | |
| | | // |
| | | // PangleNativeBannerView.h |
| | | // BUADDemo |
| | | // |
| | | // Created by bytedance on 2020/4/24. |
| | | // Copyright © 2020 Bytedance. All rights reserved. |
| | | // |
| | | |
| | | #import <UIKit/UIKit.h> |
| | | #import <BUAdSDK/BUNativeAd.h> |
| | | |
| | | NS_ASSUME_NONNULL_BEGIN |
| | | static CGFloat const bottomHeight = 30; |
| | | |
| | | @interface PangleNativeBannerView : UIView |
| | | @property (nonatomic, strong) BUNativeAd *nativeAd; |
| | | - (instancetype)initWithSize:(CGSize)size; |
| | | - (void)refreshUIWithAd:(BUNativeAd *_Nonnull)nativeAd; |
| | | @end |
| | | NS_ASSUME_NONNULL_END |
New file |
| | |
| | | // |
| | | // PangleNativeInterstitialView.h |
| | | // BUDemo |
| | | // |
| | | // Created by bytedance on 2020/4/24. |
| | | // Copyright © 2020 bytedance. All rights reserved. |
| | | // |
| | | |
| | | #import <UIKit/UIKit.h> |
| | | #import <BUAdSDK/BUNativeAd.h> |
| | | |
| | | NS_ASSUME_NONNULL_BEGIN |
| | | |
| | | @protocol PangleNativeInterstitialViewDelegate <NSObject> |
| | | |
| | | - (void)nativeInterstitialAdWillClose:(BUNativeAd *)nativeAd; |
| | | - (void)nativeInterstitialAdDidClose:(BUNativeAd *)nativeAd; |
| | | |
| | | @end |
| | | |
| | | @interface PangleNativeInterstitialView : UIViewController |
| | | |
| | | @property (nonatomic, getter=isAdValid, readonly) BOOL adValid; |
| | | |
| | | - (void)refreshUIWithAd:(BUNativeAd *_Nonnull)nativeAd; |
| | | - (BOOL)showAdFromRootViewController:(UIViewController *)rootViewController delegate:(id <PangleNativeInterstitialViewDelegate>)delegate; |
| | | @end |
| | | |
| | | NS_ASSUME_NONNULL_END |
New file |
| | |
| | | framework module BUAdSDK { |
| | | umbrella header "BUAdSDK.h" |
| | | |
| | | export * |
| | | module * { export * } |
| | | } |
New file |
| | |
| | | // |
| | | // BUBaseRequest.h |
| | | // BUAdSDK |
| | | // |
| | | // Created by 李盛 on 2018/4/2. |
| | | // Copyright © 2018年 bytedance. All rights reserved. |
| | | // |
| | | |
| | | #import <Foundation/Foundation.h> |
| | | |
| | | NS_ASSUME_NONNULL_BEGIN |
| | | |
| | | /// HTTP Request method. |
| | | typedef NS_ENUM(NSInteger, BURequestMethod) { |
| | | BURequestMethodGET = 0, |
| | | BURequestMethodPOST, |
| | | BURequestMethodHEAD, |
| | | BURequestMethodPUT, |
| | | BURequestMethodDELETE, |
| | | BURequestMethodPATCH, |
| | | }; |
| | | |
| | | /// Request serializer type. |
| | | typedef NS_ENUM(NSInteger, BURequestSerializerType) { |
| | | BURequestSerializerTypeHTTP = 0, |
| | | BURequestSerializerTypeJSON, |
| | | }; |
| | | |
| | | /// Response serializer type, which determines response serialization process and |
| | | /// the type of `responseObject`. |
| | | typedef NS_ENUM(NSInteger, BUResponseSerializerType) { |
| | | /// NSData type |
| | | BUResponseSerializerTypeHTTP, |
| | | /// JSON object type |
| | | BUResponseSerializerTypeJSON, |
| | | }; |
| | | |
| | | /// Request priority |
| | | typedef NS_ENUM(NSInteger, BURequestPriority) { |
| | | BURequestPriorityLow = -4L, |
| | | BURequestPriorityDefault = 0, |
| | | BURequestPriorityHigh = 4, |
| | | }; |
| | | |
| | | @protocol BU_AFMultipartFormData; |
| | | |
| | | typedef void (^BUAFConstructingBlock)(id<BU_AFMultipartFormData> formData); |
| | | typedef void (^BUAFURLSessionTaskProgressBlock)(NSProgress *); |
| | | |
| | | @class BUBaseRequest; |
| | | |
| | | typedef void(^BURequestCompletionBlock)(__kindof BUBaseRequest *request); |
| | | |
| | | @interface BUBaseRequest : NSObject |
| | | |
| | | /// The underlying NSURLSessionTask. |
| | | /// |
| | | /// @warning This value is actually nil and should not be accessed before the request starts. |
| | | @property (nonatomic, strong) NSURLSessionTask *requestTask; |
| | | @property (nonatomic, strong) NSData *responseData; |
| | | @property (nonatomic, strong) id responseJSONObject; |
| | | @property (nonatomic, strong) id responseObject; |
| | | @property (nonatomic, strong) NSString *responseString; |
| | | @property (nonatomic, strong) NSError *error; |
| | | @property (nonatomic, assign) BURequestMethod requestMethod; |
| | | /// For post method, when httpbody can not be Serialized from NSDictionary json. if httpBody exists, please use httpBody directively and ignore 'requestArgument' |
| | | @property (nonatomic, strong) NSData *httpBody; |
| | | |
| | | /// Shortcut for `requestTask.currentRequest`.当前活跃的request |
| | | @property (nonatomic, strong, readonly) NSURLRequest *currentRequest; |
| | | |
| | | /// Shortcut for `requestTask.originalRequest`.在task创建的时候传入的request(有可能会重定向) |
| | | @property (nonatomic, strong, readonly) NSURLRequest *originalRequest; |
| | | |
| | | /// Shortcut for `requestTask.response`. |
| | | @property (nonatomic, strong, readonly) NSHTTPURLResponse *response; |
| | | |
| | | /// The response status code. |
| | | @property (nonatomic, readonly) NSInteger responseStatusCode; |
| | | |
| | | /// The success callback. Note if this value is not nil and `requestFinished` delegate method is |
| | | /// also implemented, both will be executed but delegate method is first called. This block |
| | | /// will be called on the main queue. |
| | | @property (nonatomic, copy, nullable) BURequestCompletionBlock successCompletionBlock; |
| | | |
| | | /// The failure callback. Note if this value is not nil and `requestFailed` delegate method is |
| | | /// also implemented, both will be executed but delegate method is first called. This block |
| | | /// will be called on the main queue. |
| | | @property (nonatomic, copy, nullable) BURequestCompletionBlock failureCompletionBlock; |
| | | |
| | | /// Additional HTTP request header field. |
| | | - (nullable NSDictionary<NSString *, NSString *> *)requestHeaderFieldValueDictionary; |
| | | |
| | | /// Request serializer type. |
| | | - (BURequestSerializerType)requestSerializerType; |
| | | |
| | | /// Response serializer type. See also `responseObject`. |
| | | - (BUResponseSerializerType)responseSerializerType; |
| | | |
| | | /// Request cache policy. |
| | | - (NSURLRequestCachePolicy)bu_requestCachePolicy; |
| | | |
| | | //constructingBodyWithBlock:在此block种可以为上传的参数添加(拼接)新的需要的上传的数据,适用于上传给服务器的数据流比较大的时候 |
| | | @property (nonatomic, copy, nullable) BUAFConstructingBlock constructingBodyBlock; |
| | | |
| | | - (NSString *)requestUrl; |
| | | - (NSString *)cdnUrl; |
| | | - (NSString *)baseUrl; |
| | | - (NSTimeInterval)requestTimeoutInterval; |
| | | - (nullable id)requestArgument; |
| | | /// Whether the request is allowed to use the cellular radio (if present). Default is YES. |
| | | - (BOOL)allowsCellularAccess; |
| | | /// Nil out both success and failure callback blocks. |
| | | - (void)clearCompletionBlock; |
| | | |
| | | @property (nonatomic) BURequestPriority requestPriority; |
| | | |
| | | /// Should use CDN when sending request. |
| | | - (BOOL)useCDN; |
| | | |
| | | #pragma mark - Request Action |
| | | ///============================================================================= |
| | | /// @name Request Action |
| | | ///============================================================================= |
| | | |
| | | /// Append self to request queue and start the request. |
| | | - (void)start; |
| | | |
| | | /// Remove self from request queue and cancel the request. |
| | | - (void)stop; |
| | | |
| | | /// Convenience method to start the request with block callbacks. |
| | | - (void)startWithCompletionBlockWithSuccess:(nullable BURequestCompletionBlock)success |
| | | failure:(nullable BURequestCompletionBlock)failure; |
| | | |
| | | /// Return cancelled state of request task. |
| | | @property (nonatomic, readonly, getter=isCancelled) BOOL cancelled; |
| | | |
| | | /// Executing state of request task. |
| | | @property (nonatomic, readonly, getter=isExecuting) BOOL executing; |
| | | |
| | | @end |
| | | |
| | | NS_ASSUME_NONNULL_END |
New file |
| | |
| | | // |
| | | // BUBundleHelper.h |
| | | // BUFoundation |
| | | // |
| | | // Created by wangchao on 2020/6/10. |
| | | // Copyright © 2020 Union. All rights reserved. |
| | | // |
| | | |
| | | #import <Foundation/Foundation.h> |
| | | |
| | | NS_ASSUME_NONNULL_BEGIN |
| | | |
| | | @interface BUBundleHelper : NSObject |
| | | |
| | | // 获取资源文件 |
| | | + (NSBundle *)resourceBundle; |
| | | |
| | | @end |
| | | |
| | | NS_ASSUME_NONNULL_END |
New file |
| | |
| | | /* |
| | | CocoaSecurity 1.1 |
| | | |
| | | Created by Kelp on 12/5/12. |
| | | Copyright (c) 2012 Kelp http://kelp.phate.org/ |
| | | MIT License |
| | | |
| | | CocoaSecurity is core. It provides AES encrypt, AES decrypt, Hash(MD5, HmacMD5, SHA1~SHA512, HmacSHA1~HmacSHA512) messages. |
| | | */ |
| | | |
| | | #import <Foundation/Foundation.h> |
| | | #import <Foundation/NSException.h> |
| | | |
| | | |
| | | #pragma mark - BUCocoaSecurityResult |
| | | @interface BUCocoaSecurityResult : NSObject |
| | | |
| | | @property (strong, nonatomic, readonly) NSData *data; |
| | | @property (strong, nonatomic, readonly) NSString *utf8String; |
| | | @property (strong, nonatomic, readonly) NSString *hex; |
| | | @property (strong, nonatomic, readonly) NSString *hexLower; |
| | | @property (strong, nonatomic, readonly) NSString *base64; |
| | | |
| | | - (instancetype)initWithBytes:(unsigned char[])initData length:(NSUInteger)length; |
| | | |
| | | @end |
| | | |
| | | |
| | | #pragma mark - CocoaSecurity |
| | | @interface BUCocoaSecurity : NSObject |
| | | #pragma mark - AES Encrypt |
| | | + (BUCocoaSecurityResult *)aesEncrypt:(NSString *)data key:(NSString *)key; |
| | | + (BUCocoaSecurityResult *)aesEncrypt:(NSString *)data hexKey:(NSString *)key hexIv:(NSString *)iv; |
| | | + (BUCocoaSecurityResult *)aesEncrypt:(NSString *)data key:(NSData *)key iv:(NSData *)iv; |
| | | + (BUCocoaSecurityResult *)aesEncryptWithData:(NSData *)data key:(NSData *)key iv:(NSData *)iv; |
| | | #pragma mark AES Decrypt |
| | | + (BUCocoaSecurityResult *)aesDecryptWithBase64:(NSString *)data key:(NSString *)key; |
| | | + (BUCocoaSecurityResult *)aesDecryptWithBase64:(NSString *)data hexKey:(NSString *)key hexIv:(NSString *)iv; |
| | | + (BUCocoaSecurityResult *)aesDecryptWithBase64:(NSString *)data key:(NSData *)key iv:(NSData *)iv; |
| | | + (BUCocoaSecurityResult *)aesDecryptWithData:(NSData *)data key:(NSData *)key iv:(NSData *)iv; |
| | | |
| | | #pragma mark - MD5 |
| | | + (BUCocoaSecurityResult *)md5:(NSString *)hashString; |
| | | + (BUCocoaSecurityResult *)md5WithData:(NSData *)hashData; |
| | | #pragma mark HMAC-MD5 |
| | | + (BUCocoaSecurityResult *)hmacMd5:(NSString *)hashString hmacKey:(NSString *)key; |
| | | + (BUCocoaSecurityResult *)hmacMd5WithData:(NSData *)hashData hmacKey:(NSString *)key; |
| | | |
| | | #pragma mark - SHA |
| | | + (BUCocoaSecurityResult *)sha1:(NSString *)hashString; |
| | | + (BUCocoaSecurityResult *)sha1WithData:(NSData *)hashData; |
| | | + (BUCocoaSecurityResult *)sha224:(NSString *)hashString; |
| | | + (BUCocoaSecurityResult *)sha224WithData:(NSData *)hashData; |
| | | + (BUCocoaSecurityResult *)sha256:(NSString *)hashString; |
| | | + (BUCocoaSecurityResult *)sha256WithData:(NSData *)hashData; |
| | | + (BUCocoaSecurityResult *)sha384:(NSString *)hashString; |
| | | + (BUCocoaSecurityResult *)sha384WithData:(NSData *)hashData; |
| | | + (BUCocoaSecurityResult *)sha512:(NSString *)hashString; |
| | | + (BUCocoaSecurityResult *)sha512WithData:(NSData *)hashData; |
| | | #pragma mark HMAC-SHA |
| | | + (BUCocoaSecurityResult *)hmacSha1:(NSString *)hashString hmacKey:(NSString *)key; |
| | | + (BUCocoaSecurityResult *)hmacSha1WithData:(NSData *)hashData hmacKey:(NSString *)key; |
| | | + (BUCocoaSecurityResult *)hmacSha224:(NSString *)hashString hmacKey:(NSString *)key; |
| | | + (BUCocoaSecurityResult *)hmacSha224WithData:(NSData *)hashData hmacKey:(NSString *)key; |
| | | + (BUCocoaSecurityResult *)hmacSha256:(NSString *)hashString hmacKey:(NSString *)key; |
| | | + (BUCocoaSecurityResult *)hmacSha256WithData:(NSData *)hashData hmacKey:(NSString *)key; |
| | | + (BUCocoaSecurityResult *)hmacSha384:(NSString *)hashString hmacKey:(NSString *)key; |
| | | + (BUCocoaSecurityResult *)hmacSha384WithData:(NSData *)hashData hmacKey:(NSString *)key; |
| | | + (BUCocoaSecurityResult *)hmacSha512:(NSString *)hashString hmacKey:(NSString *)key; |
| | | + (BUCocoaSecurityResult *)hmacSha512WithData:(NSData *)hashData hmacKey:(NSString *)key; |
| | | @end |
| | | |
| | | |
| | | #pragma mark - BUCocoaSecurityEncoder |
| | | @interface BUCocoaSecurityEncoder : NSObject |
| | | - (NSString *)base64:(NSData *)data; |
| | | - (NSString *)hex:(NSData *)data useLower:(BOOL)isOutputLower; |
| | | @end |
| | | |
| | | |
| | | #pragma mark - BUCocoaSecurityDecoder |
| | | @interface BUCocoaSecurityDecoder : NSObject |
| | | - (NSData *)base64:(NSString *)data; |
| | | - (NSData *)hex:(NSString *)data; |
| | | @end |
New file |
| | |
| | | // |
| | | // BUCommonMacros.h |
| | | // BUAdSDK |
| | | // |
| | | // Created by 崔亚楠 on 2018/10/23. |
| | | // Copyright © 2018年 bytedance. All rights reserved. |
| | | // |
| | | |
| | | #import <Foundation/Foundation.h> |
| | | |
| | | FOUNDATION_EXPORT NSString * const BUSDKVersion; |
| | | |
| | | |
| | | /** String **/ |
| | | #define BUEmptyString (@""); |
| | | #define BUSafeString(__string) ((__string && [__string isKindOfClass:[NSString class]]) ? __string :@"") |
| | | #define BUSafeDictionary(__aDictionary) ((__aDictionary && [__aDictionary isKindOfClass:[NSDictionary class]]) ? __aDictionary :@{}) |
| | | |
| | | /** VALID CHECKING**/ |
| | | #define BUCheckValidString(__string) (__string && [__string isKindOfClass:[NSString class]] && [__string length]) |
| | | #define BUCheckValidNumber(__aNumber) (__aNumber && [__aNumber isKindOfClass:[NSNumber class]]) |
| | | #define BUCheckValidArray(__aArray) (__aArray && [__aArray isKindOfClass:[NSArray class]] && [__aArray count]) |
| | | #define BUCheckValidDictionary(__aDictionary) (__aDictionary && [__aDictionary isKindOfClass:[NSDictionary class]] && [__aDictionary count]) |
| | | |
| | | /** Color String**/ |
| | | #define BUColorString(__string) [UIColor bu_colorWithHexString:(__string)] |
| | | |
| | | /*********************************************************************************************************/ |
| | | //强弱引用转换,用于解决代码块(block)与强引用对象之间的循环引用问题 |
| | | #ifndef bu_weakify |
| | | #if __has_feature(objc_arc) |
| | | #define bu_weakify(object) __weak __typeof__(object) weak##object = object; |
| | | #else |
| | | #define bu_weakify(object) __block __typeof__(object) block##object = object; |
| | | #endif |
| | | #endif |
| | | #ifndef bu_strongify |
| | | #if __has_feature(objc_arc) |
| | | #define bu_strongify(object) __typeof__(object) object = weak##object; |
| | | #else |
| | | #define bu_strongify(object) __typeof__(object) object = block##object; |
| | | #endif |
| | | #endif |
| | | /*********************************************************************************************************/ |
| | | |
| | | #ifndef BUisEmptyString |
| | | #define BUisEmptyString(str) (!str || ![str isKindOfClass:[NSString class]] || str.length == 0) |
| | | #endif |
| | | |
| | | #ifndef BUIsEmptyArray |
| | | #define BUIsEmptyArray(array) (!array || ![array isKindOfClass:[NSArray class]] || array.count == 0) |
| | | #endif |
| | | |
| | | #ifndef BUIsEmptyDictionary |
| | | #define BUIsEmptyDictionary(dict) (!dict || ![dict isKindOfClass:[NSDictionary class]] || ((NSDictionary *)dict).count == 0) |
| | | #endif |
| | | |
| | | |
| | | #ifndef BUMinX |
| | | #define BUMinX(view) CGRectGetMinX(view.frame) |
| | | #endif |
| | | |
| | | #ifndef BUMinY |
| | | #define BUMinY(view) CGRectGetMinY(view.frame) |
| | | #endif |
| | | |
| | | #ifndef BUMaxX |
| | | #define BUMaxX(view) CGRectGetMaxX(view.frame) |
| | | #endif |
| | | |
| | | #ifndef BUMaxY |
| | | #define BUMaxY(view) CGRectGetMaxY(view.frame) |
| | | #endif |
| | | |
| | | #ifndef BUWidth |
| | | #define BUWidth(view) view.frame.size.width |
| | | #endif |
| | | |
| | | #ifndef BUHeight |
| | | #define BUHeight(view) view.frame.size.height |
| | | #endif |
| | | |
| | | #ifndef BUScreenWidth |
| | | #define BUScreenWidth [[UIScreen mainScreen] bounds].size.width |
| | | #endif |
| | | |
| | | #ifndef BUScreenHeight |
| | | #define BUScreenHeight [[UIScreen mainScreen] bounds].size.height |
| | | #endif |
| | | |
| | | #ifndef BUMINScreenSide |
| | | #define BUMINScreenSide MIN([UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height) |
| | | #endif |
| | | |
| | | #ifndef BUMAXScreenSide |
| | | #define BUMAXScreenSide MAX([UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height) |
| | | #endif |
| | | |
| | | #define BUiPhoneX ((BUMAXScreenSide == 812.0) || (BUMAXScreenSide == 896)) |
| | | #define kBUDefaultNavigationBarHeight (BUiPhoneX?88:64) // 导航条高度 |
| | | #define kBUSafeTopMargin (BUiPhoneX?24:0) |
| | | #define kBUDefaultStautsBarHeight (BUiPhoneX?44:20) // 状态栏高度 |
| | | |
| | | #define BUOnePixel (1.0f/[[UIScreen mainScreen] scale]) |
| | | |
| | | ///全局队列 |
| | | #ifndef BUDispatchGetGlobalQueue |
| | | #define BUDispatchGetGlobalQueue dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0) |
| | | #endif |
| | | |
| | | #ifndef BUDispatchGetHighQueue |
| | | #define BUDispatchGetHighQueue dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0) |
| | | #endif |
| | | |
| | | //单例 |
| | | #define BU_SINGLETION(...) \ |
| | | + (instancetype)sharedInstance NS_SWIFT_NAME(shared()); |
| | | |
| | | #define BU_DEF_SINGLETION(...) \ |
| | | + (instancetype)sharedInstance \ |
| | | { \ |
| | | static dispatch_once_t once; \ |
| | | static id __singletion; \ |
| | | dispatch_once(&once,^{__singletion = [[self alloc] init];}); \ |
| | | return __singletion; \ |
| | | } |
| | | |
| | | FOUNDATION_EXPORT void bu_safe_dispatch_sync_main_queue(void (^block)(void)); |
| | | FOUNDATION_EXPORT void bu_safe_dispatch_async_main_queue(void (^block)(void)); |
| | | |
| | | FOUNDATION_EXPORT id BU_JSONObjectByRemovingKeysWithNullValues(id JSONObject); |
| | | |
| | | |
| | | /** LOG **/ |
| | | #define BU_Log_Foundation(frmt, ...) BU_Log_Base(BUFoundationLog, frmt, ##__VA_ARGS__) |
| | | |
| | | #define BU_Log_Base(BULogTypeString, frmt, ...) BU_LOG_MAYBE(BULogTypeString, BU_LOG_ENABLED, frmt, ##__VA_ARGS__) |
| | | |
| | | #define BU_LOG_MAYBE(BULogTypeString, flg, frmt, ...) \ |
| | | do { \ |
| | | if(flg) NSLog(@"【BytedanceUnion V%@】-【%@】%@", BUSDKVersion, BULogTypeString, [NSString stringWithFormat:frmt,##__VA_ARGS__]); \ |
| | | } while(0) |
| | | |
| | | FOUNDATION_EXPORT NSString * const BUFoundationLog; |
| | | FOUNDATION_EXPORT BOOL BU_LOG_ENABLED; |
New file |
| | |
| | | // |
| | | // BUDeviceHelper.h |
| | | // BUSDKProject |
| | | // |
| | | // Created by ranny_90 on 2017/5/20. |
| | | // Copyright © 2017年 ranny_90. All rights reserved. |
| | | // |
| | | #import <Foundation/Foundation.h> |
| | | #import <UIKit/UIKit.h> |
| | | |
| | | NS_ASSUME_NONNULL_BEGIN |
| | | |
| | | @interface BUDeviceHelper : NSObject |
| | | |
| | | /// 判断设备是否越狱 |
| | | + (BOOL)isJailBroken; |
| | | |
| | | /// 获取idfa |
| | | + (nullable NSString *)idfaString; |
| | | |
| | | /// 获取idfv |
| | | + (nullable NSString *)idfvString; |
| | | |
| | | /// 获取uuid |
| | | + (NSString *)uuid; |
| | | |
| | | /// 获取系统版本号 |
| | | + (float)OSVersionNumber; |
| | | |
| | | /// 获取当前语言种类 |
| | | + (nullable NSString *)currentLanguage; |
| | | |
| | | @end |
| | | |
| | | |
| | | @interface BUDeviceHelper (Hardware) |
| | | |
| | | /// 返回设备平台信息 |
| | | + (NSString *)platform; |
| | | |
| | | /// 返回设备type:iphone/ipad/ipod/apple tv等 |
| | | + (NSString *)platformTypeString; |
| | | |
| | | /// 具体到型号,如iPhone1,1 |
| | | + (NSString *)platformString; |
| | | |
| | | /// 返回硬盘空闲空间 |
| | | + (NSNumber *)freeDiskSpace; |
| | | |
| | | /// 设备的总内存 单位MB |
| | | + (NSInteger)totolDeviceMemory; |
| | | |
| | | /// APP已使用的内存 单位MB |
| | | + (NSInteger)usedAPPMemory; |
| | | |
| | | // 是否是低端机型 |
| | | // 1. 非iPhone机型不是低端机型 |
| | | // 2. iPhone5s及以下是低端机型 |
| | | + (BOOL)lowEndMode; |
| | | @end |
| | | |
| | | |
| | | @interface BUDeviceHelper (ProcessesAdditions) |
| | | |
| | | /// 获取当前设备的进程,仅适用于(iOS9以下) |
| | | + (NSArray *)runningProcesses; |
| | | |
| | | @end |
| | | |
| | | NS_ASSUME_NONNULL_END |
New file |
| | |
| | | // |
| | | // BUDynamicPlugin.h |
| | | // BURexxar |
| | | // |
| | | // Created by muhuai on 2017/4/26. |
| | | // Copyright © 2017年 muhuai. All rights reserved. |
| | | // |
| | | |
| | | #import <Foundation/Foundation.h> |
| | | #import "BUJSBDefine.h" |
| | | #import "BURexxarEngine.h" |
| | | |
| | | |
| | | //推荐使用动态的方式 |
| | | /** |
| | | 使用方法: |
| | | 1.继承BUDynamicPlugin |
| | | 2.在.h中使用宏 BU_EXPORT_HANDLER(abc)声明需要暴露的方法 |
| | | 3.在.m中实现此方法, 输入-(void)abc 即可获得ide补全提示 |
| | | 4.通过传入的callback来回调执行结果. 注意.无论成功与否都必须执行这个callback |
| | | */ |
| | | @interface BUDynamicPlugin : NSObject |
| | | |
| | | /** |
| | | plugin执行时所处的engine |
| | | */ |
| | | @property (nonatomic, weak) id<BURexxarEngine> engine; |
| | | |
| | | |
| | | /** |
| | | BUJSBInstanceTypeGlobal时 需要实现此方法, 没有特殊需要 不推荐使用 |
| | | |
| | | @return 单例plugin |
| | | */ |
| | | + (instancetype)sharedPlugin; |
| | | |
| | | + (BUJSBInstanceType)instanceType; |
| | | @end |
New file |
| | |
| | | // |
| | | // BUFoundation.h |
| | | // BUFoundation |
| | | // |
| | | // Created by Siwant on 2019/8/26. |
| | | // Copyright © 2019 Union. All rights reserved. |
| | | // |
| | | |
| | | /// Utils |
| | | #import <BUFoundation/BUPersistence.h> |
| | | #import <BUFoundation/BURouter.h> |
| | | #import <BUFoundation/BUUIResponderHelper.h> |
| | | #import <BUFoundation/BUTLocationService.h> |
| | | #import <BUFoundation/BUBaseRequest.h> |
| | | #import <BUFoundation/BURuntimeUtil.h> |
| | | #import <BUFoundation/BUTimer.h> |
| | | #import <BUFoundation/BUDynamicPlugin.h> |
| | | #import <BUFoundation/BUStaticPlugin.h> |
| | | #import <BUFoundation/BUJSBForwarding.h> |
| | | #import <BUFoundation/BUJSBCommand.h> |
| | | #import <BUFoundation/BUJSBAuthorization.h> |
| | | #import <BUFoundation/BUJSBDefine.h> |
| | | #import <BUFoundation/BURexxarEngine.h> |
| | | #import <BUFoundation/BUWKWebView.h> |
| | | #import <BUFoundation/BUJSInjectorRule.h> |
| | | #import <BUFoundation/BUWebViewDefine.h> |
| | | #import <BUFoundation/BUJSInjector.h> |
| | | #import <BUFoundation/BUWebViewProgressView.h> |
| | | #import <BUFoundation/BUWebViewApplication.h> |
| | | #import <BUFoundation/BURexxarEngineFactory.h> |
| | | #import <BUFoundation/BUImageUtility.h> |
| | | #import <BUFoundation/BUGifImageView.h> |
| | | #import <BUFoundation/BUGifImage.h> |
| | | #import <BUFoundation/BUThreadSafeDictionary.h> |
| | | #import <BUFoundation/BUThreadSafeMutableArray.h> |
| | | #import <BUFoundation/BUCocoaSecurity.h> |
| | | #import <BUFoundation/BUInfoHelper.h> |
| | | #import <BUFoundation/BUReachability.h> |
| | | #import <BUFoundation/BUNetInfoHelper.h> |
| | | #import <BUFoundation/BUDeviceHelper.h> |
| | | #import <BUFoundation/BUScreenHelper.h> |
| | | #import <BUFoundation/BUCommonMacros.h> |
| | | #import <BUFoundation/BUFoundationAddress.h> |
| | | #import <BUFoundation/BUBundleHelper.h> |
| | | |
| | | |
| | | /// Category |
| | | #import <BUFoundation/UIViewController+BUUtilities.h> |
| | | #import <BUFoundation/NSArray+BUUtilities.h> |
| | | #import <BUFoundation/NSString+BUAddtion.h> |
| | | #import <BUFoundation/NSTimer+BUBlockSupport.h> |
| | | #import <BUFoundation/UIView+BUAdditions.h> |
| | | #import <BUFoundation/NSDictionary+BUUtilities.h> |
| | | #import <BUFoundation/NSPointerArray+BUSafely.h> |
| | | #import <BUFoundation/UIColor+BUTheme.h> |
| | | #import <BUFoundation/UIImage+BUIcon.h> |
| | | #import <BUFoundation/NSObject+BUSafeKVO.h> |
| | | |
| | | |
| | | /************************************ ThirdParty***********************************/ |
| | | // AFN |
| | | #import <BUFoundation/BU_AFURLSessionManager.h> |
| | | #import <BUFoundation/BU_AFURLResponseSerialization.h> |
| | | #import <BUFoundation/BU_AFURLRequestSerialization.h> |
| | | #import <BUFoundation/BU_AFSecurityPolicy.h> |
| | | #import <BUFoundation/BU_AFAutoPurgingImageCache.h> |
| | | #import <BUFoundation/BU_AFHTTPSessionManager.h> |
| | | |
| | | // SD |
| | | #import <BUFoundation/BU_SDWebImageManager.h> |
| | | #import <BUFoundation/UIImageView+BUWebCache.h> |
| | | #import <BUFoundation/BU_SDImageCache.h> |
| | | |
| | | // ByteFinder |
| | | #import <BUFoundation/EBAppLog.h> |
| | | #import <BUFoundation/EBAppLogConfig.h> |
| | | //#import <BUFoundation/HMDBUToBCrashTrackerRestrict.h> |
| | | //#import <BUFoundation/HMDBUToBAddressRange.h> |
| | | //#import <BUFoundation/HMDBUToBCrashTracker.h> |
| | | /************************************ ThirdParty***********************************/ |
New file |
| | |
| | | // |
| | | // BUFoundationAddress.h |
| | | // BUFoundation |
| | | // |
| | | // Created by Siwant on 2020/2/5. |
| | | // Copyright © 2020 Union. All rights reserved. |
| | | // |
| | | |
| | | #import <Foundation/Foundation.h> |
| | | |
| | | NS_ASSUME_NONNULL_BEGIN |
| | | |
| | | @interface BUFoundationAddress : NSObject |
| | | |
| | | + (int64_t)begainAddress; |
| | | |
| | | + (int64_t)endAddress; |
| | | |
| | | @end |
| | | |
| | | NS_ASSUME_NONNULL_END |
New file |
| | |
| | | // |
| | | // BUGeo.h |
| | | // BUAdSDK |
| | | // |
| | | // Created by chenren on 10/05/2017. |
| | | // Copyright © 2017 bytedance. All rights reserved. |
| | | // |
| | | |
| | | #import <Foundation/Foundation.h> |
| | | |
| | | @interface BUGeo : NSObject |
| | | |
| | | // 经度 |
| | | @property (atomic, strong) NSNumber *latitude; |
| | | |
| | | // 纬度 |
| | | @property (atomic, strong) NSNumber *longitude; |
| | | |
| | | - (NSDictionary *)dictionaryValue; |
| | | |
| | | @end |
| | | |
New file |
| | |
| | | // |
| | | // BUGifImage.h |
| | | // BUGif |
| | | // |
| | | // Created by Johnil on 14-3-6. |
| | | // Copyright (c) 2014年 Johnil. All rights reserved. |
| | | // |
| | | |
| | | #import <UIKit/UIKit.h> |
| | | |
| | | @interface BUGifImage : UIImage |
| | | |
| | | @property (nonatomic,assign) NSInteger currentPlayIndex; |
| | | @property (nonatomic,strong) NSData *data; |
| | | |
| | | + (instancetype)gifWithData:(NSData *)data; |
| | | |
| | | - (UIImage *)nextImage; |
| | | - (NSInteger)count; |
| | | - (CGFloat)frameDuration; |
| | | - (void)resumeIndex; |
| | | /// 是否还有下一桢 |
| | | - (BOOL) hasNextImage; |
| | | |
| | | @end |
New file |
| | |
| | | // |
| | | // TTGifImageView.h |
| | | // Article |
| | | // |
| | | // Created by carl on 2017/5/21. |
| | | // |
| | | // |
| | | |
| | | #import <UIKit/UIKit.h> |
| | | #import "BUGifImage.h" |
| | | |
| | | @protocol BUAnimationImageView |
| | | @property (nonatomic, assign) BOOL repeats; |
| | | @property (nonatomic, copy) void (^completionHandler)(BOOL); |
| | | @property (nonatomic, strong, readonly) BUGifImage *gifImage; |
| | | @property (nonatomic, assign) NSInteger currentPlayIndex; |
| | | @property (nonatomic, assign) BOOL delayDuration; |
| | | @end |
| | | |
| | | @interface BUGifImageView : UIImageView <BUAnimationImageView> |
| | | @property (nonatomic, assign) BOOL repeats; |
| | | @property (nonatomic, copy) void (^completionHandler)(BOOL); |
| | | @property (nonatomic, strong, readonly) BUGifImage *gifImage; |
| | | @property (nonatomic, assign) NSInteger currentPlayIndex; |
| | | @property (nonatomic, assign) BOOL delayDuration; |
| | | @end |
New file |
| | |
| | | // |
| | | // BUImageUtility.h |
| | | // BUAdSDK |
| | | // |
| | | // Created by Siwant on 2019/8/8. |
| | | // Copyright © 2019 bytedance. All rights reserved. |
| | | // |
| | | |
| | | #import <Foundation/Foundation.h> |
| | | #import <UIKit/UIKit.h> |
| | | |
| | | NS_ASSUME_NONNULL_BEGIN |
| | | |
| | | @interface BUImageUtility : NSObject |
| | | /// 返回类型不只是UIImage,也包括BUGifImage |
| | | + (UIImage *_Nullable)imageWithData:(NSData *_Nullable)data; |
| | | @end |
| | | |
| | | NS_ASSUME_NONNULL_END |
New file |
| | |
| | | // |
| | | // BUInfoHelper.h |
| | | // BUSDKProject |
| | | // |
| | | // Created by ranny_90 on 2017/5/20. |
| | | // Copyright © 2017年 ranny_90. All rights reserved. |
| | | // |
| | | |
| | | #import <Foundation/Foundation.h> |
| | | #import <UIKit/UIKit.h> |
| | | |
| | | NS_ASSUME_NONNULL_BEGIN |
| | | |
| | | @interface BUInfoHelper : NSObject |
| | | |
| | | /** |
| | | * 获取info.plist中的CFBundleDisplayName |
| | | * |
| | | * @return 如果没有,返回CFBundleName |
| | | */ |
| | | + (nullable NSString *)appDisplayName; |
| | | |
| | | /** |
| | | * 获取info.plist发布版本号 |
| | | * |
| | | * @return 可能为nil |
| | | */ |
| | | + (nullable NSString *)versionName; |
| | | |
| | | /** |
| | | * @return 获取plist中的CFBundleIdentifier |
| | | */ |
| | | + (nullable NSString *)bundleIdentifier; |
| | | |
| | | /** |
| | | * @return 获取aid |
| | | */ |
| | | + (nullable NSString *)ssAppID; |
| | | |
| | | @end |
| | | |
| | | NS_ASSUME_NONNULL_END |
New file |
| | |
| | | // |
| | | // BUJSBAuthorization.h |
| | | // BURexxar |
| | | // |
| | | // Created by muhuai on 2017/4/27. |
| | | // Copyright © 2017年 muhuai. All rights reserved. |
| | | // |
| | | |
| | | #import <Foundation/Foundation.h> |
| | | #import "BUJSBDefine.h" |
| | | #import "BUJSBCommand.h" |
| | | #import "BURexxarEngine.h" |
| | | |
| | | @protocol BUJSBAuthorization <NSObject> |
| | | |
| | | |
| | | /** |
| | | 验证是否有权限执行这个JSB |
| | | |
| | | @param engine 上下文engine |
| | | @param command JSBCommand |
| | | @param domain 所在页面 |
| | | @return 是否有权限 |
| | | */ |
| | | - (BOOL)engine:(id<BURexxarEngine>)engine isAuthorizedJSB:(BUJSBCommand *)command domain:(NSString *)domain; |
| | | |
| | | |
| | | /** |
| | | fireEvent发送之前 验证是否有权限发送这个事件 |
| | | |
| | | @param engine 上下文engine |
| | | @param eventName 事件名字 |
| | | @param domain 所在页面 |
| | | @return 是否有权限 |
| | | */ |
| | | - (BOOL)engine:(id<BURexxarEngine>)engine isAuthorizedEvent:(NSString *)eventName domain:(NSString *)domain; |
| | | |
| | | @end |
New file |
| | |
| | | // |
| | | // BUJSBMessage.h |
| | | // BURexxar |
| | | // |
| | | // Created by muhuai on 2017/4/26. |
| | | // Copyright © 2017年 muhuai. All rights reserved. |
| | | // |
| | | |
| | | #import <Foundation/Foundation.h> |
| | | |
| | | @interface BUJSBCommand : NSObject |
| | | |
| | | @property (nonatomic, copy) NSString *messageType; |
| | | |
| | | @property (nonatomic, copy) NSString *eventID; |
| | | |
| | | @property (nonatomic, copy) NSString *callbackID; |
| | | |
| | | @property (nonatomic, copy) NSDictionary *params; |
| | | |
| | | |
| | | /** |
| | | 前端传过来的方法名, 有"isLogin" 和 "TTRLogin.isLogin"两种格式 |
| | | */ |
| | | @property(nonatomic, copy) NSString *fullName; |
| | | |
| | | /** |
| | | 经过别名映射后, 该property为 映射前的fullName |
| | | */ |
| | | @property(nonatomic, copy) NSString *origName; |
| | | |
| | | /** |
| | | 动态plugin的 类名 |
| | | */ |
| | | @property(nonatomic, copy) NSString *className; |
| | | |
| | | |
| | | /** |
| | | 动态plugin的 方法名 |
| | | */ |
| | | @property(nonatomic, copy) NSString *methodName; |
| | | |
| | | /** |
| | | 没卵用 |
| | | */ |
| | | @property(nonatomic, copy) NSString *JSSDKVersion; |
| | | |
| | | - (instancetype)initWithDictonary:(NSDictionary *)dic; |
| | | |
| | | - (NSString *)toJSONString; |
| | | @end |
New file |
| | |
| | | // |
| | | // BUJSBDefine.h |
| | | // BURexxar |
| | | // |
| | | // Created by muhuai on 2017/5/5. |
| | | // Copyright © 2017年 muhuai. All rights reserved. |
| | | // |
| | | |
| | | #import <Foundation/Foundation.h> |
| | | //#import "BURexxarEngine.h" |
| | | |
| | | #define BU_EXPORT_HANDLER(NAME) - (void)NAME##WithParam:(NSDictionary *)param callback:(BUJSBResponse)callback webView:(UIView<BURexxarEngine> *)webview controller:(UIViewController *)controller; |
| | | |
| | | #define _BU_HANDLER_SET(NAME, HANDLERS) \ |
| | | - (NSSet<NSString *> *)NAME { \ |
| | | if (![HANDLERS isKindOfClass:[NSArray class]]) {\ |
| | | return nil;\ |
| | | }\ |
| | | return [NSSet setWithArray:HANDLERS];\ |
| | | } |
| | | |
| | | #define ARRAY(...) [NSArray arrayWithObjects: (id []){ __VA_ARGS__ } count: sizeof((id []){ __VA_ARGS__ }) / sizeof(id)] |
| | | |
| | | #define BU_PROTECTED_HANDLER(...) \ |
| | | _BU_HANDLER_SET(protectedHandlerSet, ARRAY(__VA_ARGS__)) |
| | | |
| | | #define BU_PRIVATE_HANDLER(...) \ |
| | | _BU_HANDLER_SET(privateHandlerSet, ARRAY(__VA_ARGS__)) |
| | | |
| | | #define BU_CALLBACK_SUCCESS \ |
| | | if (callback) {\ |
| | | callback(BUJSBMsgSuccess, @{@"code": @"1"});\ |
| | | }\ |
| | | |
| | | #define BU_CALLBACK_FAILED \ |
| | | if (callback) {\ |
| | | callback(BUJSBMsgFailed, @{@"code": @"0"});\ |
| | | }\ |
| | | |
| | | #define BU_CALLBACK_FAILED_MSG(msg) \ |
| | | if (callback) {\ |
| | | callback(BUJSBMsgFailed, @{@"code": @"0", @"msg": [NSString stringWithFormat:msg]? :@""});\ |
| | | }\ |
| | | |
| | | #define BU_CALLBACK_WITH_MSG(status, msg) \ |
| | | if (callback) {\ |
| | | callback(status, @{@"code": status == BUJSBMsgSuccess? @"1": @"0", @"msg": [NSString stringWithFormat:msg]? [NSString stringWithFormat:msg] :@""});\ |
| | | }\ |
| | | |
| | | |
| | | typedef NS_ENUM(NSUInteger, BUJSBInstanceType) { |
| | | BUJSBInstanceTypeNormal, //每次调用都是不同实例(默认, 推荐) |
| | | BUJSBInstanceTypeGlobal, //全局单例, 需要实现 +(instance)sharedPlugin; |
| | | BUJSBInstanceTypeWebView, //对同一个webview复用一个实例 |
| | | }; |
| | | |
| | | typedef NS_ENUM(NSUInteger, BUJSBAuthType){ |
| | | BUJSBAuthPublic, // 所有均可调用(默认) |
| | | BUJSBAuthProtected, //内部domain,及外部授权可调用 |
| | | BUJSBAuthPrivate // 仅内部domain,appinfo不可见 |
| | | }; |
| | | |
| | | typedef enum : NSUInteger { |
| | | BUJSBMsgSuccess, |
| | | BUJSBMsgFailed, |
| | | BUJSBMsgParamError, |
| | | BUJSBMsgNoHandler, |
| | | BUJSBMsgNoPermission |
| | | } BUJSBMsg; |
| | | |
| | | typedef void(^BUJSBResponse)(BUJSBMsg, NSDictionary *); |
New file |
| | |
| | | // |
| | | // BUJSBForwarding.h |
| | | // BURexxar |
| | | // |
| | | // Created by muhuai on 2017/4/27. |
| | | // Copyright © 2017年 muhuai. All rights reserved. |
| | | // |
| | | |
| | | #import <Foundation/Foundation.h> |
| | | #import "BUJSBCommand.h" |
| | | #import "BURexxarEngine.h" |
| | | #import "BUJSBDefine.h" |
| | | |
| | | @interface BUJSBForwarding : NSObject |
| | | |
| | | + (instancetype)sharedInstance; |
| | | |
| | | |
| | | /** |
| | | 转发到对应的插件 |
| | | |
| | | @param command JSB命令 |
| | | @param engine Hybrid容器, 可是webview, RNView, weex. 实现此协议即可 |
| | | @param completion 完成回调 |
| | | */ |
| | | - (void)forwardJSBWithCommand:(BUJSBCommand *)command engine:(id<BURexxarEngine>)engine completion:(BUJSBResponse)completion; |
| | | |
| | | /** |
| | | 注册JSBridge别名 |
| | | |
| | | @param alias 新名 |
| | | @param orig 原名 |
| | | */ |
| | | - (void)registeJSBAlias:(NSString *)alias for:(NSString *)orig; |
| | | |
| | | |
| | | /** |
| | | 原名 -> 别名 |
| | | |
| | | @param orig 原名 |
| | | @return 别名 |
| | | */ |
| | | - (NSString *)aliasJSBForOrig:(NSString *)orig; |
| | | @end |
| | | |
New file |
| | |
| | | // |
| | | // BUJSInjector.h |
| | | // BURexxar |
| | | // |
| | | // Created by muhuai on 2017/6/17. |
| | | // Copyright © 2017年 muhuai. All rights reserved. |
| | | // |
| | | |
| | | #import <Foundation/Foundation.h> |
| | | #import <UIKit/UIKit.h> |
| | | |
| | | @protocol BUWebView; |
| | | /** |
| | | BUWebView的JS注入器 |
| | | 当页面加载完成后, 注入器会向WebView容器里注入一段JS脚本. |
| | | |
| | | 使用场景: |
| | | 容器是其他人提供的, 但是你需要往里面注入一些脚本. |
| | | |
| | | 有两个级别: |
| | | 1. webview级别, 只对当前webview生效. BUWebView.injector |
| | | 2. 全局级别, 对所有webview生效. [BUJSInjector sharedInstance] |
| | | |
| | | 请自行根据需求使用, 不要滥用全局级别 |
| | | |
| | | */ |
| | | |
| | | @interface BUJSInjector : NSObject |
| | | |
| | | /** |
| | | 全局级别的注入器. |
| | | 需评估影响范围, 慎用 |
| | | |
| | | @return 注入器 |
| | | */ |
| | | + (instancetype)sharedInstance; |
| | | |
| | | /** |
| | | 对匹配正则的页面注入脚本 |
| | | 非线程安全 |
| | | |
| | | @param script 脚本 |
| | | @param regex 正则表达式 |
| | | @param key 该条规则的key, 用于remove和 检验规则唯一性 |
| | | @note 如果有多条规则成功匹配, 则会注入多段JS脚本 |
| | | 多段注入会按照注册先后顺序, 并且web级别 > 全局级别 |
| | | */ |
| | | - (void)addInjectRuleWithScript:(NSString *)script regex:(NSString *)regex key:(NSString *)key; |
| | | |
| | | /** |
| | | 移除指定规则 |
| | | 非线程安全 |
| | | |
| | | @param key 规则的key |
| | | */ |
| | | - (void)removeScriptWithKey:(NSString *)key; |
| | | |
| | | /** |
| | | 移除全部规则. |
| | | 非线程安全 |
| | | |
| | | 慎用..小心被人打... |
| | | */ |
| | | - (void)removeAllScript; |
| | | |
| | | /** |
| | | 对webview注入 符合规则的脚本 |
| | | |
| | | @param webview BUWebView |
| | | */ |
| | | - (void)injectScriptInWebView:(UIView<BUWebView> *)webview; |
| | | @end |
New file |
| | |
| | | // |
| | | // BUJSInjectorRule.h |
| | | // BURexxar |
| | | // |
| | | // Created by muhuai on 2017/6/17. |
| | | // Copyright © 2017年 muhuai. All rights reserved. |
| | | // |
| | | |
| | | #import <Foundation/Foundation.h> |
| | | |
| | | NS_ASSUME_NONNULL_BEGIN |
| | | @interface BUJSInjectorRule : NSObject |
| | | |
| | | @property (nonatomic, copy) NSString *script; |
| | | @property (nonatomic, copy) NSString *regex; |
| | | @property (nonatomic, copy) NSString *key; |
| | | |
| | | @property (nonatomic, strong, readonly) NSRegularExpression *regExpression; |
| | | |
| | | + (instancetype)ruleWithScript:(NSString *)script withRegex:(NSString *)regex key:(NSString *)key; |
| | | |
| | | @end |
| | | NS_ASSUME_NONNULL_END |
New file |
| | |
| | | // |
| | | // BUNetInfoHelper.h |
| | | // BUAdSDK |
| | | // |
| | | // Created by 曹清然 on 2017/5/27. |
| | | // Copyright © 2017年 chenren. All rights reserved. |
| | | // |
| | | |
| | | #import <Foundation/Foundation.h> |
| | | #import <UIKit/UIKit.h> |
| | | #import "BUReachability.h" |
| | | |
| | | NS_ASSUME_NONNULL_BEGIN |
| | | |
| | | @interface BUNetInfoHelper : NSObject |
| | | |
| | | + (nullable NSString *)userAgentString; |
| | | |
| | | /// 网络连接状态的字符串描述 |
| | | + (NSString *)GetNetWorkType; |
| | | |
| | | + (BUNetWorkTypeCode)GetNetWorkTypeCode; |
| | | |
| | | /// 获取carrierName |
| | | + (nullable NSString *)carrierName; |
| | | |
| | | /// 获取mobileCountryCode |
| | | + (nullable NSString *)carrierMCC; |
| | | |
| | | /// 获取mobileNetworkCode |
| | | + (nullable NSString *)carrierMNC; |
| | | |
| | | /// 获取IP地址 |
| | | + (nullable NSDictionary *)getIPAddresses; |
| | | |
| | | /** |
| | | * @param preferIPv4 是否ipv4格式 |
| | | * @return ip地址 |
| | | */ |
| | | + (NSString *)getIPAddress:(BOOL)preferIPv4; |
| | | |
| | | /// host |
| | | + (nullable NSString*)addressOfHost:(nullable NSString *)host; |
| | | |
| | | @end |
| | | |
| | | NS_ASSUME_NONNULL_END |
New file |
| | |
| | | // |
| | | // BUPersistence.h |
| | | // BUPersistence |
| | | // |
| | | // Created by Chen Hong on 2017/1/10. |
| | | // Copyright © 2017年 Chen Hong. All rights reserved. |
| | | // |
| | | |
| | | #import <Foundation/Foundation.h> |
| | | |
| | | NS_ASSUME_NONNULL_BEGIN |
| | | |
| | | |
| | | typedef NS_ENUM(NSUInteger, BUPersistentType) { |
| | | BUPersistentTypePlist, |
| | | BUPersistentTypeKeyChain, |
| | | BUPersistentTypeCustom, |
| | | }; |
| | | |
| | | @interface BUPersistenceOption : NSObject |
| | | |
| | | @property (nonatomic) BUPersistentType type; |
| | | |
| | | @property (nonatomic) BOOL shouldRemoveAllObjectsOnMemoryWarning; |
| | | |
| | | @property (nonatomic) BOOL shouldRemoveAllObjectsWhenEnteringBackground; |
| | | |
| | | @property (nonatomic) BOOL supportNSCoding; |
| | | |
| | | @end |
| | | |
| | | @protocol BUPersistenceProtocol <NSObject> |
| | | |
| | | - (NSArray *)allObjects; |
| | | |
| | | - (nullable id)objectForKey:(NSString *)key; |
| | | |
| | | - (nullable NSArray *)objectsForKeys:(NSArray *)keys; |
| | | |
| | | - (void)updateObjectsForKeys:(NSArray *)keys WithBlock:(NSDictionary * (^)(NSArray *objects))block; |
| | | |
| | | - (BOOL)setObject:(nullable id<NSCoding>)object forKey:(NSString *)key; |
| | | |
| | | - (BOOL)hasObjectForKey:(NSString *)key; |
| | | |
| | | - (BOOL)removeAll; |
| | | |
| | | - (BOOL)removeObjectsForKeys:(NSArray<NSString *> *)keys; |
| | | |
| | | - (BOOL)save; |
| | | |
| | | @end |
| | | |
| | | @interface BUPersistence : NSObject <BUPersistenceProtocol> |
| | | |
| | | + (nullable instancetype)persistenceWithName:(NSString *)name; |
| | | |
| | | + (nullable instancetype)persistenceWithName:(NSString *)name option:(BUPersistenceOption *)option; |
| | | |
| | | + (void)deleteWithName:(NSString *)name; |
| | | |
| | | + (NSString *)cacheDirectory; |
| | | |
| | | @end |
| | | |
| | | NS_ASSUME_NONNULL_END |
New file |
| | |
| | | /* |
| | | File: BUReachability.h |
| | | Abstract: Basic demonstration of how to use the SystemConfiguration Reachablity APIs. |
| | | Version: 3.5 |
| | | |
| | | Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple |
| | | Inc. ("Apple") in consideration of your agreement to the following |
| | | terms, and your use, installation, modification or redistribution of |
| | | this Apple software constitutes acceptance of these terms. If you do |
| | | not agree with these terms, please do not use, install, modify or |
| | | redistribute this Apple software. |
| | | |
| | | In consideration of your agreement to abide by the following terms, and |
| | | subject to these terms, Apple grants you a personal, non-exclusive |
| | | license, under Apple's copyrights in this original Apple software (the |
| | | "Apple Software"), to use, reproduce, modify and redistribute the Apple |
| | | Software, with or without modifications, in source and/or binary forms; |
| | | provided that if you redistribute the Apple Software in its entirety and |
| | | without modifications, you must retain this notice and the following |
| | | text and disclaimers in all such redistributions of the Apple Software. |
| | | Neither the name, trademarks, service marks or logos of Apple Inc. may |
| | | be used to endorse or promote products derived from the Apple Software |
| | | without specific prior written permission from Apple. Except as |
| | | expressly stated in this notice, no other rights or licenses, express or |
| | | implied, are granted by Apple herein, including but not limited to any |
| | | patent rights that may be infringed by your derivative works or by other |
| | | works in which the Apple Software may be incorporated. |
| | | |
| | | The Apple Software is provided by Apple on an "AS IS" basis. APPLE |
| | | MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION |
| | | THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS |
| | | FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND |
| | | OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. |
| | | |
| | | IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL |
| | | OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
| | | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
| | | INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, |
| | | MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED |
| | | AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), |
| | | STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE |
| | | POSSIBILITY OF SUCH DAMAGE. |
| | | |
| | | Copyright (C) 2014 Apple Inc. All Rights Reserved. |
| | | |
| | | */ |
| | | |
| | | #import <Foundation/Foundation.h> |
| | | #import <SystemConfiguration/SystemConfiguration.h> |
| | | #import <netinet/in.h> |
| | | |
| | | typedef NS_ENUM(NSInteger, BUNetWorkTypeCode) { |
| | | // 初始状态,未连接 |
| | | BUNetWorkTypeCode_None = -1, |
| | | // 未知 |
| | | BUNetWorkTypeCode_Unknown = 0, |
| | | BUNetWorkTypeCode_Mobile = 1, |
| | | BUNetWorkTypeCode_2G = 2, |
| | | BUNetWorkTypeCode_3G = 3, |
| | | BUNetWorkTypeCode_Wifi = 4, |
| | | BUNetWorkTypeCode_4G = 5, |
| | | }; |
| | | |
| | | typedef NS_ENUM(NSInteger) { |
| | | // 程序无法判断出 App 的网络权限设置 |
| | | kBUNetworkAuthorizationStatusCantDetermined = 0, |
| | | // App 未开启蜂窝数据网络权限 |
| | | kBUNetworkAuthorizationStatusCellNotPermitted, |
| | | // App 未开启无线局域网与蜂窝移动网络权限,此项仅可能在国行 iPhone 手机上出现 |
| | | kBUNetworkAuthorizationStatusWLANAndCellNotPermitted, |
| | | } kBUNetworkAuthorizationStatus; |
| | | |
| | | extern NSString *kBUReachabilityChangedNotification; |
| | | |
| | | // 是否开启 “网络状态检测” 的优化,需要外部调用方以 [[NSUserDefaults standardUserDefaults] setBool:forKey:] 方式写入 |
| | | extern NSString * const BUReachabilityDetectOptimizeKey; |
| | | |
| | | @interface BUReachability : NSObject |
| | | |
| | | |
| | | /** |
| | | 判断指定域名的连通性 |
| | | |
| | | @param hostName 域名 |
| | | @return BUReachability对象 |
| | | */ |
| | | + (instancetype)reachabilityWithHostName:(NSString *)hostName; |
| | | |
| | | |
| | | /** |
| | | 判断指定IP地址的连通性 |
| | | |
| | | @param hostAddress IP地址 |
| | | @return BUReachability对象 |
| | | */ |
| | | + (instancetype)reachabilityWithAddress:(const struct sockaddr_in *)hostAddress; |
| | | |
| | | /** |
| | | 判断网络默认连接的连通性(应用连接到指定host主机时除外) |
| | | |
| | | @return BUReachability对象 |
| | | */ |
| | | + (instancetype)reachabilityForInternetConnection; |
| | | |
| | | /** |
| | | 开始在当前runloop监听连通性通知 |
| | | |
| | | @return 是否成功开始监听 |
| | | */ |
| | | - (BOOL)startNotifier; |
| | | |
| | | |
| | | /** |
| | | 结束监听连通性通知 |
| | | */ |
| | | - (void)stopNotifier; |
| | | |
| | | |
| | | /** |
| | | 当前连通性状态 |
| | | |
| | | @return NetworkStatus枚举值 |
| | | */ |
| | | - (BUNetWorkTypeCode)currentReachabilityStatus; |
| | | |
| | | /** |
| | | 是否需要连接。如WWAN需要首先建立一个可用连接才能被激活。WiFi可能需要一个VPN连接等 |
| | | |
| | | @return 是否需要连接 |
| | | */ |
| | | - (BOOL)connectionRequired; |
| | | |
| | | |
| | | /** |
| | | 获取 App 当前的网络权限设置状态 |
| | | |
| | | 因苹果尚未提供网络权限判断的 API,此方法目前只是在网络 NotReachable 时检查系统连接状态, |
| | | 利用排除法推断出 App 当前没有 蜂窝数据网络权限 或者 WIFI及蜂窝数据网络权限,排除原理参见 |
| | | https://wiki.bytedance.net/pages/viewpage.action?pageId=107808003 |
| | | |
| | | 在其它情况下(例如网络 Reachable 或者飞行模式)均返回 CantDetermined,上层业务调用方需注意 |
| | | |
| | | @return 参见 kBUNetworkAuthorizationStatus 定义 |
| | | */ |
| | | - (kBUNetworkAuthorizationStatus)currentNetworkAuthorizationStatus; |
| | | |
| | | @end |
| | | |
| | | |
| | | @interface BUReachability (Cellular) |
| | | |
| | | /** |
| | | 2G网络是否连通 |
| | | |
| | | @return 是否连通 |
| | | */ |
| | | + (BOOL)is2GConnected; |
| | | |
| | | /** |
| | | 3G网络是否连通 |
| | | |
| | | @return 是否连通 |
| | | */ |
| | | + (BOOL)is3GConnected; |
| | | |
| | | /** |
| | | 4G网络是否连通 |
| | | |
| | | @return 是否连通 |
| | | */ |
| | | + (BOOL)is4GConnected; |
| | | |
| | | |
| | | /** |
| | | 2017.5.22添加 |
| | | 借鉴微信方式判断当前网络是否连通 |
| | | |
| | | @return 网络是否可以联调 |
| | | */ |
| | | + (BOOL)isNetworkConnected; |
| | | |
| | | @end |
| | | |
| | | |
| | | |
New file |
| | |
| | | // |
| | | // BURexxarEngine.h |
| | | // BURexxar |
| | | // |
| | | // Created by muhuai on 2017/4/26. |
| | | // Copyright © 2017年 muhuai. All rights reserved. |
| | | // |
| | | |
| | | #import <Foundation/Foundation.h> |
| | | #import <UIKit/UIKit.h> |
| | | #import "BUStaticPlugin.h" |
| | | |
| | | @protocol BUJSBAuthorization; |
| | | @protocol BURexxarEngine <NSObject> |
| | | |
| | | @required |
| | | |
| | | /** |
| | | engine所在的ViewController, 提供JSBridge更多的上下文. 可为空. |
| | | */ |
| | | @property (nonatomic, weak) UIViewController *ttr_sourceController; |
| | | |
| | | /** |
| | | engine所挂载的静态plugin集合 |
| | | */ |
| | | @property (nonatomic, strong) BUStaticPlugin *ttr_staticPlugin; |
| | | |
| | | /** |
| | | engine当前页面地址 |
| | | */ |
| | | @property (nonatomic, strong, readonly) NSURL *ttr_url; |
| | | |
| | | @optional |
| | | /** |
| | | JSBridge授权器, 每个业务方可自行注入. 默认为nil, 全部public权限 |
| | | */ |
| | | @property (nonatomic, strong) id<BUJSBAuthorization> ttr_authorization; |
| | | |
| | | #pragma mark - Executing JavaScript |
| | | @required |
| | | |
| | | /** |
| | | 注入JavaScrip |
| | | |
| | | @param script 需要注入的script |
| | | @param completion 完成的回调 |
| | | */ |
| | | - (void)ttr_evaluateJavaScript:(NSString *)script completionHandler:(void (^)(id result, NSError *error))completion; |
| | | |
| | | |
| | | |
| | | /** |
| | | 对容器内发送通知 |
| | | |
| | | @param event 通知名称 |
| | | @param data 携带的信息 |
| | | */ |
| | | - (void)ttr_fireEvent:(NSString *)event data:(NSDictionary *)data; |
| | | @end |
New file |
| | |
| | | // |
| | | // BURexxarEngineFactory.h |
| | | // BURexxar |
| | | // |
| | | // Created by muhuai on 2017/5/5. |
| | | // Copyright © 2017年 muhuai. All rights reserved. |
| | | // |
| | | |
| | | #import <Foundation/Foundation.h> |
| | | #import "BURexxarEngine.h" |
| | | |
| | | @interface BURexxarEngineFactory : NSObject |
| | | |
| | | @end |
New file |
| | |
| | | // |
| | | // BUActionHelper.h |
| | | // BUAdSDK |
| | | // |
| | | // Created by carl on 2018/1/4. |
| | | // Copyright © 2018年 bytedance. All rights reserved. |
| | | // |
| | | |
| | | #import <Foundation/Foundation.h> |
| | | #import <UIKit/UIKit.h> |
| | | #import "UIViewController+BUUtilities.h" |
| | | |
| | | @interface BURouter : NSObject |
| | | + (void)pushFromViewController:(UIViewController *)fromVC toViewController:(UIViewController *)toVC; |
| | | @end |
New file |
| | |
| | | // |
| | | // BURuntimeUtil.h |
| | | // BUAdSDK |
| | | // |
| | | // Created by bytedance_yuanhuan on 2018/2/28. |
| | | // Copyright © 2018年 bytedance. All rights reserved. |
| | | // |
| | | |
| | | #import <Foundation/Foundation.h> |
| | | |
| | | @interface BURuntimeUtil : NSObject |
| | | |
| | | ///当originClass不存在originSEL时,该方法会自动添加一个imp为targetSEL的实现并替换targetSEL为原方法。调用该方法不需要再调用前做任何添加方法操作。 |
| | | + (void)exchangeClassSEL:(SEL)originClassSEL |
| | | originClass:(Class)originClass |
| | | targetClassSEL:(SEL)targetClassSEL |
| | | targetClass:(Class)targetClass; |
| | | |
| | | + (void)exchangeInstanceSEL:(SEL)originInstanceSEL |
| | | originClass:(Class)originClass |
| | | targetInstanceSEL:(SEL)targetInstanceSEL |
| | | targetClass:(Class)targetClass; |
| | | |
| | | + (void)exchangeClassSEL:(SEL)originClassSEL |
| | | targetClassSEL:(SEL)targetClassSEL |
| | | aClass:(Class)aClass; |
| | | |
| | | + (void)exchangeInstanceSEL:(SEL)originSEL |
| | | targetInstanceSEL:(SEL)targetSEL |
| | | aClass:(Class)aClass; |
| | | //判断当前类是否重写了方法 |
| | | + (BOOL)hasImpletionClass:(Class)targetClass sel:(SEL)sel; |
| | | @end |
New file |
| | |
| | | // |
| | | // BDUScreenHelp.h |
| | | // BUAdSDK |
| | | // |
| | | // Created by bytedance_yuanhuan on 2018/11/28. |
| | | // Copyright © 2018年 bytedance. All rights reserved. |
| | | // |
| | | |
| | | #import <Foundation/Foundation.h> |
| | | #import <UIKit/UIKit.h> |
| | | |
| | | //设备类型 |
| | | typedef NS_ENUM(NSInteger, BUDeviceMode) { |
| | | //iPad |
| | | BUDeviceModePad, |
| | | //iPhone6plus,iPhone6Splus |
| | | BUDeviceMode736, |
| | | //iPhone6,iPhone6S |
| | | BUDeviceMode667, |
| | | //iPhone5,iPhone5C,iPhone5S,iPhoneSE |
| | | BUDeviceMode568, |
| | | //iPhone4,iPhone4s |
| | | BUDeviceMode480, |
| | | //iPhoneX,iphoneXS |
| | | BUDeviceMode812, |
| | | //iphoneXR,iphoneRS Max |
| | | BUDeviceMode896 |
| | | }; |
| | | |
| | | NS_ASSUME_NONNULL_BEGIN |
| | | |
| | | @interface BUScreenHelper: NSObject |
| | | |
| | | /** |
| | | * 判断设备是iPhone4, iPhone4S |
| | | * |
| | | * @return Yes or No |
| | | */ |
| | | + (BOOL)is480Screen; |
| | | |
| | | /** |
| | | * 判断设备是iPhone5, iPhone5C, iPhone5S, iPhoneSE |
| | | * |
| | | * @return Yes or No |
| | | */ |
| | | + (BOOL)is568Screen; |
| | | |
| | | /** |
| | | * 判断设备是iPhone6,iPhone6S |
| | | * |
| | | * @return Yes or No |
| | | */ |
| | | + (BOOL)is667Screen; |
| | | |
| | | /** |
| | | * 判断设备是iPhone6plus, iPhone6Splus |
| | | * |
| | | * @return Yes or No |
| | | */ |
| | | + (BOOL)is736Screen; |
| | | // iphone6,iphone6 plus |
| | | |
| | | /** |
| | | * 判断设备是iPhoneX,iphoneXS |
| | | * |
| | | * @return Yes or No |
| | | */ |
| | | + (BOOL)is812Screen; |
| | | |
| | | /** |
| | | * 判断设备是iphoneXR,iphoneRS Max |
| | | * |
| | | * @return Yes or No |
| | | */ |
| | | + (BOOL)is896Screen; |
| | | |
| | | /** |
| | | * 判断设备的宽度大于320 |
| | | * |
| | | * @return Yes or No |
| | | */ |
| | | + (BOOL)isScreenWidthLarge320; |
| | | |
| | | /** |
| | | * 判断设备是iPad |
| | | * |
| | | * @return Yes or No |
| | | */ |
| | | + (BOOL)isPadDevice; |
| | | |
| | | /** |
| | | * 判断设备是iPad pro |
| | | * |
| | | * @return Yes or No |
| | | */ |
| | | + (BOOL)isIpadProDevice; |
| | | |
| | | /** |
| | | * 获取设备类型 |
| | | * |
| | | * @return BUDeviceType类型 |
| | | */ |
| | | + (BUDeviceMode)getDeviceType; |
| | | |
| | | /** |
| | | * 分辨率,区分横竖屏,形如@"414*736" |
| | | * @return 横竖屏返回样式,横屏样式@"736*414",竖屏样式@"414*736" |
| | | */ |
| | | + (nullable NSString *)resolutionString; |
| | | |
| | | /** |
| | | * 分辨率,区分横竖屏,形如@"414x736" |
| | | * @return 横竖屏返回样式,横屏样式@"736x414",竖屏样式@"414x736" |
| | | */ |
| | | + (NSString *)displayDensity; |
| | | |
| | | @end |
| | | |
| | | NS_ASSUME_NONNULL_END |
New file |
| | |
| | | // |
| | | // BUStaticPlugin.h |
| | | // BURexxar |
| | | // |
| | | // Created by muhuai on 2017/4/27. |
| | | // Copyright © 2017年 muhuai. All rights reserved. |
| | | // |
| | | |
| | | #import <Foundation/Foundation.h> |
| | | #import "BUJSBDefine.h" |
| | | #import "BUJSBCommand.h" |
| | | |
| | | @protocol BURexxarEngine; |
| | | |
| | | typedef void(^BUJSBStaticHandler)(NSDictionary *params, BUJSBResponse completion); |
| | | |
| | | @interface BUStaticPlugin : NSObject |
| | | |
| | | - (void)registerHandlerBlock:(BUJSBStaticHandler)handler forMethodName:(NSString*)method; |
| | | |
| | | - (BOOL)callHandlerWithCommand:(BUJSBCommand *)command engine:(id<BURexxarEngine>)engine completion:(BUJSBResponse)completion; |
| | | @end |
New file |
| | |
| | | // |
| | | // BUTLocationService.h |
| | | // BUAdSDK |
| | | // |
| | | // Created by carl on 2017/8/17. |
| | | // Copyright © 2017年 bytedance. All rights reserved. |
| | | // |
| | | |
| | | #import <Foundation/Foundation.h> |
| | | #import "BUGeo.h" |
| | | |
| | | @interface BUTLocationService : NSObject |
| | | |
| | | @property (nonatomic, strong, readonly) BUGeo *geo; |
| | | + (instancetype)locationService; |
| | | - (void)requestLatestStatus; |
| | | @end |
New file |
| | |
| | | |
| | | // BUThreadSafeDictionary.h |
| | | // Created by Siwant on 2018/1/22. |
| | | // Copyright © 2018年 bytedance. All rights reserved. |
| | | |
| | | #import <Foundation/Foundation.h> |
| | | |
| | | @interface BUThreadSafeDictionary: NSMutableDictionary |
| | | - (id)objectForKey:(id <NSCopying>)aKey; |
| | | - (id)valueForKey:(id)aKey; |
| | | - (void)setObject:(id)object forKey:(id <NSCopying>)aKey; |
| | | - (void)setValue:(id)value forKey:(NSString *)key; |
| | | - (void)removeAllObjects; |
| | | - (void)removeObjectForKey:(id <NSCopying>)aKey; |
| | | - (NSDictionary *)dictionary; |
| | | - (NSArray *)allKeys; |
| | | - (NSArray *)allValues; |
| | | - (void)removeObjectsForKeys:(NSArray *)keyArray; |
| | | @end |
New file |
| | |
| | | // |
| | | // BUThreadSafeMutableArray.h |
| | | // BUAdSDK |
| | | // |
| | | // Created by 李盛 on 2019/1/3. |
| | | // Copyright © 2019 bytedance. All rights reserved. |
| | | // |
| | | |
| | | #import <Foundation/Foundation.h> |
| | | |
| | | NS_ASSUME_NONNULL_BEGIN |
| | | |
| | | @interface BUThreadSafeMutableArray : NSMutableArray |
| | | |
| | | @end |
| | | |
| | | NS_ASSUME_NONNULL_END |
New file |
| | |
| | | // |
| | | // BUTimer.h |
| | | // BUAdSDK |
| | | // |
| | | // Created by 李盛 on 2018/6/20. |
| | | // Copyright © 2018年 bytedance. All rights reserved. |
| | | // |
| | | |
| | | #import <Foundation/Foundation.h> |
| | | |
| | | @interface BUTimer : NSObject |
| | | |
| | | @property (nonatomic, copy) NSString *runLoopMode; |
| | | |
| | | + (BUTimer *)timerWithTimeInterval:(NSTimeInterval)seconds |
| | | target:(id)target |
| | | selector:(SEL)aSelector |
| | | repeats:(BOOL)repeats; |
| | | |
| | | - (BOOL)isValid; |
| | | - (void)invalidate; |
| | | - (BOOL)isScheduled; |
| | | - (BOOL)scheduleNow; |
| | | - (BOOL)pause; |
| | | - (BOOL)resume; |
| | | - (NSTimeInterval)initialTimeInterval; |
| | | |
| | | @end |
New file |
| | |
| | | // |
| | | // BUUIResponderHelper.h |
| | | // BUSDKProject |
| | | // |
| | | // Created by ranny_90 on 2017/5/20. |
| | | // Copyright © 2017年 ranny_90. All rights reserved. |
| | | // |
| | | |
| | | #import <Foundation/Foundation.h> |
| | | #import <UIKit/UIKit.h> |
| | | |
| | | NS_ASSUME_NONNULL_BEGIN |
| | | |
| | | @interface BUUIResponderHelper : NSObject |
| | | |
| | | // 获取当前应用的广义mainWindow |
| | | + (nullable UIWindow *)mainWindow; |
| | | |
| | | // 获取广义mainWindow的rootViewController |
| | | + (nullable UIViewController*)mainWindowRootViewController; |
| | | |
| | | // 广义mainWindow的大小(兼容iOS7) |
| | | + (CGSize)windowSize; |
| | | |
| | | |
| | | // 获取指定UIResponder的链下游第一个ViewController对象 |
| | | + (nullable UIViewController*)nextViewControllerFor:(UIResponder* _Nullable)responder; |
| | | |
| | | // 获取指定UIResponder的链下游第一个UINavigationController对象 |
| | | + (nullable UINavigationController*)nextNavigationControllerFor:(UIResponder* _Nullable)responder; |
| | | |
| | | @end |
| | | |
| | | NS_ASSUME_NONNULL_END |
New file |
| | |
| | | // |
| | | // BUWKWebView.h |
| | | // BURexxar |
| | | // |
| | | // Created by muhuai on 2017/5/5. |
| | | // Copyright © 2017年 muhuai. All rights reserved. |
| | | // |
| | | |
| | | #import <Foundation/Foundation.h> |
| | | #import <WebKit/WebKit.h> |
| | | #import "BUWebViewDefine.h" |
| | | |
| | | @interface BUWKWebView : WKWebView<BUWebView> |
| | | /// 白屏检测 |
| | | - (void)bu_detectBlankWebViewCompleteBlock:(void(^)(BOOL, NSError *))block; |
| | | |
| | | /// 白屏检测百分比 |
| | | - (void)bu_detectBlankPercentCompleteBlock:(void(^)(CGFloat bgColorPercent, NSError *error))block; |
| | | @end |
New file |
| | |
| | | // |
| | | // BUJSApplication.h |
| | | // BURexxar |
| | | // |
| | | // Created by muhuai on 2017/4/26. |
| | | // Copyright © 2017年 muhuai. All rights reserved. |
| | | // |
| | | |
| | | #import <Foundation/Foundation.h> |
| | | #import <UIKit/UIKit.h> |
| | | |
| | | #import "BURexxarEngine.h" |
| | | #import "BUWebViewDefine.h" |
| | | |
| | | extern NSString *const kBUBytedanceScheme; |
| | | extern NSString *const kBUBytedanceDomReadyHost; |
| | | |
| | | @interface BUWebViewApplication : NSObject |
| | | |
| | | |
| | | + (BOOL)handleRequest:(NSURLRequest *)request withWebView:(UIView<BUWebView> *)webView viewController:(UIViewController *)viewController; |
| | | |
| | | + (void)fireEvent:(NSString *)eventName data:(NSDictionary *)data withWebView:(UIView<BUWebView> *)webview; |
| | | |
| | | /** |
| | | 注册JSBridge别名 |
| | | @warning 会优先查找别名 |
| | | @param alias 新名 |
| | | @param orig 原名 |
| | | */ |
| | | + (void)registeJSBAlias:(NSString *)alias for:(NSString *)orig; |
| | | @end |
New file |
| | |
| | | // |
| | | // BUWebViewDefine.h |
| | | // BURexxar |
| | | // |
| | | // Created by muhuai on 2017/5/17. |
| | | // Copyright © 2017年 muhuai. All rights reserved. |
| | | // |
| | | |
| | | #import <Foundation/Foundation.h> |
| | | #import <UIKit/UIKit.h> |
| | | #import "BURexxarEngine.h" |
| | | #import "BUJSInjector.h" |
| | | |
| | | typedef NS_ENUM(NSInteger, BUWebViewNavigationType) { |
| | | BUWebViewNavigationTypeLinkClicked, |
| | | BUWebViewNavigationTypeFormSubmitted, |
| | | BUWebViewNavigationTypeBackForward, |
| | | BUWebViewNavigationTypeReload, |
| | | BUWebViewNavigationTypeFormResubmitted, |
| | | BUWebViewNavigationTypeOther |
| | | }; |
| | | |
| | | @protocol BUWebView; |
| | | |
| | | @protocol BUWebViewDelegate <NSObject> |
| | | |
| | | @optional |
| | | - (BOOL)webView:(UIView<BUWebView> *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(BUWebViewNavigationType)navigationType; |
| | | |
| | | - (void)webViewDidStartLoad:(UIView<BUWebView> *)webView; |
| | | |
| | | - (void)webViewDidFinishLoad:(UIView<BUWebView> *)webView; |
| | | |
| | | - (void)webView:(UIView<BUWebView> *)webView didFailLoadWithError:(NSError *)error; |
| | | |
| | | - (void)webViewWebContentProcessDidTerminate:(UIView<BUWebView> *)webView API_AVAILABLE(macosx(10.11), ios(9.0)); |
| | | |
| | | //二方页面有 domReady回调 |
| | | - (void)webViewDomReady:(UIView<BUWebView> *)webView; |
| | | @end |
| | | |
| | | |
| | | /** |
| | | BUWKWebView 都会实现此协议, 用来对平两个容器之间API的差异 |
| | | */ |
| | | @protocol BUWebView <BURexxarEngine> |
| | | |
| | | @property (nonatomic, strong ,readonly) UIScrollView *ttr_scrollView; |
| | | |
| | | /** |
| | | JS脚本注入器 使用说明见:BUJSInjector.h |
| | | */ |
| | | @property (nonatomic, strong, readonly) BUJSInjector *ttr_injector; |
| | | #pragma mark - Loading Content |
| | | |
| | | - (void)ttr_loadRequest:(NSURLRequest *)request; |
| | | |
| | | - (void)ttr_loadHTMLString:(NSString *)string baseURL:(NSURL *)baseURL; |
| | | |
| | | |
| | | /** |
| | | WK下特有的方法 |
| | | |
| | | @param URL 本地文件URL, 注意需要为file:// |
| | | @param readAccessURL WK下可以指定获取一个本地目录的权限 |
| | | */ |
| | | - (void)ttr_loadFileURL:(NSURL *)URL allowingReadAccessToURL:(NSURL *)readAccessURL; |
| | | |
| | | - (void)ttr_stopLoading; |
| | | |
| | | - (void)ttr_reload; |
| | | |
| | | #pragma mark - Moving Back and Forward |
| | | - (BOOL)ttr_canGoBack; |
| | | |
| | | - (BOOL)ttr_canGoForward; |
| | | |
| | | - (void)ttr_goBack; |
| | | |
| | | - (void)ttr_goForward; |
| | | |
| | | |
| | | #pragma mark - Multi Delegate |
| | | /** |
| | | BUWKWebView内部实现成多路代理, 按注册的顺序来依次询问. |
| | | |
| | | @param delegate webview代理 |
| | | */ |
| | | - (void)ttr_addDelegate:(id<BUWebViewDelegate>)delegate; |
| | | |
| | | /** |
| | | 移除指定代理 |
| | | |
| | | @param delegate 需要移除的代理 |
| | | */ |
| | | - (void)ttr_removeDelegate:(id<BUWebViewDelegate>)delegate; |
| | | |
| | | /** |
| | | 移除所有代理 |
| | | */ |
| | | - (void)ttr_removeAllDelegate; |
| | | @end |
| | | |
New file |
| | |
| | | // |
| | | // BUWebViewProgressView.h |
| | | // BURexxar |
| | | // |
| | | // Created by muhuai on 2017/6/13. |
| | | // Copyright © 2017年 muhuai. All rights reserved. |
| | | // |
| | | |
| | | #import "BUWebViewDefine.h" |
| | | |
| | | #import <UIKit/UIKit.h> |
| | | #import <WebKit/WebKit.h> |
| | | |
| | | |
| | | /** |
| | | 假进度条 |
| | | 使用方法: |
| | | 1.addSubView到 WebView中 |
| | | 2.通过多路代理将此控件设为其中一个子代理 |
| | | */ |
| | | @interface BUWebViewProgressView : UIView<BUWebViewDelegate> |
| | | |
| | | @property (nonatomic, strong) UIColor *lineFillColor; |
| | | |
| | | @end |
New file |
| | |
| | | // BU_AFAutoPurgingImageCache.h |
| | | // Copyright (c) 2011–2016 Alamofire Software Foundation ( http://alamofire.org/ ) |
| | | // |
| | | // Permission is hereby granted, free of charge, to any person obtaining a copy |
| | | // of this software and associated documentation files (the "Software"), to deal |
| | | // in the Software without restriction, including without limitation the rights |
| | | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
| | | // copies of the Software, and to permit persons to whom the Software is |
| | | // furnished to do so, subject to the following conditions: |
| | | // |
| | | // The above copyright notice and this permission notice shall be included in |
| | | // all copies or substantial portions of the Software. |
| | | // |
| | | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
| | | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
| | | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
| | | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
| | | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
| | | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
| | | // THE SOFTWARE. |
| | | |
| | | #import <TargetConditionals.h> |
| | | #import <Foundation/Foundation.h> |
| | | |
| | | #if TARGET_OS_IOS || TARGET_OS_TV |
| | | #import <UIKit/UIKit.h> |
| | | |
| | | NS_ASSUME_NONNULL_BEGIN |
| | | |
| | | /** |
| | | The `BU_AFImageCache` protocol defines a set of APIs for adding, removing and fetching images from a cache synchronously. |
| | | */ |
| | | @protocol BU_AFImageCache <NSObject> |
| | | |
| | | /** |
| | | Adds the image to the cache with the given identifier. |
| | | |
| | | @param image The image to cache. |
| | | @param identifier The unique identifier for the image in the cache. |
| | | */ |
| | | - (void)addImage:(NSData *)image withIdentifier:(NSString *)identifier; |
| | | |
| | | /** |
| | | Removes the image from the cache matching the given identifier. |
| | | |
| | | @param identifier The unique identifier for the image in the cache. |
| | | |
| | | @return A BOOL indicating whether or not the image was removed from the cache. |
| | | */ |
| | | - (BOOL)removeImageWithIdentifier:(NSString *)identifier; |
| | | |
| | | /** |
| | | Removes all images from the cache. |
| | | |
| | | @return A BOOL indicating whether or not all images were removed from the cache. |
| | | */ |
| | | - (BOOL)removeAllImages; |
| | | |
| | | /** |
| | | Returns the image in the cache associated with the given identifier. |
| | | |
| | | @param identifier The unique identifier for the image in the cache. |
| | | |
| | | @return An image for the matching identifier, or nil. |
| | | */ |
| | | - (nullable NSData *)imageWithIdentifier:(NSString *)identifier; |
| | | @end |
| | | |
| | | |
| | | /** |
| | | The `ImageRequestCache` protocol extends the `ImageCache` protocol by adding methods for adding, removing and fetching images from a cache given an `NSURLRequest` and additional identifier. |
| | | */ |
| | | @protocol BU_AFImageRequestCache <BU_AFImageCache> |
| | | |
| | | /** |
| | | Adds the image to the cache using an identifier created from the request and additional identifier. |
| | | |
| | | @param image The image to cache. |
| | | @param request The unique URL request identifing the image asset. |
| | | @param identifier The additional identifier to apply to the URL request to identify the image. |
| | | */ |
| | | - (void)addImage:(NSData *)image forRequest:(NSURLRequest *)request withAdditionalIdentifier:(nullable NSString *)identifier; |
| | | |
| | | /** |
| | | Removes the image from the cache using an identifier created from the request and additional identifier. |
| | | |
| | | @param request The unique URL request identifing the image asset. |
| | | @param identifier The additional identifier to apply to the URL request to identify the image. |
| | | |
| | | @return A BOOL indicating whether or not all images were removed from the cache. |
| | | */ |
| | | - (BOOL)removeImageforRequest:(NSURLRequest *)request withAdditionalIdentifier:(nullable NSString *)identifier; |
| | | |
| | | /** |
| | | Returns the image from the cache associated with an identifier created from the request and additional identifier. |
| | | |
| | | @param request The unique URL request identifing the image asset. |
| | | @param identifier The additional identifier to apply to the URL request to identify the image. |
| | | |
| | | @return An image for the matching request and identifier, or nil. |
| | | */ |
| | | - (nullable NSData *)imageforRequest:(NSURLRequest *)request withAdditionalIdentifier:(nullable NSString *)identifier; |
| | | |
| | | @end |
| | | |
| | | /** |
| | | The `AutoPurgingImageCache` in an in-memory image cache used to store images up to a given memory capacity. When the memory capacity is reached, the image cache is sorted by last access date, then the oldest image is continuously purged until the preferred memory usage after purge is met. Each time an image is accessed through the cache, the internal access date of the image is updated. |
| | | */ |
| | | @interface BU_AFAutoPurgingImageCache : NSObject <BU_AFImageRequestCache> |
| | | |
| | | /** |
| | | The total memory capacity of the cache in bytes. |
| | | */ |
| | | @property (nonatomic, assign) UInt64 memoryCapacity; |
| | | |
| | | /** |
| | | The preferred memory usage after purge in bytes. During a purge, images will be purged until the memory capacity drops below this limit. |
| | | */ |
| | | @property (nonatomic, assign) UInt64 preferredMemoryUsageAfterPurge; |
| | | |
| | | /** |
| | | The current total memory usage in bytes of all images stored within the cache. |
| | | */ |
| | | @property (nonatomic, assign, readonly) UInt64 memoryUsage; |
| | | |
| | | /** |
| | | Initialies the `AutoPurgingImageCache` instance with default values for memory capacity and preferred memory usage after purge limit. `memoryCapcity` defaults to `100 MB`. `preferredMemoryUsageAfterPurge` defaults to `60 MB`. |
| | | |
| | | @return The new `AutoPurgingImageCache` instance. |
| | | */ |
| | | - (instancetype)init; |
| | | |
| | | /** |
| | | Initialies the `AutoPurgingImageCache` instance with the given memory capacity and preferred memory usage |
| | | after purge limit. |
| | | |
| | | @param memoryCapacity The total memory capacity of the cache in bytes. |
| | | @param preferredMemoryCapacity The preferred memory usage after purge in bytes. |
| | | |
| | | @return The new `AutoPurgingImageCache` instance. |
| | | */ |
| | | - (instancetype)initWithMemoryCapacity:(UInt64)memoryCapacity preferredMemoryCapacity:(UInt64)preferredMemoryCapacity; |
| | | |
| | | @end |
| | | |
| | | NS_ASSUME_NONNULL_END |
| | | |
| | | #endif |
| | | |
New file |
| | |
| | | // BU_AFHTTPSessionManager.h |
| | | // Copyright (c) 2011–2016 Alamofire Software Foundation ( http://alamofire.org/ ) |
| | | // |
| | | // Permission is hereby granted, free of charge, to any person obtaining a copy |
| | | // of this software and associated documentation files (the "Software"), to deal |
| | | // in the Software without restriction, including without limitation the rights |
| | | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
| | | // copies of the Software, and to permit persons to whom the Software is |
| | | // furnished to do so, subject to the following conditions: |
| | | // |
| | | // The above copyright notice and this permission notice shall be included in |
| | | // all copies or substantial portions of the Software. |
| | | // |
| | | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
| | | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
| | | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
| | | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
| | | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
| | | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
| | | // THE SOFTWARE. |
| | | |
| | | #import <Foundation/Foundation.h> |
| | | #if !TARGET_OS_WATCH |
| | | #import <SystemConfiguration/SystemConfiguration.h> |
| | | #endif |
| | | #import <TargetConditionals.h> |
| | | |
| | | #if TARGET_OS_IOS || TARGET_OS_WATCH || TARGET_OS_TV |
| | | #import <MobileCoreServices/MobileCoreServices.h> |
| | | #else |
| | | #import <CoreServices/CoreServices.h> |
| | | #endif |
| | | |
| | | #import "BU_AFURLSessionManager.h" |
| | | |
| | | /** |
| | | `BU_AFHTTPSessionManager` is a subclass of `BU_AFURLSessionManager` with convenience methods for making HTTP requests. When a `baseURL` is provided, requests made with the `GET` / `POST` / et al. convenience methods can be made with relative paths. |
| | | |
| | | ## Subclassing Notes |
| | | |
| | | Developers targeting iOS 7 or Mac OS X 10.9 or later that deal extensively with a web service are encouraged to subclass `BU_AFHTTPSessionManager`, providing a class method that returns a shared singleton object on which authentication and other configuration can be shared across the application. |
| | | |
| | | For developers targeting iOS 6 or Mac OS X 10.8 or earlier, `AFHTTPRequestOperationManager` may be used to similar effect. |
| | | |
| | | ## Methods to Override |
| | | |
| | | To change the behavior of all data task operation construction, which is also used in the `GET` / `POST` / et al. convenience methods, override `dataTaskWithRequest:uploadProgress:downloadProgress:completionHandler:`. |
| | | |
| | | ## Serialization |
| | | |
| | | Requests created by an HTTP client will contain default headers and encode parameters according to the `requestSerializer` property, which is an object conforming to `<BU_AFURLRequestSerialization>`. |
| | | |
| | | Responses received from the server are automatically validated and serialized by the `responseSerializers` property, which is an object conforming to `<BU_AFURLResponseSerialization>` |
| | | |
| | | ## URL Construction Using Relative Paths |
| | | |
| | | For HTTP convenience methods, the request serializer constructs URLs from the path relative to the `-baseURL`, using `NSURL +URLWithString:relativeToURL:`, when provided. If `baseURL` is `nil`, `path` needs to resolve to a valid `NSURL` object using `NSURL +URLWithString:`. |
| | | |
| | | Below are a few examples of how `baseURL` and relative paths interact: |
| | | |
| | | NSURL *baseURL = [NSURL URLWithString:@"http://example.com/v1/"]; |
| | | [NSURL URLWithString:@"foo" relativeToURL:baseURL]; // http://example.com/v1/foo |
| | | [NSURL URLWithString:@"foo?bar=baz" relativeToURL:baseURL]; // http://example.com/v1/foo?bar=baz |
| | | [NSURL URLWithString:@"/foo" relativeToURL:baseURL]; // http://example.com/foo |
| | | [NSURL URLWithString:@"foo/" relativeToURL:baseURL]; // http://example.com/v1/foo |
| | | [NSURL URLWithString:@"/foo/" relativeToURL:baseURL]; // http://example.com/foo/ |
| | | [NSURL URLWithString:@"http://example2.com/" relativeToURL:baseURL]; // http://example2.com/ |
| | | |
| | | Also important to note is that a trailing slash will be added to any `baseURL` without one. This would otherwise cause unexpected behavior when constructing URLs using paths without a leading slash. |
| | | |
| | | @warning Managers for background sessions must be owned for the duration of their use. This can be accomplished by creating an application-wide or shared singleton instance. |
| | | */ |
| | | |
| | | NS_ASSUME_NONNULL_BEGIN |
| | | |
| | | @interface BU_AFHTTPSessionManager : BU_AFURLSessionManager <NSSecureCoding, NSCopying> |
| | | |
| | | /** |
| | | The URL used to construct requests from relative paths in methods like `requestWithMethod:URLString:parameters:`, and the `GET` / `POST` / et al. convenience methods. |
| | | */ |
| | | @property (readonly, nonatomic, strong, nullable) NSURL *baseURL; |
| | | |
| | | /** |
| | | Requests created with `requestWithMethod:URLString:parameters:` & `multipartFormRequestWithMethod:URLString:parameters:constructingBodyWithBlock:` are constructed with a set of default headers using a parameter serialization specified by this property. By default, this is set to an instance of `BU_AFHTTPRequestSerializer`, which serializes query string parameters for `GET`, `HEAD`, and `DELETE` requests, or otherwise URL-form-encodes HTTP message bodies. |
| | | |
| | | @warning `requestSerializer` must not be `nil`. |
| | | */ |
| | | @property (nonatomic, strong) BU_AFHTTPRequestSerializer <BU_AFURLRequestSerialization> * requestSerializer; |
| | | |
| | | /** |
| | | Responses sent from the server in data tasks created with `dataTaskWithRequest:success:failure:` and run using the `GET` / `POST` / et al. convenience methods are automatically validated and serialized by the response serializer. By default, this property is set to an instance of `BU_AFJSONResponseSerializer`. |
| | | |
| | | @warning `responseSerializer` must not be `nil`. |
| | | */ |
| | | @property (nonatomic, strong) BU_AFHTTPResponseSerializer <BU_AFURLResponseSerialization> * responseSerializer; |
| | | |
| | | ///------------------------------- |
| | | /// @name Managing Security Policy |
| | | ///------------------------------- |
| | | |
| | | /** |
| | | The security policy used by created session to evaluate server trust for secure connections. `BU_AFURLSessionManager` uses the `defaultPolicy` unless otherwise specified. A security policy configured with `BU_AFSSLPinningModePublicKey` or `BU_AFSSLPinningModeCertificate` can only be applied on a session manager initialized with a secure base URL (i.e. https). Applying a security policy with pinning enabled on an insecure session manager throws an `Invalid Security Policy` exception. |
| | | */ |
| | | @property (nonatomic, strong) BU_AFSecurityPolicy *securityPolicy; |
| | | |
| | | ///--------------------- |
| | | /// @name Initialization |
| | | ///--------------------- |
| | | |
| | | /** |
| | | Creates and returns an `BU_AFHTTPSessionManager` object. |
| | | */ |
| | | + (instancetype)manager; |
| | | |
| | | /** |
| | | Initializes an `BU_AFHTTPSessionManager` object with the specified base URL. |
| | | |
| | | @param url The base URL for the HTTP client. |
| | | |
| | | @return The newly-initialized HTTP client |
| | | */ |
| | | - (instancetype)initWithBaseURL:(nullable NSURL *)url; |
| | | |
| | | /** |
| | | Initializes an `BU_AFHTTPSessionManager` object with the specified base URL. |
| | | |
| | | This is the designated initializer. |
| | | |
| | | @param url The base URL for the HTTP client. |
| | | @param configuration The configuration used to create the managed session. |
| | | |
| | | @return The newly-initialized HTTP client |
| | | */ |
| | | - (instancetype)initWithBaseURL:(nullable NSURL *)url |
| | | sessionConfiguration:(nullable NSURLSessionConfiguration *)configuration NS_DESIGNATED_INITIALIZER; |
| | | |
| | | ///--------------------------- |
| | | /// @name Making HTTP Requests |
| | | ///--------------------------- |
| | | |
| | | /** |
| | | Creates and runs an `NSURLSessionDataTask` with a `GET` request. |
| | | |
| | | @param URLString The URL string used to create the request URL. |
| | | @param parameters The parameters to be encoded according to the client request serializer. |
| | | @param success A block object to be executed when the task finishes successfully. This block has no return value and takes two arguments: the data task, and the response object created by the client response serializer. |
| | | @param failure A block object to be executed when the task finishes unsuccessfully, or that finishes successfully, but encountered an error while parsing the response data. This block has no return value and takes a two arguments: the data task and the error describing the network or parsing error that occurred. |
| | | |
| | | @see -dataTaskWithRequest:completionHandler: |
| | | */ |
| | | - (nullable NSURLSessionDataTask *)GET:(NSString *)URLString |
| | | parameters:(nullable id)parameters |
| | | success:(nullable void (^)(NSURLSessionDataTask *task, id _Nullable responseObject))success |
| | | failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure DEPRECATED_ATTRIBUTE; |
| | | |
| | | |
| | | /** |
| | | Creates and runs an `NSURLSessionDataTask` with a `GET` request. |
| | | |
| | | @param URLString The URL string used to create the request URL. |
| | | @param parameters The parameters to be encoded according to the client request serializer. |
| | | @param downloadProgress A block object to be executed when the download progress is updated. Note this block is called on the session queue, not the main queue. |
| | | @param success A block object to be executed when the task finishes successfully. This block has no return value and takes two arguments: the data task, and the response object created by the client response serializer. |
| | | @param failure A block object to be executed when the task finishes unsuccessfully, or that finishes successfully, but encountered an error while parsing the response data. This block has no return value and takes a two arguments: the data task and the error describing the network or parsing error that occurred. |
| | | |
| | | @see -dataTaskWithRequest:uploadProgress:downloadProgress:completionHandler: |
| | | */ |
| | | - (nullable NSURLSessionDataTask *)GET:(NSString *)URLString |
| | | parameters:(nullable id)parameters |
| | | progress:(nullable void (^)(NSProgress *downloadProgress))downloadProgress |
| | | success:(nullable void (^)(NSURLSessionDataTask *task, id _Nullable responseObject))success |
| | | failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure; |
| | | |
| | | |
| | | /** |
| | | Creates and runs an `NSURLSessionDataTask` with a `POST` request. |
| | | |
| | | @param URLString The URL string used to create the request URL. |
| | | @param parameters The parameters to be encoded according to the client request serializer. |
| | | @param success A block object to be executed when the task finishes successfully. This block has no return value and takes two arguments: the data task, and the response object created by the client response serializer. |
| | | @param failure A block object to be executed when the task finishes unsuccessfully, or that finishes successfully, but encountered an error while parsing the response data. This block has no return value and takes a two arguments: the data task and the error describing the network or parsing error that occurred. |
| | | |
| | | @see -dataTaskWithRequest:completionHandler: |
| | | */ |
| | | - (nullable NSURLSessionDataTask *)POST:(NSString *)URLString |
| | | parameters:(nullable id)parameters |
| | | success:(nullable void (^)(NSURLSessionDataTask *task, id _Nullable responseObject))success |
| | | failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure DEPRECATED_ATTRIBUTE; |
| | | |
| | | /** |
| | | Creates and runs an `NSURLSessionDataTask` with a `POST` request. |
| | | |
| | | @param URLString The URL string used to create the request URL. |
| | | @param parameters The parameters to be encoded according to the client request serializer. |
| | | @param uploadProgress A block object to be executed when the upload progress is updated. Note this block is called on the session queue, not the main queue. |
| | | @param success A block object to be executed when the task finishes successfully. This block has no return value and takes two arguments: the data task, and the response object created by the client response serializer. |
| | | @param failure A block object to be executed when the task finishes unsuccessfully, or that finishes successfully, but encountered an error while parsing the response data. This block has no return value and takes a two arguments: the data task and the error describing the network or parsing error that occurred. |
| | | |
| | | @see -dataTaskWithRequest:uploadProgress:downloadProgress:completionHandler: |
| | | */ |
| | | - (nullable NSURLSessionDataTask *)POST:(NSString *)URLString |
| | | parameters:(nullable id)parameters |
| | | progress:(nullable void (^)(NSProgress *uploadProgress))uploadProgress |
| | | success:(nullable void (^)(NSURLSessionDataTask *task, id _Nullable responseObject))success |
| | | failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure; |
| | | |
| | | /** |
| | | Creates and runs an `NSURLSessionDataTask` with a multipart `POST` request. |
| | | |
| | | @param URLString The URL string used to create the request URL. |
| | | @param parameters The parameters to be encoded according to the client request serializer. |
| | | @param block A block that takes a single argument and appends data to the HTTP body. The block argument is an object adopting the `BU_AFMultipartFormData` protocol. |
| | | @param success A block object to be executed when the task finishes successfully. This block has no return value and takes two arguments: the data task, and the response object created by the client response serializer. |
| | | @param failure A block object to be executed when the task finishes unsuccessfully, or that finishes successfully, but encountered an error while parsing the response data. This block has no return value and takes a two arguments: the data task and the error describing the network or parsing error that occurred. |
| | | |
| | | @see -dataTaskWithRequest:completionHandler: |
| | | */ |
| | | - (nullable NSURLSessionDataTask *)POST:(NSString *)URLString |
| | | parameters:(nullable id)parameters |
| | | constructingBodyWithBlock:(nullable void (^)(id <BU_AFMultipartFormData> formData))block |
| | | success:(nullable void (^)(NSURLSessionDataTask *task, id _Nullable responseObject))success |
| | | failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure DEPRECATED_ATTRIBUTE; |
| | | |
| | | /** |
| | | Creates and runs an `NSURLSessionDataTask` with a multipart `POST` request. |
| | | |
| | | @param URLString The URL string used to create the request URL. |
| | | @param parameters The parameters to be encoded according to the client request serializer. |
| | | @param block A block that takes a single argument and appends data to the HTTP body. The block argument is an object adopting the `BU_AFMultipartFormData` protocol. |
| | | @param uploadProgress A block object to be executed when the upload progress is updated. Note this block is called on the session queue, not the main queue. |
| | | @param success A block object to be executed when the task finishes successfully. This block has no return value and takes two arguments: the data task, and the response object created by the client response serializer. |
| | | @param failure A block object to be executed when the task finishes unsuccessfully, or that finishes successfully, but encountered an error while parsing the response data. This block has no return value and takes a two arguments: the data task and the error describing the network or parsing error that occurred. |
| | | |
| | | @see -dataTaskWithRequest:uploadProgress:downloadProgress:completionHandler: |
| | | */ |
| | | - (nullable NSURLSessionDataTask *)POST:(NSString *)URLString |
| | | parameters:(nullable id)parameters |
| | | constructingBodyWithBlock:(nullable void (^)(id <BU_AFMultipartFormData> formData))block |
| | | progress:(nullable void (^)(NSProgress *uploadProgress))uploadProgress |
| | | success:(nullable void (^)(NSURLSessionDataTask *task, id _Nullable responseObject))success |
| | | failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure; |
| | | |
| | | @end |
| | | |
| | | NS_ASSUME_NONNULL_END |
New file |
| | |
| | | // BU_AFSecurityPolicy.h |
| | | // Copyright (c) 2011–2016 Alamofire Software Foundation ( http://alamofire.org/ ) |
| | | // |
| | | // Permission is hereby granted, free of charge, to any person obtaining a copy |
| | | // of this software and associated documentation files (the "Software"), to deal |
| | | // in the Software without restriction, including without limitation the rights |
| | | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
| | | // copies of the Software, and to permit persons to whom the Software is |
| | | // furnished to do so, subject to the following conditions: |
| | | // |
| | | // The above copyright notice and this permission notice shall be included in |
| | | // all copies or substantial portions of the Software. |
| | | // |
| | | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
| | | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
| | | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
| | | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
| | | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
| | | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
| | | // THE SOFTWARE. |
| | | |
| | | #import <Foundation/Foundation.h> |
| | | #import <Security/Security.h> |
| | | |
| | | typedef NS_ENUM(NSUInteger, BU_AFSSLPinningMode) { |
| | | BU_AFSSLPinningModeNone, |
| | | BU_AFSSLPinningModePublicKey, |
| | | BU_AFSSLPinningModeCertificate, |
| | | }; |
| | | |
| | | /** |
| | | `BU_AFSecurityPolicy` evaluates server trust against pinned X.509 certificates and public keys over secure connections. |
| | | |
| | | Adding pinned SSL certificates to your app helps prevent man-in-the-middle attacks and other vulnerabilities. Applications dealing with sensitive customer data or financial information are strongly encouraged to route all communication over an HTTPS connection with SSL pinning configured and enabled. |
| | | */ |
| | | |
| | | NS_ASSUME_NONNULL_BEGIN |
| | | |
| | | @interface BU_AFSecurityPolicy : NSObject <NSSecureCoding, NSCopying> |
| | | |
| | | /** |
| | | The criteria by which server trust should be evaluated against the pinned SSL certificates. Defaults to `BU_AFSSLPinningModeNone`. |
| | | */ |
| | | @property (readonly, nonatomic, assign) BU_AFSSLPinningMode SSLPinningMode; |
| | | |
| | | /** |
| | | The certificates used to evaluate server trust according to the SSL pinning mode. |
| | | |
| | | By default, this property is set to any (`.cer`) certificates included in the target compiling BU_AFNetworking. Note that if you are using BU_AFNetworking as embedded framework, no certificates will be pinned by default. Use `certificatesInBundle` to load certificates from your target, and then create a new policy by calling `policyWithPinningMode:withPinnedCertificates`. |
| | | |
| | | Note that if pinning is enabled, `evaluateServerTrust:forDomain:` will return true if any pinned certificate matches. |
| | | */ |
| | | @property (nonatomic, strong, nullable) NSSet <NSData *> *pinnedCertificates; |
| | | |
| | | /** |
| | | Whether or not to trust servers with an invalid or expired SSL certificates. Defaults to `NO`. |
| | | */ |
| | | @property (nonatomic, assign) BOOL allowInvalidCertificates; |
| | | |
| | | /** |
| | | Whether or not to validate the domain name in the certificate's CN field. Defaults to `YES`. |
| | | */ |
| | | @property (nonatomic, assign) BOOL validatesDomainName; |
| | | |
| | | ///----------------------------------------- |
| | | /// @name Getting Certificates from the Bundle |
| | | ///----------------------------------------- |
| | | |
| | | /** |
| | | Returns any certificates included in the bundle. If you are using BU_AFNetworking as an embedded framework, you must use this method to find the certificates you have included in your app bundle, and use them when creating your security policy by calling `policyWithPinningMode:withPinnedCertificates`. |
| | | |
| | | @return The certificates included in the given bundle. |
| | | */ |
| | | + (NSSet <NSData *> *)certificatesInBundle:(NSBundle *)bundle; |
| | | |
| | | ///----------------------------------------- |
| | | /// @name Getting Specific Security Policies |
| | | ///----------------------------------------- |
| | | |
| | | /** |
| | | Returns the shared default security policy, which does not allow invalid certificates, validates domain name, and does not validate against pinned certificates or public keys. |
| | | |
| | | @return The default security policy. |
| | | */ |
| | | + (instancetype)defaultPolicy; |
| | | |
| | | ///--------------------- |
| | | /// @name Initialization |
| | | ///--------------------- |
| | | |
| | | /** |
| | | Creates and returns a security policy with the specified pinning mode. |
| | | |
| | | @param pinningMode The SSL pinning mode. |
| | | |
| | | @return A new security policy. |
| | | */ |
| | | + (instancetype)policyWithPinningMode:(BU_AFSSLPinningMode)pinningMode; |
| | | |
| | | /** |
| | | Creates and returns a security policy with the specified pinning mode. |
| | | |
| | | @param pinningMode The SSL pinning mode. |
| | | @param pinnedCertificates The certificates to pin against. |
| | | |
| | | @return A new security policy. |
| | | */ |
| | | + (instancetype)policyWithPinningMode:(BU_AFSSLPinningMode)pinningMode withPinnedCertificates:(NSSet <NSData *> *)pinnedCertificates; |
| | | |
| | | ///------------------------------ |
| | | /// @name Evaluating Server Trust |
| | | ///------------------------------ |
| | | |
| | | /** |
| | | Whether or not the specified server trust should be accepted, based on the security policy. |
| | | |
| | | This method should be used when responding to an authentication challenge from a server. |
| | | |
| | | @param serverTrust The X.509 certificate trust of the server. |
| | | @param domain The domain of serverTrust. If `nil`, the domain will not be validated. |
| | | |
| | | @return Whether or not to trust the server. |
| | | */ |
| | | - (BOOL)evaluateServerTrust:(SecTrustRef)serverTrust |
| | | forDomain:(nullable NSString *)domain; |
| | | |
| | | @end |
| | | |
| | | NS_ASSUME_NONNULL_END |
| | | |
| | | ///---------------- |
| | | /// @name Constants |
| | | ///---------------- |
| | | |
| | | /** |
| | | ## SSL Pinning Modes |
| | | |
| | | The following constants are provided by `BU_AFSSLPinningMode` as possible SSL pinning modes. |
| | | |
| | | enum { |
| | | BU_AFSSLPinningModeNone, |
| | | BU_AFSSLPinningModePublicKey, |
| | | BU_AFSSLPinningModeCertificate, |
| | | } |
| | | |
| | | `BU_AFSSLPinningModeNone` |
| | | Do not used pinned certificates to validate servers. |
| | | |
| | | `BU_AFSSLPinningModePublicKey` |
| | | Validate host certificates against public keys of pinned certificates. |
| | | |
| | | `BU_AFSSLPinningModeCertificate` |
| | | Validate host certificates against pinned certificates. |
| | | */ |
New file |
| | |
| | | // BU_AFURLRequestSerialization.h |
| | | // Copyright (c) 2011–2016 Alamofire Software Foundation ( http://alamofire.org/ ) |
| | | // |
| | | // Permission is hereby granted, free of charge, to any person obtaining a copy |
| | | // of this software and associated documentation files (the "Software"), to deal |
| | | // in the Software without restriction, including without limitation the rights |
| | | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
| | | // copies of the Software, and to permit persons to whom the Software is |
| | | // furnished to do so, subject to the following conditions: |
| | | // |
| | | // The above copyright notice and this permission notice shall be included in |
| | | // all copies or substantial portions of the Software. |
| | | // |
| | | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
| | | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
| | | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
| | | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
| | | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
| | | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
| | | // THE SOFTWARE. |
| | | |
| | | #import <Foundation/Foundation.h> |
| | | #import <TargetConditionals.h> |
| | | |
| | | #if TARGET_OS_IOS || TARGET_OS_TV |
| | | #import <UIKit/UIKit.h> |
| | | #elif TARGET_OS_WATCH |
| | | #import <WatchKit/WatchKit.h> |
| | | #endif |
| | | |
| | | NS_ASSUME_NONNULL_BEGIN |
| | | |
| | | /** |
| | | Returns a percent-escaped string following RFC 3986 for a query string key or value. |
| | | RFC 3986 states that the following characters are "reserved" characters. |
| | | - General Delimiters: ":", "#", "[", "]", "@", "?", "/" |
| | | - Sub-Delimiters: "!", "$", "&", "'", "(", ")", "*", "+", ",", ";", "=" |
| | | |
| | | In RFC 3986 - Section 3.4, it states that the "?" and "/" characters should not be escaped to allow |
| | | query strings to include a URL. Therefore, all "reserved" characters with the exception of "?" and "/" |
| | | should be percent-escaped in the query string. |
| | | |
| | | @param string The string to be percent-escaped. |
| | | |
| | | @return The percent-escaped string. |
| | | */ |
| | | FOUNDATION_EXPORT NSString * BU_AFPercentEscapedStringFromString(NSString *string); |
| | | |
| | | /** |
| | | A helper method to generate encoded url query parameters for appending to the end of a URL. |
| | | |
| | | @param parameters A dictionary of key/values to be encoded. |
| | | |
| | | @return A url encoded query string |
| | | */ |
| | | FOUNDATION_EXPORT NSString * BU_AFQueryStringFromParameters(NSDictionary *parameters); |
| | | |
| | | /** |
| | | The `BU_AFURLRequestSerialization` protocol is adopted by an object that encodes parameters for a specified HTTP requests. Request serializers may encode parameters as query strings, HTTP bodies, setting the appropriate HTTP header fields as necessary. |
| | | |
| | | For example, a JSON request serializer may set the HTTP body of the request to a JSON representation, and set the `Content-Type` HTTP header field value to `application/json`. |
| | | */ |
| | | @protocol BU_AFURLRequestSerialization <NSObject, NSSecureCoding, NSCopying> |
| | | |
| | | /** |
| | | Returns a request with the specified parameters encoded into a copy of the original request. |
| | | |
| | | @param request The original request. |
| | | @param parameters The parameters to be encoded. |
| | | @param error The error that occurred while attempting to encode the request parameters. |
| | | |
| | | @return A serialized request. |
| | | */ |
| | | - (nullable NSURLRequest *)requestBySerializingRequest:(NSURLRequest *)request |
| | | withParameters:(nullable id)parameters |
| | | error:(NSError * _Nullable __autoreleasing *)error NS_SWIFT_NOTHROW; |
| | | |
| | | @end |
| | | |
| | | #pragma mark - |
| | | |
| | | /** |
| | | |
| | | */ |
| | | typedef NS_ENUM(NSUInteger, BU_AFHTTPRequestQueryStringSerializationStyle) { |
| | | BU_AFHTTPRequestQueryStringDefaultStyle = 0, |
| | | }; |
| | | |
| | | @protocol BU_AFMultipartFormData; |
| | | |
| | | /** |
| | | `BU_AFHTTPRequestSerializer` conforms to the `BU_AFURLRequestSerialization` & `BU_AFURLResponseSerialization` protocols, offering a concrete base implementation of query string / URL form-encoded parameter serialization and default request headers, as well as response status code and content type validation. |
| | | |
| | | Any request or response serializer dealing with HTTP is encouraged to subclass `BU_AFHTTPRequestSerializer` in order to ensure consistent default behavior. |
| | | */ |
| | | @interface BU_AFHTTPRequestSerializer : NSObject <BU_AFURLRequestSerialization> |
| | | |
| | | /** |
| | | The string encoding used to serialize parameters. `NSUTF8StringEncoding` by default. |
| | | */ |
| | | @property (nonatomic, assign) NSStringEncoding stringEncoding; |
| | | |
| | | /** |
| | | Whether created requests can use the device’s cellular radio (if present). `YES` by default. |
| | | |
| | | @see NSMutableURLRequest -setAllowsCellularAccess: |
| | | */ |
| | | @property (nonatomic, assign) BOOL allowsCellularAccess; |
| | | |
| | | /** |
| | | The cache policy of created requests. `NSURLRequestUseProtocolCachePolicy` by default. |
| | | |
| | | @see NSMutableURLRequest -setCachePolicy: |
| | | */ |
| | | @property (nonatomic, assign) NSURLRequestCachePolicy cachePolicy; |
| | | |
| | | /** |
| | | Whether created requests should use the default cookie handling. `YES` by default. |
| | | |
| | | @see NSMutableURLRequest -setHTTPShouldHandleCookies: |
| | | */ |
| | | @property (nonatomic, assign) BOOL HTTPShouldHandleCookies; |
| | | |
| | | /** |
| | | Whether created requests can continue transmitting data before receiving a response from an earlier transmission. `NO` by default |
| | | |
| | | @see NSMutableURLRequest -setHTTPShouldUsePipelining: |
| | | */ |
| | | @property (nonatomic, assign) BOOL HTTPShouldUsePipelining; |
| | | |
| | | /** |
| | | The network service type for created requests. `NSURLNetworkServiceTypeDefault` by default. |
| | | |
| | | @see NSMutableURLRequest -setNetworkServiceType: |
| | | */ |
| | | @property (nonatomic, assign) NSURLRequestNetworkServiceType networkServiceType; |
| | | |
| | | /** |
| | | The timeout interval, in seconds, for created requests. The default timeout interval is 60 seconds. |
| | | |
| | | @see NSMutableURLRequest -setTimeoutInterval: |
| | | */ |
| | | @property (nonatomic, assign) NSTimeInterval timeoutInterval; |
| | | |
| | | ///--------------------------------------- |
| | | /// @name Configuring HTTP Request Headers |
| | | ///--------------------------------------- |
| | | |
| | | /** |
| | | Default HTTP header field values to be applied to serialized requests. By default, these include the following: |
| | | |
| | | - `Accept-Language` with the contents of `NSLocale +preferredLanguages` |
| | | - `User-Agent` with the contents of various bundle identifiers and OS designations |
| | | |
| | | @discussion To add or remove default request headers, use `setValue:forHTTPHeaderField:`. |
| | | */ |
| | | @property (readonly, nonatomic, strong) NSDictionary <NSString *, NSString *> *HTTPRequestHeaders; |
| | | |
| | | /** |
| | | Creates and returns a serializer with default configuration. |
| | | */ |
| | | + (instancetype)serializer; |
| | | |
| | | /** |
| | | Sets the value for the HTTP headers set in request objects made by the HTTP client. If `nil`, removes the existing value for that header. |
| | | |
| | | @param field The HTTP header to set a default value for |
| | | @param value The value set as default for the specified header, or `nil` |
| | | */ |
| | | - (void)setValue:(nullable NSString *)value |
| | | forHTTPHeaderField:(NSString *)field; |
| | | |
| | | /** |
| | | Returns the value for the HTTP headers set in the request serializer. |
| | | |
| | | @param field The HTTP header to retrieve the default value for |
| | | |
| | | @return The value set as default for the specified header, or `nil` |
| | | */ |
| | | - (nullable NSString *)valueForHTTPHeaderField:(NSString *)field; |
| | | |
| | | /** |
| | | Sets the "Authorization" HTTP header set in request objects made by the HTTP client to a basic authentication value with Base64-encoded username and password. This overwrites any existing value for this header. |
| | | |
| | | @param username The HTTP basic auth username |
| | | @param password The HTTP basic auth password |
| | | */ |
| | | - (void)setAuthorizationHeaderFieldWithUsername:(NSString *)username |
| | | password:(NSString *)password; |
| | | |
| | | /** |
| | | Clears any existing value for the "Authorization" HTTP header. |
| | | */ |
| | | - (void)clearAuthorizationHeader; |
| | | |
| | | ///------------------------------------------------------- |
| | | /// @name Configuring Query String Parameter Serialization |
| | | ///------------------------------------------------------- |
| | | |
| | | /** |
| | | HTTP methods for which serialized requests will encode parameters as a query string. `GET`, `HEAD`, and `DELETE` by default. |
| | | */ |
| | | @property (nonatomic, strong) NSSet <NSString *> *HTTPMethodsEncodingParametersInURI; |
| | | |
| | | /** |
| | | Set the method of query string serialization according to one of the pre-defined styles. |
| | | |
| | | @param style The serialization style. |
| | | |
| | | @see BU_AFHTTPRequestQueryStringSerializationStyle |
| | | */ |
| | | - (void)setQueryStringSerializationWithStyle:(BU_AFHTTPRequestQueryStringSerializationStyle)style; |
| | | |
| | | /** |
| | | Set the a custom method of query string serialization according to the specified block. |
| | | |
| | | @param block A block that defines a process of encoding parameters into a query string. This block returns the query string and takes three arguments: the request, the parameters to encode, and the error that occurred when attempting to encode parameters for the given request. |
| | | */ |
| | | - (void)setQueryStringSerializationWithBlock:(nullable NSString * (^)(NSURLRequest *request, id parameters, NSError * __autoreleasing *error))block; |
| | | |
| | | ///------------------------------- |
| | | /// @name Creating Request Objects |
| | | ///------------------------------- |
| | | |
| | | /** |
| | | Creates an `NSMutableURLRequest` object with the specified HTTP method and URL string. |
| | | |
| | | If the HTTP method is `GET`, `HEAD`, or `DELETE`, the parameters will be used to construct a url-encoded query string that is appended to the request's URL. Otherwise, the parameters will be encoded according to the value of the `parameterEncoding` property, and set as the request body. |
| | | |
| | | @param method The HTTP method for the request, such as `GET`, `POST`, `PUT`, or `DELETE`. This parameter must not be `nil`. |
| | | @param URLString The URL string used to create the request URL. |
| | | @param parameters The parameters to be either set as a query string for `GET` requests, or the request HTTP body. |
| | | @param error The error that occurred while constructing the request. |
| | | |
| | | @return An `NSMutableURLRequest` object. |
| | | */ |
| | | - (NSMutableURLRequest *)requestWithMethod:(NSString *)method |
| | | URLString:(NSString *)URLString |
| | | parameters:(nullable id)parameters |
| | | error:(NSError * _Nullable __autoreleasing *)error; |
| | | |
| | | /** |
| | | Creates an `NSMutableURLRequest` object with the specified HTTP method and URLString, and constructs a `multipart/form-data` HTTP body, using the specified parameters and multipart form data block. See http://www.w3.org/TR/html4/interact/forms.html#h-17.13.4.2 |
| | | |
| | | Multipart form requests are automatically streamed, reading files directly from disk along with in-memory data in a single HTTP body. The resulting `NSMutableURLRequest` object has an `HTTPBodyStream` property, so refrain from setting `HTTPBodyStream` or `HTTPBody` on this request object, as it will clear out the multipart form body stream. |
| | | |
| | | @param method The HTTP method for the request. This parameter must not be `GET` or `HEAD`, or `nil`. |
| | | @param URLString The URL string used to create the request URL. |
| | | @param parameters The parameters to be encoded and set in the request HTTP body. |
| | | @param block A block that takes a single argument and appends data to the HTTP body. The block argument is an object adopting the `BU_AFMultipartFormData` protocol. |
| | | @param error The error that occurred while constructing the request. |
| | | |
| | | @return An `NSMutableURLRequest` object |
| | | */ |
| | | - (NSMutableURLRequest *)multipartFormRequestWithMethod:(NSString *)method |
| | | URLString:(NSString *)URLString |
| | | parameters:(nullable NSDictionary <NSString *, id> *)parameters |
| | | constructingBodyWithBlock:(nullable void (^)(id <BU_AFMultipartFormData> formData))block |
| | | error:(NSError * _Nullable __autoreleasing *)error; |
| | | |
| | | /** |
| | | Creates an `NSMutableURLRequest` by removing the `HTTPBodyStream` from a request, and asynchronously writing its contents into the specified file, invoking the completion handler when finished. |
| | | |
| | | @param request The multipart form request. The `HTTPBodyStream` property of `request` must not be `nil`. |
| | | @param fileURL The file URL to write multipart form contents to. |
| | | @param handler A handler block to execute. |
| | | |
| | | @discussion There is a bug in `NSURLSessionTask` that causes requests to not send a `Content-Length` header when streaming contents from an HTTP body, which is notably problematic when interacting with the Amazon S3 webservice. As a workaround, this method takes a request constructed with `multipartFormRequestWithMethod:URLString:parameters:constructingBodyWithBlock:error:`, or any other request with an `HTTPBodyStream`, writes the contents to the specified file and returns a copy of the original request with the `HTTPBodyStream` property set to `nil`. From here, the file can either be passed to `BU_AFURLSessionManager -uploadTaskWithRequest:fromFile:progress:completionHandler:`, or have its contents read into an `NSData` that's assigned to the `HTTPBody` property of the request. |
| | | |
| | | @see https://github.com/BU_AFNetworking/BU_AFNetworking/issues/1398 |
| | | */ |
| | | - (NSMutableURLRequest *)requestWithMultipartFormRequest:(NSURLRequest *)request |
| | | writingStreamContentsToFile:(NSURL *)fileURL |
| | | completionHandler:(nullable void (^)(NSError * _Nullable error))handler; |
| | | |
| | | @end |
| | | |
| | | #pragma mark - |
| | | |
| | | /** |
| | | The `BU_AFMultipartFormData` protocol defines the methods supported by the parameter in the block argument of `BU_AFHTTPRequestSerializer -multipartFormRequestWithMethod:URLString:parameters:constructingBodyWithBlock:`. |
| | | */ |
| | | @protocol BU_AFMultipartFormData |
| | | |
| | | /** |
| | | Appends the HTTP header `Content-Disposition: file; filename=#{generated filename}; name=#{name}"` and `Content-Type: #{generated mimeType}`, followed by the encoded file data and the multipart form boundary. |
| | | |
| | | The filename and MIME type for this data in the form will be automatically generated, using the last path component of the `fileURL` and system associated MIME type for the `fileURL` extension, respectively. |
| | | |
| | | @param fileURL The URL corresponding to the file whose content will be appended to the form. This parameter must not be `nil`. |
| | | @param name The name to be associated with the specified data. This parameter must not be `nil`. |
| | | @param error If an error occurs, upon return contains an `NSError` object that describes the problem. |
| | | |
| | | @return `YES` if the file data was successfully appended, otherwise `NO`. |
| | | */ |
| | | - (BOOL)appendPartWithFileURL:(NSURL *)fileURL |
| | | name:(NSString *)name |
| | | error:(NSError * _Nullable __autoreleasing *)error; |
| | | |
| | | /** |
| | | Appends the HTTP header `Content-Disposition: file; filename=#{filename}; name=#{name}"` and `Content-Type: #{mimeType}`, followed by the encoded file data and the multipart form boundary. |
| | | |
| | | @param fileURL The URL corresponding to the file whose content will be appended to the form. This parameter must not be `nil`. |
| | | @param name The name to be associated with the specified data. This parameter must not be `nil`. |
| | | @param fileName The file name to be used in the `Content-Disposition` header. This parameter must not be `nil`. |
| | | @param mimeType The declared MIME type of the file data. This parameter must not be `nil`. |
| | | @param error If an error occurs, upon return contains an `NSError` object that describes the problem. |
| | | |
| | | @return `YES` if the file data was successfully appended otherwise `NO`. |
| | | */ |
| | | - (BOOL)appendPartWithFileURL:(NSURL *)fileURL |
| | | name:(NSString *)name |
| | | fileName:(NSString *)fileName |
| | | mimeType:(NSString *)mimeType |
| | | error:(NSError * _Nullable __autoreleasing *)error; |
| | | |
| | | /** |
| | | Appends the HTTP header `Content-Disposition: file; filename=#{filename}; name=#{name}"` and `Content-Type: #{mimeType}`, followed by the data from the input stream and the multipart form boundary. |
| | | |
| | | @param inputStream The input stream to be appended to the form data |
| | | @param name The name to be associated with the specified input stream. This parameter must not be `nil`. |
| | | @param fileName The filename to be associated with the specified input stream. This parameter must not be `nil`. |
| | | @param length The length of the specified input stream in bytes. |
| | | @param mimeType The MIME type of the specified data. (For example, the MIME type for a JPEG image is image/jpeg.) For a list of valid MIME types, see http://www.iana.org/assignments/media-types/. This parameter must not be `nil`. |
| | | */ |
| | | - (void)appendPartWithInputStream:(nullable NSInputStream *)inputStream |
| | | name:(NSString *)name |
| | | fileName:(NSString *)fileName |
| | | length:(int64_t)length |
| | | mimeType:(NSString *)mimeType; |
| | | |
| | | /** |
| | | Appends the HTTP header `Content-Disposition: file; filename=#{filename}; name=#{name}"` and `Content-Type: #{mimeType}`, followed by the encoded file data and the multipart form boundary. |
| | | |
| | | @param data The data to be encoded and appended to the form data. |
| | | @param name The name to be associated with the specified data. This parameter must not be `nil`. |
| | | @param fileName The filename to be associated with the specified data. This parameter must not be `nil`. |
| | | @param mimeType The MIME type of the specified data. (For example, the MIME type for a JPEG image is image/jpeg.) For a list of valid MIME types, see http://www.iana.org/assignments/media-types/. This parameter must not be `nil`. |
| | | */ |
| | | - (void)appendPartWithFileData:(NSData *)data |
| | | name:(NSString *)name |
| | | fileName:(NSString *)fileName |
| | | mimeType:(NSString *)mimeType; |
| | | |
| | | /** |
| | | Appends the HTTP headers `Content-Disposition: form-data; name=#{name}"`, followed by the encoded data and the multipart form boundary. |
| | | |
| | | @param data The data to be encoded and appended to the form data. |
| | | @param name The name to be associated with the specified data. This parameter must not be `nil`. |
| | | */ |
| | | |
| | | - (void)appendPartWithFormData:(NSData *)data |
| | | name:(NSString *)name; |
| | | |
| | | |
| | | /** |
| | | Appends HTTP headers, followed by the encoded data and the multipart form boundary. |
| | | |
| | | @param headers The HTTP headers to be appended to the form data. |
| | | @param body The data to be encoded and appended to the form data. This parameter must not be `nil`. |
| | | */ |
| | | - (void)appendPartWithHeaders:(nullable NSDictionary <NSString *, NSString *> *)headers |
| | | body:(NSData *)body; |
| | | |
| | | /** |
| | | Throttles request bandwidth by limiting the packet size and adding a delay for each chunk read from the upload stream. |
| | | |
| | | When uploading over a 3G or EDGE connection, requests may fail with "request body stream exhausted". Setting a maximum packet size and delay according to the recommended values (`kBU_AFUploadStream3GSuggestedPacketSize` and `kBU_AFUploadStream3GSuggestedDelay`) lowers the risk of the input stream exceeding its allocated bandwidth. Unfortunately, there is no definite way to distinguish between a 3G, EDGE, or LTE connection over `NSURLConnection`. As such, it is not recommended that you throttle bandwidth based solely on network reachability. Instead, you should consider checking for the "request body stream exhausted" in a failure block, and then retrying the request with throttled bandwidth. |
| | | |
| | | @param numberOfBytes Maximum packet size, in number of bytes. The default packet size for an input stream is 16kb. |
| | | @param delay Duration of delay each time a packet is read. By default, no delay is set. |
| | | */ |
| | | - (void)throttleBandwidthWithPacketSize:(NSUInteger)numberOfBytes |
| | | delay:(NSTimeInterval)delay; |
| | | |
| | | @end |
| | | |
| | | #pragma mark - |
| | | |
| | | /** |
| | | `BU_AFJSONRequestSerializer` is a subclass of `BU_AFHTTPRequestSerializer` that encodes parameters as JSON using `NSJSONSerialization`, setting the `Content-Type` of the encoded request to `application/json`. |
| | | */ |
| | | @interface BU_AFJSONRequestSerializer : BU_AFHTTPRequestSerializer |
| | | |
| | | /** |
| | | Options for writing the request JSON data from Foundation objects. For possible values, see the `NSJSONSerialization` documentation section "NSJSONWritingOptions". `0` by default. |
| | | */ |
| | | @property (nonatomic, assign) NSJSONWritingOptions writingOptions; |
| | | |
| | | /** |
| | | Creates and returns a JSON serializer with specified reading and writing options. |
| | | |
| | | @param writingOptions The specified JSON writing options. |
| | | */ |
| | | + (instancetype)serializerWithWritingOptions:(NSJSONWritingOptions)writingOptions; |
| | | |
| | | @end |
| | | |
| | | |
| | | #pragma mark - |
| | | |
| | | ///---------------- |
| | | /// @name Constants |
| | | ///---------------- |
| | | |
| | | /** |
| | | ## Error Domains |
| | | |
| | | The following error domain is predefined. |
| | | |
| | | - `NSString * const BU_AFURLRequestSerializationErrorDomain` |
| | | |
| | | ### Constants |
| | | |
| | | `BU_AFURLRequestSerializationErrorDomain` |
| | | AFURLRequestSerializer errors. Error codes for `BU_AFURLRequestSerializationErrorDomain` correspond to codes in `NSURLErrorDomain`. |
| | | */ |
| | | FOUNDATION_EXPORT NSString * const BU_AFURLRequestSerializationErrorDomain; |
| | | |
| | | /** |
| | | ## User info dictionary keys |
| | | |
| | | These keys may exist in the user info dictionary, in addition to those defined for NSError. |
| | | |
| | | - `NSString * const BU_AFNetworkingOperationFailingURLRequestErrorKey` |
| | | |
| | | ### Constants |
| | | |
| | | `BU_AFNetworkingOperationFailingURLRequestErrorKey` |
| | | The corresponding value is an `NSURLRequest` containing the request of the operation associated with an error. This key is only present in the `BU_AFURLRequestSerializationErrorDomain`. |
| | | */ |
| | | FOUNDATION_EXPORT NSString * const BU_AFNetworkingOperationFailingURLRequestErrorKey; |
| | | |
| | | /** |
| | | ## Throttling Bandwidth for HTTP Request Input Streams |
| | | |
| | | @see -throttleBandwidthWithPacketSize:delay: |
| | | |
| | | ### Constants |
| | | |
| | | `kBU_AFUploadStream3GSuggestedPacketSize` |
| | | Maximum packet size, in number of bytes. Equal to 16kb. |
| | | |
| | | `kBU_AFUploadStream3GSuggestedDelay` |
| | | Duration of delay each time a packet is read. Equal to 0.2 seconds. |
| | | */ |
| | | FOUNDATION_EXPORT NSUInteger const kBU_AFUploadStream3GSuggestedPacketSize; |
| | | FOUNDATION_EXPORT NSTimeInterval const kBU_AFUploadStream3GSuggestedDelay; |
| | | |
| | | NS_ASSUME_NONNULL_END |
New file |
| | |
| | | // BU_AFURLResponseSerialization.h |
| | | // Copyright (c) 2011–2016 Alamofire Software Foundation ( http://alamofire.org/ ) |
| | | // |
| | | // Permission is hereby granted, free of charge, to any person obtaining a copy |
| | | // of this software and associated documentation files (the "Software"), to deal |
| | | // in the Software without restriction, including without limitation the rights |
| | | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
| | | // copies of the Software, and to permit persons to whom the Software is |
| | | // furnished to do so, subject to the following conditions: |
| | | // |
| | | // The above copyright notice and this permission notice shall be included in |
| | | // all copies or substantial portions of the Software. |
| | | // |
| | | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
| | | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
| | | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
| | | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
| | | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
| | | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
| | | // THE SOFTWARE. |
| | | |
| | | #import <Foundation/Foundation.h> |
| | | #import <CoreGraphics/CoreGraphics.h> |
| | | |
| | | NS_ASSUME_NONNULL_BEGIN |
| | | |
| | | /** |
| | | The `BU_AFURLResponseSerialization` protocol is adopted by an object that decodes data into a more useful object representation, according to details in the server response. Response serializers may additionally perform validation on the incoming response and data. |
| | | |
| | | For example, a JSON response serializer may check for an acceptable status code (`2XX` range) and content type (`application/json`), decoding a valid JSON response into an object. |
| | | */ |
| | | @protocol BU_AFURLResponseSerialization <NSObject, NSSecureCoding, NSCopying> |
| | | |
| | | /** |
| | | The response object decoded from the data associated with a specified response. |
| | | |
| | | @param response The response to be processed. |
| | | @param data The response data to be decoded. |
| | | @param error The error that occurred while attempting to decode the response data. |
| | | |
| | | @return The object decoded from the specified response data. |
| | | */ |
| | | - (nullable id)responseObjectForResponse:(nullable NSURLResponse *)response |
| | | data:(nullable NSData *)data |
| | | error:(NSError * _Nullable __autoreleasing *)error NS_SWIFT_NOTHROW; |
| | | |
| | | @end |
| | | |
| | | #pragma mark - |
| | | |
| | | /** |
| | | `BU_AFHTTPResponseSerializer` conforms to the `BU_AFURLRequestSerialization` & `BU_AFURLResponseSerialization` protocols, offering a concrete base implementation of query string / URL form-encoded parameter serialization and default request headers, as well as response status code and content type validation. |
| | | |
| | | Any request or response serializer dealing with HTTP is encouraged to subclass `BU_AFHTTPResponseSerializer` in order to ensure consistent default behavior. |
| | | */ |
| | | @interface BU_AFHTTPResponseSerializer : NSObject <BU_AFURLResponseSerialization> |
| | | |
| | | - (instancetype)init; |
| | | /** |
| | | Creates and returns a serializer with default configuration. |
| | | */ |
| | | + (instancetype)serializer; |
| | | |
| | | ///----------------------------------------- |
| | | /// @name Configuring Response Serialization |
| | | ///----------------------------------------- |
| | | |
| | | /** |
| | | The acceptable HTTP status codes for responses. When non-`nil`, responses with status codes not contained by the set will result in an error during validation. |
| | | |
| | | See http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html |
| | | */ |
| | | @property (nonatomic, copy, nullable) NSIndexSet *acceptableStatusCodes; |
| | | |
| | | /** |
| | | The acceptable MIME types for responses. When non-`nil`, responses with a `Content-Type` with MIME types that do not intersect with the set will result in an error during validation. |
| | | */ |
| | | @property (nonatomic, copy, nullable) NSSet <NSString *> *acceptableContentTypes; |
| | | |
| | | /** |
| | | Validates the specified response and data. |
| | | |
| | | In its base implementation, this method checks for an acceptable status code and content type. Subclasses may wish to add other domain-specific checks. |
| | | |
| | | @param response The response to be validated. |
| | | @param data The data associated with the response. |
| | | @param error The error that occurred while attempting to validate the response. |
| | | |
| | | @return `YES` if the response is valid, otherwise `NO`. |
| | | */ |
| | | - (BOOL)validateResponse:(nullable NSHTTPURLResponse *)response |
| | | data:(nullable NSData *)data |
| | | error:(NSError * _Nullable __autoreleasing *)error; |
| | | |
| | | @end |
| | | |
| | | #pragma mark - |
| | | |
| | | |
| | | /** |
| | | `BU_AFJSONResponseSerializer` is a subclass of `BU_AFHTTPResponseSerializer` that validates and decodes JSON responses. |
| | | |
| | | By default, `BU_AFJSONResponseSerializer` accepts the following MIME types, which includes the official standard, `application/json`, as well as other commonly-used types: |
| | | |
| | | - `application/json` |
| | | - `text/json` |
| | | - `text/javascript` |
| | | */ |
| | | @interface BU_AFJSONResponseSerializer : BU_AFHTTPResponseSerializer |
| | | |
| | | - (instancetype)init; |
| | | |
| | | /** |
| | | Options for reading the response JSON data and creating the Foundation objects. For possible values, see the `NSJSONSerialization` documentation section "NSJSONReadingOptions". `0` by default. |
| | | */ |
| | | @property (nonatomic, assign) NSJSONReadingOptions readingOptions; |
| | | |
| | | /** |
| | | Whether to remove keys with `NSNull` values from response JSON. Defaults to `NO`. |
| | | */ |
| | | @property (nonatomic, assign) BOOL removesKeysWithNullValues; |
| | | |
| | | /** |
| | | Creates and returns a JSON serializer with specified reading and writing options. |
| | | |
| | | @param readingOptions The specified JSON reading options. |
| | | */ |
| | | + (instancetype)serializerWithReadingOptions:(NSJSONReadingOptions)readingOptions; |
| | | |
| | | @end |
| | | |
| | | #pragma mark - |
| | | |
| | | /** |
| | | `BU_AFImageResponseSerializer` is a subclass of `BU_AFHTTPResponseSerializer` that validates and decodes image responses. |
| | | |
| | | By default, `BU_AFImageResponseSerializer` accepts the following MIME types, which correspond to the image formats supported by UIImage or NSImage: |
| | | |
| | | - `image/tiff` |
| | | - `image/jpeg` |
| | | - `image/gif` |
| | | - `image/png` |
| | | - `image/ico` |
| | | - `image/x-icon` |
| | | - `image/bmp` |
| | | - `image/x-bmp` |
| | | - `image/x-xbitmap` |
| | | - `image/x-win-bitmap` |
| | | */ |
| | | @interface BU_AFImageResponseSerializer : BU_AFHTTPResponseSerializer |
| | | |
| | | #if TARGET_OS_IOS || TARGET_OS_TV || TARGET_OS_WATCH |
| | | /** |
| | | The scale factor used when interpreting the image data to construct `responseImage`. Specifying a scale factor of 1.0 results in an image whose size matches the pixel-based dimensions of the image. Applying a different scale factor changes the size of the image as reported by the size property. This is set to the value of scale of the main screen by default, which automatically scales images for retina displays, for instance. |
| | | */ |
| | | @property (nonatomic, assign) CGFloat imageScale; |
| | | |
| | | /** |
| | | Whether to automatically inflate response image data for compressed formats (such as PNG or JPEG). Enabling this can significantly improve drawing performance on iOS when used with `setCompletionBlockWithSuccess:failure:`, as it allows a bitmap representation to be constructed in the background rather than on the main thread. `YES` by default. |
| | | */ |
| | | @property (nonatomic, assign) BOOL automaticallyInflatesResponseImage; |
| | | #endif |
| | | |
| | | @end |
| | | |
| | | #pragma mark - |
| | | |
| | | /** |
| | | `AFCompoundSerializer` is a subclass of `BU_AFHTTPResponseSerializer` that delegates the response serialization to the first `BU_AFHTTPResponseSerializer` object that returns an object for `responseObjectForResponse:data:error:`, falling back on the default behavior of `BU_AFHTTPResponseSerializer`. This is useful for supporting multiple potential types and structures of server responses with a single serializer. |
| | | */ |
| | | @interface BU_AFCompoundResponseSerializer : BU_AFHTTPResponseSerializer |
| | | |
| | | /** |
| | | The component response serializers. |
| | | */ |
| | | @property (readonly, nonatomic, copy) NSArray <id<BU_AFURLResponseSerialization>> *responseSerializers; |
| | | |
| | | /** |
| | | Creates and returns a compound serializer comprised of the specified response serializers. |
| | | |
| | | @warning Each response serializer specified must be a subclass of `BU_AFHTTPResponseSerializer`, and response to `-validateResponse:data:error:`. |
| | | */ |
| | | + (instancetype)compoundSerializerWithResponseSerializers:(NSArray <id<BU_AFURLResponseSerialization>> *)responseSerializers; |
| | | |
| | | @end |
| | | |
| | | ///---------------- |
| | | /// @name Constants |
| | | ///---------------- |
| | | |
| | | /** |
| | | ## Error Domains |
| | | |
| | | The following error domain is predefined. |
| | | |
| | | - `NSString * const BU_AFURLResponseSerializationErrorDomain` |
| | | |
| | | ### Constants |
| | | |
| | | `BU_AFURLResponseSerializationErrorDomain` |
| | | AFURLResponseSerializer errors. Error codes for `BU_AFURLResponseSerializationErrorDomain` correspond to codes in `NSURLErrorDomain`. |
| | | */ |
| | | FOUNDATION_EXPORT NSString * const BU_AFURLResponseSerializationErrorDomain; |
| | | |
| | | /** |
| | | ## User info dictionary keys |
| | | |
| | | These keys may exist in the user info dictionary, in addition to those defined for NSError. |
| | | |
| | | - `NSString * const BU_AFNetworkingOperationFailingURLResponseErrorKey` |
| | | - `NSString * const BU_AFNetworkingOperationFailingURLResponseDataErrorKey` |
| | | |
| | | ### Constants |
| | | |
| | | `BU_AFNetworkingOperationFailingURLResponseErrorKey` |
| | | The corresponding value is an `NSURLResponse` containing the response of the operation associated with an error. This key is only present in the `BU_AFURLResponseSerializationErrorDomain`. |
| | | |
| | | `BU_AFNetworkingOperationFailingURLResponseDataErrorKey` |
| | | The corresponding value is an `NSData` containing the original data of the operation associated with an error. This key is only present in the `BU_AFURLResponseSerializationErrorDomain`. |
| | | */ |
| | | FOUNDATION_EXPORT NSString * const BU_AFNetworkingOperationFailingURLResponseErrorKey; |
| | | |
| | | FOUNDATION_EXPORT NSString * const BU_AFNetworkingOperationFailingURLResponseDataErrorKey; |
| | | |
| | | NS_ASSUME_NONNULL_END |
New file |
| | |
| | | // BU_AFURLSessionManager.h |
| | | // Copyright (c) 2011–2016 Alamofire Software Foundation ( http://alamofire.org/ ) |
| | | // |
| | | // Permission is hereby granted, free of charge, to any person obtaining a copy |
| | | // of this software and associated documentation files (the "Software"), to deal |
| | | // in the Software without restriction, including without limitation the rights |
| | | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
| | | // copies of the Software, and to permit persons to whom the Software is |
| | | // furnished to do so, subject to the following conditions: |
| | | // |
| | | // The above copyright notice and this permission notice shall be included in |
| | | // all copies or substantial portions of the Software. |
| | | // |
| | | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
| | | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
| | | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
| | | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
| | | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
| | | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
| | | // THE SOFTWARE. |
| | | |
| | | |
| | | #import <Foundation/Foundation.h> |
| | | |
| | | #import "BU_AFURLResponseSerialization.h" |
| | | #import "BU_AFURLRequestSerialization.h" |
| | | #import "BU_AFSecurityPolicy.h" |
| | | |
| | | /** |
| | | `BU_AFURLSessionManager` creates and manages an `NSURLSession` object based on a specified `NSURLSessionConfiguration` object, which conforms to `<NSURLSessionTaskDelegate>`, `<NSURLSessionDataDelegate>`, `<NSURLSessionDownloadDelegate>`, and `<NSURLSessionDelegate>`. |
| | | |
| | | ## Subclassing Notes |
| | | |
| | | This is the base class for `BU_AFHTTPSessionManager`, which adds functionality specific to making HTTP requests. If you are looking to extend `BU_AFURLSessionManager` specifically for HTTP, consider subclassing `BU_AFHTTPSessionManager` instead. |
| | | |
| | | ## NSURLSession & NSURLSessionTask Delegate Methods |
| | | |
| | | `BU_AFURLSessionManager` implements the following delegate methods: |
| | | |
| | | ### `NSURLSessionDelegate` |
| | | |
| | | - `URLSession:didBecomeInvalidWithError:` |
| | | - `URLSession:didReceiveChallenge:completionHandler:` |
| | | - `URLSessionDidFinishEventsForBackgroundURLSession:` |
| | | |
| | | ### `NSURLSessionTaskDelegate` |
| | | |
| | | - `URLSession:willPerformHTTPRedirection:newRequest:completionHandler:` |
| | | - `URLSession:task:didReceiveChallenge:completionHandler:` |
| | | - `URLSession:task:didSendBodyData:totalBytesSent:totalBytesExpectedToSend:` |
| | | - `URLSession:task:needNewBodyStream:` |
| | | - `URLSession:task:didCompleteWithError:` |
| | | |
| | | ### `NSURLSessionDataDelegate` |
| | | |
| | | - `URLSession:dataTask:didReceiveResponse:completionHandler:` |
| | | - `URLSession:dataTask:didBecomeDownloadTask:` |
| | | - `URLSession:dataTask:didReceiveData:` |
| | | - `URLSession:dataTask:willCacheResponse:completionHandler:` |
| | | |
| | | ### `NSURLSessionDownloadDelegate` |
| | | |
| | | - `URLSession:downloadTask:didFinishDownloadingToURL:` |
| | | - `URLSession:downloadTask:didWriteData:totalBytesWritten:totalBytesWritten:totalBytesExpectedToWrite:` |
| | | - `URLSession:downloadTask:didResumeAtOffset:expectedTotalBytes:` |
| | | |
| | | If any of these methods are overridden in a subclass, they _must_ call the `super` implementation first. |
| | | |
| | | ## Network Reachability Monitoring |
| | | |
| | | Network reachability status and change monitoring is available through the `reachabilityManager` property. Applications may choose to monitor network reachability conditions in order to prevent or suspend any outbound requests. See `AFNetworkReachabilityManager` for more details. |
| | | |
| | | ## NSCoding Caveats |
| | | |
| | | - Encoded managers do not include any block properties. Be sure to set delegate callback blocks when using `-initWithCoder:` or `NSKeyedUnarchiver`. |
| | | |
| | | ## NSCopying Caveats |
| | | |
| | | - `-copy` and `-copyWithZone:` return a new manager with a new `NSURLSession` created from the configuration of the original. |
| | | - Operation copies do not include any delegate callback blocks, as they often strongly captures a reference to `self`, which would otherwise have the unintuitive side-effect of pointing to the _original_ session manager when copied. |
| | | |
| | | @warning Managers for background sessions must be owned for the duration of their use. This can be accomplished by creating an application-wide or shared singleton instance. |
| | | */ |
| | | |
| | | NS_ASSUME_NONNULL_BEGIN |
| | | |
| | | @interface BU_AFURLSessionManager : NSObject <NSURLSessionDelegate, NSURLSessionTaskDelegate, NSURLSessionDataDelegate, NSURLSessionDownloadDelegate, NSSecureCoding, NSCopying> |
| | | |
| | | /** |
| | | The managed session. |
| | | */ |
| | | @property (readonly, nonatomic, strong) NSURLSession *session; |
| | | |
| | | /** |
| | | The operation queue on which delegate callbacks are run. |
| | | */ |
| | | @property (readonly, nonatomic, strong) NSOperationQueue *operationQueue; |
| | | |
| | | /** |
| | | Responses sent from the server in data tasks created with `dataTaskWithRequest:success:failure:` and run using the `GET` / `POST` / et al. convenience methods are automatically validated and serialized by the response serializer. By default, this property is set to an instance of `BU_AFJSONResponseSerializer`. |
| | | |
| | | @warning `responseSerializer` must not be `nil`. |
| | | */ |
| | | @property (nonatomic, strong) id <BU_AFURLResponseSerialization> responseSerializer; |
| | | |
| | | ///------------------------------- |
| | | /// @name Managing Security Policy |
| | | ///------------------------------- |
| | | |
| | | /** |
| | | The security policy used by created session to evaluate server trust for secure connections. `BU_AFURLSessionManager` uses the `defaultPolicy` unless otherwise specified. |
| | | */ |
| | | @property (nonatomic, strong) BU_AFSecurityPolicy *securityPolicy; |
| | | |
| | | ///---------------------------- |
| | | /// @name Getting Session Tasks |
| | | ///---------------------------- |
| | | |
| | | /** |
| | | The data, upload, and download tasks currently run by the managed session. |
| | | */ |
| | | @property (readonly, nonatomic, strong) NSArray <NSURLSessionTask *> *tasks; |
| | | |
| | | /** |
| | | The data tasks currently run by the managed session. |
| | | */ |
| | | @property (readonly, nonatomic, strong) NSArray <NSURLSessionDataTask *> *dataTasks; |
| | | |
| | | /** |
| | | The upload tasks currently run by the managed session. |
| | | */ |
| | | @property (readonly, nonatomic, strong) NSArray <NSURLSessionUploadTask *> *uploadTasks; |
| | | |
| | | /** |
| | | The download tasks currently run by the managed session. |
| | | */ |
| | | @property (readonly, nonatomic, strong) NSArray <NSURLSessionDownloadTask *> *downloadTasks; |
| | | |
| | | ///------------------------------- |
| | | /// @name Managing Callback Queues |
| | | ///------------------------------- |
| | | |
| | | /** |
| | | The dispatch queue for `completionBlock`. If `NULL` (default), the main queue is used. |
| | | */ |
| | | @property (nonatomic, strong, nullable) dispatch_queue_t completionQueue; |
| | | |
| | | /** |
| | | The dispatch group for `completionBlock`. If `NULL` (default), a private dispatch group is used. |
| | | */ |
| | | @property (nonatomic, strong, nullable) dispatch_group_t completionGroup; |
| | | |
| | | ///--------------------------------- |
| | | /// @name Working Around System Bugs |
| | | ///--------------------------------- |
| | | |
| | | /** |
| | | Whether to attempt to retry creation of upload tasks for background sessions when initial call returns `nil`. `NO` by default. |
| | | |
| | | @bug As of iOS 7.0, there is a bug where upload tasks created for background tasks are sometimes `nil`. As a workaround, if this property is `YES`, BU_AFNetworking will follow Apple's recommendation to try creating the task again. |
| | | |
| | | @see https://github.com/BU_AFNetworking/BU_AFNetworking/issues/1675 |
| | | */ |
| | | @property (nonatomic, assign) BOOL attemptsToRecreateUploadTasksForBackgroundSessions; |
| | | |
| | | ///--------------------- |
| | | /// @name Initialization |
| | | ///--------------------- |
| | | |
| | | /** |
| | | Creates and returns a manager for a session created with the specified configuration. This is the designated initializer. |
| | | |
| | | @param configuration The configuration used to create the managed session. |
| | | |
| | | @return A manager for a newly-created session. |
| | | */ |
| | | - (instancetype)initWithSessionConfiguration:(nullable NSURLSessionConfiguration *)configuration NS_DESIGNATED_INITIALIZER; |
| | | |
| | | /** |
| | | Invalidates the managed session, optionally canceling pending tasks. |
| | | |
| | | @param cancelPendingTasks Whether or not to cancel pending tasks. |
| | | */ |
| | | - (void)invalidateSessionCancelingTasks:(BOOL)cancelPendingTasks; |
| | | |
| | | ///------------------------- |
| | | /// @name Running Data Tasks |
| | | ///------------------------- |
| | | |
| | | /** |
| | | Creates an `NSURLSessionDataTask` with the specified request. |
| | | |
| | | @param request The HTTP request for the request. |
| | | @param completionHandler A block object to be executed when the task finishes. This block has no return value and takes three arguments: the server response, the response object created by that serializer, and the error that occurred, if any. |
| | | */ |
| | | - (NSURLSessionDataTask *)dataTaskWithRequest:(NSURLRequest *)request |
| | | completionHandler:(nullable void (^)(NSURLResponse *response, id _Nullable responseObject, NSError * _Nullable error))completionHandler DEPRECATED_ATTRIBUTE; |
| | | |
| | | /** |
| | | Creates an `NSURLSessionDataTask` with the specified request. |
| | | |
| | | @param request The HTTP request for the request. |
| | | @param uploadProgressBlock A block object to be executed when the upload progress is updated. Note this block is called on the session queue, not the main queue. |
| | | @param downloadProgressBlock A block object to be executed when the download progress is updated. Note this block is called on the session queue, not the main queue. |
| | | @param completionHandler A block object to be executed when the task finishes. This block has no return value and takes three arguments: the server response, the response object created by that serializer, and the error that occurred, if any. |
| | | */ |
| | | - (NSURLSessionDataTask *)dataTaskWithRequest:(NSURLRequest *)request |
| | | uploadProgress:(nullable void (^)(NSProgress *uploadProgress))uploadProgressBlock |
| | | downloadProgress:(nullable void (^)(NSProgress *downloadProgress))downloadProgressBlock |
| | | completionHandler:(nullable void (^)(NSURLResponse *response, id _Nullable responseObject, NSError * _Nullable error))completionHandler; |
| | | |
| | | ///--------------------------- |
| | | /// @name Running Upload Tasks |
| | | ///--------------------------- |
| | | |
| | | /** |
| | | Creates an `NSURLSessionUploadTask` with the specified request for a local file. |
| | | |
| | | @param request The HTTP request for the request. |
| | | @param fileURL A URL to the local file to be uploaded. |
| | | @param uploadProgressBlock A block object to be executed when the upload progress is updated. Note this block is called on the session queue, not the main queue. |
| | | @param completionHandler A block object to be executed when the task finishes. This block has no return value and takes three arguments: the server response, the response object created by that serializer, and the error that occurred, if any. |
| | | |
| | | @see `attemptsToRecreateUploadTasksForBackgroundSessions` |
| | | */ |
| | | - (NSURLSessionUploadTask *)uploadTaskWithRequest:(NSURLRequest *)request |
| | | fromFile:(NSURL *)fileURL |
| | | progress:(nullable void (^)(NSProgress *uploadProgress))uploadProgressBlock |
| | | completionHandler:(nullable void (^)(NSURLResponse *response, id _Nullable responseObject, NSError * _Nullable error))completionHandler; |
| | | |
| | | /** |
| | | Creates an `NSURLSessionUploadTask` with the specified request for an HTTP body. |
| | | |
| | | @param request The HTTP request for the request. |
| | | @param bodyData A data object containing the HTTP body to be uploaded. |
| | | @param uploadProgressBlock A block object to be executed when the upload progress is updated. Note this block is called on the session queue, not the main queue. |
| | | @param completionHandler A block object to be executed when the task finishes. This block has no return value and takes three arguments: the server response, the response object created by that serializer, and the error that occurred, if any. |
| | | */ |
| | | - (NSURLSessionUploadTask *)uploadTaskWithRequest:(NSURLRequest *)request |
| | | fromData:(nullable NSData *)bodyData |
| | | progress:(nullable void (^)(NSProgress *uploadProgress))uploadProgressBlock |
| | | completionHandler:(nullable void (^)(NSURLResponse *response, id _Nullable responseObject, NSError * _Nullable error))completionHandler; |
| | | |
| | | /** |
| | | Creates an `NSURLSessionUploadTask` with the specified streaming request. |
| | | |
| | | @param request The HTTP request for the request. |
| | | @param uploadProgressBlock A block object to be executed when the upload progress is updated. Note this block is called on the session queue, not the main queue. |
| | | @param completionHandler A block object to be executed when the task finishes. This block has no return value and takes three arguments: the server response, the response object created by that serializer, and the error that occurred, if any. |
| | | */ |
| | | - (NSURLSessionUploadTask *)uploadTaskWithStreamedRequest:(NSURLRequest *)request |
| | | progress:(nullable void (^)(NSProgress *uploadProgress))uploadProgressBlock |
| | | completionHandler:(nullable void (^)(NSURLResponse *response, id _Nullable responseObject, NSError * _Nullable error))completionHandler; |
| | | |
| | | ///----------------------------- |
| | | /// @name Running Download Tasks |
| | | ///----------------------------- |
| | | |
| | | /** |
| | | Creates an `NSURLSessionDownloadTask` with the specified request. |
| | | |
| | | @param request The HTTP request for the request. |
| | | @param downloadProgressBlock A block object to be executed when the download progress is updated. Note this block is called on the session queue, not the main queue. |
| | | @param destination A block object to be executed in order to determine the destination of the downloaded file. This block takes two arguments, the target path & the server response, and returns the desired file URL of the resulting download. The temporary file used during the download will be automatically deleted after being moved to the returned URL. |
| | | @param completionHandler A block to be executed when a task finishes. This block has no return value and takes three arguments: the server response, the path of the downloaded file, and the error describing the network or parsing error that occurred, if any. |
| | | |
| | | @warning If using a background `NSURLSessionConfiguration` on iOS, these blocks will be lost when the app is terminated. Background sessions may prefer to use `-setDownloadTaskDidFinishDownloadingBlock:` to specify the URL for saving the downloaded file, rather than the destination block of this method. |
| | | */ |
| | | - (NSURLSessionDownloadTask *)downloadTaskWithRequest:(NSURLRequest *)request |
| | | progress:(nullable void (^)(NSProgress *downloadProgress))downloadProgressBlock |
| | | destination:(nullable NSURL * (^)(NSURL *targetPath, NSURLResponse *response))destination |
| | | completionHandler:(nullable void (^)(NSURLResponse *response, NSURL * _Nullable filePath, NSError * _Nullable error))completionHandler; |
| | | |
| | | /** |
| | | Creates an `NSURLSessionDownloadTask` with the specified resume data. |
| | | |
| | | @param resumeData The data used to resume downloading. |
| | | @param downloadProgressBlock A block object to be executed when the download progress is updated. Note this block is called on the session queue, not the main queue. |
| | | @param destination A block object to be executed in order to determine the destination of the downloaded file. This block takes two arguments, the target path & the server response, and returns the desired file URL of the resulting download. The temporary file used during the download will be automatically deleted after being moved to the returned URL. |
| | | @param completionHandler A block to be executed when a task finishes. This block has no return value and takes three arguments: the server response, the path of the downloaded file, and the error describing the network or parsing error that occurred, if any. |
| | | */ |
| | | - (NSURLSessionDownloadTask *)downloadTaskWithResumeData:(NSData *)resumeData |
| | | progress:(nullable void (^)(NSProgress *downloadProgress))downloadProgressBlock |
| | | destination:(nullable NSURL * (^)(NSURL *targetPath, NSURLResponse *response))destination |
| | | completionHandler:(nullable void (^)(NSURLResponse *response, NSURL * _Nullable filePath, NSError * _Nullable error))completionHandler; |
| | | |
| | | ///--------------------------------- |
| | | /// @name Getting Progress for Tasks |
| | | ///--------------------------------- |
| | | |
| | | /** |
| | | Returns the upload progress of the specified task. |
| | | |
| | | @param task The session task. Must not be `nil`. |
| | | |
| | | @return An `NSProgress` object reporting the upload progress of a task, or `nil` if the progress is unavailable. |
| | | */ |
| | | - (nullable NSProgress *)uploadProgressForTask:(NSURLSessionTask *)task; |
| | | |
| | | /** |
| | | Returns the download progress of the specified task. |
| | | |
| | | @param task The session task. Must not be `nil`. |
| | | |
| | | @return An `NSProgress` object reporting the download progress of a task, or `nil` if the progress is unavailable. |
| | | */ |
| | | - (nullable NSProgress *)downloadProgressForTask:(NSURLSessionTask *)task; |
| | | |
| | | ///----------------------------------------- |
| | | /// @name Setting Session Delegate Callbacks |
| | | ///----------------------------------------- |
| | | |
| | | /** |
| | | Sets a block to be executed when the managed session becomes invalid, as handled by the `NSURLSessionDelegate` method `URLSession:didBecomeInvalidWithError:`. |
| | | |
| | | @param block A block object to be executed when the managed session becomes invalid. The block has no return value, and takes two arguments: the session, and the error related to the cause of invalidation. |
| | | */ |
| | | - (void)setSessionDidBecomeInvalidBlock:(nullable void (^)(NSURLSession *session, NSError *error))block; |
| | | |
| | | /** |
| | | Sets a block to be executed when a connection level authentication challenge has occurred, as handled by the `NSURLSessionDelegate` method `URLSession:didReceiveChallenge:completionHandler:`. |
| | | |
| | | @param block A block object to be executed when a connection level authentication challenge has occurred. The block returns the disposition of the authentication challenge, and takes three arguments: the session, the authentication challenge, and a pointer to the credential that should be used to resolve the challenge. |
| | | */ |
| | | - (void)setSessionDidReceiveAuthenticationChallengeBlock:(nullable NSURLSessionAuthChallengeDisposition (^)(NSURLSession *session, NSURLAuthenticationChallenge *challenge, NSURLCredential * _Nullable __autoreleasing * _Nullable credential))block; |
| | | |
| | | ///-------------------------------------- |
| | | /// @name Setting Task Delegate Callbacks |
| | | ///-------------------------------------- |
| | | |
| | | /** |
| | | Sets a block to be executed when a task requires a new request body stream to send to the remote server, as handled by the `NSURLSessionTaskDelegate` method `URLSession:task:needNewBodyStream:`. |
| | | |
| | | @param block A block object to be executed when a task requires a new request body stream. |
| | | */ |
| | | - (void)setTaskNeedNewBodyStreamBlock:(nullable NSInputStream * (^)(NSURLSession *session, NSURLSessionTask *task))block; |
| | | |
| | | /** |
| | | Sets a block to be executed when an HTTP request is attempting to perform a redirection to a different URL, as handled by the `NSURLSessionTaskDelegate` method `URLSession:willPerformHTTPRedirection:newRequest:completionHandler:`. |
| | | |
| | | @param block A block object to be executed when an HTTP request is attempting to perform a redirection to a different URL. The block returns the request to be made for the redirection, and takes four arguments: the session, the task, the redirection response, and the request corresponding to the redirection response. |
| | | */ |
| | | - (void)setTaskWillPerformHTTPRedirectionBlock:(nullable NSURLRequest * _Nullable (^)(NSURLSession *session, NSURLSessionTask *task, NSURLResponse *response, NSURLRequest *request))block; |
| | | |
| | | /** |
| | | Sets a block to be executed when a session task has received a request specific authentication challenge, as handled by the `NSURLSessionTaskDelegate` method `URLSession:task:didReceiveChallenge:completionHandler:`. |
| | | |
| | | @param block A block object to be executed when a session task has received a request specific authentication challenge. The block returns the disposition of the authentication challenge, and takes four arguments: the session, the task, the authentication challenge, and a pointer to the credential that should be used to resolve the challenge. |
| | | */ |
| | | - (void)setTaskDidReceiveAuthenticationChallengeBlock:(nullable NSURLSessionAuthChallengeDisposition (^)(NSURLSession *session, NSURLSessionTask *task, NSURLAuthenticationChallenge *challenge, NSURLCredential * _Nullable __autoreleasing * _Nullable credential))block; |
| | | |
| | | /** |
| | | Sets a block to be executed periodically to track upload progress, as handled by the `NSURLSessionTaskDelegate` method `URLSession:task:didSendBodyData:totalBytesSent:totalBytesExpectedToSend:`. |
| | | |
| | | @param block A block object to be called when an undetermined number of bytes have been uploaded to the server. This block has no return value and takes five arguments: the session, the task, the number of bytes written since the last time the upload progress block was called, the total bytes written, and the total bytes expected to be written during the request, as initially determined by the length of the HTTP body. This block may be called multiple times, and will execute on the main thread. |
| | | */ |
| | | - (void)setTaskDidSendBodyDataBlock:(nullable void (^)(NSURLSession *session, NSURLSessionTask *task, int64_t bytesSent, int64_t totalBytesSent, int64_t totalBytesExpectedToSend))block; |
| | | |
| | | /** |
| | | Sets a block to be executed as the last message related to a specific task, as handled by the `NSURLSessionTaskDelegate` method `URLSession:task:didCompleteWithError:`. |
| | | |
| | | @param block A block object to be executed when a session task is completed. The block has no return value, and takes three arguments: the session, the task, and any error that occurred in the process of executing the task. |
| | | */ |
| | | - (void)setTaskDidCompleteBlock:(nullable void (^)(NSURLSession *session, NSURLSessionTask *task, NSError * _Nullable error))block; |
| | | |
| | | ///------------------------------------------- |
| | | /// @name Setting Data Task Delegate Callbacks |
| | | ///------------------------------------------- |
| | | |
| | | /** |
| | | Sets a block to be executed when a data task has received a response, as handled by the `NSURLSessionDataDelegate` method `URLSession:dataTask:didReceiveResponse:completionHandler:`. |
| | | |
| | | @param block A block object to be executed when a data task has received a response. The block returns the disposition of the session response, and takes three arguments: the session, the data task, and the received response. |
| | | */ |
| | | - (void)setDataTaskDidReceiveResponseBlock:(nullable NSURLSessionResponseDisposition (^)(NSURLSession *session, NSURLSessionDataTask *dataTask, NSURLResponse *response))block; |
| | | |
| | | /** |
| | | Sets a block to be executed when a data task has become a download task, as handled by the `NSURLSessionDataDelegate` method `URLSession:dataTask:didBecomeDownloadTask:`. |
| | | |
| | | @param block A block object to be executed when a data task has become a download task. The block has no return value, and takes three arguments: the session, the data task, and the download task it has become. |
| | | */ |
| | | - (void)setDataTaskDidBecomeDownloadTaskBlock:(nullable void (^)(NSURLSession *session, NSURLSessionDataTask *dataTask, NSURLSessionDownloadTask *downloadTask))block; |
| | | |
| | | /** |
| | | Sets a block to be executed when a data task receives data, as handled by the `NSURLSessionDataDelegate` method `URLSession:dataTask:didReceiveData:`. |
| | | |
| | | @param block A block object to be called when an undetermined number of bytes have been downloaded from the server. This block has no return value and takes three arguments: the session, the data task, and the data received. This block may be called multiple times, and will execute on the session manager operation queue. |
| | | */ |
| | | - (void)setDataTaskDidReceiveDataBlock:(nullable void (^)(NSURLSession *session, NSURLSessionDataTask *dataTask, NSData *data))block; |
| | | |
| | | /** |
| | | Sets a block to be executed to determine the caching behavior of a data task, as handled by the `NSURLSessionDataDelegate` method `URLSession:dataTask:willCacheResponse:completionHandler:`. |
| | | |
| | | @param block A block object to be executed to determine the caching behavior of a data task. The block returns the response to cache, and takes three arguments: the session, the data task, and the proposed cached URL response. |
| | | */ |
| | | - (void)setDataTaskWillCacheResponseBlock:(nullable NSCachedURLResponse * (^)(NSURLSession *session, NSURLSessionDataTask *dataTask, NSCachedURLResponse *proposedResponse))block; |
| | | |
| | | /** |
| | | Sets a block to be executed once all messages enqueued for a session have been delivered, as handled by the `NSURLSessionDataDelegate` method `URLSessionDidFinishEventsForBackgroundURLSession:`. |
| | | |
| | | @param block A block object to be executed once all messages enqueued for a session have been delivered. The block has no return value and takes a single argument: the session. |
| | | */ |
| | | - (void)setDidFinishEventsForBackgroundURLSessionBlock:(nullable void (^)(NSURLSession *session))block; |
| | | |
| | | ///----------------------------------------------- |
| | | /// @name Setting Download Task Delegate Callbacks |
| | | ///----------------------------------------------- |
| | | |
| | | /** |
| | | Sets a block to be executed when a download task has completed a download, as handled by the `NSURLSessionDownloadDelegate` method `URLSession:downloadTask:didFinishDownloadingToURL:`. |
| | | |
| | | @param block A block object to be executed when a download task has completed. The block returns the URL the download should be moved to, and takes three arguments: the session, the download task, and the temporary location of the downloaded file. If the file manager encounters an error while attempting to move the temporary file to the destination, an `BU_AFURLSessionDownloadTaskDidFailToMoveFileNotification` will be posted, with the download task as its object, and the user info of the error. |
| | | */ |
| | | - (void)setDownloadTaskDidFinishDownloadingBlock:(nullable NSURL * _Nullable (^)(NSURLSession *session, NSURLSessionDownloadTask *downloadTask, NSURL *location))block; |
| | | |
| | | /** |
| | | Sets a block to be executed periodically to track download progress, as handled by the `NSURLSessionDownloadDelegate` method `URLSession:downloadTask:didWriteData:totalBytesWritten:totalBytesWritten:totalBytesExpectedToWrite:`. |
| | | |
| | | @param block A block object to be called when an undetermined number of bytes have been downloaded from the server. This block has no return value and takes five arguments: the session, the download task, the number of bytes read since the last time the download progress block was called, the total bytes read, and the total bytes expected to be read during the request, as initially determined by the expected content size of the `NSHTTPURLResponse` object. This block may be called multiple times, and will execute on the session manager operation queue. |
| | | */ |
| | | - (void)setDownloadTaskDidWriteDataBlock:(nullable void (^)(NSURLSession *session, NSURLSessionDownloadTask *downloadTask, int64_t bytesWritten, int64_t totalBytesWritten, int64_t totalBytesExpectedToWrite))block; |
| | | |
| | | /** |
| | | Sets a block to be executed when a download task has been resumed, as handled by the `NSURLSessionDownloadDelegate` method `URLSession:downloadTask:didResumeAtOffset:expectedTotalBytes:`. |
| | | |
| | | @param block A block object to be executed when a download task has been resumed. The block has no return value and takes four arguments: the session, the download task, the file offset of the resumed download, and the total number of bytes expected to be downloaded. |
| | | */ |
| | | - (void)setDownloadTaskDidResumeBlock:(nullable void (^)(NSURLSession *session, NSURLSessionDownloadTask *downloadTask, int64_t fileOffset, int64_t expectedTotalBytes))block; |
| | | |
| | | @end |
| | | |
| | | ///-------------------- |
| | | /// @name Notifications |
| | | ///-------------------- |
| | | |
| | | /** |
| | | Posted when a task resumes. |
| | | */ |
| | | FOUNDATION_EXPORT NSString * const BU_AFNetworkingTaskDidResumeNotification; |
| | | |
| | | /** |
| | | Posted when a task finishes executing. Includes a userInfo dictionary with additional information about the task. |
| | | */ |
| | | FOUNDATION_EXPORT NSString * const BU_AFNetworkingTaskDidCompleteNotification; |
| | | |
| | | /** |
| | | Posted when a task suspends its execution. |
| | | */ |
| | | FOUNDATION_EXPORT NSString * const BU_AFNetworkingTaskDidSuspendNotification; |
| | | |
| | | /** |
| | | Posted when a session is invalidated. |
| | | */ |
| | | FOUNDATION_EXPORT NSString * const BU_AFURLSessionDidInvalidateNotification; |
| | | |
| | | /** |
| | | Posted when a session download task encountered an error when moving the temporary download file to a specified destination. |
| | | */ |
| | | FOUNDATION_EXPORT NSString * const BU_AFURLSessionDownloadTaskDidFailToMoveFileNotification; |
| | | |
| | | /** |
| | | The raw response data of the task. Included in the userInfo dictionary of the `BU_AFNetworkingTaskDidCompleteNotification` if response data exists for the task. |
| | | */ |
| | | FOUNDATION_EXPORT NSString * const BU_AFNetworkingTaskDidCompleteResponseDataKey; |
| | | |
| | | /** |
| | | The serialized response object of the task. Included in the userInfo dictionary of the `BU_AFNetworkingTaskDidCompleteNotification` if the response was serialized. |
| | | */ |
| | | FOUNDATION_EXPORT NSString * const BU_AFNetworkingTaskDidCompleteSerializedResponseKey; |
| | | |
| | | /** |
| | | The response serializer used to serialize the response. Included in the userInfo dictionary of the `BU_AFNetworkingTaskDidCompleteNotification` if the task has an associated response serializer. |
| | | */ |
| | | FOUNDATION_EXPORT NSString * const BU_AFNetworkingTaskDidCompleteResponseSerializerKey; |
| | | |
| | | /** |
| | | The file path associated with the download task. Included in the userInfo dictionary of the `BU_AFNetworkingTaskDidCompleteNotification` if an the response data has been stored directly to disk. |
| | | */ |
| | | FOUNDATION_EXPORT NSString * const BU_AFNetworkingTaskDidCompleteAssetPathKey; |
| | | |
| | | /** |
| | | Any error associated with the task, or the serialization of the response. Included in the userInfo dictionary of the `BU_AFNetworkingTaskDidCompleteNotification` if an error exists. |
| | | */ |
| | | FOUNDATION_EXPORT NSString * const BU_AFNetworkingTaskDidCompleteErrorKey; |
| | | |
| | | NS_ASSUME_NONNULL_END |
New file |
| | |
| | | /* |
| | | * This file is part of the SDWebImage package. |
| | | * (c) Olivier Poitrey <rs@dailymotion.com> |
| | | * |
| | | * For the full copyright and license information, please view the LICENSE |
| | | * file that was distributed with this source code. |
| | | */ |
| | | |
| | | #import "BU_SDWebImageCompat.h" |
| | | |
| | | @class BU_SDImageCacheConfig; |
| | | /** |
| | | A protocol to allow custom disk cache used in SDImageCache. |
| | | */ |
| | | @protocol BU_SDDiskCache <NSObject> |
| | | |
| | | // All of these method are called from the same global queue to avoid blocking on main queue and thread-safe problem. But it's also recommend to ensure thread-safe yourself using lock or other ways. |
| | | @required |
| | | /** |
| | | Create a new disk cache based on the specified path. You can check `maxDiskSize` and `maxDiskAge` used for disk cache. |
| | | |
| | | @param cachePath Full path of a directory in which the cache will write data. |
| | | Once initialized you should not read and write to this directory. |
| | | @param config The cache config to be used to create the cache. |
| | | |
| | | @return A new cache object, or nil if an error occurs. |
| | | */ |
| | | - (nullable instancetype)initWithCachePath:(nonnull NSString *)cachePath config:(nonnull BU_SDImageCacheConfig *)config; |
| | | |
| | | /** |
| | | Returns a boolean value that indicates whether a given key is in cache. |
| | | This method may blocks the calling thread until file read finished. |
| | | |
| | | @param key A string identifying the data. If nil, just return NO. |
| | | @return Whether the key is in cache. |
| | | */ |
| | | - (BOOL)containsDataForKey:(nonnull NSString *)key; |
| | | |
| | | /** |
| | | Returns the data associated with a given key. |
| | | This method may blocks the calling thread until file read finished. |
| | | |
| | | @param key A string identifying the data. If nil, just return nil. |
| | | @return The value associated with key, or nil if no value is associated with key. |
| | | */ |
| | | - (nullable NSData *)dataForKey:(nonnull NSString *)key; |
| | | |
| | | /** |
| | | Sets the value of the specified key in the cache. |
| | | This method may blocks the calling thread until file write finished. |
| | | |
| | | @param data The data to be stored in the cache. |
| | | @param key The key with which to associate the value. If nil, this method has no effect. |
| | | */ |
| | | - (void)setData:(nullable NSData *)data forKey:(nonnull NSString *)key; |
| | | |
| | | /** |
| | | Removes the value of the specified key in the cache. |
| | | This method may blocks the calling thread until file delete finished. |
| | | |
| | | @param key The key identifying the value to be removed. If nil, this method has no effect. |
| | | */ |
| | | - (void)removeDataForKey:(nonnull NSString *)key; |
| | | |
| | | /** |
| | | Empties the cache. |
| | | This method may blocks the calling thread until file delete finished. |
| | | */ |
| | | - (void)removeAllData; |
| | | |
| | | /** |
| | | Removes the expired data from the cache. You can choose the data to remove base on `ageLimit`, `countLimit` and `sizeLimit` options. |
| | | */ |
| | | - (void)removeExpiredData; |
| | | |
| | | /** |
| | | The cache path for key |
| | | |
| | | @param key A string identifying the value |
| | | @return The cache path for key. Or nil if the key can not associate to a path |
| | | */ |
| | | - (nullable NSString *)cachePathForKey:(nonnull NSString *)key; |
| | | |
| | | /** |
| | | Returns the number of data in this cache. |
| | | This method may blocks the calling thread until file read finished. |
| | | |
| | | @return The total data count. |
| | | */ |
| | | - (NSUInteger)totalCount; |
| | | |
| | | /** |
| | | Returns the total size (in bytes) of data in this cache. |
| | | This method may blocks the calling thread until file read finished. |
| | | |
| | | @return The total data size in bytes. |
| | | */ |
| | | - (NSUInteger)totalSize; |
| | | |
| | | @end |
| | | |
| | | /** |
| | | The built-in disk cache. |
| | | */ |
| | | @interface BU_SDDiskCache : NSObject <BU_SDDiskCache> |
| | | /** |
| | | Cache Config object - storing all kind of settings. |
| | | */ |
| | | @property (nonatomic, strong, readonly, nonnull) BU_SDImageCacheConfig *config; |
| | | |
| | | - (nonnull instancetype)init NS_UNAVAILABLE; |
| | | |
| | | /** |
| | | Move the cache directory from old location to new location, the old location will be removed after finish. |
| | | If the old location does not exist, does nothing. |
| | | If the new location does not exist, only do a movement of directory. |
| | | If the new location does exist, will move and merge the files from old location. |
| | | If the new location does exist, but is not a directory, will remove it and do a movement of directory. |
| | | |
| | | @param srcPath old location of cache directory |
| | | @param dstPath new location of cache directory |
| | | */ |
| | | - (void)moveCacheDirectoryFromPath:(nonnull NSString *)srcPath toPath:(nonnull NSString *)dstPath; |
| | | |
| | | @end |
New file |
| | |
| | | /* |
| | | * This file is part of the SDWebImage package. |
| | | * (c) Olivier Poitrey <rs@dailymotion.com> |
| | | * |
| | | * For the full copyright and license information, please view the LICENSE |
| | | * file that was distributed with this source code. |
| | | */ |
| | | |
| | | #import <Foundation/Foundation.h> |
| | | #import "BU_SDWebImageCompat.h" |
| | | #import "BU_SDWebImageDefine.h" |
| | | #import "BU_SDImageCacheConfig.h" |
| | | #import "BU_SDImageCacheDefine.h" |
| | | #import "BU_SDMemoryCache.h" |
| | | #import "BU_SDDiskCache.h" |
| | | |
| | | /// Image Cache Options |
| | | typedef NS_OPTIONS(NSUInteger, BU_SDImageCacheOptions) { |
| | | /** |
| | | * By default, we do not query image data when the image is already cached in memory. This mask can force to query image data at the same time. However, this query is asynchronously unless you specify `SDImageCacheQueryMemoryDataSync` |
| | | */ |
| | | BU_SDImageCacheQueryMemoryData = 1 << 0, |
| | | /** |
| | | * By default, when you only specify `SDImageCacheQueryMemoryData`, we query the memory image data asynchronously. Combined this mask as well to query the memory image data synchronously. |
| | | */ |
| | | BU_SDImageCacheQueryMemoryDataSync = 1 << 1, |
| | | /** |
| | | * By default, when the memory cache miss, we query the disk cache asynchronously. This mask can force to query disk cache (when memory cache miss) synchronously. |
| | | @note These 3 query options can be combined together. For the full list about these masks combination, see wiki page. |
| | | */ |
| | | BU_SDImageCacheQueryDiskDataSync = 1 << 2, |
| | | /** |
| | | * By default, images are decoded respecting their original size. On iOS, this flag will scale down the |
| | | * images to a size compatible with the constrained memory of devices. |
| | | */ |
| | | BU_SDImageCacheScaleDownLargeImages = 1 << 3, |
| | | /** |
| | | * By default, we will decode the image in the background during cache query and download from the network. This can help to improve performance because when rendering image on the screen, it need to be firstly decoded. But this happen on the main queue by Core Animation. |
| | | * However, this process may increase the memory usage as well. If you are experiencing a issue due to excessive memory consumption, This flag can prevent decode the image. |
| | | */ |
| | | BU_SDImageCacheAvoidDecodeImage = 1 << 4, |
| | | /** |
| | | * By default, we decode the animated image. This flag can force decode the first frame only and produece the static image. |
| | | */ |
| | | BU_SDImageCacheDecodeFirstFrameOnly = 1 << 5, |
| | | /** |
| | | * By default, for `BU_SDAnimatedImage`, we decode the animated image frame during rendering to reduce memory usage. This flag actually trigger `preloadAllAnimatedImageFrames = YES` after image load from disk cache |
| | | */ |
| | | BU_SDImageCachePreloadAllFrames = 1 << 6, |
| | | /** |
| | | * By default, when you use `BU_SDWebImageContextAnimatedImageClass` context option (like using `SDAnimatedImageView` which designed to use `BU_SDAnimatedImage`), we may still use `UIImage` when the memory cache hit, or image decoder is not available, to behave as a fallback solution. |
| | | * Using this option, can ensure we always produce image with your provided class. If failed, a error with code `SDWebImageErrorBadImageData` will been used. |
| | | * Note this options is not compatible with `SDImageCacheDecodeFirstFrameOnly`, which always produce a UIImage/NSImage. |
| | | */ |
| | | BU_SDImageCacheMatchAnimatedImageClass = 1 << 7, |
| | | }; |
| | | |
| | | /** |
| | | * SDImageCache maintains a memory cache and a disk cache. Disk cache write operations are performed |
| | | * asynchronous so it doesn’t add unnecessary latency to the UI. |
| | | */ |
| | | @interface BU_SDImageCache : NSObject |
| | | |
| | | #pragma mark - Properties |
| | | |
| | | /** |
| | | * Cache Config object - storing all kind of settings. |
| | | * The property is copy so change of currrent config will not accidentally affect other cache's config. |
| | | */ |
| | | @property (nonatomic, copy, nonnull, readonly) BU_SDImageCacheConfig *config; |
| | | |
| | | /** |
| | | * The memory cache implementation object used for current image cache. |
| | | * By default we use `SDMemoryCache` class, you can also use this to call your own implementation class method. |
| | | * @note To customize this class, check `SDImageCacheConfig.memoryCacheClass` property. |
| | | */ |
| | | @property (nonatomic, strong, readonly, nonnull) id<BU_SDMemoryCache> memoryCache; |
| | | |
| | | /** |
| | | * The disk cache implementation object used for current image cache. |
| | | * By default we use `SDMemoryCache` class, you can also use this to call your own implementation class method. |
| | | * @note To customize this class, check `SDImageCacheConfig.diskCacheClass` property. |
| | | * @warning When calling method about read/write in disk cache, be sure to either make your disk cache implementation IO-safe or using the same access queue to avoid issues. |
| | | */ |
| | | @property (nonatomic, strong, readonly, nonnull) id<BU_SDDiskCache> diskCache; |
| | | |
| | | /** |
| | | * The disk cache's root path |
| | | */ |
| | | @property (nonatomic, copy, nonnull, readonly) NSString *diskCachePath; |
| | | |
| | | /** |
| | | * The additional disk cache path to check if the query from disk cache not exist; |
| | | * The `key` param is the image cache key. The returned file path will be used to load the disk cache. If return nil, ignore it. |
| | | * Useful if you want to bundle pre-loaded images with your app |
| | | */ |
| | | @property (nonatomic, copy, nullable) SDImageCacheAdditionalCachePathBlock additionalCachePathBlock; |
| | | |
| | | #pragma mark - Singleton and initialization |
| | | |
| | | /** |
| | | * Returns global shared cache instance |
| | | */ |
| | | @property (nonatomic, class, readonly, nonnull) BU_SDImageCache *sharedImageCache; |
| | | |
| | | /** |
| | | * Init a new cache store with a specific namespace |
| | | * |
| | | * @param ns The namespace to use for this cache store |
| | | */ |
| | | - (nonnull instancetype)initWithNamespace:(nonnull NSString *)ns; |
| | | |
| | | /** |
| | | * Init a new cache store with a specific namespace and directory. |
| | | * If you don't provide the disk cache directory, we will use the User Cache directory with prefix (~/Library/Caches/com.hackemist.SDImageCache/). |
| | | * |
| | | * @param ns The namespace to use for this cache store |
| | | * @param directory Directory to cache disk images in |
| | | */ |
| | | - (nonnull instancetype)initWithNamespace:(nonnull NSString *)ns |
| | | diskCacheDirectory:(nullable NSString *)directory; |
| | | |
| | | /** |
| | | * Init a new cache store with a specific namespace, directory and file manager |
| | | * The final disk cache directory should looks like ($directory/$namespace). And the default config of shared cache, should result in (~/Library/Caches/com.hackemist.SDImageCache/default/) |
| | | * |
| | | * @param ns The namespace to use for this cache store |
| | | * @param directory Directory to cache disk images in |
| | | * @param config The cache config to be used to create the cache. You can provide custom memory cache or disk cache class in the cache config |
| | | */ |
| | | - (nonnull instancetype)initWithNamespace:(nonnull NSString *)ns |
| | | diskCacheDirectory:(nullable NSString *)directory |
| | | config:(nullable BU_SDImageCacheConfig *)config NS_DESIGNATED_INITIALIZER; |
| | | |
| | | #pragma mark - Cache paths |
| | | |
| | | /** |
| | | Get the cache path for a certain key |
| | | |
| | | @param key The unique image cache key |
| | | @return The cache path. You can check `lastPathComponent` to grab the file name. |
| | | */ |
| | | - (nullable NSString *)cachePathForKey:(nullable NSString *)key; |
| | | |
| | | #pragma mark - Store Ops |
| | | |
| | | /** |
| | | * Asynchronously store an image into memory and disk cache at the given key. |
| | | * |
| | | * @param image The image to store |
| | | * @param key The unique image cache key, usually it's image absolute URL |
| | | * @param completionBlock A block executed after the operation is finished |
| | | */ |
| | | - (void)storeImage:(nullable UIImage *)image |
| | | forKey:(nullable NSString *)key |
| | | completion:(nullable SDWebImageNoParamsBlock)completionBlock; |
| | | |
| | | /** |
| | | * Asynchronously store an image into memory and disk cache at the given key. |
| | | * |
| | | * @param image The image to store |
| | | * @param key The unique image cache key, usually it's image absolute URL |
| | | * @param toDisk Store the image to disk cache if YES. If NO, the completion block is called synchronously |
| | | * @param completionBlock A block executed after the operation is finished |
| | | */ |
| | | - (void)storeImage:(nullable UIImage *)image |
| | | forKey:(nullable NSString *)key |
| | | toDisk:(BOOL)toDisk |
| | | completion:(nullable SDWebImageNoParamsBlock)completionBlock; |
| | | |
| | | /** |
| | | * Asynchronously store an image into memory and disk cache at the given key. |
| | | * |
| | | * @param image The image to store |
| | | * @param imageData The image data as returned by the server, this representation will be used for disk storage |
| | | * instead of converting the given image object into a storable/compressed image format in order |
| | | * to save quality and CPU |
| | | * @param key The unique image cache key, usually it's image absolute URL |
| | | * @param toDisk Store the image to disk cache if YES. If NO, the completion block is called synchronously |
| | | * @param completionBlock A block executed after the operation is finished |
| | | */ |
| | | - (void)storeImage:(nullable UIImage *)image |
| | | imageData:(nullable NSData *)imageData |
| | | forKey:(nullable NSString *)key |
| | | toDisk:(BOOL)toDisk |
| | | completion:(nullable SDWebImageNoParamsBlock)completionBlock; |
| | | |
| | | /** |
| | | * Synchronously store image into memory cache at the given key. |
| | | * |
| | | * @param image The image to store |
| | | * @param key The unique image cache key, usually it's image absolute URL |
| | | */ |
| | | - (void)storeImageToMemory:(nullable UIImage*)image |
| | | forKey:(nullable NSString *)key; |
| | | |
| | | /** |
| | | * Synchronously store image data into disk cache at the given key. |
| | | * |
| | | * @param imageData The image data to store |
| | | * @param key The unique image cache key, usually it's image absolute URL |
| | | */ |
| | | - (void)storeImageDataToDisk:(nullable NSData *)imageData |
| | | forKey:(nullable NSString *)key; |
| | | |
| | | |
| | | #pragma mark - Contains and Check Ops |
| | | |
| | | /** |
| | | * Asynchronously check if image exists in disk cache already (does not load the image) |
| | | * |
| | | * @param key the key describing the url |
| | | * @param completionBlock the block to be executed when the check is done. |
| | | * @note the completion block will be always executed on the main queue |
| | | */ |
| | | - (void)diskImageExistsWithKey:(nullable NSString *)key completion:(nullable SDImageCacheCheckCompletionBlock)completionBlock; |
| | | |
| | | /** |
| | | * Synchronously check if image data exists in disk cache already (does not load the image) |
| | | * |
| | | * @param key the key describing the url |
| | | */ |
| | | - (BOOL)diskImageDataExistsWithKey:(nullable NSString *)key; |
| | | |
| | | #pragma mark - Query and Retrieve Ops |
| | | |
| | | /** |
| | | * Asynchronously queries the cache with operation and call the completion when done. |
| | | * Query the image data for the given key synchronously. |
| | | * |
| | | * @param key The unique key used to store the wanted image |
| | | * @return The image data for the given key, or nil if not found. |
| | | */ |
| | | - (nullable NSData *)diskImageDataForKey:(nullable NSString *)key; |
| | | |
| | | /** |
| | | * Operation that queries the cache asynchronously and call the completion when done. |
| | | * |
| | | * @param key The unique key used to store the wanted image |
| | | * @param doneBlock The completion block. Will not get called if the operation is cancelled |
| | | * |
| | | * @return a NSOperation instance containing the cache op |
| | | */ |
| | | - (nullable NSOperation *)queryCacheOperationForKey:(nullable NSString *)key done:(nullable BU_SDImageCacheQueryCompletionBlock)doneBlock; |
| | | |
| | | /** |
| | | * Asynchronously queries the cache with operation and call the completion when done. |
| | | * |
| | | * @param key The unique key used to store the wanted image |
| | | * @param options A mask to specify options to use for this cache query |
| | | * @param doneBlock The completion block. Will not get called if the operation is cancelled |
| | | * |
| | | * @return a NSOperation instance containing the cache op |
| | | */ |
| | | - (nullable NSOperation *)queryCacheOperationForKey:(nullable NSString *)key options:(BU_SDImageCacheOptions)options done:(nullable BU_SDImageCacheQueryCompletionBlock)doneBlock; |
| | | |
| | | /** |
| | | * Asynchronously queries the cache with operation and call the completion when done. |
| | | * |
| | | * @param key The unique key used to store the wanted image |
| | | * @param options A mask to specify options to use for this cache query |
| | | * @param context A context contains different options to perform specify changes or processes, see `BU_SDWebImageContextOption`. This hold the extra objects which `options` enum can not hold. |
| | | * @param doneBlock The completion block. Will not get called if the operation is cancelled |
| | | * |
| | | * @return a NSOperation instance containing the cache op |
| | | */ |
| | | - (nullable NSOperation *)queryCacheOperationForKey:(nullable NSString *)key options:(BU_SDImageCacheOptions)options context:(nullable SDWebImageContext *)context done:(nullable BU_SDImageCacheQueryCompletionBlock)doneBlock; |
| | | |
| | | /** |
| | | * Synchronously query the memory cache. |
| | | * |
| | | * @param key The unique key used to store the image |
| | | * @return The image for the given key, or nil if not found. |
| | | */ |
| | | - (nullable UIImage *)imageFromMemoryCacheForKey:(nullable NSString *)key; |
| | | |
| | | /** |
| | | * Synchronously query the disk cache. |
| | | * |
| | | * @param key The unique key used to store the image |
| | | * @return The image for the given key, or nil if not found. |
| | | */ |
| | | - (nullable UIImage *)imageFromDiskCacheForKey:(nullable NSString *)key; |
| | | |
| | | /** |
| | | * Synchronously query the cache (memory and or disk) after checking the memory cache. |
| | | * |
| | | * @param key The unique key used to store the image |
| | | * @return The image for the given key, or nil if not found. |
| | | */ |
| | | - (nullable UIImage *)imageFromCacheForKey:(nullable NSString *)key; |
| | | |
| | | #pragma mark - Remove Ops |
| | | |
| | | /** |
| | | * Asynchronously remove the image from memory and disk cache |
| | | * |
| | | * @param key The unique image cache key |
| | | * @param completion A block that should be executed after the image has been removed (optional) |
| | | */ |
| | | - (void)removeImageForKey:(nullable NSString *)key withCompletion:(nullable SDWebImageNoParamsBlock)completion; |
| | | |
| | | /** |
| | | * Asynchronously remove the image from memory and optionally disk cache |
| | | * |
| | | * @param key The unique image cache key |
| | | * @param fromDisk Also remove cache entry from disk if YES. If NO, the completion block is called synchronously |
| | | * @param completion A block that should be executed after the image has been removed (optional) |
| | | */ |
| | | - (void)removeImageForKey:(nullable NSString *)key fromDisk:(BOOL)fromDisk withCompletion:(nullable SDWebImageNoParamsBlock)completion; |
| | | |
| | | /** |
| | | Synchronously remove the image from memory cache. |
| | | |
| | | @param key The unique image cache key |
| | | */ |
| | | - (void)removeImageFromMemoryForKey:(nullable NSString *)key; |
| | | |
| | | /** |
| | | Synchronously remove the image from disk cache. |
| | | |
| | | @param key The unique image cache key |
| | | */ |
| | | - (void)removeImageFromDiskForKey:(nullable NSString *)key; |
| | | |
| | | #pragma mark - Cache clean Ops |
| | | |
| | | /** |
| | | * Synchronously Clear all memory cached images |
| | | */ |
| | | - (void)clearMemory; |
| | | |
| | | /** |
| | | * Asynchronously clear all disk cached images. Non-blocking method - returns immediately. |
| | | * @param completion A block that should be executed after cache expiration completes (optional) |
| | | */ |
| | | - (void)clearDiskOnCompletion:(nullable SDWebImageNoParamsBlock)completion; |
| | | |
| | | /** |
| | | * Asynchronously remove all expired cached image from disk. Non-blocking method - returns immediately. |
| | | * @param completionBlock A block that should be executed after cache expiration completes (optional) |
| | | */ |
| | | - (void)deleteOldFilesWithCompletionBlock:(nullable SDWebImageNoParamsBlock)completionBlock; |
| | | |
| | | #pragma mark - Cache Info |
| | | |
| | | /** |
| | | * Get the total bytes size of images in the disk cache |
| | | */ |
| | | - (NSUInteger)totalDiskSize; |
| | | |
| | | /** |
| | | * Get the number of images in the disk cache |
| | | */ |
| | | - (NSUInteger)totalDiskCount; |
| | | |
| | | /** |
| | | * Asynchronously calculate the disk cache's size. |
| | | */ |
| | | - (void)calculateSizeWithCompletionBlock:(nullable SDImageCacheCalculateSizeBlock)completionBlock; |
| | | |
| | | @end |
| | | |
| | | /** |
| | | * SDImageCache is the built-in image cache implementation for web image manager. It adopts `SDImageCache` protocol to provide the function for web image manager to use for image loading process. |
| | | */ |
| | | @interface BU_SDImageCache (BU_SDImageCache) <BU_SDImageCache> |
| | | |
| | | @end |
New file |
| | |
| | | /* |
| | | * This file is part of the SDWebImage package. |
| | | * (c) Olivier Poitrey <rs@dailymotion.com> |
| | | * |
| | | * For the full copyright and license information, please view the LICENSE |
| | | * file that was distributed with this source code. |
| | | */ |
| | | |
| | | #import <Foundation/Foundation.h> |
| | | #import "BU_SDWebImageCompat.h" |
| | | |
| | | /// Image Cache Expire Type |
| | | typedef NS_ENUM(NSUInteger, BU_SDImageCacheConfigExpireType) { |
| | | /** |
| | | * When the image is accessed it will update this value |
| | | */ |
| | | BU_SDImageCacheConfigExpireTypeAccessDate, |
| | | /** |
| | | * The image was obtained from the disk cache (Default) |
| | | */ |
| | | BU_SDImageCacheConfigExpireTypeModificationDate |
| | | }; |
| | | |
| | | /** |
| | | The class contains all the config for image cache |
| | | @note This class conform to NSCopying, make sure to add the property in `copyWithZone:` as well. |
| | | */ |
| | | @interface BU_SDImageCacheConfig : NSObject <NSCopying> |
| | | |
| | | /** |
| | | Gets the default cache config used for shared instance or initialization when it does not provide any cache config. Such as `SDImageCache.sharedImageCache`. |
| | | @note You can modify the property on default cache config, which can be used for later created cache instance. The already created cache instance does not get affected. |
| | | */ |
| | | @property (nonatomic, class, readonly, nonnull) BU_SDImageCacheConfig *defaultCacheConfig; |
| | | |
| | | /** |
| | | * Whether or not to disable iCloud backup |
| | | * Defaults to YES. |
| | | */ |
| | | @property (assign, nonatomic) BOOL shouldDisableiCloud; |
| | | |
| | | /** |
| | | * Whether or not to use memory cache |
| | | * @note When the memory cache is disabled, the weak memory cache will also be disabled. |
| | | * Defaults to YES. |
| | | */ |
| | | @property (assign, nonatomic) BOOL shouldCacheImagesInMemory; |
| | | |
| | | /* |
| | | * The option to control weak memory cache for images. When enable, `SDImageCache`'s memory cache will use a weak maptable to store the image at the same time when it stored to memory, and get removed at the same time. |
| | | * However when memory warning is triggered, since the weak maptable does not hold a strong reference to image instance, even when the memory cache itself is purged, some images which are held strongly by UIImageViews or other live instances can be recovered again, to avoid later re-query from disk cache or network. This may be helpful for the case, for example, when app enter background and memory is purged, cause cell flashing after re-enter foreground. |
| | | * Defautls to YES. You can change this option dynamically. |
| | | */ |
| | | @property (assign, nonatomic) BOOL shouldUseWeakMemoryCache; |
| | | |
| | | /** |
| | | * Whether or not to remove the expired disk data when application entering the background. (Not works for macOS) |
| | | * Defaults to YES. |
| | | */ |
| | | @property (assign, nonatomic) BOOL shouldRemoveExpiredDataWhenEnterBackground; |
| | | |
| | | /** |
| | | * The reading options while reading cache from disk. |
| | | * Defaults to 0. You can set this to `NSDataReadingMappedIfSafe` to improve performance. |
| | | */ |
| | | @property (assign, nonatomic) NSDataReadingOptions diskCacheReadingOptions; |
| | | |
| | | /** |
| | | * The writing options while writing cache to disk. |
| | | * Defaults to `NSDataWritingAtomic`. You can set this to `NSDataWritingWithoutOverwriting` to prevent overwriting an existing file. |
| | | */ |
| | | @property (assign, nonatomic) NSDataWritingOptions diskCacheWritingOptions; |
| | | |
| | | /** |
| | | * The maximum length of time to keep an image in the disk cache, in seconds. |
| | | * Setting this to a negative value means no expiring. |
| | | * Setting this to zero means that all cached files would be removed when do expiration check. |
| | | * Defaults to 1 week. |
| | | */ |
| | | @property (assign, nonatomic) NSTimeInterval maxDiskAge; |
| | | |
| | | /** |
| | | * The maximum size of the disk cache, in bytes. |
| | | * Defaults to 0. Which means there is no cache size limit. |
| | | */ |
| | | @property (assign, nonatomic) NSUInteger maxDiskSize; |
| | | |
| | | /** |
| | | * The maximum "total cost" of the in-memory image cache. The cost function is the bytes size held in memory. |
| | | * @note The memory cost is bytes size in memory, but not simple pixels count. For common ARGB8888 image, one pixel is 4 bytes (32 bits). |
| | | * Defaults to 0. Which means there is no memory cost limit. |
| | | */ |
| | | @property (assign, nonatomic) NSUInteger maxMemoryCost; |
| | | |
| | | /** |
| | | * The maximum number of objects in-memory image cache should hold. |
| | | * Defaults to 0. Which means there is no memory count limit. |
| | | */ |
| | | @property (assign, nonatomic) NSUInteger maxMemoryCount; |
| | | |
| | | /* |
| | | * The attribute which the clear cache will be checked against when clearing the disk cache |
| | | * Default is Modified Date |
| | | */ |
| | | @property (assign, nonatomic) BU_SDImageCacheConfigExpireType diskCacheExpireType; |
| | | |
| | | /** |
| | | * The custom file manager for disk cache. Pass nil to let disk cache choose the proper file manager. |
| | | * Defaults to nil. |
| | | * @note This value does not support dynamic changes. Which means further modification on this value after cache initlized has no effect. |
| | | * @note Since `NSFileManager` does not support `NSCopying`. We just pass this by reference during copying. So it's not recommend to set this value on `defaultCacheConfig`. |
| | | */ |
| | | @property (strong, nonatomic, nullable) NSFileManager *fileManager; |
| | | |
| | | /** |
| | | * The custom memory cache class. Provided class instance must conform to `SDMemoryCache` protocol to allow usage. |
| | | * Defaults to built-in `SDMemoryCache` class. |
| | | * @note This value does not support dynamic changes. Which means further modification on this value after cache initlized has no effect. |
| | | */ |
| | | @property (assign, nonatomic, nonnull) Class memoryCacheClass; |
| | | |
| | | /** |
| | | * The custom disk cache class. Provided class instance must conform to `SDDiskCache` protocol to allow usage. |
| | | * Defaults to built-in `SDDiskCache` class. |
| | | * @note This value does not support dynamic changes. Which means further modification on this value after cache initlized has no effect. |
| | | */ |
| | | @property (assign ,nonatomic, nonnull) Class diskCacheClass; |
| | | |
| | | @end |
New file |
| | |
| | | /* |
| | | * This file is part of the SDWebImage package. |
| | | * (c) Olivier Poitrey <rs@dailymotion.com> |
| | | * |
| | | * For the full copyright and license information, please view the LICENSE |
| | | * file that was distributed with this source code. |
| | | */ |
| | | |
| | | #import <Foundation/Foundation.h> |
| | | #import "BU_SDWebImageCompat.h" |
| | | #import "BU_SDWebImageOperation.h" |
| | | #import "BU_SDWebImageDefine.h" |
| | | |
| | | /// Image Cache Type |
| | | typedef NS_ENUM(NSInteger, BU_SDImageCacheType) { |
| | | /** |
| | | * For query and contains op in response, means the image isn't available in the image cache |
| | | * For op in request, this type is not available and take no effect. |
| | | */ |
| | | BU_SDImageCacheTypeNone, |
| | | /** |
| | | * For query and contains op in response, means the image was obtained from the disk cache. |
| | | * For op in request, means process only disk cache. |
| | | */ |
| | | BU_SDImageCacheTypeDisk, |
| | | /** |
| | | * For query and contains op in response, means the image was obtained from the memory cache. |
| | | * For op in request, means process only memory cache. |
| | | */ |
| | | BU_SDImageCacheTypeMemory, |
| | | /** |
| | | * For query and contains op in response, this type is not available and take no effect. |
| | | * For op in request, means process both memory cache and disk cache. |
| | | */ |
| | | BU_SDImageCacheTypeAll |
| | | }; |
| | | |
| | | typedef void(^SDImageCacheCheckCompletionBlock)(BOOL isInCache); |
| | | typedef void(^SDImageCacheCalculateSizeBlock)(NSUInteger fileCount, NSUInteger totalSize); |
| | | typedef NSString * _Nullable (^SDImageCacheAdditionalCachePathBlock)(NSString * _Nonnull key); |
| | | typedef void(^BU_SDImageCacheQueryCompletionBlock)(UIImage * _Nullable image, NSData * _Nullable data, BU_SDImageCacheType cacheType); |
| | | typedef void(^BU_SDImageCacheContainsCompletionBlock)(BU_SDImageCacheType containsCacheType); |
| | | |
| | | /** |
| | | This is the built-in decoding process for image query from cache. |
| | | @note If you want to implement your custom loader with `queryImageForKey:options:context:completion:` API, but also want to keep compatible with SDWebImage's behavior, you'd better use this to produce image. |
| | | |
| | | @param imageData The image data from the cache. Should not be nil |
| | | @param cacheKey The image cache key from the input. Should not be nil |
| | | @param options The options arg from the input |
| | | @param context The context arg from the input |
| | | @return The decoded image for current image data query from cache |
| | | */ |
| | | FOUNDATION_EXPORT UIImage * _Nullable BU_SDImageCacheDecodeImageData(NSData * _Nonnull imageData, NSString * _Nonnull cacheKey, BU_SDWebImageOptions options, SDWebImageContext * _Nullable context); |
| | | |
| | | /** |
| | | This is the image cache protocol to provide custom image cache for `SDWebImageManager`. |
| | | Though the best practice to custom image cache, is to write your own class which conform `SDMemoryCache` or `SDDiskCache` protocol for `SDImageCache` class (See more on `SDImageCacheConfig.memoryCacheClass & SDImageCacheConfig.diskCacheClass`). |
| | | However, if your own cache implementation contains more advanced feature beyond `SDImageCache` itself, you can consider to provide this instead. For example, you can even use a cache manager like `SDImageCachesManager` to register multiple caches. |
| | | */ |
| | | @protocol BU_SDImageCache <NSObject> |
| | | |
| | | @required |
| | | /** |
| | | Query the cached image from image cache for given key. The operation can be used to cancel the query. |
| | | If image is cached in memory, completion is called synchronously, else aynchronously and depends on the options arg (See `SDWebImageQueryDiskSync`) |
| | | |
| | | @param key The image cache key |
| | | @param options A mask to specify options to use for this query |
| | | @param context A context contains different options to perform specify changes or processes, see `BU_SDWebImageContextOption`. This hold the extra objects which `options` enum can not hold. |
| | | @param completionBlock The completion block. Will not get called if the operation is cancelled |
| | | @return The operation for this query |
| | | */ |
| | | - (nullable id<BU_SDWebImageOperation>)queryImageForKey:(nullable NSString *)key |
| | | options:(BU_SDWebImageOptions)options |
| | | context:(nullable SDWebImageContext *)context |
| | | completion:(nullable BU_SDImageCacheQueryCompletionBlock)completionBlock; |
| | | |
| | | /** |
| | | Store the image into image cache for the given key. If cache type is memory only, completion is called synchronously, else aynchronously. |
| | | |
| | | @param image The image to store |
| | | @param imageData The image data to be used for disk storage |
| | | @param key The image cache key |
| | | @param cacheType The image store op cache type |
| | | @param completionBlock A block executed after the operation is finished |
| | | */ |
| | | - (void)storeImage:(nullable UIImage *)image |
| | | imageData:(nullable NSData *)imageData |
| | | forKey:(nullable NSString *)key |
| | | cacheType:(BU_SDImageCacheType)cacheType |
| | | completion:(nullable SDWebImageNoParamsBlock)completionBlock; |
| | | |
| | | /** |
| | | Remove the image from image cache for the given key. If cache type is memory only, completion is called synchronously, else aynchronously. |
| | | |
| | | @param key The image cache key |
| | | @param cacheType The image remove op cache type |
| | | @param completionBlock A block executed after the operation is finished |
| | | */ |
| | | - (void)removeImageForKey:(nullable NSString *)key |
| | | cacheType:(BU_SDImageCacheType)cacheType |
| | | completion:(nullable SDWebImageNoParamsBlock)completionBlock; |
| | | |
| | | /** |
| | | Check if image cache contains the image for the given key (does not load the image). If image is cached in memory, completion is called synchronously, else aynchronously. |
| | | |
| | | @param key The image cache key |
| | | @param cacheType The image contains op cache type |
| | | @param completionBlock A block executed after the operation is finished. |
| | | */ |
| | | - (void)containsImageForKey:(nullable NSString *)key |
| | | cacheType:(BU_SDImageCacheType)cacheType |
| | | completion:(nullable BU_SDImageCacheContainsCompletionBlock)completionBlock; |
| | | |
| | | /** |
| | | Clear all the cached images for image cache. If cache type is memory only, completion is called synchronously, else aynchronously. |
| | | |
| | | @param cacheType The image clear op cache type |
| | | @param completionBlock A block executed after the operation is finished |
| | | */ |
| | | - (void)clearWithCacheType:(BU_SDImageCacheType)cacheType |
| | | completion:(nullable SDWebImageNoParamsBlock)completionBlock; |
| | | |
| | | @end |
New file |
| | |
| | | /* |
| | | * This file is part of the SDWebImage package. |
| | | * (c) Olivier Poitrey <rs@dailymotion.com> |
| | | * |
| | | * For the full copyright and license information, please view the LICENSE |
| | | * file that was distributed with this source code. |
| | | */ |
| | | |
| | | #import "BU_SDWebImageCompat.h" |
| | | #import "BU_SDWebImageDefine.h" |
| | | #import "BU_SDWebImageOperation.h" |
| | | |
| | | typedef void(^SDImageLoaderProgressBlock)(NSInteger receivedSize, NSInteger expectedSize, NSURL * _Nullable targetURL); |
| | | typedef void(^SDImageLoaderCompletedBlock)(UIImage * _Nullable image, NSData * _Nullable data, NSError * _Nullable error, BOOL finished); |
| | | |
| | | #pragma mark - Context Options |
| | | |
| | | /** |
| | | A `UIImage` instance from `SDWebImageManager` when you specify `SDWebImageRefreshCached` and image cache hit. |
| | | This can be a hint for image loader to load the image from network and refresh the image from remote location if needed. If the image from remote location does not change, you should call the completion with `SDWebImageErrorCacheNotModified` error. (UIImage) |
| | | @note If you don't implement `SDWebImageRefreshCached` support, you do not need to care abot this context option. |
| | | */ |
| | | FOUNDATION_EXPORT BU_SDWebImageContextOption _Nonnull const BU_SDWebImageContextLoaderCachedImage; |
| | | |
| | | #pragma mark - Helper method |
| | | |
| | | /** |
| | | This is the built-in decoding process for image download from network or local file. |
| | | @note If you want to implement your custom loader with `requestImageWithURL:options:context:progress:completed:` API, but also want to keep compatible with SDWebImage's behavior, you'd better use this to produce image. |
| | | |
| | | @param imageData The image data from the network. Should not be nil |
| | | @param imageURL The image URL from the input. Should not be nil |
| | | @param options The options arg from the input |
| | | @param context The context arg from the input |
| | | @return The decoded image for current image data load from the network |
| | | */ |
| | | FOUNDATION_EXPORT UIImage * _Nullable BU_SDImageLoaderDecodeImageData(NSData * _Nonnull imageData, NSURL * _Nonnull imageURL, BU_SDWebImageOptions options, SDWebImageContext * _Nullable context); |
| | | |
| | | /** |
| | | This is the built-in decoding process for image progressive download from network. It's used when `SDWebImageProgressiveLoad` option is set. (It's not required when your loader does not support progressive image loading) |
| | | @note If you want to implement your custom loader with `requestImageWithURL:options:context:progress:completed:` API, but also want to keep compatible with SDWebImage's behavior, you'd better use this to produce image. |
| | | |
| | | @param imageData The image data from the network so far. Should not be nil |
| | | @param imageURL The image URL from the input. Should not be nil |
| | | @param finished Pass NO to specify the download process has not finished. Pass YES when all image data has finished. |
| | | @param operation The loader operation associated with current progressive download. Why to provide this is because progressive decoding need to store the partial decoded context for each operation to avoid conflict. You should provide the operation from `loadImageWithURL:` method return value. |
| | | @param options The options arg from the input |
| | | @param context The context arg from the input |
| | | @return The decoded progressive image for current image data load from the network |
| | | */ |
| | | FOUNDATION_EXPORT UIImage * _Nullable BU_SDImageLoaderDecodeProgressiveImageData(NSData * _Nonnull imageData, NSURL * _Nonnull imageURL, BOOL finished, id<BU_SDWebImageOperation> _Nonnull operation, BU_SDWebImageOptions options, SDWebImageContext * _Nullable context); |
| | | |
| | | #pragma mark - SDImageLoader |
| | | |
| | | /** |
| | | This is the protocol to specify custom image load process. You can create your own class to conform this protocol and use as a image loader to load image from network or any avaiable remote resources defined by yourself. |
| | | If you want to implement custom loader for image download from network or local file, you just need to concentrate on image data download only. After the download finish, call `BU_SDImageLoaderDecodeImageData` or `BU_SDImageLoaderDecodeProgressiveImageData` to use the built-in decoding process and produce image (Remember to call in the global queue). And finally callback the completion block. |
| | | If you directlly get the image instance using some third-party SDKs, such as image directlly from Photos framework. You can process the image data and image instance by yourself without that built-in decoding process. And finally callback the completion block. |
| | | @note It's your responsibility to load the image in the desired global queue(to avoid block main queue). We do not dispatch these method call in a global queue but just from the call queue (For `SDWebImageManager`, it typically call from the main queue). |
| | | */ |
| | | @protocol BU_SDImageLoader <NSObject> |
| | | |
| | | /** |
| | | Whether current image loader supports to load the provide image URL. |
| | | This will be checked everytime a new image request come for loader. If this return NO, we will mark this image load as failed. If return YES, we will start to call `requestImageWithURL:options:context:progress:completed:`. |
| | | |
| | | @param url The image URL to be loaded. |
| | | @return YES to continue download, NO to stop download. |
| | | */ |
| | | - (BOOL)canRequestImageForURL:(nullable NSURL *)url; |
| | | |
| | | /** |
| | | Load the image and image data with the given URL and return the image data. You're responsible for producing the image instance. |
| | | |
| | | @param url The URL represent the image. Note this may not be a HTTP URL |
| | | @param options A mask to specify options to use for this request |
| | | @param context A context contains different options to perform specify changes or processes, see `BU_SDWebImageContextOption`. This hold the extra objects which `options` enum can not hold. |
| | | @param progressBlock A block called while image is downloading |
| | | * @note the progress block is executed on a background queue |
| | | @param completedBlock A block called when operation has been completed. |
| | | @return An operation which allow the user to cancel the current request. |
| | | */ |
| | | - (nullable id<BU_SDWebImageOperation>)requestImageWithURL:(nullable NSURL *)url |
| | | options:(BU_SDWebImageOptions)options |
| | | context:(nullable SDWebImageContext *)context |
| | | progress:(nullable SDImageLoaderProgressBlock)progressBlock |
| | | completed:(nullable SDImageLoaderCompletedBlock)completedBlock; |
| | | |
| | | |
| | | /** |
| | | Whether the error from image loader should be marked indded un-recoverable or not. |
| | | If this return YES, failed URL which does not using `SDWebImageRetryFailed` will be blocked into black list. Else not. |
| | | |
| | | @param url The URL represent the image. Note this may not be a HTTP URL |
| | | @param error The URL's loading error, from previous `requestImageWithURL:options:context:progress:completed:` completedBlock's error. |
| | | @return Whether to block this url or not. Return YES to mark this URL as failed. |
| | | */ |
| | | - (BOOL)shouldBlockFailedURLWithURL:(nonnull NSURL *)url |
| | | error:(nonnull NSError *)error; |
| | | |
| | | @end |
New file |
| | |
| | | /* |
| | | * This file is part of the SDWebImage package. |
| | | * (c) Olivier Poitrey <rs@dailymotion.com> |
| | | * |
| | | * For the full copyright and license information, please view the LICENSE |
| | | * file that was distributed with this source code. |
| | | */ |
| | | |
| | | #import "BU_SDWebImageCompat.h" |
| | | #import "UIImage+BUTransform.h" |
| | | |
| | | /** |
| | | Return the transformed cache key which applied with specify transformerKey. |
| | | |
| | | @param key The original cache key |
| | | @param transformerKey The transformer key from the transformer |
| | | @return The transformed cache key |
| | | */ |
| | | FOUNDATION_EXPORT NSString * _Nullable BU_SDTransformedKeyForKey(NSString * _Nullable key, NSString * _Nonnull transformerKey); |
| | | |
| | | /** |
| | | A transformer protocol to transform the image load from cache or from download. |
| | | You can provide transformer to cache and manager (Through the `transformer` property or context option `BU_SDWebImageContextImageTransformer`). |
| | | |
| | | @note The transform process is called from a global queue in order to not to block the main queue. |
| | | */ |
| | | @protocol BU_SDImageTransformer <NSObject> |
| | | |
| | | @required |
| | | /** |
| | | For each transformer, it must contains its cache key to used to store the image cache or query from the cache. This key will be appened after the original cache key generated by URL or from user. |
| | | |
| | | @return The cache key to appended after the original cache key. Should not be nil. |
| | | */ |
| | | @property (nonatomic, copy, readonly, nonnull) NSString *transformerKey; |
| | | |
| | | /** |
| | | Transform the image to another image. |
| | | |
| | | @param image The image to be transformed |
| | | @param key The cache key associated to the image |
| | | @return The transformed image, or nil if transform failed |
| | | */ |
| | | - (nullable UIImage *)transformedImageWithImage:(nonnull UIImage *)image forKey:(nonnull NSString *)key; |
| | | |
| | | @end |
| | | |
| | | #pragma mark - Pipeline |
| | | |
| | | /** |
| | | Pipeline transformer. Which you can bind multiple transformers together to let the image to be transformed one by one in order and generate the final image. |
| | | @note Because transformers are lightweight, if you want to append or arrange transfomers, create another pipeline transformer instead. This class is considered as immutable. |
| | | */ |
| | | @interface BU_SDImagePipelineTransformer : NSObject <BU_SDImageTransformer> |
| | | |
| | | /** |
| | | All transformers in pipeline |
| | | */ |
| | | @property (nonatomic, copy, readonly, nonnull) NSArray<id<BU_SDImageTransformer>> *transformers; |
| | | |
| | | - (nonnull instancetype)init NS_UNAVAILABLE; |
| | | + (nonnull instancetype)transformerWithTransformers:(nonnull NSArray<id<BU_SDImageTransformer>> *)transformers; |
| | | |
| | | @end |
| | | |
| | | // There are some built-in transformers based on the `UIImage+BUTransformer` category to provide the common image geometry, image blending and image effect process. Those transform are useful for static image only but you can create your own to support animated image as well. |
| | | // Because transformers are lightweight, these class are considered as immutable. |
| | | #pragma mark - Image Geometry |
| | | |
| | | /** |
| | | Image round corner transformer |
| | | */ |
| | | @interface BU_SDImageRoundCornerTransformer: NSObject <BU_SDImageTransformer> |
| | | |
| | | /** |
| | | The radius of each corner oval. Values larger than half the |
| | | rectangle's width or height are clamped appropriately to |
| | | half the width or height. |
| | | */ |
| | | @property (nonatomic, assign, readonly) CGFloat cornerRadius; |
| | | |
| | | /** |
| | | A bitmask value that identifies the corners that you want |
| | | rounded. You can use this parameter to round only a subset |
| | | of the corners of the rectangle. |
| | | */ |
| | | @property (nonatomic, assign, readonly) BU_SDRectCorner corners; |
| | | |
| | | /** |
| | | The inset border line width. Values larger than half the rectangle's |
| | | width or height are clamped appropriately to half the width |
| | | or height. |
| | | */ |
| | | @property (nonatomic, assign, readonly) CGFloat borderWidth; |
| | | |
| | | /** |
| | | The border stroke color. nil means clear color. |
| | | */ |
| | | @property (nonatomic, strong, readonly, nullable) UIColor *borderColor; |
| | | |
| | | - (nonnull instancetype)init NS_UNAVAILABLE; |
| | | + (nonnull instancetype)transformerWithRadius:(CGFloat)cornerRadius corners:(BU_SDRectCorner)corners borderWidth:(CGFloat)borderWidth borderColor:(nullable UIColor *)borderColor; |
| | | |
| | | @end |
| | | |
| | | /** |
| | | Image resizing transformer |
| | | */ |
| | | @interface BU_SDImageResizingTransformer : NSObject <BU_SDImageTransformer> |
| | | |
| | | /** |
| | | The new size to be resized, values should be positive. |
| | | */ |
| | | @property (nonatomic, assign, readonly) CGSize size; |
| | | |
| | | /** |
| | | The scale mode for image content. |
| | | */ |
| | | @property (nonatomic, assign, readonly) BU_SDImageScaleMode scaleMode; |
| | | |
| | | - (nonnull instancetype)init NS_UNAVAILABLE; |
| | | + (nonnull instancetype)transformerWithSize:(CGSize)size scaleMode:(BU_SDImageScaleMode)scaleMode; |
| | | |
| | | @end |
| | | |
| | | /** |
| | | Image cropping transformer |
| | | */ |
| | | @interface BU_SDImageCroppingTransformer : NSObject <BU_SDImageTransformer> |
| | | |
| | | /** |
| | | Image's inner rect. |
| | | */ |
| | | @property (nonatomic, assign, readonly) CGRect rect; |
| | | |
| | | - (nonnull instancetype)init NS_UNAVAILABLE; |
| | | + (nonnull instancetype)transformerWithRect:(CGRect)rect; |
| | | |
| | | @end |
| | | |
| | | /** |
| | | Image flipping transformer |
| | | */ |
| | | @interface BU_SDImageFlippingTransformer : NSObject <BU_SDImageTransformer> |
| | | |
| | | /** |
| | | YES to flip the image horizontally. ⇋ |
| | | */ |
| | | @property (nonatomic, assign, readonly) BOOL horizontal; |
| | | |
| | | /** |
| | | YES to flip the image vertically. ⥯ |
| | | */ |
| | | @property (nonatomic, assign, readonly) BOOL vertical; |
| | | |
| | | - (nonnull instancetype)init NS_UNAVAILABLE; |
| | | + (nonnull instancetype)transformerWithHorizontal:(BOOL)horizontal vertical:(BOOL)vertical; |
| | | |
| | | @end |
| | | |
| | | /** |
| | | Image rotation transformer |
| | | */ |
| | | @interface BU_SDImageRotationTransformer : NSObject <BU_SDImageTransformer> |
| | | |
| | | /** |
| | | Rotated radians in counterclockwise.⟲ |
| | | */ |
| | | @property (nonatomic, assign, readonly) CGFloat angle; |
| | | |
| | | /** |
| | | YES: new image's size is extend to fit all content. |
| | | NO: image's size will not change, content may be clipped. |
| | | */ |
| | | @property (nonatomic, assign, readonly) BOOL fitSize; |
| | | |
| | | - (nonnull instancetype)init NS_UNAVAILABLE; |
| | | + (nonnull instancetype)transformerWithAngle:(CGFloat)angle fitSize:(BOOL)fitSize; |
| | | |
| | | @end |
| | | |
| | | #pragma mark - Image Blending |
| | | |
| | | /** |
| | | Image tint color transformer |
| | | */ |
| | | @interface BU_SDImageTintTransformer : NSObject <BU_SDImageTransformer> |
| | | |
| | | /** |
| | | The tint color. |
| | | */ |
| | | @property (nonatomic, strong, readonly, nonnull) UIColor *tintColor; |
| | | |
| | | - (nonnull instancetype)init NS_UNAVAILABLE; |
| | | + (nonnull instancetype)transformerWithColor:(nonnull UIColor *)tintColor; |
| | | |
| | | @end |
| | | |
| | | #pragma mark - Image Effect |
| | | |
| | | /** |
| | | Image blur effect transformer |
| | | */ |
| | | @interface BU_SDImageBlurTransformer : NSObject <BU_SDImageTransformer> |
| | | |
| | | /** |
| | | The radius of the blur in points, 0 means no blur effect. |
| | | */ |
| | | @property (nonatomic, assign, readonly) CGFloat blurRadius; |
| | | |
| | | - (nonnull instancetype)init NS_UNAVAILABLE; |
| | | + (nonnull instancetype)transformerWithRadius:(CGFloat)blurRadius; |
| | | |
| | | @end |
| | | |
| | | #if SD_UIKIT || SD_MAC |
| | | /** |
| | | Core Image filter transformer |
| | | */ |
| | | @interface BU_SDImageFilterTransformer: NSObject <BU_SDImageTransformer> |
| | | |
| | | /** |
| | | The CIFilter to be applied to the image. |
| | | */ |
| | | @property (nonatomic, strong, readonly, nonnull) CIFilter *filter; |
| | | |
| | | - (nonnull instancetype)init NS_UNAVAILABLE; |
| | | + (nonnull instancetype)transformerWithFilter:(nonnull CIFilter *)filter; |
| | | |
| | | @end |
| | | #endif |
New file |
| | |
| | | /* |
| | | * This file is part of the SDWebImage package. |
| | | * (c) Olivier Poitrey <rs@dailymotion.com> |
| | | * |
| | | * For the full copyright and license information, please view the LICENSE |
| | | * file that was distributed with this source code. |
| | | */ |
| | | |
| | | #import "BU_SDWebImageCompat.h" |
| | | |
| | | @class BU_SDImageCacheConfig; |
| | | /** |
| | | A protocol to allow custom memory cache used in SDImageCache. |
| | | */ |
| | | @protocol BU_SDMemoryCache <NSObject> |
| | | |
| | | @required |
| | | /** |
| | | Create a new memory cache instance with the specify cache config. You can check `maxMemoryCost` and `maxMemoryCount` used for memory cache. |
| | | |
| | | @param config The cache config to be used to create the cache. |
| | | @return The new memory cache instance. |
| | | */ |
| | | - (nonnull instancetype)initWithConfig:(nonnull BU_SDImageCacheConfig *)config; |
| | | |
| | | /** |
| | | Returns the value associated with a given key. |
| | | |
| | | @param key An object identifying the value. If nil, just return nil. |
| | | @return The value associated with key, or nil if no value is associated with key. |
| | | */ |
| | | - (nullable id)objectForKey:(nonnull id)key; |
| | | |
| | | /** |
| | | Sets the value of the specified key in the cache (0 cost). |
| | | |
| | | @param object The object to be stored in the cache. If nil, it calls `removeObjectForKey:`. |
| | | @param key The key with which to associate the value. If nil, this method has no effect. |
| | | @discussion Unlike an NSMutableDictionary object, a cache does not copy the key |
| | | objects that are put into it. |
| | | */ |
| | | - (void)setObject:(nullable id)object forKey:(nonnull id)key; |
| | | |
| | | /** |
| | | Sets the value of the specified key in the cache, and associates the key-value |
| | | pair with the specified cost. |
| | | |
| | | @param object The object to store in the cache. If nil, it calls `removeObjectForKey`. |
| | | @param key The key with which to associate the value. If nil, this method has no effect. |
| | | @param cost The cost with which to associate the key-value pair. |
| | | @discussion Unlike an NSMutableDictionary object, a cache does not copy the key |
| | | objects that are put into it. |
| | | */ |
| | | - (void)setObject:(nullable id)object forKey:(nonnull id)key cost:(NSUInteger)cost; |
| | | |
| | | /** |
| | | Removes the value of the specified key in the cache. |
| | | |
| | | @param key The key identifying the value to be removed. If nil, this method has no effect. |
| | | */ |
| | | - (void)removeObjectForKey:(nonnull id)key; |
| | | |
| | | /** |
| | | Empties the cache immediately. |
| | | */ |
| | | - (void)removeAllObjects; |
| | | |
| | | @end |
| | | |
| | | /** |
| | | A memory cache which auto purge the cache on memory warning and support weak cache. |
| | | */ |
| | | @interface BU_SDMemoryCache <KeyType, ObjectType> : NSCache <KeyType, ObjectType> <BU_SDMemoryCache> |
| | | |
| | | @property (nonatomic, strong, nonnull, readonly) BU_SDImageCacheConfig *config; |
| | | |
| | | @end |
New file |
| | |
| | | /* |
| | | * This file is part of the SDWebImage package. |
| | | * (c) Olivier Poitrey <rs@dailymotion.com> |
| | | * |
| | | * For the full copyright and license information, please view the LICENSE |
| | | * file that was distributed with this source code. |
| | | */ |
| | | |
| | | #import <Foundation/Foundation.h> |
| | | #import "BU_SDWebImageCompat.h" |
| | | |
| | | typedef NSString * _Nullable(^SDWebImageCacheKeyFilterBlock)(NSURL * _Nonnull url); |
| | | |
| | | /** |
| | | This is the protocol for cache key filter. |
| | | We can use a block to specify the cache key filter. But Using protocol can make this extensible, and allow Swift user to use it easily instead of using `@convention(block)` to store a block into context options. |
| | | */ |
| | | @protocol BU_SDWebImageCacheKeyFilter <NSObject> |
| | | |
| | | - (nullable NSString *)cacheKeyForURL:(nonnull NSURL *)url; |
| | | |
| | | @end |
| | | |
| | | /** |
| | | A cache key filter class with block. |
| | | */ |
| | | @interface BU_SDWebImageCacheKeyFilter : NSObject <BU_SDWebImageCacheKeyFilter> |
| | | |
| | | - (nonnull instancetype)initWithBlock:(nonnull SDWebImageCacheKeyFilterBlock)block; |
| | | + (nonnull instancetype)cacheKeyFilterWithBlock:(nonnull SDWebImageCacheKeyFilterBlock)block; |
| | | |
| | | @end |
New file |
| | |
| | | /* |
| | | * This file is part of the SDWebImage package. |
| | | * (c) Olivier Poitrey <rs@dailymotion.com> |
| | | * |
| | | * For the full copyright and license information, please view the LICENSE |
| | | * file that was distributed with this source code. |
| | | */ |
| | | |
| | | #import <Foundation/Foundation.h> |
| | | #import "BU_SDWebImageCompat.h" |
| | | |
| | | typedef NSData * _Nullable(^BU_SDWebImageCacheSerializerBlock)(UIImage * _Nonnull image, NSData * _Nullable data, NSURL * _Nullable imageURL); |
| | | |
| | | /** |
| | | This is the protocol for cache serializer. |
| | | We can use a block to specify the cache serializer. But Using protocol can make this extensible, and allow Swift user to use it easily instead of using `@convention(block)` to store a block into context options. |
| | | */ |
| | | @protocol BU_SDWebImageCacheSerializer <NSObject> |
| | | |
| | | - (nullable NSData *)cacheDataWithImage:(nonnull UIImage *)image originalData:(nullable NSData *)data imageURL:(nullable NSURL *)imageURL; |
| | | |
| | | @end |
| | | |
| | | /** |
| | | A cache serializer class with block. |
| | | */ |
| | | @interface BU_SDWebImageCacheSerializer : NSObject <BU_SDWebImageCacheSerializer> |
| | | |
| | | - (nonnull instancetype)initWithBlock:(nonnull BU_SDWebImageCacheSerializerBlock)block; |
| | | + (nonnull instancetype)cacheSerializerWithBlock:(nonnull BU_SDWebImageCacheSerializerBlock)block; |
| | | |
| | | @end |
New file |
| | |
| | | /* |
| | | * This file is part of the SDWebImage package. |
| | | * (c) Olivier Poitrey <rs@dailymotion.com> |
| | | * (c) Jamie Pinkham |
| | | * |
| | | * For the full copyright and license information, please view the LICENSE |
| | | * file that was distributed with this source code. |
| | | */ |
| | | |
| | | #import <TargetConditionals.h> |
| | | |
| | | #ifdef __OBJC_GC__ |
| | | #error SDWebImage does not support Objective-C Garbage Collection |
| | | #endif |
| | | |
| | | // Seems like TARGET_OS_MAC is always defined (on all platforms). |
| | | // To determine if we are running on macOS, use TARGET_OS_OSX in Xcode 8 |
| | | #if TARGET_OS_OSX |
| | | #define SD_MAC 1 |
| | | #else |
| | | #define SD_MAC 0 |
| | | #endif |
| | | |
| | | // iOS and tvOS are very similar, UIKit exists on both platforms |
| | | // Note: watchOS also has UIKit, but it's very limited |
| | | #if TARGET_OS_IOS || TARGET_OS_TV |
| | | #define SD_UIKIT 1 |
| | | #else |
| | | #define SD_UIKIT 0 |
| | | #endif |
| | | |
| | | #if TARGET_OS_IOS |
| | | #define SD_IOS 1 |
| | | #else |
| | | #define SD_IOS 0 |
| | | #endif |
| | | |
| | | #if TARGET_OS_TV |
| | | #define SD_TV 1 |
| | | #else |
| | | #define SD_TV 0 |
| | | #endif |
| | | |
| | | #if TARGET_OS_WATCH |
| | | #define SD_WATCH 1 |
| | | #else |
| | | #define SD_WATCH 0 |
| | | #endif |
| | | |
| | | |
| | | #if SD_MAC |
| | | #import <AppKit/AppKit.h> |
| | | #ifndef UIImage |
| | | #define UIImage NSImage |
| | | #endif |
| | | #ifndef UIImageView |
| | | #define UIImageView NSImageView |
| | | #endif |
| | | #ifndef UIView |
| | | #define UIView NSView |
| | | #endif |
| | | #ifndef UIColor |
| | | #define UIColor NSColor |
| | | #endif |
| | | #else |
| | | #if SD_UIKIT |
| | | #import <UIKit/UIKit.h> |
| | | #endif |
| | | #if SD_WATCH |
| | | #import <WatchKit/WatchKit.h> |
| | | #ifndef UIView |
| | | #define UIView WKInterfaceObject |
| | | #endif |
| | | #ifndef UIImageView |
| | | #define UIImageView WKInterfaceImage |
| | | #endif |
| | | #endif |
| | | #endif |
| | | |
| | | #ifndef NS_ENUM |
| | | #define NS_ENUM(_type, _name) enum _name : _type _name; enum _name : _type |
| | | #endif |
| | | |
| | | #ifndef NS_OPTIONS |
| | | #define NS_OPTIONS(_type, _name) enum _name : _type _name; enum _name : _type |
| | | #endif |
| | | |
| | | #ifndef dispatch_main_async_safe |
| | | #define dispatch_main_async_safe(block)\ |
| | | if (dispatch_queue_get_label(DISPATCH_CURRENT_QUEUE_LABEL) == dispatch_queue_get_label(dispatch_get_main_queue())) {\ |
| | | block();\ |
| | | } else {\ |
| | | dispatch_async(dispatch_get_main_queue(), block);\ |
| | | } |
| | | #endif |
New file |
| | |
| | | /* |
| | | * This file is part of the SDWebImage package. |
| | | * (c) Olivier Poitrey <rs@dailymotion.com> |
| | | * |
| | | * For the full copyright and license information, please view the LICENSE |
| | | * file that was distributed with this source code. |
| | | */ |
| | | |
| | | #import "BU_SDWebImageCompat.h" |
| | | |
| | | typedef void(^SDWebImageNoParamsBlock)(void); |
| | | typedef NSString * BU_SDWebImageContextOption NS_EXTENSIBLE_STRING_ENUM; |
| | | typedef NSDictionary<BU_SDWebImageContextOption, id> SDWebImageContext; |
| | | typedef NSMutableDictionary<BU_SDWebImageContextOption, id> SDWebImageMutableContext; |
| | | |
| | | #pragma mark - Image scale |
| | | |
| | | /** |
| | | Return the image scale factor for the specify key, supports file name and url key. |
| | | This is the built-in way to check the scale factor when we have no context about it. Because scale factor is not stored in image data (It's typically from filename). |
| | | However, you can also provide custom scale factor as well, see `BU_SDWebImageContextImageScaleFactor`. |
| | | |
| | | @param key The image cache key |
| | | @return The scale factor for image |
| | | */ |
| | | FOUNDATION_EXPORT CGFloat BU_SDImageScaleFactorForKey(NSString * _Nullable key); |
| | | |
| | | /** |
| | | Scale the image with the scale factor for the specify key. If no need to scale, return the original image. |
| | | This works for `UIImage`(UIKit) or `NSImage`(AppKit). And this function also preserve the associated value in `UIImage+BUMetadata.h`. |
| | | @note This is actually a convenience function, which firstlly call `BU_SDImageScaleFactorForKey` and then call `BU_SDScaledImageForScaleFactor`, kept for backward compatibility. |
| | | |
| | | @param key The image cache key |
| | | @param image The image |
| | | @return The scaled image |
| | | */ |
| | | FOUNDATION_EXPORT UIImage * _Nullable BU_SDScaledImageForKey(NSString * _Nullable key, UIImage * _Nullable image); |
| | | |
| | | /** |
| | | Scale the image with the scale factor. If no need to scale, return the original image. |
| | | This works for `UIImage`(UIKit) or `NSImage`(AppKit). And this function also preserve the associated value in `UIImage+BUMetadata.h`. |
| | | |
| | | @param scale The image scale factor |
| | | @param image The image |
| | | @return The scaled image |
| | | */ |
| | | FOUNDATION_EXPORT UIImage * _Nullable BU_SDScaledImageForScaleFactor(CGFloat scale, UIImage * _Nullable image); |
| | | |
| | | #pragma mark - WebCache Options |
| | | |
| | | /// BU_WebCache options |
| | | typedef NS_OPTIONS(NSUInteger, BU_SDWebImageOptions) { |
| | | /** |
| | | * By default, when a URL fail to be downloaded, the URL is blacklisted so the library won't keep trying. |
| | | * This flag disable this blacklisting. |
| | | */ |
| | | BU_SDWebImageRetryFailed = 1 << 0, |
| | | |
| | | /** |
| | | * By default, image downloads are started during UI interactions, this flags disable this feature, |
| | | * leading to delayed download on UIScrollView deceleration for instance. |
| | | */ |
| | | BU_SDWebImageLowPriority = 1 << 1, |
| | | |
| | | /** |
| | | * This flag enables progressive download, the image is displayed progressively during download as a browser would do. |
| | | * By default, the image is only displayed once completely downloaded. |
| | | */ |
| | | BU_SDWebImageProgressiveLoad = 1 << 2, |
| | | |
| | | /** |
| | | * Even if the image is cached, respect the HTTP response cache control, and refresh the image from remote location if needed. |
| | | * The disk caching will be handled by NSURLCache instead of SDWebImage leading to slight performance degradation. |
| | | * This option helps deal with images changing behind the same request URL, e.g. Facebook graph api profile pics. |
| | | * If a cached image is refreshed, the completion block is called once with the cached image and again with the final image. |
| | | * |
| | | * Use this flag only if you can't make your URLs static with embedded cache busting parameter. |
| | | */ |
| | | BU_SDWebImageRefreshCached = 1 << 3, |
| | | |
| | | /** |
| | | * In iOS 4+, continue the download of the image if the app goes to background. This is achieved by asking the system for |
| | | * extra time in background to let the request finish. If the background task expires the operation will be cancelled. |
| | | */ |
| | | BU_SDWebImageContinueInBackground = 1 << 4, |
| | | |
| | | /** |
| | | * Handles cookies stored in NSHTTPCookieStore by setting |
| | | * NSMutableURLRequest.HTTPShouldHandleCookies = YES; |
| | | */ |
| | | BU_SDWebImageHandleCookies = 1 << 5, |
| | | |
| | | /** |
| | | * Enable to allow untrusted SSL certificates. |
| | | * Useful for testing purposes. Use with caution in production. |
| | | */ |
| | | BU_SDWebImageAllowInvalidSSLCertificates = 1 << 6, |
| | | |
| | | /** |
| | | * By default, images are loaded in the order in which they were queued. This flag moves them to |
| | | * the front of the queue. |
| | | */ |
| | | BU_SDWebImageHighPriority = 1 << 7, |
| | | |
| | | /** |
| | | * By default, placeholder images are loaded while the image is loading. This flag will delay the loading |
| | | * of the placeholder image until after the image has finished loading. |
| | | */ |
| | | BU_SDWebImageDelayPlaceholder = 1 << 8, |
| | | |
| | | /** |
| | | * We usually don't apply transform on animated images as most transformers could not manage animated images. |
| | | * Use this flag to transform them anyway. |
| | | */ |
| | | BU_SDWebImageTransformAnimatedImage = 1 << 9, |
| | | |
| | | /** |
| | | * By default, image is added to the imageView after download. But in some cases, we want to |
| | | * have the hand before setting the image (apply a filter or add it with cross-fade animation for instance) |
| | | * Use this flag if you want to manually set the image in the completion when success |
| | | */ |
| | | BU_SDWebImageAvoidAutoSetImage = 1 << 10, |
| | | |
| | | /** |
| | | * By default, images are decoded respecting their original size. On iOS, this flag will scale down the |
| | | * images to a size compatible with the constrained memory of devices. |
| | | * This flag take no effect if `SDWebImageAvoidDecodeImage` is set. And it will be ignored if `SDWebImageProgressiveLoad` is set. |
| | | */ |
| | | BU_SDWebImageScaleDownLargeImages = 1 << 11, |
| | | |
| | | /** |
| | | * By default, we do not query image data when the image is already cached in memory. This mask can force to query image data at the same time. However, this query is asynchronously unless you specify `SDWebImageQueryMemoryDataSync` |
| | | */ |
| | | BU_SDWebImageQueryMemoryData = 1 << 12, |
| | | |
| | | /** |
| | | * By default, when you only specify `SDWebImageQueryMemoryData`, we query the memory image data asynchronously. Combined this mask as well to query the memory image data synchronously. |
| | | * @note Query data synchronously is not recommend, unless you want to ensure the image is loaded in the same runloop to avoid flashing during cell reusing. |
| | | */ |
| | | BU_SDWebImageQueryMemoryDataSync = 1 << 13, |
| | | |
| | | /** |
| | | * By default, when the memory cache miss, we query the disk cache asynchronously. This mask can force to query disk cache (when memory cache miss) synchronously. |
| | | * @note These 3 query options can be combined together. For the full list about these masks combination, see wiki page. |
| | | * @note Query data synchronously is not recommend, unless you want to ensure the image is loaded in the same runloop to avoid flashing during cell reusing. |
| | | */ |
| | | BU_SDWebImageQueryDiskDataSync = 1 << 14, |
| | | |
| | | /** |
| | | * By default, when the cache missed, the image is load from the loader. This flag can prevent this to load from cache only. |
| | | */ |
| | | BU_SDWebImageFromCacheOnly = 1 << 15, |
| | | |
| | | /** |
| | | * By default, we query the cache before the image is load from the loader. This flag can prevent this to load from loader only. |
| | | */ |
| | | BU_SDWebImageFromLoaderOnly = 1 << 16, |
| | | |
| | | /** |
| | | * By default, when you use `SDWebImageTransition` to do some view transition after the image load finished, this transition is only applied for image download from the network. This mask can force to apply view transition for memory and disk cache as well. |
| | | */ |
| | | BU_SDWebImageForceTransition = 1 << 17, |
| | | |
| | | /** |
| | | * By default, we will decode the image in the background during cache query and download from the network. This can help to improve performance because when rendering image on the screen, it need to be firstly decoded. But this happen on the main queue by Core Animation. |
| | | * However, this process may increase the memory usage as well. If you are experiencing a issue due to excessive memory consumption, This flag can prevent decode the image. |
| | | */ |
| | | BU_SDWebImageAvoidDecodeImage = 1 << 18, |
| | | |
| | | /** |
| | | * By default, we decode the animated image. This flag can force decode the first frame only and produece the static image. |
| | | */ |
| | | BU_SDWebImageDecodeFirstFrameOnly = 1 << 19, |
| | | |
| | | /** |
| | | * By default, for `BU_SDAnimatedImage`, we decode the animated image frame during rendering to reduce memory usage. However, you can specify to preload all frames into memory to reduce CPU usage when the animated image is shared by lots of imageViews. |
| | | * This will actually trigger `preloadAllAnimatedImageFrames` in the background queue(Disk Cache & Download only). |
| | | */ |
| | | BU_SDWebImagePreloadAllFrames = 1 << 20, |
| | | |
| | | /** |
| | | * By default, when you use `BU_SDWebImageContextAnimatedImageClass` context option (like using `SDAnimatedImageView` which designed to use `BU_SDAnimatedImage`), we may still use `UIImage` when the memory cache hit, or image decoder is not available to produce one exactlly matching your custom class as a fallback solution. |
| | | * Using this option, can ensure we always callback image with your provided class. If failed to produce one, a error with code `SDWebImageErrorBadImageData` will been used. |
| | | * Note this options is not compatible with `SDWebImageDecodeFirstFrameOnly`, which always produce a UIImage/NSImage. |
| | | */ |
| | | BU_SDWebImageMatchAnimatedImageClass = 1 << 21, |
| | | }; |
| | | |
| | | |
| | | #pragma mark - Context Options |
| | | |
| | | /** |
| | | A String to be used as the operation key for view category to store the image load operation. This is used for view instance which supports different image loading process. If nil, will use the class name as operation key. (NSString *) |
| | | */ |
| | | FOUNDATION_EXPORT BU_SDWebImageContextOption _Nonnull const BU_SDWebImageContextSetImageOperationKey; |
| | | |
| | | /** |
| | | A SDWebImageManager instance to control the image download and cache process using in UIImageView+BU_WebCache category and likes. If not provided, use the shared manager (SDWebImageManager *) |
| | | */ |
| | | FOUNDATION_EXPORT BU_SDWebImageContextOption _Nonnull const BU_SDWebImageContextCustomManager; |
| | | |
| | | /** |
| | | A id<BU_SDImageTransformer> instance which conforms `BU_SDImageTransformer` protocol. It's used for image transform after the image load finished and store the transformed image to cache. If you provide one, it will ignore the `transformer` in manager and use provided one instead. (id<BU_SDImageTransformer>) |
| | | */ |
| | | FOUNDATION_EXPORT BU_SDWebImageContextOption _Nonnull const BU_SDWebImageContextImageTransformer; |
| | | |
| | | /** |
| | | A CGFloat raw value which specify the image scale factor. The number should be greater than or equal to 1.0. If not provide or the number is invalid, we will use the cache key to specify the scale factor. (NSNumber) |
| | | */ |
| | | FOUNDATION_EXPORT BU_SDWebImageContextOption _Nonnull const BU_SDWebImageContextImageScaleFactor; |
| | | |
| | | /** |
| | | A BU_SDImageCacheType raw value which specify the store cache type when the image has just been downloaded and will be stored to the cache. Specify `BU_SDImageCacheTypeNone` to disable cache storage; `BU_SDImageCacheTypeDisk` to store in disk cache only; `BU_SDImageCacheTypeMemory` to store in memory only. And `BU_SDImageCacheTypeAll` to store in both memory cache and disk cache. |
| | | If you use image transformer feature, this actually apply for the transformed image, but not the original image itself. Use `BU_SDWebImageContextOriginalStoreCacheType` if you want to control the original image's store cache type at the same time. |
| | | If not provide or the value is invalid, we will use `BU_SDImageCacheTypeAll`. (NSNumber) |
| | | */ |
| | | FOUNDATION_EXPORT BU_SDWebImageContextOption _Nonnull const BU_SDWebImageContextStoreCacheType; |
| | | |
| | | /** |
| | | The same behavior like `BU_SDWebImageContextStoreCacheType`, but control the store cache type for the original image when you use image transformer feature. This allows the detail control of cache storage for these two images. For example, if you want to store the transformed image into both memory/disk cache, store the original image into disk cache only, use `[.storeCacheType : .all, .originalStoreCacheType : .disk]` |
| | | If not provide or the value is invalid, we will use `BU_SDImageCacheTypeNone`, which does not store the original image into cache. (NSNumber) |
| | | */ |
| | | FOUNDATION_EXPORT BU_SDWebImageContextOption _Nonnull const BU_SDWebImageContextOriginalStoreCacheType; |
| | | |
| | | /** |
| | | A Class object which the instance is a `UIImage/NSImage` subclass and adopt `BU_SDAnimatedImage` protocol. We will call `initWithData:scale:options:` to create the instance (or `initWithAnimatedCoder:scale:` when using progressive download) . If the instance create failed, fallback to normal `UIImage/NSImage`. |
| | | This can be used to improve animated images rendering performance (especially memory usage on big animated images) with `SDAnimatedImageView` (Class). |
| | | */ |
| | | FOUNDATION_EXPORT BU_SDWebImageContextOption _Nonnull const BU_SDWebImageContextAnimatedImageClass; |
| | | |
| | | /** |
| | | A id<SDWebImageDownloaderRequestModifier> instance to modify the image download request. It's used for downloader to modify the original request from URL and options. If you provide one, it will ignore the `requestModifier` in downloader and use provided one instead. (id<SDWebImageDownloaderRequestModifier>) |
| | | */ |
| | | FOUNDATION_EXPORT BU_SDWebImageContextOption _Nonnull const BU_SDWebImageContextDownloadRequestModifier; |
| | | |
| | | /** |
| | | A id<BU_SDWebImageCacheKeyFilter> instance to convert an URL into a cache key. It's used when manager need cache key to use image cache. If you provide one, it will ignore the `cacheKeyFilter` in manager and use provided one instead. (id<BU_SDWebImageCacheKeyFilter>) |
| | | */ |
| | | FOUNDATION_EXPORT BU_SDWebImageContextOption _Nonnull const BU_SDWebImageContextCacheKeyFilter; |
| | | |
| | | /** |
| | | A id<BU_SDWebImageCacheSerializer> instance to convert the decoded image, the source downloaded data, to the actual data. It's used for manager to store image to the disk cache. If you provide one, it will ignore the `cacheSerializer` in manager and use provided one instead. (id<BU_SDWebImageCacheSerializer>) |
| | | */ |
| | | FOUNDATION_EXPORT BU_SDWebImageContextOption _Nonnull const BU_SDWebImageContextCacheSerializer; |
New file |
| | |
| | | /* |
| | | * This file is part of the SDWebImage package. |
| | | * (c) Olivier Poitrey <rs@dailymotion.com> |
| | | * |
| | | * For the full copyright and license information, please view the LICENSE |
| | | * file that was distributed with this source code. |
| | | */ |
| | | |
| | | #import "BU_SDWebImageCompat.h" |
| | | #import "BU_SDWebImageOperation.h" |
| | | #import "BU_SDImageCacheDefine.h" |
| | | #import "BU_SDImageLoader.h" |
| | | #import "BU_SDImageTransformer.h" |
| | | #import "BU_SDWebImageCacheKeyFilter.h" |
| | | #import "BU_SDWebImageCacheSerializer.h" |
| | | #import "BU_SDWebImageOptionsProcessor.h" |
| | | |
| | | typedef void(^BU_SDExternalCompletionBlock)(UIImage * _Nullable image, NSError * _Nullable error, BU_SDImageCacheType cacheType, NSURL * _Nullable imageURL); |
| | | |
| | | typedef void(^BU_SDInternalCompletionBlock)(UIImage * _Nullable image, NSData * _Nullable data, NSError * _Nullable error, BU_SDImageCacheType cacheType, BOOL finished, NSURL * _Nullable imageURL); |
| | | |
| | | /** |
| | | A combined operation representing the cache and loader operation. You can use it to cancel the load process. |
| | | */ |
| | | @interface BU_SDWebImageCombinedOperation : NSObject <BU_SDWebImageOperation> |
| | | |
| | | /** |
| | | Cancel the current operation, including cache and loader process |
| | | */ |
| | | - (void)cancel; |
| | | |
| | | /** |
| | | The cache operation from the image cache query |
| | | */ |
| | | @property (strong, nonatomic, nullable, readonly) id<BU_SDWebImageOperation> cacheOperation; |
| | | |
| | | /** |
| | | The loader operation from the image loader (such as download operation) |
| | | */ |
| | | @property (strong, nonatomic, nullable, readonly) id<BU_SDWebImageOperation> loaderOperation; |
| | | |
| | | @end |
| | | |
| | | |
| | | @class BU_SDWebImageManager; |
| | | |
| | | /** |
| | | The manager delegate protocol. |
| | | */ |
| | | @protocol BU_SDWebImageManagerDelegate <NSObject> |
| | | |
| | | @optional |
| | | |
| | | /** |
| | | * Controls which image should be downloaded when the image is not found in the cache. |
| | | * |
| | | * @param imageManager The current `SDWebImageManager` |
| | | * @param imageURL The url of the image to be downloaded |
| | | * |
| | | * @return Return NO to prevent the downloading of the image on cache misses. If not implemented, YES is implied. |
| | | */ |
| | | - (BOOL)imageManager:(nonnull BU_SDWebImageManager *)imageManager shouldDownloadImageForURL:(nonnull NSURL *)imageURL; |
| | | |
| | | /** |
| | | * Controls the complicated logic to mark as failed URLs when download error occur. |
| | | * If the delegate implement this method, we will not use the built-in way to mark URL as failed based on error code; |
| | | @param imageManager The current `SDWebImageManager` |
| | | @param imageURL The url of the image |
| | | @param error The download error for the url |
| | | @return Whether to block this url or not. Return YES to mark this URL as failed. |
| | | */ |
| | | - (BOOL)imageManager:(nonnull BU_SDWebImageManager *)imageManager shouldBlockFailedURL:(nonnull NSURL *)imageURL withError:(nonnull NSError *)error; |
| | | |
| | | @end |
| | | |
| | | /** |
| | | * The SDWebImageManager is the class behind the UIImageView+BU_WebCache category and likes. |
| | | * It ties the asynchronous downloader (SDWebImageDownloader) with the image cache store (SDImageCache). |
| | | * You can use this class directly to benefit from web image downloading with caching in another context than |
| | | * a UIView. |
| | | * |
| | | * Here is a simple example of how to use SDWebImageManager: |
| | | * |
| | | * @code |
| | | |
| | | SDWebImageManager *manager = [SDWebImageManager sharedManager]; |
| | | [manager loadImageWithURL:imageURL |
| | | options:0 |
| | | progress:nil |
| | | completed:^(UIImage *image, NSError *error, BU_SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) { |
| | | if (image) { |
| | | // do something with image |
| | | } |
| | | }]; |
| | | |
| | | * @endcode |
| | | */ |
| | | @interface BU_SDWebImageManager : NSObject |
| | | |
| | | /** |
| | | * The delegate for manager. Defatuls to nil. |
| | | */ |
| | | @property (weak, nonatomic, nullable) id <BU_SDWebImageManagerDelegate> delegate; |
| | | |
| | | /** |
| | | * The image cache used by manager to query image cache. |
| | | */ |
| | | @property (strong, nonatomic, readonly, nonnull) id<BU_SDImageCache> imageCache; |
| | | |
| | | /** |
| | | * The image loader used by manager to load image. |
| | | */ |
| | | @property (strong, nonatomic, readonly, nonnull) id<BU_SDImageLoader> imageLoader; |
| | | |
| | | /** |
| | | The image transformer for manager. It's used for image transform after the image load finished and store the transformed image to cache, see `BU_SDImageTransformer`. |
| | | Defaults to nil, which means no transform is applied. |
| | | @note This will affect all the load requests for this manager if you provide. However, you can pass `BU_SDWebImageContextImageTransformer` in context arg to explicitly use that transformer instead. |
| | | */ |
| | | @property (strong, nonatomic, nullable) id<BU_SDImageTransformer> transformer; |
| | | |
| | | /** |
| | | * The cache filter is used to convert an URL into a cache key each time SDWebImageManager need cache key to use image cache. |
| | | * |
| | | * The following example sets a filter in the application delegate that will remove any query-string from the |
| | | * URL before to use it as a cache key: |
| | | * |
| | | * @code |
| | | SDWebImageManager.sharedManager.cacheKeyFilter =[BU_SDWebImageCacheKeyFilter cacheKeyFilterWithBlock:^NSString * _Nullable(NSURL * _Nonnull url) { |
| | | url = [[NSURL alloc] initWithScheme:url.scheme host:url.host path:url.path]; |
| | | return [url absoluteString]; |
| | | }]; |
| | | * @endcode |
| | | */ |
| | | @property (nonatomic, strong, nullable) id<BU_SDWebImageCacheKeyFilter> cacheKeyFilter; |
| | | |
| | | /** |
| | | * The cache serializer is used to convert the decoded image, the source downloaded data, to the actual data used for storing to the disk cache. If you return nil, means to generate the data from the image instance, see `SDImageCache`. |
| | | * For example, if you are using WebP images and facing the slow decoding time issue when later retriving from disk cache again. You can try to encode the decoded image to JPEG/PNG format to disk cache instead of source downloaded data. |
| | | * @note The `image` arg is nonnull, but when you also provide a image transformer and the image is transformed, the `data` arg may be nil, take attention to this case. |
| | | * @note This method is called from a global queue in order to not to block the main thread. |
| | | * @code |
| | | SDWebImageManager.sharedManager.cacheSerializer = [BU_SDWebImageCacheSerializer cacheSerializerWithBlock:^NSData * _Nullable(UIImage * _Nonnull image, NSData * _Nullable data, NSURL * _Nullable imageURL) { |
| | | BU_SDImageFormat format = [NSData sdBu_imageFormatForImageData:data]; |
| | | switch (format) { |
| | | case BU_SDImageFormatWebP: |
| | | return image.images ? data : nil; |
| | | default: |
| | | return data; |
| | | } |
| | | }]; |
| | | * @endcode |
| | | * The default value is nil. Means we just store the source downloaded data to disk cache. |
| | | */ |
| | | @property (nonatomic, strong, nullable) id<BU_SDWebImageCacheSerializer> cacheSerializer; |
| | | |
| | | /** |
| | | The options processor is used, to have a global control for all the image request options and context option for current manager. |
| | | @note If you use `transformer`, `cacheKeyFilter` or `cacheSerializer` property of manager, the input context option already apply those properties before passed. This options processor is a better replacement for those property in common usage. |
| | | For example, you can control the global options, based on the URL or original context option like the below code. |
| | | |
| | | @code |
| | | SDWebImageManager.sharedManager.optionsProcessor = [BU_SDWebImageOptionsProcessor optionsProcessorWithBlock:^BU_SDWebImageOptionsResult * _Nullable(NSURL * _Nullable url, BU_SDWebImageOptions options, SDWebImageContext * _Nullable context) { |
| | | // Only do animation on `SDAnimatedImageView` |
| | | if (!context[BU_SDWebImageContextAnimatedImageClass]) { |
| | | options |= SDWebImageDecodeFirstFrameOnly; |
| | | } |
| | | // Do not force decode for png url |
| | | if ([url.lastPathComponent isEqualToString:@"png"]) { |
| | | options |= SDWebImageAvoidDecodeImage; |
| | | } |
| | | // Always use screen scale factor |
| | | SDWebImageMutableContext *mutableContext = [NSDictionary dictionaryWithDictionary:context]; |
| | | mutableContext[BU_SDWebImageContextImageScaleFactor] = @(UIScreen.mainScreen.scale); |
| | | context = [mutableContext copy]; |
| | | |
| | | return [[BU_SDWebImageOptionsResult alloc] initWithOptions:options context:context]; |
| | | }]; |
| | | @endcode |
| | | */ |
| | | @property (nonatomic, strong, nullable) id<BU_SDWebImageOptionsProcessor> optionsProcessor; |
| | | |
| | | /** |
| | | * Check one or more operations running |
| | | */ |
| | | @property (nonatomic, assign, readonly, getter=isRunning) BOOL running; |
| | | |
| | | /** |
| | | The default image cache when the manager which is created with no arguments. Such as shared manager or init. |
| | | Defaults to nil. Means using `SDImageCache.sharedImageCache` |
| | | */ |
| | | @property (nonatomic, class, nullable) id<BU_SDImageCache> defaultImageCache; |
| | | |
| | | /** |
| | | The default image loader for manager which is created with no arguments. Such as shared manager or init. |
| | | Defaults to nil. Means using `SDWebImageDownloader.sharedDownloader` |
| | | */ |
| | | @property (nonatomic, class, nullable) id<BU_SDImageLoader> defaultImageLoader; |
| | | |
| | | /** |
| | | * Returns global shared manager instance. |
| | | */ |
| | | @property (nonatomic, class, readonly, nonnull) BU_SDWebImageManager *sharedManager; |
| | | |
| | | /** |
| | | * Allows to specify instance of cache and image loader used with image manager. |
| | | * @return new instance of `SDWebImageManager` with specified cache and loader. |
| | | */ |
| | | - (nonnull instancetype)initWithCache:(nonnull id<BU_SDImageCache>)cache loader:(nonnull id<BU_SDImageLoader>)loader NS_DESIGNATED_INITIALIZER; |
| | | |
| | | /** |
| | | * Downloads the image at the given URL if not present in cache or return the cached version otherwise. |
| | | * |
| | | * @param url The URL to the image |
| | | * @param options A mask to specify options to use for this request |
| | | * @param progressBlock A block called while image is downloading |
| | | * @note the progress block is executed on a background queue |
| | | * @param completedBlock A block called when operation has been completed. |
| | | * |
| | | * This parameter is required. |
| | | * |
| | | * This block has no return value and takes the requested UIImage as first parameter and the NSData representation as second parameter. |
| | | * In case of error the image parameter is nil and the third parameter may contain an NSError. |
| | | * |
| | | * The forth parameter is an `BU_SDImageCacheType` enum indicating if the image was retrieved from the local cache |
| | | * or from the memory cache or from the network. |
| | | * |
| | | * The fith parameter is set to NO when the SDWebImageProgressiveLoad option is used and the image is |
| | | * downloading. This block is thus called repeatedly with a partial image. When image is fully downloaded, the |
| | | * block is called a last time with the full image and the last parameter set to YES. |
| | | * |
| | | * The last parameter is the original image URL |
| | | * |
| | | * @return Returns an instance of BU_SDWebImageCombinedOperation, which you can cancel the loading process. |
| | | */ |
| | | - (nullable BU_SDWebImageCombinedOperation *)loadImageWithURL:(nullable NSURL *)url |
| | | options:(BU_SDWebImageOptions)options |
| | | progress:(nullable SDImageLoaderProgressBlock)progressBlock |
| | | completed:(nonnull BU_SDInternalCompletionBlock)completedBlock; |
| | | |
| | | /** |
| | | * Downloads the image at the given URL if not present in cache or return the cached version otherwise. |
| | | * |
| | | * @param url The URL to the image |
| | | * @param options A mask to specify options to use for this request |
| | | * @param context A context contains different options to perform specify changes or processes, see `BU_SDWebImageContextOption`. This hold the extra objects which `options` enum can not hold. |
| | | * @param progressBlock A block called while image is downloading |
| | | * @note the progress block is executed on a background queue |
| | | * @param completedBlock A block called when operation has been completed. |
| | | * |
| | | * @return Returns an instance of BU_SDWebImageCombinedOperation, which you can cancel the loading process. |
| | | */ |
| | | - (nullable BU_SDWebImageCombinedOperation *)loadImageWithURL:(nullable NSURL *)url |
| | | options:(BU_SDWebImageOptions)options |
| | | context:(nullable SDWebImageContext *)context |
| | | progress:(nullable SDImageLoaderProgressBlock)progressBlock |
| | | completed:(nonnull BU_SDInternalCompletionBlock)completedBlock; |
| | | |
| | | /** |
| | | * Cancel all current operations |
| | | */ |
| | | - (void)cancelAll; |
| | | |
| | | /** |
| | | * Return the cache key for a given URL |
| | | */ |
| | | - (nullable NSString *)cacheKeyForURL:(nullable NSURL *)url; |
| | | |
| | | @end |
New file |
| | |
| | | /* |
| | | * This file is part of the SDWebImage package. |
| | | * (c) Olivier Poitrey <rs@dailymotion.com> |
| | | * |
| | | * For the full copyright and license information, please view the LICENSE |
| | | * file that was distributed with this source code. |
| | | */ |
| | | |
| | | #import <Foundation/Foundation.h> |
| | | |
| | | /// A protocol represents cancelable operation. |
| | | @protocol BU_SDWebImageOperation <NSObject> |
| | | |
| | | - (void)cancel; |
| | | |
| | | @end |
| | | |
| | | /// NSOperation conform to `BU_SDWebImageOperation`. |
| | | @interface NSOperation (BU_SDWebImageOperation) <BU_SDWebImageOperation> |
| | | |
| | | @end |
New file |
| | |
| | | /* |
| | | * This file is part of the SDWebImage package. |
| | | * (c) Olivier Poitrey <rs@dailymotion.com> |
| | | * |
| | | * For the full copyright and license information, please view the LICENSE |
| | | * file that was distributed with this source code. |
| | | */ |
| | | |
| | | #import <Foundation/Foundation.h> |
| | | #import "BU_SDWebImageCompat.h" |
| | | #import "BU_SDWebImageDefine.h" |
| | | |
| | | @class BU_SDWebImageOptionsResult; |
| | | |
| | | typedef BU_SDWebImageOptionsResult * _Nullable(^BU_SDWebImageOptionsProcessorBlock)(NSURL * _Nullable url, BU_SDWebImageOptions options, SDWebImageContext * _Nullable context); |
| | | |
| | | /** |
| | | The options result contains both options and context. |
| | | */ |
| | | @interface BU_SDWebImageOptionsResult : NSObject |
| | | |
| | | /** |
| | | BU_WebCache options. |
| | | */ |
| | | @property (nonatomic, assign, readonly) BU_SDWebImageOptions options; |
| | | |
| | | /** |
| | | Context options. |
| | | */ |
| | | @property (nonatomic, copy, readonly, nullable) SDWebImageContext *context; |
| | | |
| | | /** |
| | | Create a new options result. |
| | | |
| | | @param options options |
| | | @param context context |
| | | @return The options result contains both options and context. |
| | | */ |
| | | - (nonnull instancetype)initWithOptions:(BU_SDWebImageOptions)options context:(nullable SDWebImageContext *)context; |
| | | |
| | | @end |
| | | |
| | | /** |
| | | This is the protocol for options processor. |
| | | Options processor can be used, to control the final result for individual image request's `BU_SDWebImageOptions` and `SDWebImageContext` |
| | | Implements the protocol to have a global control for each indivadual image request's option. |
| | | */ |
| | | @protocol BU_SDWebImageOptionsProcessor <NSObject> |
| | | |
| | | /** |
| | | Return the processed options result for specify image URL, with its options and context |
| | | |
| | | @param url The URL to the image |
| | | @param options A mask to specify options to use for this request |
| | | @param context A context contains different options to perform specify changes or processes, see `BU_SDWebImageContextOption`. This hold the extra objects which `options` enum can not hold. |
| | | @return The processed result, contains both options and context |
| | | */ |
| | | - (nullable BU_SDWebImageOptionsResult *)processedResultForURL:(nullable NSURL *)url |
| | | options:(BU_SDWebImageOptions)options |
| | | context:(nullable SDWebImageContext *)context; |
| | | |
| | | @end |
| | | |
| | | /** |
| | | A options processor class with block. |
| | | */ |
| | | @interface BU_SDWebImageOptionsProcessor : NSObject<BU_SDWebImageOptionsProcessor> |
| | | |
| | | - (nonnull instancetype)initWithBlock:(nonnull BU_SDWebImageOptionsProcessorBlock)block; |
| | | + (nonnull instancetype)optionsProcessorWithBlock:(nonnull BU_SDWebImageOptionsProcessorBlock)block; |
| | | |
| | | @end |
New file |
| | |
| | | // |
| | | // EBAppLog.h |
| | | // RangersAppLog |
| | | // |
| | | // Created by bob on 2019/7/5. |
| | | // |
| | | |
| | | #import <Foundation/Foundation.h> |
| | | #import "EBAppLogConfig.h" |
| | | #import "EBAppLogDelegateProtocol.h" |
| | | |
| | | NS_ASSUME_NONNULL_BEGIN |
| | | |
| | | /*! |
| | | EBAppLog日志上报功能的类 |
| | | */ |
| | | @interface EBAppLog : NSObject |
| | | |
| | | /*! @abstract settings delegate */ |
| | | @property (class, nonatomic, copy) id<EBAppLogDelegateProtocol> delegate; |
| | | |
| | | /*! @abstract The SDK version. */ |
| | | @property (class, nonatomic, copy, readonly) NSString *sdkVersion; |
| | | |
| | | /*! @abstract The unique device ID that get from register server. */ |
| | | @property (class, nonatomic, copy, readonly, nullable) NSString *deviceID; |
| | | |
| | | /*! @abstract The unique install ID that get from register server. |
| | | @discussion Embed版本值为nil |
| | | */ |
| | | @property (class, nonatomic, copy, readonly, nullable) NSString *installID; |
| | | |
| | | /*! @abstract The unique ssID that get from register server. |
| | | @discussion Embed版本值为nil |
| | | */ |
| | | @property (class, nonatomic, copy, readonly, nullable) NSString *ssID; |
| | | |
| | | /*! @abstract 初始化注册 |
| | | @param config 初始化配置,AppID AppName Channel是必须的 |
| | | @discussion 初始化接口可以重复调用,但是AppID必须相同且只有一个。 |
| | | */ |
| | | + (void)startTrackWithConfig:(EBAppLogConfig *)config; |
| | | |
| | | /*! @abstract 手动触发获取SDK上报配置值请求 |
| | | @discussion 手动触发请求 |
| | | */ |
| | | + (void)startFetchTrackerConfiguration; |
| | | |
| | | /*! @abstract userAgent |
| | | @discussion 每次启动SDK的时候设置一次,发生变化的时候设置即可。一般不会发生变化,只需要设置一次即可 |
| | | @param userAgent 日志上报HTTP/HTTPS 请求里面的 userAgent |
| | | */ |
| | | + (void)setUserAgent:(nullable NSString *)userAgent; |
| | | |
| | | /*! @abstract UserUniqueID发生变化时设置 |
| | | @discussion 有值,则设置为ID值;登出,可以设置为nil |
| | | @discussion SDK会保存,因此只需要变化的时候设置 |
| | | @param uniqueID 用户id |
| | | */ |
| | | + (void)setCurrentUserUniqueID:(nullable NSString *)uniqueID; |
| | | |
| | | /*! @abstract 设置上报Host地区,有国内、新加坡、美东三个选项 |
| | | @discussion 发生变化可以更新,不需要一直重复设置 |
| | | @param serviceVendor 地区 |
| | | */ |
| | | + (void)setServiceVendor:(EBAppLogServiceVendor)serviceVendor; |
| | | |
| | | /*! @abstract 地区 |
| | | @discussion 如果设置过,会保存值,直到下次改变或者清空 |
| | | @discussion 如果没有值,默认会读取 `[[NSLocale currentLocale] objectForKey:NSLocaleCountryCode]` |
| | | @discussion 发生变化时候请调用 `+[EBAppLog setAppRegion:]`更新值 |
| | | */ |
| | | + (void)setAppRegion:(nullable NSString *)appRegion; |
| | | |
| | | /*! @abstract 语言 |
| | | @discussion 如果设置过,会保存值,直到下次改变或者清空 |
| | | @discussion 如果没有值,默认会读取 `[[NSLocale currentLocale] objectForKey:NSLocaleLanguageCode]` |
| | | @discussion 发生变化时候请调用 `+[EBAppLog setAppLauguage:]`更新值 |
| | | */ |
| | | + (void)setAppLauguage:(nullable NSString *)appLauguage; |
| | | |
| | | /*! @abstract 设置注册成功回调 |
| | | @param registerFinishBlock id发生变化可能重新触发请求,请求回调。 |
| | | @discussion registerFinishBlock 会覆盖之前的初始化或者上一次设置的回调,如果为nil会清空回调 |
| | | @discussion block在初始化之前设置一次即可,每次拉取成功都会回调,请勿一直重复设置 |
| | | */ |
| | | + (void)setRegisterFinishBlock:(nullable EBAppLogRegisterFinishBlock)registerFinishBlock; |
| | | |
| | | /*! @abstract 添加自定义上报信息 |
| | | @param customHeaderBlock 自定义上报信息 |
| | | @discussion customHeaderBlock 一次App启动设置一次即可;App重启需要重新设置,因为SDK不会保存上次设置的值;会覆盖之前的初始化的或者上一次设置的,如果为nil会清空回调 |
| | | @discussion block在初始化之前设置一次即可,每次都会回调,不会把block返回参数保存,而导致获取不到变化的值,请勿一直重复设置 |
| | | */ |
| | | + (void)setCustomHeaderBlock:(nullable EBAppLogCustomHeaderBlock)customHeaderBlock; |
| | | |
| | | /*! @abstract 日志上报 |
| | | @param event 事件名称,不能为nil或空字符串 |
| | | @param params 事件参数。可以为空或者nil,但是param如果非空,需要可序列化成json |
| | | @discussion params 请参考文档中的日志格式要求 |
| | | @result 是否成功,如果失败,则表示此日志不会被上报。原因是无法序列化。 |
| | | */ |
| | | + (BOOL)eventV3:(NSString *)event params:(nullable NSDictionary *)params; |
| | | |
| | | #pragma mark - private API |
| | | /*! @abstract 调用用户激活接口。一般情况下,请勿调用,除非知晓调用可能的问题。预留给内部CP接口使用 |
| | | */ |
| | | + (void)activeUser; |
| | | |
| | | @end |
| | | |
| | | NS_ASSUME_NONNULL_END |
New file |
| | |
| | | // |
| | | // EBAppLogConfig.h |
| | | // EmbedAppLog |
| | | // |
| | | // Created by 陈奕 on 2019/7/14. |
| | | // |
| | | |
| | | #import <Foundation/Foundation.h> |
| | | |
| | | /*! @abstract 日志输出 |
| | | @param log 输出的日志 |
| | | @discussion 请使用自己的日志SDK输出日志 |
| | | */ |
| | | typedef void(^EBAppLogLogger)(NSString * _Nullable log); |
| | | |
| | | /*! @abstract ABTest配置拉取回调 |
| | | @param ABTestEnabled ABTest是否开启 |
| | | @param allConfigs 后台返回的全部配置 |
| | | @discussion ABTestEnabled如果未开启,则,即使有config,SDK也会返回默认值;如果无网络或者其他原因注册失败,不会回调 |
| | | */ |
| | | typedef void(^EBAppLogABTestFinishBlock)(BOOL ABTestEnabled, NSDictionary * _Nullable allConfigs); |
| | | |
| | | /*! @abstract 设备注册回调 |
| | | @param deviceID did |
| | | @param installID iid |
| | | @param ssID ssid |
| | | @discussion 可能为空,如果无网络或者其他原因注册失败,不会回调 |
| | | */ |
| | | typedef void(^EBAppLogRegisterFinishBlock)(NSString * _Nullable deviceID, NSString * _Nullable installID, NSString * _Nullable ssID); |
| | | |
| | | /*! @abstract 自定义上报信息 |
| | | @discussion 每次上报都会回调,设置一次即可,格式要求同日志要求,需要可序列化;如果无法序列化,会被丢弃 |
| | | */ |
| | | typedef NSDictionary<NSString*, id> *_Nonnull (^EBAppLogCustomHeaderBlock)(void); |
| | | |
| | | /*! @abstract 日志上报地区属性 |
| | | @discussion 上报地区请求擅自选择,需要与申请服务的地区一致,或者咨询接口人确认 |
| | | */ |
| | | typedef NS_ENUM(NSInteger, EBAppLogServiceVendor) { |
| | | EBAppLogServiceVendorCN = 0x020, // 国内 中国 |
| | | EBAppLogServiceVendorSG, // 新加坡 |
| | | EBAppLogServiceVendorVA, // 美东 |
| | | }; |
| | | |
| | | NS_ASSUME_NONNULL_BEGIN |
| | | |
| | | /*! |
| | | EBAppLog日志上报配置 |
| | | */ |
| | | @interface EBAppLogConfig : NSObject |
| | | |
| | | /*! @abstract channel要求非空,必须设置, Release版本只有 @"App Store", debug版本可以任意设置. */ |
| | | @property (nonatomic, copy) NSString *channel; |
| | | |
| | | /*! @abstract 申请appID时候填写的英文名称,非空,必须设置 */ |
| | | @property (nonatomic, copy) NSString *appName; |
| | | |
| | | /*! @abstract AppID,非空,必须设置 */ |
| | | @property (nonatomic, copy) NSString *appID; |
| | | |
| | | /*! @abstract 默认国内,初始化时一定要传正确的值 |
| | | @discussion 发生变化时候请调用 `+[EBAppLog setServiceVendor:]`更新值 |
| | | @discussion 会影响注册和日志上报。所以如果发生变化后,下次启动初始化请传入正确的值 |
| | | */ |
| | | @property (nonatomic, assign) EBAppLogServiceVendor serviceVendor; |
| | | |
| | | /*! @abstract 是否自动激活。默认YES,一般情况请不要修改 */ |
| | | @property (nonatomic, assign) BOOL autoActiveUser; |
| | | |
| | | /*! @abstract 采集事件的时候输出日志,在控制台中可以查看 |
| | | @discussion 需要同时设置logger,因为NSLog低效,且在iOS 13中有问题。release版本请设置为NO |
| | | */ |
| | | @property (nonatomic, assign) BOOL showDebugLog; |
| | | |
| | | /*! @abstract 采集事件的时候输出日志,在控制台中可以查看 |
| | | @discussion logger为nil,则不会输出日志 |
| | | */ |
| | | @property (nonatomic, copy, nullable) EBAppLogLogger logger; |
| | | |
| | | /*! @abstract 日志上报是否加密。用于debug情况可以抓包调试 */ |
| | | @property (nonatomic, assign) BOOL logNeedEncrypt; |
| | | |
| | | /*! @abstract 语言,默认会读取当前系统语言。 |
| | | @discussion 如果设置过,会保存值,直到下次改变或者清空 |
| | | @discussion 如果没有值,默认会读取当前系统值 |
| | | @discussion 发生变化时候请调用 `+[EBAppLog setAppLauguage:]`更新值 |
| | | */ |
| | | |
| | | /*! @abstract 地区,默认会读取当前系统region。 |
| | | @discussion 如果设置过,会保存值,直到下次改变或者清空 |
| | | @discussion 如果没有值,默认会读取当前系统值 |
| | | @discussion 发生变化时候请调用 `+[EBAppLog setAppRegion:]`更新值 |
| | | */ |
| | | |
| | | /*! @abstract 用户ID。如果初始化的时候有值,可以初始化的时候设置。无,则不需要设置。 |
| | | @discussion 发生变化时候,请调用 `+[EBAppLog setCurrentUserUniqueID:]`更新值 |
| | | */ |
| | | |
| | | /*! @abstractABTest相关值 |
| | | @discussion 发生变化时候,请调用 `+[EBAppLog setServerVersions:]`更新值 |
| | | */ |
| | | |
| | | /*! @abstract ABTest配置拉取回调 |
| | | @discussion 请改用 +[EBAppLog setRegisterFinishBlock:] |
| | | */ |
| | | |
| | | /*! @abstract 注册回调. |
| | | @discussion 请改用 +[EBAppLog setRegisterFinishBlock:] |
| | | */ |
| | | |
| | | /*! @abstract 自定义上报信息. |
| | | @discussion 请改用 +[EBAppLog setCustomHeaderBlock:] |
| | | */ |
| | | |
| | | @end |
| | | |
| | | NS_ASSUME_NONNULL_END |
New file |
| | |
| | | // |
| | | // EBAppLogDelegateProtocol.h |
| | | // Pods |
| | | // |
| | | // Created by 朱元清 on 2020/8/11. |
| | | // |
| | | #import <Foundation/Foundation.h> |
| | | |
| | | #ifndef EBAppLogDelegateProtocol_h |
| | | #define EBAppLogDelegateProtocol_h |
| | | |
| | | @protocol EBAppLogDelegateProtocol <NSObject> |
| | | |
| | | - (NSArray *)appRequestFieldsAllowed; |
| | | |
| | | @end |
| | | |
| | | #endif /* EBAppLogDelegateProtocol_h */ |
New file |
| | |
| | | // |
| | | // NSMutableArray+Utilities.h |
| | | // BUAdSDK |
| | | // |
| | | // Created by 李盛 on 2018/2/28. |
| | | // Copyright © 2018年 bytedance. All rights reserved. |
| | | // |
| | | |
| | | #import <Foundation/Foundation.h> |
| | | |
| | | @interface NSMutableArray (BU_Utilities) |
| | | |
| | | - (void)bu_safeAddObject:(id)object; |
| | | - (void)bu_safeAddNilObject; |
| | | - (void)bu_safeInsertObject:(id)object atIndex:(NSUInteger)index; |
| | | - (void)bu_safeInsertObjects:(NSArray *)objects atIndexes:(NSIndexSet *)indexes; |
| | | - (void)bu_safeRemoveObject:(id)object; |
| | | - (instancetype)bu_objectAtIndexSafely:(NSUInteger)index; |
| | | - (void)bu_removeObjectAtIndexSafely:(NSUInteger)index; |
| | | |
| | | @end |
| | | |
| | | @interface NSArray(BU_JSONValue) |
| | | - (NSString *)bu_JSONRepresentation:(NSError **)error; |
| | | @end |
| | | |
New file |
| | |
| | | // |
| | | // NSMutableDictionary+Utilities.h |
| | | // BUAdSDK |
| | | // |
| | | // Created by 李盛 on 2018/2/28. |
| | | // Copyright © 2018年 bytedance. All rights reserved. |
| | | // |
| | | |
| | | #import <Foundation/Foundation.h> |
| | | |
| | | @interface NSDictionary (BU_Helper) |
| | | |
| | | - (BOOL)bu_isNull:(id)value; |
| | | - (instancetype)bu_objectForKeySafely:(id)aKey; |
| | | - (instancetype)bu_valueForKeySafely:(NSString *)key; |
| | | - (instancetype)bu_valueForKeyPathSafely:(NSString *)keyPath; |
| | | |
| | | #pragma mark - Safe Value Type From Key |
| | | - (NSString *)bu_stringForKey:(NSString *)key defaultValue:(NSString *)defalutValue; |
| | | - (NSInteger)bu_integerForKey:(NSString *)key defaultValue:(NSInteger)defalutValue; |
| | | - (NSTimeInterval)bu_timeIntervalForKey:(NSString *)key defaultValue:(NSTimeInterval)defalutValue; |
| | | - (NSArray *)bu_arrayForKey:(NSString *)key defaultValue:(NSArray *)defalutValue; |
| | | - (NSDictionary *)bu_dictionaryForKey:(NSString *)key defaultValue:(NSDictionary *)defalutValue; |
| | | @end |
| | | |
| | | @interface NSDictionary(BU_JSONValue) |
| | | |
| | | - (NSString *)bu_JSONRepresentation:(NSError **)error; |
| | | + (id)bu_dictionaryWithJSONData:(NSData *)inData error:(NSError **)outError; |
| | | + (id)bu_dictionaryWithJSONString:(NSString *)inJSON error:(NSError **)outError; |
| | | @end |
New file |
| | |
| | | // |
| | | // NSObject+BUSafeKVO.h |
| | | // BUFoundation |
| | | // |
| | | // Created by Siwant on 2019/9/2. |
| | | // Copyright © 2019 Union. All rights reserved. |
| | | // |
| | | |
| | | #import <Foundation/Foundation.h> |
| | | |
| | | @interface NSObject (BUSafeKVO) |
| | | |
| | | - (void)bu_addObserver:(NSObject *)observer |
| | | forKeyPath:(NSString *)keyPath |
| | | options:(NSKeyValueObservingOptions)options |
| | | context:(void *)context; |
| | | |
| | | - (void)bu_removeObserver:(NSObject *)observer |
| | | forKeyPath:(NSString *)keyPath |
| | | context:(void *)context; |
| | | |
| | | - (void)bu_removeObserver:(NSObject *)observer |
| | | forKeyPath:(NSString *)keyPath; |
| | | |
| | | @end |
New file |
| | |
| | | // |
| | | // NSPointerArray+Safely.h |
| | | // BUAdSDK |
| | | // |
| | | // Created by bytedance_yuanhuan on 2018/6/21. |
| | | // Copyright © 2018年 bytedance. All rights reserved. |
| | | // |
| | | |
| | | #import <Foundation/Foundation.h> |
| | | |
| | | @interface NSPointerArray (BU_Safely) |
| | | - (id)bu_safelyAccessObjectAtIndex:(NSUInteger)index; |
| | | @end |
New file |
| | |
| | | // |
| | | // NSString+URLEncoding.h |
| | | // BUAdSDK |
| | | // |
| | | // Created by carl on 2017/10/26. |
| | | // Copyright © 2017年 bytedance. All rights reserved. |
| | | // |
| | | |
| | | #import <Foundation/Foundation.h> |
| | | |
| | | typedef NS_ENUM(NSUInteger, BULanguageType) {//"万"转换规则 |
| | | BULanguageType_showWan = 0, //直接拼接万,默认 |
| | | BULanguageType_showNum = 1, //直接展示数字 |
| | | }; |
| | | |
| | | @interface NSString (BU_URLCoding) |
| | | - (NSString *)bu_URLEncodedString; |
| | | - (NSString *)bu_URLDecodedString; |
| | | @end |
| | | |
| | | @interface NSString (BU_Encryption) |
| | | - (NSString *)bu_sha256; |
| | | /** |
| | | * @brief 返回自身的md5 |
| | | * @return 返回自身的md5的16进制字串 |
| | | */ |
| | | - (NSString *)bu_MD5HashString; |
| | | @end |
| | | |
| | | @interface NSString (BU_NumberToWan) |
| | | /// 数字转换成x万(以1w为界限,小于1w显示原始数字) 没有”万“走另一套展示逻辑 |
| | | + (NSString *)bu_numberToWan:(NSInteger)target wan:(NSString *)wan; |
| | | |
| | | /// 大于1w就用k表示,不大于就直接展示多少个评分 |
| | | + (NSString *)bu_numberToThousand:(NSInteger)target; |
| | | |
| | | @end |
| | | |
| | | @interface NSString (BU_URLStringAppend) |
| | | /* |
| | | * |
| | | string转URL |
| | | */ |
| | | + (NSURL *)bu_URLWithURLString:(NSString *)str; |
| | | /* |
| | | * |
| | | string转字典 |
| | | */ |
| | | + (NSDictionary*)bu_parametersOfURLString:(NSString*)urlString; |
| | | /* |
| | | * |
| | | url字符串拼接参数,需要判断是否是第一个 |
| | | */ |
| | | + (NSString *)bu_urlStringWithOriginUrlString:(NSString *)originUrlString appendParameters:(NSDictionary *)parameters; |
| | | @end |
| | | |
| | | |
| | | @interface NSString (BU_Sandbox) |
| | | /** |
| | | * 获取缓存路径 |
| | | * |
| | | * @return path where to cache |
| | | */ |
| | | - (NSString *)bu_CachePath; |
| | | |
| | | /** |
| | | * @brief 获取程序的用户文档目录的路径加上自身 |
| | | * @return 用户文档目录路径字串加上自身,该字符串是自动释放的 |
| | | */ |
| | | - (NSString *)bu_DocumentsPath; |
| | | @end |
| | | |
| | | |
| | | @interface NSString(BU_JSONValue) |
| | | |
| | | - (id)bu_JSONValue:(NSError **)error; |
| | | + (id)bu_objectWithJSONData:(NSData *)inData error:(NSError **)outError; |
| | | |
| | | @end |
| | | |
| | | |
| | | @interface NSString(BU_Time) |
| | | |
| | | + (NSString*)bu_dateNowString; |
| | | |
| | | + (NSString*)bu_dateStringSince:(NSTimeInterval)timeInterval; |
| | | |
| | | + (NSNumber*)bu_currentInterval; |
| | | |
| | | @end |
| | | |
| | | |
| | | @interface NSString(BU_Random) |
| | | |
| | | /* @deccription生成随机字符 |
| | | * @param count 多少位随机数 |
| | | */ |
| | | + (NSString *)randomStringWithCount:(NSUInteger)count; |
| | | @end |
| | | |
| | | |
New file |
| | |
| | | // |
| | | // NSTimer+BUBlockSupport.h |
| | | // BUAdSDK |
| | | // |
| | | // Created by gdp on 2017/12/23. |
| | | // Copyright © 2017年 bytedance. All rights reserved. |
| | | // |
| | | |
| | | #import <Foundation/Foundation.h> |
| | | |
| | | @interface NSTimer (BU_BlockSupport) |
| | | |
| | | + (NSTimer *)bu_scheduledTimerWithTimeInterval:(NSTimeInterval)interval |
| | | repeats:(BOOL)repeats |
| | | block:(void (^)(NSTimer *))block; |
| | | @end |
New file |
| | |
| | | // |
| | | // UIColor+BUTheme.h |
| | | // BUAdSDK |
| | | // |
| | | // Created by carl on 2017/8/15. |
| | | // Copyright © 2017年 bytedance. All rights reserved. |
| | | // |
| | | |
| | | #import <UIKit/UIKit.h> |
| | | |
| | | @interface UIColor (BU_Theme) |
| | | + (UIColor *)bu_colorWithHEX:(NSUInteger)hex; |
| | | + (UIColor *)bu_colorWithHEX:(NSUInteger)hex alpha:(CGFloat)alpha; |
| | | |
| | | + (UIColor *)bu_colorWithHexString:(NSString *)color; |
| | | + (UIColor *)bu_colorWithHexString:(NSString *)color alpha:(CGFloat)alpha; |
| | | |
| | | @end |
New file |
| | |
| | | // |
| | | // UIImage+BUIcon.h |
| | | // BUAdSDK |
| | | // |
| | | // Created by carl on 2017/8/10. |
| | | // Copyright © 2017年 bytedance. All rights reserved. |
| | | // |
| | | |
| | | #import <UIKit/UIKit.h> |
| | | |
| | | extern NSString *const kBU_endCardClose; |
| | | extern NSString *const kBU_fullClose; |
| | | extern NSString *const kBU_close; |
| | | extern NSString *const kBU_dislike; |
| | | extern NSString *const kBU_leftback; |
| | | extern NSString *const kBU_nextCell; |
| | | extern NSString *const kBU_play; |
| | | extern NSString *const kBU_pause; |
| | | extern NSString *const kBU_sliderDot; |
| | | extern NSString *const kBU_fullScreen; |
| | | extern NSString *const kBU_bottomPlay; |
| | | extern NSString *const kBU_bottomPause; |
| | | extern NSString *const kBU_bottomShadow; |
| | | extern NSString *const kBU_topShadow; |
| | | extern NSString *const kBU_shrinkScreen; |
| | | extern NSString *const kBU_fastForward; |
| | | extern NSString *const kBU_fastBackward; |
| | | extern NSString *const kBU_replay; |
| | | extern NSString *const kBU_voice; |
| | | extern NSString *const kBU_voice_silent; |
| | | extern NSString *const kBU_logo; |
| | | extern NSString *const kBU_logoAd; |
| | | extern NSString *const kBU_logoAd_oversea; |
| | | extern NSString *const kBU_GDPRBack; |
| | | extern NSString *const kBU_playableLoading; |
| | | |
| | | @interface UIImage (BU_Icon) |
| | | // 异步获取image 不阻塞主线程 |
| | | + (void)bu_compatImageNamed:(NSString *)imageName block:(void(^)(UIImage *image))block; |
| | | // 同步方式 |
| | | + (UIImage *)bu_compatImageNamed:(NSString *)imageName; |
| | | |
| | | @end |
New file |
| | |
| | | /* |
| | | * This file is part of the SDWebImage package. |
| | | * (c) Olivier Poitrey <rs@dailymotion.com> |
| | | * |
| | | * For the full copyright and license information, please view the LICENSE |
| | | * file that was distributed with this source code. |
| | | */ |
| | | |
| | | #import "BU_SDWebImageCompat.h" |
| | | |
| | | typedef NS_ENUM(NSUInteger, BU_SDImageScaleMode) { |
| | | BU_SDImageScaleModeFill = 0, |
| | | BU_SDImageScaleModeAspectFit = 1, |
| | | BU_SDImageScaleModeAspectFill = 2 |
| | | }; |
| | | |
| | | #if SD_UIKIT || SD_WATCH |
| | | typedef UIRectCorner BU_SDRectCorner; |
| | | #else |
| | | typedef NS_OPTIONS(NSUInteger, BU_SDRectCorner) { |
| | | BU_SDRectCornerTopLeft = 1 << 0, |
| | | BU_SDRectCornerTopRight = 1 << 1, |
| | | BU_SDRectCornerBottomLeft = 1 << 2, |
| | | BU_SDRectCornerBottomRight = 1 << 3, |
| | | BU_SDRectCornerAllCorners = ~0UL |
| | | }; |
| | | #endif |
| | | |
| | | /** |
| | | Provide some commen method for `UIImage`. |
| | | Image process is based on Core Graphics and vImage. |
| | | */ |
| | | @interface UIImage (BU_Transform) |
| | | |
| | | #pragma mark - Image Geometry |
| | | |
| | | /** |
| | | Returns a new image which is resized from this image. |
| | | You can specify a larger or smaller size than the image size. The image content will be changed with the scale mode. |
| | | |
| | | @param size The new size to be resized, values should be positive. |
| | | @param scaleMode The scale mode for image content. |
| | | @return The new image with the given size. |
| | | */ |
| | | - (nullable UIImage *)sdBu_resizedImageWithSize:(CGSize)size scaleMode:(BU_SDImageScaleMode)scaleMode; |
| | | |
| | | /** |
| | | Returns a new image which is cropped from this image. |
| | | |
| | | @param rect Image's inner rect. |
| | | @return The new image with the cropping rect. |
| | | */ |
| | | - (nullable UIImage *)sdBu_croppedImageWithRect:(CGRect)rect; |
| | | |
| | | /** |
| | | Rounds a new image with a given corner radius and corners. |
| | | |
| | | @param cornerRadius The radius of each corner oval. Values larger than half the |
| | | rectangle's width or height are clamped appropriately to |
| | | half the width or height. |
| | | @param corners A bitmask value that identifies the corners that you want |
| | | rounded. You can use this parameter to round only a subset |
| | | of the corners of the rectangle. |
| | | @param borderWidth The inset border line width. Values larger than half the rectangle's |
| | | width or height are clamped appropriately to half the width |
| | | or height. |
| | | @param borderColor The border stroke color. nil means clear color. |
| | | @return The new image with the round corner. |
| | | */ |
| | | - (nullable UIImage *)sdBu_roundedCornerImageWithRadius:(CGFloat)cornerRadius |
| | | corners:(BU_SDRectCorner)corners |
| | | borderWidth:(CGFloat)borderWidth |
| | | borderColor:(nullable UIColor *)borderColor; |
| | | |
| | | /** |
| | | Returns a new rotated image (relative to the center). |
| | | |
| | | @param angle Rotated radians in counterclockwise.⟲ |
| | | @param fitSize YES: new image's size is extend to fit all content. |
| | | NO: image's size will not change, content may be clipped. |
| | | @return The new image with the rotation. |
| | | */ |
| | | - (nullable UIImage *)sdBu_rotatedImageWithAngle:(CGFloat)angle fitSize:(BOOL)fitSize; |
| | | |
| | | /** |
| | | Returns a new horizontally(vertically) flipped image. |
| | | |
| | | @param horizontal YES to flip the image horizontally. ⇋ |
| | | @param vertical YES to flip the image vertically. ⥯ |
| | | @return The new image with the flipping. |
| | | */ |
| | | - (nullable UIImage *)sdBu_flippedImageWithHorizontal:(BOOL)horizontal vertical:(BOOL)vertical; |
| | | |
| | | #pragma mark - Image Blending |
| | | |
| | | /** |
| | | Return a tinted image with the given color. This actually use alpha blending of current image and the tint color. |
| | | |
| | | @param tintColor The tint color. |
| | | @return The new image with the tint color. |
| | | */ |
| | | - (nullable UIImage *)sdBu_tintedImageWithColor:(nonnull UIColor *)tintColor; |
| | | |
| | | /** |
| | | Return the pixel color at specify position. The point is from the top-left to the bottom-right and 0-based. The returned the color is always be RGBA format. The image must be CG-based. |
| | | @note The point's x/y should not be smaller than 0, or greater than or equal to width/height. |
| | | @note The overhead of object creation means this method is best suited for infrequent color sampling. For heavy image processing, grab the raw bitmap data and process yourself. |
| | | |
| | | @param point The position of pixel |
| | | @return The color for specify pixel, or nil if any error occur |
| | | */ |
| | | - (nullable UIColor *)sdBu_colorAtPoint:(CGPoint)point; |
| | | |
| | | /** |
| | | Return the pixel color array with specify rectangle. The rect is from the top-left to the bottom-right and 0-based. The returned the color is always be RGBA format. The image must be CG-based. |
| | | @note The rect's width/height should not be smaller than or equal to 0. The minX/minY should not be smaller than 0. The maxX/maxY should not be greater than width/height. Attention this limit is different from `sdBu_colorAtPoint:` (point: (0, 0) like rect: (0, 0, 1, 1)) |
| | | @note The overhead of object creation means this method is best suited for infrequent color sampling. For heavy image processing, grab the raw bitmap data and process yourself. |
| | | |
| | | @param rect The rectangle of pixels |
| | | @return The color array for specify pixels, or nil if any error occur |
| | | */ |
| | | - (nullable NSArray<UIColor *> *)sdBu_colorsWithRect:(CGRect)rect; |
| | | |
| | | #pragma mark - Image Effect |
| | | |
| | | /** |
| | | Return a new image applied a blur effect. |
| | | |
| | | @param blurRadius The radius of the blur in points, 0 means no blur effect. |
| | | |
| | | @return The new image with blur effect, or nil if an error occurs (e.g. no enough memory). |
| | | */ |
| | | - (nullable UIImage *)sdBu_blurredImageWithRadius:(CGFloat)blurRadius; |
| | | |
| | | #if SD_UIKIT || SD_MAC |
| | | /** |
| | | Return a new image applied a CIFilter. |
| | | |
| | | @param filter The CIFilter to be applied to the image. |
| | | @return The new image with the CIFilter, or nil if an error occurs (e.g. no |
| | | enough memory). |
| | | */ |
| | | - (nullable UIImage *)sdBu_filteredImageWithFilter:(nonnull CIFilter *)filter; |
| | | #endif |
| | | |
| | | @end |
New file |
| | |
| | | /* |
| | | * This file is part of the SDWebImage package. |
| | | * (c) Olivier Poitrey <rs@dailymotion.com> |
| | | * |
| | | * For the full copyright and license information, please view the LICENSE |
| | | * file that was distributed with this source code. |
| | | */ |
| | | |
| | | #import "BU_SDWebImageCompat.h" |
| | | #import "BU_SDWebImageManager.h" |
| | | |
| | | /** |
| | | * Usage with a UITableViewCell sub-class: |
| | | * |
| | | * @code |
| | | |
| | | #import <SDWebImage/UIImageView+BU_WebCache.h> |
| | | |
| | | ... |
| | | |
| | | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath |
| | | { |
| | | static NSString *MyIdentifier = @"MyIdentifier"; |
| | | |
| | | UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier]; |
| | | |
| | | if (cell == nil) { |
| | | cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:MyIdentifier]; |
| | | } |
| | | |
| | | // Here we use the provided sdBu_setImageWithURL:placeholderImage: method to load the web image |
| | | // Ensure you use a placeholder image otherwise cells will be initialized with no image |
| | | [cell.imageView sdBu_setImageWithURL:[NSURL URLWithString:@"http://example.com/image.jpg"] |
| | | placeholderImage:[UIImage imageNamed:@"placeholder"]]; |
| | | |
| | | cell.textLabel.text = @"My BU_Text"; |
| | | return cell; |
| | | } |
| | | |
| | | * @endcode |
| | | */ |
| | | |
| | | /** |
| | | * Integrates SDWebImage async downloading and caching of remote images with UIImageView. |
| | | */ |
| | | @interface UIImageView (BUWebCache) |
| | | |
| | | /** |
| | | * Set the imageView `image` with an `url`. |
| | | * |
| | | * The download is asynchronous and cached. |
| | | * |
| | | * @param url The url for the image. |
| | | */ |
| | | - (void)sdBu_setImageWithURL:(nullable NSURL *)url NS_REFINED_FOR_SWIFT; |
| | | |
| | | /** |
| | | * Set the imageView `image` with an `url` and a placeholder. |
| | | * |
| | | * The download is asynchronous and cached. |
| | | * |
| | | * @param url The url for the image. |
| | | * @param placeholder The image to be set initially, until the image request finishes. |
| | | * @see sdBu_setImageWithURL:placeholderImage:options: |
| | | */ |
| | | - (void)sdBu_setImageWithURL:(nullable NSURL *)url |
| | | placeholderImage:(nullable UIImage *)placeholder NS_REFINED_FOR_SWIFT; |
| | | |
| | | /** |
| | | * Set the imageView `image` with an `url`, placeholder and custom options. |
| | | * |
| | | * The download is asynchronous and cached. |
| | | * |
| | | * @param url The url for the image. |
| | | * @param placeholder The image to be set initially, until the image request finishes. |
| | | * @param options The options to use when downloading the image. @see BU_SDWebImageOptions for the possible values. |
| | | */ |
| | | - (void)sdBu_setImageWithURL:(nullable NSURL *)url |
| | | placeholderImage:(nullable UIImage *)placeholder |
| | | options:(BU_SDWebImageOptions)options NS_REFINED_FOR_SWIFT; |
| | | |
| | | /** |
| | | * Set the imageView `image` with an `url`, placeholder, custom options and context. |
| | | * |
| | | * The download is asynchronous and cached. |
| | | * |
| | | * @param url The url for the image. |
| | | * @param placeholder The image to be set initially, until the image request finishes. |
| | | * @param options The options to use when downloading the image. @see BU_SDWebImageOptions for the possible values. |
| | | * @param context A context contains different options to perform specify changes or processes, see `BU_SDWebImageContextOption`. This hold the extra objects which `options` enum can not hold. |
| | | */ |
| | | - (void)sdBu_setImageWithURL:(nullable NSURL *)url |
| | | placeholderImage:(nullable UIImage *)placeholder |
| | | options:(BU_SDWebImageOptions)options |
| | | context:(nullable SDWebImageContext *)context; |
| | | |
| | | /** |
| | | * Set the imageView `image` with an `url`. |
| | | * |
| | | * The download is asynchronous and cached. |
| | | * |
| | | * @param url The url for the image. |
| | | * @param completedBlock A block called when operation has been completed. This block has no return value |
| | | * and takes the requested UIImage as first parameter. In case of error the image parameter |
| | | * is nil and the second parameter may contain an NSError. The third parameter is a Boolean |
| | | * indicating if the image was retrieved from the local cache or from the network. |
| | | * The fourth parameter is the original image url. |
| | | */ |
| | | - (void)sdBu_setImageWithURL:(nullable NSURL *)url |
| | | completed:(nullable BU_SDExternalCompletionBlock)completedBlock; |
| | | |
| | | /** |
| | | * Set the imageView `image` with an `url`, placeholder. |
| | | * |
| | | * The download is asynchronous and cached. |
| | | * |
| | | * @param url The url for the image. |
| | | * @param placeholder The image to be set initially, until the image request finishes. |
| | | * @param completedBlock A block called when operation has been completed. This block has no return value |
| | | * and takes the requested UIImage as first parameter. In case of error the image parameter |
| | | * is nil and the second parameter may contain an NSError. The third parameter is a Boolean |
| | | * indicating if the image was retrieved from the local cache or from the network. |
| | | * The fourth parameter is the original image url. |
| | | */ |
| | | - (void)sdBu_setImageWithURL:(nullable NSURL *)url |
| | | placeholderImage:(nullable UIImage *)placeholder |
| | | completed:(nullable BU_SDExternalCompletionBlock)completedBlock NS_REFINED_FOR_SWIFT; |
| | | |
| | | /** |
| | | * Set the imageView `image` with an `url`, placeholder and custom options. |
| | | * |
| | | * The download is asynchronous and cached. |
| | | * |
| | | * @param url The url for the image. |
| | | * @param placeholder The image to be set initially, until the image request finishes. |
| | | * @param options The options to use when downloading the image. @see BU_SDWebImageOptions for the possible values. |
| | | * @param completedBlock A block called when operation has been completed. This block has no return value |
| | | * and takes the requested UIImage as first parameter. In case of error the image parameter |
| | | * is nil and the second parameter may contain an NSError. The third parameter is a Boolean |
| | | * indicating if the image was retrieved from the local cache or from the network. |
| | | * The fourth parameter is the original image url. |
| | | */ |
| | | - (void)sdBu_setImageWithURL:(nullable NSURL *)url |
| | | placeholderImage:(nullable UIImage *)placeholder |
| | | options:(BU_SDWebImageOptions)options |
| | | completed:(nullable BU_SDExternalCompletionBlock)completedBlock; |
| | | |
| | | /** |
| | | * Set the imageView `image` with an `url`, placeholder and custom options. |
| | | * |
| | | * The download is asynchronous and cached. |
| | | * |
| | | * @param url The url for the image. |
| | | * @param placeholder The image to be set initially, until the image request finishes. |
| | | * @param options The options to use when downloading the image. @see BU_SDWebImageOptions for the possible values. |
| | | * @param progressBlock A block called while image is downloading |
| | | * @note the progress block is executed on a background queue |
| | | * @param completedBlock A block called when operation has been completed. This block has no return value |
| | | * and takes the requested UIImage as first parameter. In case of error the image parameter |
| | | * is nil and the second parameter may contain an NSError. The third parameter is a Boolean |
| | | * indicating if the image was retrieved from the local cache or from the network. |
| | | * The fourth parameter is the original image url. |
| | | */ |
| | | - (void)sdBu_setImageWithURL:(nullable NSURL *)url |
| | | placeholderImage:(nullable UIImage *)placeholder |
| | | options:(BU_SDWebImageOptions)options |
| | | progress:(nullable SDImageLoaderProgressBlock)progressBlock |
| | | completed:(nullable BU_SDExternalCompletionBlock)completedBlock; |
| | | |
| | | /** |
| | | * Set the imageView `image` with an `url`, placeholder, custom options and context. |
| | | * |
| | | * The download is asynchronous and cached. |
| | | * |
| | | * @param url The url for the image. |
| | | * @param placeholder The image to be set initially, until the image request finishes. |
| | | * @param options The options to use when downloading the image. @see BU_SDWebImageOptions for the possible values. |
| | | * @param context A context contains different options to perform specify changes or processes, see `BU_SDWebImageContextOption`. This hold the extra objects which `options` enum can not hold. |
| | | * @param progressBlock A block called while image is downloading |
| | | * @note the progress block is executed on a background queue |
| | | * @param completedBlock A block called when operation has been completed. This block has no return value |
| | | * and takes the requested UIImage as first parameter. In case of error the image parameter |
| | | * is nil and the second parameter may contain an NSError. The third parameter is a Boolean |
| | | * indicating if the image was retrieved from the local cache or from the network. |
| | | * The fourth parameter is the original image url. |
| | | */ |
| | | - (void)sdBu_setImageWithURL:(nullable NSURL *)url |
| | | placeholderImage:(nullable UIImage *)placeholder |
| | | options:(BU_SDWebImageOptions)options |
| | | context:(nullable SDWebImageContext *)context |
| | | progress:(nullable SDImageLoaderProgressBlock)progressBlock |
| | | completed:(nullable BU_SDExternalCompletionBlock)completedBlock; |
| | | |
| | | @end |
New file |
| | |
| | | // |
| | | // UIView+Additions.h |
| | | // BUAdSDK |
| | | // |
| | | // Created by bytedance_yuanhuan on 2018/3/15. |
| | | // Copyright © 2018年 bytedance. All rights reserved. |
| | | // |
| | | |
| | | #import <UIKit/UIKit.h> |
| | | |
| | | @interface UIView (BU_Additions) |
| | | |
| | | - (UIImage *)bu_captureView; |
| | | |
| | | @end |
| | | |
| | | typedef enum { |
| | | UIViewBorderOptionTop = 0, |
| | | UIViewBorderOptionRight, |
| | | UIViewBorderOptionBottom, |
| | | UIViewBorderOptionLeft, |
| | | UIViewBorderOptionAll |
| | | } UIViewBorderOption; |
| | | |
| | | @interface UIView (BU_Border) |
| | | |
| | | - (void)bu_setBorder:(UIViewBorderOption)option width:(CGFloat)width color:(UIColor *)color; |
| | | - (void)bu_setDashBorder:(UIViewBorderOption)option width:(CGFloat)width color:(UIColor *)color; |
| | | - (void)bu_roundCornerWithDashBorder:(CGFloat)radius width:(CGFloat)widht color:(UIColor *)color; |
| | | |
| | | @end |
| | | |
| | | |
| | | @interface UIView (BU_FrameAdditions) |
| | | @property (nonatomic) float bu_x; |
| | | @property (nonatomic) float bu_y; |
| | | @property (nonatomic) float bu_width; |
| | | @property (nonatomic) float bu_height; |
| | | @property (nonatomic, getter = bu_y,setter = setBu_y:) float top; |
| | | @property (nonatomic, getter = bu_x,setter = setBu_x:) float left; |
| | | @property (nonatomic) float bu_bottom; |
| | | @property (nonatomic) float bu_right; |
| | | @property (nonatomic) CGSize bu_size; |
| | | @property (nonatomic) CGPoint bu_origin; |
| | | @property (nonatomic) CGFloat bu_centerX; |
| | | @property (nonatomic) CGFloat bu_centerY; |
| | | |
| | | // 设置最大右边 |
| | | - (void)bu_setMaxRight:(CGFloat)maxRight; |
| | | @end |
| | | |
| | | |
| | | @interface UIView(BU_ScreenShot) |
| | | |
| | | + (UIImage *)bu_screenShot; |
| | | + (UIImage *)bu_screenShotWithoutStatusBar; |
| | | |
| | | - (UIImage *)bu_screenShot; |
| | | |
| | | @end |
| | | |
| | | |
| | | |
| | | @interface UIView (BU_TKCategory) |
| | | |
| | | // DRAW GRADIENT |
| | | + (void)bu_drawGradientInRect:(CGRect)rect withColors:(NSArray*)colors; |
| | | |
| | | // DRAW ROUNDED RECTANGLE |
| | | + (void)bu_drawRoundRectangleInRect:(CGRect)rect withRadius:(CGFloat)radius color:(UIColor*)color; |
| | | |
| | | // DRAW LINE |
| | | + (void)bu_drawLineInRect:(CGRect)rect red:(CGFloat)red green:(CGFloat)green blue:(CGFloat)blue alpha:(CGFloat)alpha; |
| | | + (void)bu_drawLineInRect:(CGRect)rect colors:(CGFloat[])colors; |
| | | + (void)bu_drawLineInRect:(CGRect)rect colors:(CGFloat[])colors width:(CGFloat)lineWidth cap:(CGLineCap)cap; |
| | | |
| | | @end |
| | | |
| | | |
| | | @interface UIView (BU_Gesture) |
| | | |
| | | - (UILongPressGestureRecognizer *)bu_addLogPressGestureWithTarget:(id)target selecter:(SEL)aSelector; |
| | | |
| | | @end |
| | | |
| | | @interface UIView (BU_FindFirstResponder) |
| | | - (UIView *)bu_findViewThatIsFirstResponder; |
| | | @end |
| | | |
| | | @interface UIView (BU_InScreen) |
| | | - (BOOL)bu_checkInCurrentScreenWithEdgeInsets:(UIEdgeInsets)edgeInsets; |
| | | - (BOOL)bu_checkInScreenYWithPaddingTop:(CGFloat)paddingTop paddingToBottom:(CGFloat)paddingToBottom; |
| | | - (BOOL)bu_checkInScreenXWithPaddingLeft:(CGFloat)paddingLeft paddingToRight:(CGFloat)paddingToRight; |
| | | @end |
| | | |
| | | @interface UIView (BU_NearestController) |
| | | - (UIViewController *)bu_findNearestController; |
| | | @end |
| | | |
| | | @interface UIView (BU_SafeArea) |
| | | - (UIEdgeInsets)bu_safeAreaInsets; |
| | | |
| | | + (UIEdgeInsets)bu_defaultAreaInsets; |
| | | |
| | | @end |
New file |
| | |
| | | // |
| | | // UIViewController+BUUtilities.h |
| | | // BUAdSDK |
| | | // |
| | | // Created by Siwant on 2019/4/11. |
| | | // Copyright © 2019 bytedance. All rights reserved. |
| | | // |
| | | |
| | | #import <UIKit/UIKit.h> |
| | | |
| | | NS_ASSUME_NONNULL_BEGIN |
| | | |
| | | @interface UIViewController (BUUtilities) |
| | | |
| | | - (void)bu_safelyPresentViewController:(UIViewController *)viewControllerToPresent animated: (BOOL)flag completion:(void (^ __nullable)(void))completion; |
| | | |
| | | @end |
| | | |
| | | NS_ASSUME_NONNULL_END |
New file |
| | |
| | | framework module BUFoundation { |
| | | umbrella header "BUFoundation.h" |
| | | |
| | | export * |
| | | module * { export * } |
| | | } |
| | |
| | | //收藏的视频 |
| | | NSDictionary *dic = _videoData[indexPath.row]; |
| | | XYRDetailViewController *play=[[XYRDetailViewController alloc] init]; |
| | | play.modalPresentationStyle = 0; |
| | | play.Model = [XYRVideoInfoModel yy_modelWithDictionary:dic]; |
| | | [self presentViewController:play animated:YES completion:^{ |
| | | |
| | |
| | | |
| | | #import "HXEasyCustomShareView.h"//分享界面 |
| | | |
| | | #import <UMMobClick/MobClick.h> //友盟统计 |
| | | #import <UMSocialCore/UMSocialCore.h> //友盟分享 |
| | | //#import <UMShare/UMShare.h> //友盟分享 |
| | | #import "UIViewController+Tools.h" |
| | | #import "BSKImagesPageView.h" |
| | | #import "NoNetworkView.h" |
| | |
| | | #define GDTYSADkey2 @"6090655777307893"//广点通原生广告_推荐第一个 |
| | | #define GDTYSADkey3 @"1010852707426274"//广点通原生广告_搜索 |
| | | #define GDTYSADkey4 @"2060055777449803"//广点通原生广告_播放页 |
| | | #define GDTYSADkey5 @"6000418684535350"//广点通原生广告_分类顶部 |
| | | #define GDTYSADkey5 @"2031734168341661"//广点通原生广告_分类顶部 |
| | | #define GDTYSADkey6 @"7010358693528617"//广点通原生广告_猜你喜欢 |
| | | #define GDTYSADkey7 @"7020351787528318"//广点通原生广告_搜索详情 |
| | | #define GDTYSADkey8 @"7030457727236454"//广点通原生广告_推荐第2个 |
| | |
| | | #pragma mark -UICollectionViewDataSource |
| | | - (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath{ |
| | | XYRDetailViewController *play=[[XYRDetailViewController alloc] init]; |
| | | play.modalPresentationStyle = 0; |
| | | play.Model = [XYRVideoInfoModel yy_modelWithDictionary:_arrDate[indexPath.row]]; |
| | | [self presentViewController:play animated:YES completion:^{ |
| | | |
New file |
| | |
| | | // |
| | | // GDTAdParams.h |
| | | // GDTMobApp |
| | | // |
| | | // Created by royqpwang on 2020/4/30. |
| | | // Copyright © 2020 Tencent. All rights reserved. |
| | | // |
| | | |
| | | #import <Foundation/Foundation.h> |
| | | |
| | | NS_ASSUME_NONNULL_BEGIN |
| | | |
| | | @interface GDTAdParams : NSObject |
| | | |
| | | /** |
| | | * 广告大小,模板 2.0 信息流广告使用。当 height = 0,自动根据 width 算高;当 height > 0,直接使用传入的 width、height 作为模板容器 View 的大小。 |
| | | */ |
| | | @property (nonatomic, assign) CGSize adSize; |
| | | |
| | | /** |
| | | * 非 WiFi 网络,视频广告是否自动播放。默认 NO。loadAd 前设置。 |
| | | */ |
| | | @property (nonatomic, assign) BOOL videoAutoPlayOnWWAN; |
| | | |
| | | /** |
| | | * 视频广告自动播放时,是否静音。默认 YES。loadAd 前设置。 |
| | | */ |
| | | @property (nonatomic, assign) BOOL videoMuted; |
| | | |
| | | /** |
| | | * 视频详情页播放时是否静音。默认NO。loadAd 前设置。 |
| | | */ |
| | | @property (nonatomic, assign) BOOL detailPageVideoMuted; |
| | | |
| | | /** |
| | | 请求视频的时长下限,视频时长有效值范围为[5,60]。 |
| | | 以下两种情况会使用系统默认的最小值设置,1:不设置 2:minVideoDuration大于maxVideoDuration |
| | | */ |
| | | @property (nonatomic) NSInteger minVideoDuration; |
| | | |
| | | /** |
| | | 请求视频的时长上限,视频时长有效值范围为[5,60]。 |
| | | */ |
| | | @property (nonatomic) NSInteger maxVideoDuration; |
| | | |
| | | @end |
| | | |
| | | NS_ASSUME_NONNULL_END |
New file |
| | |
| | | // |
| | | // GDTAdDebugSetting.h |
| | | // GDTMobSDK |
| | | // |
| | | // Created by Nancy on 2020/8/12. |
| | | // Copyright © 2020 Tencent. All rights reserved. |
| | | // |
| | | |
| | | #import <Foundation/Foundation.h> |
| | | |
| | | NS_ASSUME_NONNULL_BEGIN |
| | | |
| | | /** |
| | | 提供一些配置,用于在开发调试阶段使用 |
| | | */ |
| | | @interface GDTAdTestSetting : NSObject |
| | | @property (nonatomic, copy, nullable) NSString *playableUrl;//测试时使用的试玩广告地址 |
| | | @end |
| | | |
| | | NS_ASSUME_NONNULL_END |
New file |
| | |
| | | // |
| | | // GDTBaseAdNetworkAdapterProtocol.h |
| | | // GDTMobApp |
| | | // |
| | | // Created by royqpwang on 2019/7/25. |
| | | // Copyright © 2019 Tencent. All rights reserved. |
| | | // |
| | | |
| | | #import <Foundation/Foundation.h> |
| | | |
| | | @protocol GDTBaseAdNetworkAdapterProtocol <NSObject> |
| | | |
| | | + (NSString *)adapterVersion; |
| | | |
| | | - (instancetype)initWithAdNetworkConnector:(id)connector |
| | | posId:(NSString *)posId |
| | | extStr:(NSString *)extStr; |
| | | @optional |
| | | |
| | | - (NSInteger)eCPM; |
| | | - (NSInteger)priority; |
| | | - (NSString *)eCPMLevel; |
| | | - (void)cancelLoad; |
| | | - (NSInteger)mediationPrice; |
| | | - (BOOL)isContractAd; |
| | | |
| | | @end |
| | | |
New file |
| | |
| | | // |
| | | // GDTHybridAd.h |
| | | // GDTMobApp |
| | | // |
| | | // Created by royqpwang on 2019/3/8. |
| | | // Copyright © 2019 Tencent. All rights reserved. |
| | | // |
| | | |
| | | #import <Foundation/Foundation.h> |
| | | |
| | | NS_ASSUME_NONNULL_BEGIN |
| | | |
| | | typedef NS_OPTIONS(NSInteger, GDTHybridAdOptions) { |
| | | GDTHybridAdOptionRewardVideo = 1 << 0 |
| | | }; |
| | | |
| | | @class GDTHybridAd; |
| | | |
| | | @protocol GDTHybridAdDelegate <NSObject> |
| | | |
| | | @optional |
| | | |
| | | - (void)gdt_hybridAdDidPresented:(GDTHybridAd *)hybridAd; |
| | | - (void)gdt_hybridAdDidClose:(GDTHybridAd *)hybridAd; |
| | | - (void)gdt_hybridAdLoadURLSuccess:(GDTHybridAd *)hybridAd; |
| | | - (void)gdt_hybridAd:(GDTHybridAd *)hybridAd didFailWithError:(NSError *)error; |
| | | |
| | | @end |
| | | |
| | | @interface GDTHybridAd : NSObject |
| | | |
| | | /** |
| | | 自定义浏览器 UI 属性,请在 showWithRootViewController: 方法前设置。 |
| | | */ |
| | | @property (nonatomic, copy) NSString *titleContent; |
| | | @property (nonatomic, strong) UIColor *titleColor; |
| | | @property (nonatomic, strong) UIFont *titleFont; |
| | | @property (nonatomic, strong) UIColor *navigationBarColor; |
| | | @property (nonatomic, strong) UIColor *navigationBarBottomColor; |
| | | @property (nonatomic, strong) UIColor *separatorLineColor; |
| | | @property (nonatomic, strong) UIImage *closeImage; // 如需自定义关闭图片,请按 44*44 大小设置 |
| | | @property (nonatomic, strong) UIImage *backImage; // 如需自定义后退图片,请按 44*44 大小设置 |
| | | |
| | | |
| | | /** |
| | | 委托对象 |
| | | */ |
| | | @property (nonatomic, weak) id <GDTHybridAdDelegate> delegate; |
| | | |
| | | |
| | | /** |
| | | 构造方法 |
| | | |
| | | @param adOptions - 支持的广告类型 Options,激励视频请传 GDTHybridAdOptionRewardVideo |
| | | @return GDTHybrid 实例 |
| | | */ |
| | | - (instancetype)initWithType:(GDTHybridAdOptions)adOptions; |
| | | |
| | | |
| | | /** |
| | | 加载广告方法 支持 iOS8.1 及以上系统 |
| | | |
| | | @param url 加载的 X 中心 URL |
| | | */ |
| | | - (void)loadWithUrl:(NSString *)url; |
| | | |
| | | |
| | | /** |
| | | 展示浏览器方法 |
| | | |
| | | @param rootViewController 用于 present 浏览器 VC |
| | | */ |
| | | - (void)showWithRootViewController:(UIViewController *)rootViewController; |
| | | |
| | | @end |
| | | |
| | | NS_ASSUME_NONNULL_END |
New file |
| | |
| | | // |
| | | // GDTLoadAdParams.h |
| | | // GDTMobSDK |
| | | // |
| | | // Created by vicluo(罗翔) on 2019/4/26. |
| | | // Copyright © 2019年 Tencent. All rights reserved. |
| | | // |
| | | |
| | | #import <Foundation/Foundation.h> |
| | | #import "GDTSDKDefines.h" |
| | | |
| | | @interface GDTLoadAdParams : NSObject |
| | | |
| | | //登陆账号类型:QQ or weixin |
| | | @property (nonatomic, assign) GDTSDKLoginType loginType; |
| | | |
| | | //登陆账号体系分配的appID,如QQ分配的appID或是微信分配的appID |
| | | @property (nonatomic, copy) NSString *loginAppId; |
| | | |
| | | //登陆账号体系分配的openID,如QQ分配的openId或是微信分配的openId |
| | | @property (nonatomic, copy) NSString *loginOpenId; |
| | | |
| | | //透传字段,key跟value都由调用方自行指定 |
| | | @property (nonatomic, strong) NSDictionary *dictionary; |
| | | |
| | | - (void)setExtraInfo:(NSDictionary*)dict; |
| | | |
| | | @end |
| | | |
| | | |
New file |
| | |
| | | // |
| | | // GDTLogoView.h |
| | | // GDTMobSDK |
| | | // |
| | | // Created by nimomeng on 2018/10/10. |
| | | // Copyright © 2018 Tencent. All rights reserved. |
| | | // |
| | | |
| | | #import <UIKit/UIKit.h> |
| | | //logo默认宽度 |
| | | extern CGFloat const kGDTLogoImageViewDefaultWidth; |
| | | //logo默认高度 |
| | | extern CGFloat const kGDTLogoImageViewDefaultHeight; |
| | | |
| | | @interface GDTLogoView : UIImageView |
| | | @end |
New file |
| | |
| | | // |
| | | // GDTMediaView.h |
| | | // GDTMobSDK |
| | | // |
| | | // Created by nimomeng on 2018/10/10. |
| | | // Copyright © 2018 Tencent. All rights reserved. |
| | | // |
| | | |
| | | #import <UIKit/UIKit.h> |
| | | #import "GDTSDKDefines.h" |
| | | |
| | | @class GDTMediaView; |
| | | @protocol GDTMediaViewDelegate <NSObject> |
| | | |
| | | @optional |
| | | |
| | | /** |
| | | 用户点击 MediaView 回调,当 GDTVideoConfig userControlEnable 设为 YES,用户点击 mediaView 会回调。 |
| | | |
| | | @param mediaView 播放器实例 |
| | | */ |
| | | - (void)gdt_mediaViewDidTapped:(GDTMediaView *)mediaView; |
| | | |
| | | /** |
| | | 播放完成回调 |
| | | |
| | | @param mediaView 播放器实例 |
| | | */ |
| | | - (void)gdt_mediaViewDidPlayFinished:(GDTMediaView *)mediaView; |
| | | |
| | | @end |
| | | |
| | | @interface GDTMediaView : UIView |
| | | |
| | | /** |
| | | GDTMediaView 回调对象 |
| | | */ |
| | | @property (nonatomic, weak) id <GDTMediaViewDelegate> delegate; |
| | | |
| | | /** |
| | | * 视频广告时长,单位 ms |
| | | */ |
| | | - (CGFloat)videoDuration; |
| | | |
| | | /** |
| | | * 视频广告已播放时长,单位 ms |
| | | */ |
| | | - (CGFloat)videoPlayTime; |
| | | |
| | | /** |
| | | 播放视频 |
| | | */ |
| | | - (void)play; |
| | | |
| | | /** |
| | | 暂停视频,调用 pause 后,需要被暂停的视频广告对象,不会再自动播放,需要调用 play 才能恢复播放。 |
| | | */ |
| | | - (void)pause; |
| | | |
| | | /** |
| | | 停止播放,并展示第一帧 |
| | | */ |
| | | - (void)stop; |
| | | |
| | | /** |
| | | 播放静音开关 |
| | | @param flag 是否静音 |
| | | */ |
| | | - (void)muteEnable:(BOOL)flag; |
| | | |
| | | /** |
| | | 自定义播放按钮 |
| | | |
| | | @param image 自定义播放按钮图片,不设置为默认图 |
| | | @param size 自定义播放按钮大小,不设置为默认大小 44 * 44 |
| | | */ |
| | | - (void)setPlayButtonImage:(UIImage *)image size:(CGSize)size; |
| | | |
| | | #pragma mark - DEPRECATED |
| | | /** |
| | | 是否支持在WWAN下自动播放视频, 默认 NO,已废弃,请使用 GDTVideoConfig 类配置 |
| | | */ |
| | | @property (nonatomic, assign) BOOL videoAutoPlayOnWWAN GDT_DEPRECATED_ATTRIBUTE; |
| | | |
| | | /** |
| | | 是否静音播放视频广告, 默认 YES,已废弃,请使用 GDTVideoConfig 类配置 |
| | | */ |
| | | @property (nonatomic, assign) BOOL videoMuted GDT_DEPRECATED_ATTRIBUTE; |
| | | |
| | | @end |
| | |
| | | #import <UIKit/UIKit.h> |
| | | #import "GDTSDKDefines.h" |
| | | |
| | | /** |
| | | * 视频模板广告播放器状态 |
| | | * |
| | | * 播放器只可能处于以下状态中的一种 |
| | | * |
| | | */ |
| | | typedef NS_ENUM(NSUInteger, GDTMediaPlayerStatus) { |
| | | GDTMediaPlayerStatusInitial = 0, // 初始状态 |
| | | GDTMediaPlayerStatusLoading = 1, // 加载中 |
| | | GDTMediaPlayerStatusStarted = 2, // 开始播放 |
| | | GDTMediaPlayerStatusPaused = 3, // 用户行为导致暂停 |
| | | GDTMediaPlayerStatusStoped = 4, // 播放停止 |
| | | GDTMediaPlayerStatusError = 5, // 播放出错 |
| | | }; |
| | | |
| | | @class GDTNativeExpressAdView; |
| | | @class GDTNativeExpressAd; |
| | | |
| | |
| | | /** |
| | | * 全屏广告页将要关闭 |
| | | */ |
| | | - (void)nativeExpressAdViewWillDissmissScreen:(GDTNativeExpressAdView *)nativeExpressAdView; |
| | | - (void)nativeExpressAdViewWillDismissScreen:(GDTNativeExpressAdView *)nativeExpressAdView; |
| | | |
| | | /** |
| | | * 全屏广告页将要关闭 |
| | | */ |
| | | - (void)nativeExpressAdViewDidDissmissScreen:(GDTNativeExpressAdView *)nativeExpressAdView; |
| | | - (void)nativeExpressAdViewDidDismissScreen:(GDTNativeExpressAdView *)nativeExpressAdView; |
| | | |
| | | /** |
| | | * 原生模板广告点击之后应用进入后台时回调 |
| | | * 详解:当点击应用下载或者广告调用系统程序打开时调用 |
| | | */ |
| | | - (void)nativeExpressAdViewApplicationWillEnterBackground:(GDTNativeExpressAdView *)nativeExpressAdView; |
| | | |
| | |
| | | @property (nonatomic, assign) BOOL videoMuted; |
| | | |
| | | /** |
| | | * 视频详情页播放时是否静音。默认NO。loadAd 前设置。 |
| | | */ |
| | | @property (nonatomic, assign) BOOL detailPageVideoMuted; |
| | | |
| | | /** |
| | | 请求视频的时长下限,视频时长有效值范围为[5,60]。 |
| | | 以下两种情况会使用系统默认的最小值设置,1:不设置 2:minVideoDuration大于maxVideoDuration |
| | | */ |
| | | @property (nonatomic) NSInteger minVideoDuration; |
| | | |
| | | /** |
| | | 请求视频的时长上限,视频时长有效值范围为[5,60]。 |
| | | */ |
| | | @property (nonatomic) NSInteger maxVideoDuration; |
| | | |
| | | @property (nonatomic, readonly) NSString *placementId; |
| | | |
| | | /** |
| | | * 构造方法 |
| | | * 详解:placementId - 广告位 ID |
| | | * adSize - 广告展示的宽高 |
| | | */ |
| | | |
| | | - (instancetype)initWithPlacementId:(NSString *)placementId adSize:(CGSize)size; |
| | | |
| | | /** |
| | | * 构造方法 |
| | | * 详解:appId - 媒体 ID |
| | | * placementId - 广告位 ID |
| | | * adSize - 广告展示的宽高 |
| | | */ |
| | | - (instancetype)initWithAppId:(NSString *)appId placementId:(NSString *)placementId adSize:(CGSize)size; |
| | | - (instancetype)initWithAppId:(NSString *)appId placementId:(NSString *)placementId adSize:(CGSize)size GDT_DEPRECATED_MSG_ATTRIBUTE("接口即将废弃,请使用 initWithPlacementId:adSize:"); |
| | | |
| | | - (void)loadAd:(NSInteger)count; |
| | | |
| | | #pragma mark - DEPRECATED |
| | | - (instancetype)initWithAppkey:(NSString *)appkey placementId:(NSString *)placementId adSize:(CGSize)size GDT_DEPRECATED_MSG_ATTRIBUTE("use initWithAppId:placementId:adSize instead."); |
| | | |
| | | /** |
| | | 返回广告平台名称 |
| | | |
| | | @return 当使用流量分配功能时,用于区分广告平台;未使用时为空字符串 |
| | | */ |
| | | - (NSString *)adNetworkName; |
| | | @end |
| | |
| | | */ |
| | | - (CGFloat)videoPlayTime; |
| | | |
| | | /** |
| | | 返回广告的eCPM,单位:分 |
| | | |
| | | @return 成功返回一个大于等于0的值,-1表示无权限或后台出现异常 |
| | | */ |
| | | - (NSInteger)eCPM; |
| | | |
| | | /** |
| | | 返回广告的eCPM等级 |
| | | |
| | | @return 成功返回一个包含数字的string,@""或nil表示无权限或后台异常 |
| | | */ |
| | | - (NSString *)eCPMLevel; |
| | | |
| | | @end |
New file |
| | |
| | | // |
| | | // GDTNativeExpressProAdManager.h |
| | | // GDTMobApp |
| | | // |
| | | // Created by royqpwang on 2020/4/28. |
| | | // Copyright © 2020 Tencent. All rights reserved. |
| | | // |
| | | |
| | | #import <Foundation/Foundation.h> |
| | | #import "GDTAdParams.h" |
| | | |
| | | NS_ASSUME_NONNULL_BEGIN |
| | | |
| | | @class GDTNativeExpressProAdManager; |
| | | @class GDTNativeExpressProAdView; |
| | | |
| | | @protocol GDTNativeExpressProAdManagerDelegate <NSObject> |
| | | |
| | | @optional |
| | | /** |
| | | * 拉取原生模板2.0广告成功 |
| | | */ |
| | | - (void)gdt_nativeExpressProAdSuccessToLoad:(GDTNativeExpressProAdManager *)adManager views:(NSArray<__kindof GDTNativeExpressProAdView *> *)views; |
| | | |
| | | /** |
| | | * 拉取原生模板2.0广告失败 |
| | | */ |
| | | - (void)gdt_nativeExpressProAdFailToLoad:(GDTNativeExpressProAdManager *)adManager error:(NSError *)error; |
| | | |
| | | @end |
| | | |
| | | |
| | | @interface GDTNativeExpressProAdManager : NSObject |
| | | |
| | | /** |
| | | * 委托对象 |
| | | */ |
| | | @property (nonatomic, weak) id<GDTNativeExpressProAdManagerDelegate> delegate; |
| | | |
| | | @property (nonatomic, readonly) NSString *placementId; |
| | | |
| | | @property (nonatomic, strong, readonly) GDTAdParams *adParams; |
| | | |
| | | /** |
| | | * 构造方法 |
| | | * 详解:placementId - 广告位 ID |
| | | * adSize - 广告参数 |
| | | */ |
| | | - (instancetype)initWithPlacementId:(NSString *)placementId adPrams:(GDTAdParams *)adParams; |
| | | |
| | | - (void)loadAd:(NSInteger)count; |
| | | |
| | | @end |
| | | |
| | | NS_ASSUME_NONNULL_END |
New file |
| | |
| | | // |
| | | // GDTNativeExpressProAdView.h |
| | | // GDTMobApp |
| | | // |
| | | // Created by royqpwang on 2020/4/28. |
| | | // Copyright © 2020 Tencent. All rights reserved. |
| | | // |
| | | |
| | | #import <UIKit/UIKit.h> |
| | | #import "GDTAdParams.h" |
| | | #import "GDTSDKDefines.h" |
| | | |
| | | NS_ASSUME_NONNULL_BEGIN |
| | | |
| | | @class GDTNativeExpressProAdView; |
| | | |
| | | @protocol GDTNativeExpressProAdViewDelegate <NSObject> |
| | | |
| | | @optional |
| | | /** |
| | | * 原生模板2.0广告渲染成功, 此时的 nativeExpressAdView.size.height 根据 size.width 完成了动态更新。 |
| | | */ |
| | | - (void)gdt_NativeExpressProAdViewRenderSuccess:(GDTNativeExpressProAdView *)nativeExpressProAdView; |
| | | |
| | | /** |
| | | * 原生模板2.0广告渲染失败 |
| | | */ |
| | | - (void)gdt_NativeExpressProAdViewRenderFail:(GDTNativeExpressProAdView *)nativeExpressProAdView; |
| | | |
| | | /** |
| | | * 原生模板2.0广告曝光回调 |
| | | */ |
| | | - (void)gdt_NativeExpressProAdViewExposure:(GDTNativeExpressProAdView *)nativeExpressProAdView; |
| | | |
| | | /** |
| | | * 原生模板2.0广告点击回调 |
| | | */ |
| | | - (void)gdt_NativeExpressProAdViewClicked:(GDTNativeExpressProAdView *)nativeExpressProAdView; |
| | | |
| | | /** |
| | | * 原生模板2.0广告被关闭 |
| | | */ |
| | | - (void)gdt_NativeExpressProAdViewClosed:(GDTNativeExpressProAdView *)nativeExpressProAdView; |
| | | |
| | | /** |
| | | * 点击原生模板2.0广告以后即将弹出全屏广告页 |
| | | */ |
| | | - (void)gdt_NativeExpressProAdViewWillPresentScreen:(GDTNativeExpressProAdView *)nativeExpressProAdView; |
| | | |
| | | /** |
| | | * 点击原生模板2.0广告以后弹出全屏广告页 |
| | | */ |
| | | - (void)gdt_NativeExpressProAdViewDidPresentScreen:(GDTNativeExpressProAdView *)nativeExpressProAdView; |
| | | |
| | | /** |
| | | * 全屏广告页将要关闭 |
| | | */ |
| | | - (void)gdt_NativeExpressProAdViewWillDissmissScreen:(GDTNativeExpressProAdView *)nativeExpressProAdView; |
| | | |
| | | /** |
| | | * 全屏广告页将要关闭 |
| | | */ |
| | | - (void)gdt_NativeExpressProAdViewDidDissmissScreen:(GDTNativeExpressProAdView *)nativeExpressProAdView; |
| | | |
| | | /** |
| | | * 详解:当点击应用下载或者广告调用系统程序打开时调用 |
| | | */ |
| | | - (void)gdt_NativeExpressProAdViewApplicationWillEnterBackground:(GDTNativeExpressProAdView *)nativeExpressProAdView; |
| | | |
| | | /** |
| | | * 原生模板视频广告 player 播放状态更新回调 |
| | | */ |
| | | - (void)gdt_NativeExpressProAdView:(GDTNativeExpressProAdView *)nativeExpressProAdView playerStatusChanged:(GDTMediaPlayerStatus)status; |
| | | |
| | | @end |
| | | |
| | | @interface GDTNativeExpressProAdView : UIView |
| | | |
| | | @property (nonatomic, weak) id <GDTNativeExpressProAdViewDelegate> delegate; |
| | | |
| | | /** |
| | | * 是否渲染完毕 |
| | | */ |
| | | @property (nonatomic, assign, readonly) BOOL isReady; |
| | | |
| | | /** |
| | | * 是否是视频模板广告 |
| | | */ |
| | | @property (nonatomic, assign, readonly) BOOL isVideoAd; |
| | | |
| | | /* |
| | | * viewControllerForPresentingModalView |
| | | * 详解:[必选]开发者需传入用来弹出目标页的ViewController,一般为当前ViewController |
| | | */ |
| | | @property (nonatomic, weak) UIViewController *controller; |
| | | |
| | | /** |
| | | *[必选] |
| | | *原生模板2.0广告渲染 |
| | | */ |
| | | - (void)render; |
| | | |
| | | /** |
| | | * 视频模板广告时长,单位 ms |
| | | */ |
| | | - (CGFloat)videoDuration; |
| | | |
| | | /** |
| | | * 视频模板广告已播放时长,单位 ms |
| | | */ |
| | | - (CGFloat)videoPlayTime; |
| | | |
| | | /** |
| | | 返回广告的eCPM,单位:分 |
| | | |
| | | @return 成功返回一个大于等于0的值,-1表示无权限或后台出现异常 |
| | | */ |
| | | - (NSInteger)eCPM; |
| | | |
| | | /** |
| | | 返回广告的eCPM等级 |
| | | |
| | | @return 成功返回一个包含数字的string,@""或nil表示无权限或后台异常 |
| | | */ |
| | | - (NSString *)eCPMLevel; |
| | | |
| | | @end |
| | | |
| | | NS_ASSUME_NONNULL_END |
| | |
| | | // |
| | | |
| | | #import <Foundation/Foundation.h> |
| | | #import <UIKit/UIKit.h> |
| | | #import "GDTSDKDefines.h" |
| | | #import "GDTLoadAdParams.h" |
| | | |
| | | NS_ASSUME_NONNULL_BEGIN |
| | | |
| | | |
| | | @protocol GDTRewardedVideoAdDelegate; |
| | | |
| | | @interface GDTRewardVideoAd : NSObject |
| | | |
| | | @property (nonatomic, getter=isAdValid, readonly) BOOL adValid; |
| | | @property (nonatomic) BOOL videoMuted; |
| | | @property (nonatomic, assign, readonly) NSInteger expiredTimestamp; |
| | | @property (nonatomic, weak) id <GDTRewardedVideoAdDelegate> delegate; |
| | | @property (nonatomic, readonly) NSString *placementId; |
| | | @property (nonatomic, strong) GDTLoadAdParams *loadAdParams; |
| | | |
| | | /** |
| | | 构造方法 |
| | | |
| | | @param placementId - 广告位 ID |
| | | @return GDTRewardVideoAd 实例 |
| | | */ |
| | | - (instancetype)initWithPlacementId:(NSString *)placementId; |
| | | |
| | | |
| | | /** |
| | | 构造方法 |
| | |
| | | @param placementId - 广告位 ID |
| | | @return GDTRewardVideoAd 实例 |
| | | */ |
| | | - (instancetype)initWithAppId:(NSString *)appId placementId:(NSString *)placementId; |
| | | - (instancetype)initWithAppId:(NSString *)appId placementId:(NSString *)placementId GDT_DEPRECATED_MSG_ATTRIBUTE("接口即将废弃,请使用 initWithPlacementId:"); |
| | | |
| | | /** |
| | | 加载广告方法 支持 iOS8.1 及以上系统 |
| | | */ |
| | |
| | | @return 是否展示成功 |
| | | */ |
| | | - (BOOL)showAdFromRootViewController:(UIViewController *)rootViewController; |
| | | |
| | | |
| | | /** |
| | | 返回广告的eCPM,单位:分 |
| | | |
| | | @return 成功返回一个大于等于0的值,-1表示无权限或后台出现异常 |
| | | */ |
| | | - (NSInteger)eCPM; |
| | | |
| | | /** |
| | | 返回广告的eCPM等级 |
| | | |
| | | @return 成功返回一个包含数字的string,@""或nil表示无权限或后台异常 |
| | | */ |
| | | - (NSString *)eCPMLevel; |
| | | |
| | | |
| | | /** |
| | | 返回广告平台名称 |
| | | |
| | | @return 当使用激励视频聚合功能时,用于区分广告平台 |
| | | */ |
| | | - (NSString *)adNetworkName; |
| | | |
| | | /** |
| | | * 当广告类型为 GDTRewardAdTypeVideo时,返回视频时长,单位 ms,当广告类型为GDTRewardAdTypePage时,返回0 |
| | | */ |
| | | - (CGFloat)videoDuration; |
| | | |
| | | /** |
| | | * 激励广告的类型,需在gdt_rewardVideoAdDidLoad回调后调用 |
| | | */ |
| | | - (GDTRewardAdType)rewardAdType; |
| | | |
| | | @end |
| | | |
| | |
| | | - (void)gdt_rewardVideoAdDidPlayFinish:(GDTRewardVideoAd *)rewardedVideoAd; |
| | | |
| | | @end |
| | | |
| | | NS_ASSUME_NONNULL_END |
New file |
| | |
| | | // |
| | | // GDTRewardVideoAdNetworkAdapterProtocol.h |
| | | // GDTMobApp |
| | | // |
| | | // Created by royqpwang on 2019/6/19. |
| | | // Copyright © 2019 Tencent. All rights reserved. |
| | | // |
| | | |
| | | #import <Foundation/Foundation.h> |
| | | #import "GDTBaseAdNetworkAdapterProtocol.h" |
| | | |
| | | @protocol GDTRewardVideoAdNetworkConnectorProtocol; |
| | | |
| | | NS_ASSUME_NONNULL_BEGIN |
| | | |
| | | @protocol GDTRewardVideoAdNetworkAdapterProtocol <GDTBaseAdNetworkAdapterProtocol> |
| | | |
| | | - (void)loadAd; |
| | | |
| | | - (BOOL)showAdFromRootViewController:(UIViewController *)viewController; |
| | | |
| | | - (BOOL)isAdValid; |
| | | |
| | | - (NSInteger)expiredTimestamp; |
| | | |
| | | @optional |
| | | @property (nonatomic) BOOL videoMuted; |
| | | |
| | | @end |
| | | |
| | | NS_ASSUME_NONNULL_END |
New file |
| | |
| | | // |
| | | // GDTRewardVideoAdNetworkConnectorProtocol.h |
| | | // GDTMobApp |
| | | // |
| | | // Created by royqpwang on 2019/6/19. |
| | | // Copyright © 2019 Tencent. All rights reserved. |
| | | // |
| | | |
| | | #import <Foundation/Foundation.h> |
| | | |
| | | @protocol GDTRewardVideoAdNetworkAdapterProtocol; |
| | | |
| | | |
| | | @protocol GDTRewardVideoAdNetworkConnectorProtocol <NSObject> |
| | | |
| | | - (void)adapter_rewardVideoAdDidLoad:(id<GDTRewardVideoAdNetworkAdapterProtocol>)adapter; |
| | | |
| | | /** |
| | | 视频数据下载成功回调,已经下载过的视频会直接回调 |
| | | |
| | | @param adapter 实例 |
| | | */ |
| | | - (void)adapter_rewardVideoAdVideoDidLoad:(id<GDTRewardVideoAdNetworkAdapterProtocol>)adapter; |
| | | |
| | | /** |
| | | 视频播放页即将展示回调 |
| | | |
| | | @param adapter 实例 |
| | | */ |
| | | - (void)adapter_rewardVideoAdWillVisible:(id<GDTRewardVideoAdNetworkAdapterProtocol>)adapter; |
| | | |
| | | /** |
| | | 视频广告曝光回调 |
| | | |
| | | @param adapter 实例 |
| | | */ |
| | | - (void)adapter_rewardVideoAdDidExposed:(id<GDTRewardVideoAdNetworkAdapterProtocol>)adapter; |
| | | |
| | | /** |
| | | 视频播放页关闭回调 |
| | | |
| | | @param adapter 实例 |
| | | */ |
| | | - (void)adapter_rewardVideoAdDidClose:(id<GDTRewardVideoAdNetworkAdapterProtocol>)adapter; |
| | | |
| | | /** |
| | | 视频广告信息点击回调 |
| | | |
| | | @param adapter 实例 |
| | | */ |
| | | - (void)adapter_rewardVideoAdDidClicked:(id<GDTRewardVideoAdNetworkAdapterProtocol>)adapter; |
| | | |
| | | /** |
| | | 视频广告各种错误信息回调 |
| | | |
| | | @param adapter 实例 |
| | | @param error 具体错误信息 |
| | | */ |
| | | - (void)adapter_rewardVideoAd:(id<GDTRewardVideoAdNetworkAdapterProtocol>)adapter didFailWithError:(NSError *)error; |
| | | |
| | | /** |
| | | 视频广告播放达到激励条件回调 |
| | | |
| | | @param adapter 实例 |
| | | */ |
| | | - (void)adapter_rewardVideoAdDidRewardEffective:(id<GDTRewardVideoAdNetworkAdapterProtocol>)adapter; |
| | | |
| | | |
| | | - (void)adapter_rewardVideoAdDidPlayFinish:(id<GDTRewardVideoAdNetworkAdapterProtocol>)adapter; |
| | | |
| | | @end |
| | |
| | | |
| | | #import <Foundation/Foundation.h> |
| | | #import "GDTSDKDefines.h" |
| | | #import "GDTAdTestSetting.h" |
| | | |
| | | @interface GDTSDKConfig : NSObject |
| | | |
| | | /** |
| | | SDK 注册接口,请在 app 初始化时调用。 |
| | | @param appId - 媒体ID |
| | | |
| | | @return 注册是否成功。 |
| | | */ |
| | | + (BOOL)registerAppId:(NSString *)appId; |
| | | |
| | | /** |
| | | * 提供给聚合平台用来设定SDK 流量分类 |
| | | */ |
| | |
| | | */ |
| | | + (NSString *)sdkSrc; |
| | | |
| | | |
| | | |
| | | /** |
| | | * 获取 SDK 版本 |
| | | */ |
| | | |
| | | + (NSString *)sdkVersion; |
| | | |
| | | |
| | | |
| | | #pragma mark - DEPRECATED |
| | | + (void)enableGPS:(BOOL)enabled; |
| | | |
| | | /** |
| | | * 打开HTTPS开关 |
| | | * 详解:默认提供 HTTPS 资源,此方法废弃,请尽早删除。 |
| | | * |
| | | * 设置流量渠道号 |
| | | 渠道号信息主要用来协助平台提升流量变现效果及您的收益,请如实填写,若渠道号无法满足您的诉求请联系平台负责商务 |
| | | |
| | | 渠道号映射关系为: |
| | | 1:百度 |
| | | 2:头条 |
| | | 3:广点通 |
| | | 4:搜狗 |
| | | 5:其他网盟 |
| | | 6:oppo |
| | | 7:vivo |
| | | 8:华为 |
| | | 9:应用宝 |
| | | 10:小米 |
| | | 11:金立 |
| | | 12:百度手机助手 |
| | | 13:魅族 |
| | | 14:AppStore |
| | | 999:其他 |
| | | */ |
| | | + (void)setChannel:(NSInteger)channel; |
| | | |
| | | + (void)setSDKType:(NSInteger)type; |
| | | |
| | | /** |
| | | 在播放音频时是否使用SDK内部对AVAudioSession设置的category及options,默认使用,若不使用,SDK内部不做任何处理,由调用方在展示广告时自行设置; |
| | | SDK设置的category为AVAudioSessionCategoryAmbient,options为AVAudioSessionCategoryOptionDuckOthers |
| | | */ |
| | | + (void)setHttpsOn GDT_DEPRECATED_MSG_ATTRIBUTE(""); |
| | | + (void)enableDefaultAudioSessionSetting:(BOOL)enabled; |
| | | |
| | | + (GDTAdTestSetting *)debugSetting; |
| | | |
| | | /** |
| | | 设置开发阶段调试相关的配置 |
| | | */ |
| | | + (void)setDebugSetting:(GDTAdTestSetting *)debugSetting; |
| | | |
| | | + (void)forbiddenIDFA:(BOOL)forbiddened; |
| | | |
| | | @end |
| | | |
| | |
| | | #define GDT_DEPRECATED_ATTRIBUTE |
| | | #endif |
| | | |
| | | #define ScreenHeight ([UIScreen mainScreen].bounds.size.height) |
| | | #define ScreenWidth ([UIScreen mainScreen].bounds.size.width) |
| | | #define GDTScreenHeight ([UIScreen mainScreen].bounds.size.height) |
| | | #define GDTScreenWidth ([UIScreen mainScreen].bounds.size.width) |
| | | /** |
| | | * 视频播放器状态 |
| | | * |
| | | * 播放器只可能处于以下状态中的一种 |
| | | * |
| | | */ |
| | | typedef NS_ENUM(NSUInteger, GDTMediaPlayerStatus) { |
| | | GDTMediaPlayerStatusInitial = 0, // 初始状态 |
| | | GDTMediaPlayerStatusLoading = 1, // 加载中 |
| | | GDTMediaPlayerStatusStarted = 2, // 开始播放 |
| | | GDTMediaPlayerStatusPaused = 3, // 用户行为导致暂停 |
| | | GDTMediaPlayerStatusError = 4, // 播放出错 |
| | | GDTMediaPlayerStatusStoped = 5, // 播放停止 |
| | | }; |
| | | |
| | | #ifndef weakify |
| | | #if DEBUG |
| | | #if __has_feature(objc_arc) |
| | | #define weakify(object) autoreleasepool{} __weak __typeof__(object) weak##_##object = object; |
| | | #else |
| | | #define weakify(object) autoreleasepool{} __block __typeof__(object) block##_##object = object; |
| | | #endif |
| | | #else |
| | | #if __has_feature(objc_arc) |
| | | #define weakify(object) try{} @finally{} {} __weak __typeof__(object) weak##_##object = object; |
| | | #else |
| | | #define weakify(object) try{} @finally{} {} __block __typeof__(object) block##_##object = object; |
| | | #endif |
| | | #endif |
| | | #endif |
| | | typedef enum GDTSDKLoginType { |
| | | GDTSDKLoginTypeUnknow = 0, |
| | | GDTSDKLoginTypeWeiXin = 1, //微信账号 |
| | | GDTSDKLoginTypeQQ = 2, //QQ账号 |
| | | } GDTSDKLoginType; |
| | | |
| | | #ifndef strongify |
| | | #if DEBUG |
| | | #if __has_feature(objc_arc) |
| | | #define strongify(object) autoreleasepool{} __typeof__(object) object = weak##_##object; |
| | | #else |
| | | #define strongify(object) autoreleasepool{} __typeof__(object) object = block##_##object; |
| | | #endif |
| | | #else |
| | | #if __has_feature(objc_arc) |
| | | #define strongify(object) try{} @finally{} __typeof__(object) object = weak##_##object; |
| | | #else |
| | | #define strongify(object) try{} @finally{} __typeof__(object) object = block##_##object; |
| | | #endif |
| | | #endif |
| | | #endif |
| | | typedef NS_ENUM(NSUInteger, GDTVideoPlayPolicy) { |
| | | GDTVideoPlayPolicyUnknow = 0, // 默认值,未设置 |
| | | GDTVideoPlayPolicyAuto = 1, // 用户角度看起来是自动播放 |
| | | GDTVideoPlayPolicyManual = 2 // 用户角度看起来是手动播放或点击后播放 |
| | | }; |
| | | |
| | | typedef NS_ENUM(NSUInteger, GDTVideoRenderType) { |
| | | GDTVideoRenderTypeUnknow = 0, |
| | | GDTVideoRenderTypeSDK = 1, |
| | | GDTVideoRenderTypeDeveloper = 2 |
| | | }; |
| | | |
| | | typedef NS_ENUM (NSUInteger, GDTRewardAdType) { |
| | | GDTRewardAdTypeVideo = 0,//激励视频 |
| | | GDTRewardAdTypePage = 1 //激励浏览 |
| | | }; |
| | | |
| | | static inline BOOL isIPhoneXSeries() { |
| | | if (@available(iOS 11.0, *)) { |
| | |
| | | } |
| | | return NO; |
| | | } |
| | | |
| | | |
| | |
| | | - (void)splashAdSuccessPresentScreen:(GDTSplashAd *)splashAd; |
| | | |
| | | /** |
| | | * 开屏广告素材加载成功 |
| | | */ |
| | | - (void)splashAdDidLoad:(GDTSplashAd *)splashAd; |
| | | |
| | | /** |
| | | * 开屏广告展示失败 |
| | | */ |
| | | - (void)splashAdFailToPresent:(GDTSplashAd *)splashAd withError:(NSError *)error; |
| | |
| | | |
| | | /** |
| | | * 拉取广告超时时间,默认为3秒 |
| | | * 详解:拉取广告超时时间,开发者调用loadAd方法以后会立即展示backgroundColor,然后在该超时时间内,如果广告拉 |
| | | * 详解:拉取广告超时时间,开发者调用loadAd方法以后会立即展示backgroundImage,然后在该超时时间内,如果广告拉 |
| | | * 取成功,则立马展示开屏广告,否则放弃此次广告展示机会。 |
| | | */ |
| | | @property (nonatomic, assign) NSInteger fetchDelay; |
| | | @property (nonatomic, assign) CGFloat fetchDelay; |
| | | |
| | | /** |
| | | * 开屏广告的背景图片 |
| | |
| | | @property (nonatomic, assign) CGPoint skipButtonCenter; |
| | | |
| | | /** |
| | | 返回广告平台名称 |
| | | |
| | | @return 当使用流量分配功能时,用于区分广告平台;未使用时为空字符串 |
| | | */ |
| | | - (NSString *)adNetworkName; |
| | | |
| | | /** |
| | | 返回广告的eCPM等级 |
| | | |
| | | @return 成功返回一个包含数字的string,@""或nil表示无权限或后台异常 |
| | | */ |
| | | - (NSString *)eCPMLevel; |
| | | |
| | | /** |
| | | * 构造方法 |
| | | * 详解:placementId - 广告位 ID |
| | | */ |
| | | - (instancetype)initWithPlacementId:(NSString *)placementId; |
| | | |
| | | /** |
| | | 预加载闪屏广告接口 |
| | | |
| | | @param placementId 广告位ID |
| | | */ |
| | | + (void)preloadSplashOrderWithPlacementId:(NSString *)placementId; |
| | | |
| | | #pragma mark - Parallel method |
| | | |
| | | /** |
| | | * 返回广告是否可展示 |
| | | * 对于并行请求,在调用showAdInWindow前时需判断下 |
| | | * @return 当广告已经加载完成且未曝光时,为YES,否则为NO |
| | | */ |
| | | - (BOOL)isAdValid; |
| | | |
| | | /** |
| | | * 发起拉取广告请求,只拉取不展示 |
| | | * 详解:广告素材及广告图片拉取成功后会回调splashAdDidLoad方法,当拉取失败时会回调splashAdFailToPresent方法 |
| | | */ |
| | | - (void)loadAd; |
| | | |
| | | /** |
| | | * 展示广告,调用此方法前需调用isAdValid方法判断广告素材是否有效 |
| | | * 详解:广告展示成功时会回调splashAdSuccessPresentScreen方法,展示失败时会回调splashAdFailToPresent方法 |
| | | */ |
| | | - (void)showAdInWindow:(UIWindow *)window withBottomView:(UIView *)bottomView skipView:(UIView *)skipView; |
| | | |
| | | /** |
| | | * 构造方法 |
| | | * 详解:appId - 媒体 ID |
| | | * placementId - 广告位 ID |
| | | */ |
| | | - (instancetype)initWithAppId:(NSString *)appId placementId:(NSString *)placementId; |
| | | - (instancetype)initWithAppId:(NSString *)appId placementId:(NSString *)placementId GDT_DEPRECATED_MSG_ATTRIBUTE("接口即将废弃,请使用 initWithPlacementId:"); |
| | | |
| | | /** |
| | | * 广告发起请求并展示在Window中 |
| | |
| | | * 提示: Splash广告只支持竖屏 |
| | | * @param window 展示全屏开屏的容器 |
| | | */ |
| | | - (void)loadAdAndShowInWindow:(UIWindow *)window; |
| | | - (void)loadAdAndShowInWindow:(UIWindow *)window GDT_DEPRECATED_MSG_ATTRIBUTE("接口即将废弃,请分别使用loadAd 和 showAdInWindow:接口"); |
| | | |
| | | /** |
| | | * 广告发起请求并展示在Window中, 同时在屏幕底部设置应用自身的Logo页面或是自定义View |
| | |
| | | * @param window 展示开屏的容器 |
| | | * bottomView 自定义底部View,可以在此View中设置应用Logo |
| | | */ |
| | | - (void)loadAdAndShowInWindow:(UIWindow *)window withBottomView:(UIView *)bottomView; |
| | | - (void)loadAdAndShowInWindow:(UIWindow *)window withBottomView:(UIView *)bottomView GDT_DEPRECATED_MSG_ATTRIBUTE("接口即将废弃,请分别使用loadAd 和 showAdInWindow:接口"); |
| | | |
| | | /** |
| | | * 广告发起请求并展示在Window中, 同时在屏幕底部设置应用自身的Logo页面或是自定义View,skipView是自定义的“跳过”样式 |
| | |
| | | * bottomView 自定义底部View,可以在此View中设置应用Logo |
| | | skipView 自定义”跳过“View. |
| | | */ |
| | | - (void)loadAdAndShowInWindow:(UIWindow *)window withBottomView:(UIView *)bottomView skipView:(UIView *)skipView; |
| | | |
| | | #pragma mark - DEPRECATED |
| | | - (instancetype)initWithAppkey:(NSString *)appkey placementId:(NSString *)placementId GDT_DEPRECATED_MSG_ATTRIBUTE("use initWithAppId:placementId: instead."); |
| | | - (void)loadAdAndShowInWindow:(UIWindow *)window withBottomView:(UIView *)bottomView skipView:(UIView *)skipView GDT_DEPRECATED_MSG_ATTRIBUTE("接口即将废弃,请分别使用loadAd 和 showAdInWindow:接口"); |
| | | |
| | | @end |
New file |
| | |
| | | // |
| | | // GDTUnifiedBannerView.h |
| | | // GDTMobSDK |
| | | // |
| | | // Created by nimomeng on 2019/3/1. |
| | | // Copyright © 2019 Tencent. All rights reserved. |
| | | // |
| | | |
| | | #import <UIKit/UIKit.h> |
| | | #import "GDTLoadAdParams.h" |
| | | |
| | | NS_ASSUME_NONNULL_BEGIN |
| | | |
| | | @class GDTUnifiedBannerView; |
| | | |
| | | @protocol GDTUnifiedBannerViewDelegate <NSObject> |
| | | @optional |
| | | /** |
| | | * 请求广告条数据成功后调用 |
| | | * 当接收服务器返回的广告数据成功后调用该函数 |
| | | */ |
| | | - (void)unifiedBannerViewDidLoad:(GDTUnifiedBannerView *)unifiedBannerView; |
| | | |
| | | /** |
| | | * 请求广告条数据失败后调用 |
| | | * 当接收服务器返回的广告数据失败后调用该函数 |
| | | */ |
| | | - (void)unifiedBannerViewFailedToLoad:(GDTUnifiedBannerView *)unifiedBannerView error:(NSError *)error; |
| | | |
| | | /** |
| | | * banner2.0曝光回调 |
| | | */ |
| | | - (void)unifiedBannerViewWillExpose:(GDTUnifiedBannerView *)unifiedBannerView; |
| | | |
| | | /** |
| | | * banner2.0点击回调 |
| | | */ |
| | | - (void)unifiedBannerViewClicked:(GDTUnifiedBannerView *)unifiedBannerView; |
| | | |
| | | /** |
| | | * banner2.0广告点击以后即将弹出全屏广告页 |
| | | */ |
| | | - (void)unifiedBannerViewWillPresentFullScreenModal:(GDTUnifiedBannerView *)unifiedBannerView; |
| | | |
| | | /** |
| | | * banner2.0广告点击以后弹出全屏广告页完毕 |
| | | */ |
| | | - (void)unifiedBannerViewDidPresentFullScreenModal:(GDTUnifiedBannerView *)unifiedBannerView; |
| | | |
| | | /** |
| | | * 全屏广告页即将被关闭 |
| | | */ |
| | | - (void)unifiedBannerViewWillDismissFullScreenModal:(GDTUnifiedBannerView *)unifiedBannerView; |
| | | |
| | | /** |
| | | * 全屏广告页已经被关闭 |
| | | */ |
| | | - (void)unifiedBannerViewDidDismissFullScreenModal:(GDTUnifiedBannerView *)unifiedBannerView; |
| | | |
| | | /** |
| | | * 当点击应用下载或者广告调用系统程序打开 |
| | | */ |
| | | - (void)unifiedBannerViewWillLeaveApplication:(GDTUnifiedBannerView *)unifiedBannerView; |
| | | |
| | | /** |
| | | * banner2.0被用户关闭时调用 |
| | | */ |
| | | - (void)unifiedBannerViewWillClose:(GDTUnifiedBannerView *)unifiedBannerView; |
| | | |
| | | @end |
| | | |
| | | @interface GDTUnifiedBannerView : UIView |
| | | /** |
| | | * 委托 [可选] |
| | | */ |
| | | @property (nonatomic, weak) id<GDTUnifiedBannerViewDelegate> delegate; |
| | | |
| | | /** |
| | | * Banner展现和轮播时的动画效果开关,默认打开 |
| | | */ |
| | | @property (nonatomic) BOOL animated; |
| | | |
| | | /** |
| | | * 广告刷新间隔,范围 [30, 120] 秒,默认值 30 秒。设 0 则不刷新。 [可选] |
| | | */ |
| | | @property (nonatomic) int autoSwitchInterval; |
| | | |
| | | /** |
| | | * QQ小游戏SDK字段透传 |
| | | */ |
| | | @property (nonatomic, strong) GDTLoadAdParams *loadAdParams; |
| | | |
| | | /** |
| | | * 构造方法 |
| | | * 详解:placementId - 广告位 ID |
| | | * viewController - 视图控制器 |
| | | */ |
| | | - (instancetype)initWithPlacementId:(NSString *)placementId |
| | | viewController:(UIViewController *)viewController; |
| | | |
| | | /** |
| | | * 构造方法 |
| | | * 详解:frame - banner 展示的位置和大小 |
| | | * placementId - 广告位 ID |
| | | * viewController - 视图控制器 |
| | | */ |
| | | - (instancetype)initWithFrame:(CGRect)frame |
| | | placementId:(NSString *)placementId |
| | | viewController:(UIViewController *)viewController; |
| | | |
| | | /** |
| | | * 拉取并展示广告 |
| | | */ |
| | | - (void)loadAdAndShow; |
| | | |
| | | @end |
| | | |
| | | NS_ASSUME_NONNULL_END |
New file |
| | |
| | | // |
| | | // GDTUnifiedInterstitialAd.h |
| | | // GDTMobApp |
| | | // |
| | | // Created by nimomeng on 2019/3/4. |
| | | // Copyright © 2019 Tencent. All rights reserved. |
| | | // |
| | | |
| | | #import <Foundation/Foundation.h> |
| | | #import "GDTSDKDefines.h" |
| | | |
| | | NS_ASSUME_NONNULL_BEGIN |
| | | |
| | | @class GDTUnifiedInterstitialAd; |
| | | |
| | | @protocol GDTUnifiedInterstitialAdDelegate <NSObject> |
| | | @optional |
| | | |
| | | /** |
| | | * 插屏2.0广告预加载成功回调 |
| | | * 当接收服务器返回的广告数据成功且预加载后调用该函数 |
| | | */ |
| | | - (void)unifiedInterstitialSuccessToLoadAd:(GDTUnifiedInterstitialAd *)unifiedInterstitial; |
| | | |
| | | /** |
| | | * 插屏2.0广告预加载失败回调 |
| | | * 当接收服务器返回的广告数据失败后调用该函数 |
| | | */ |
| | | - (void)unifiedInterstitialFailToLoadAd:(GDTUnifiedInterstitialAd *)unifiedInterstitial error:(NSError *)error; |
| | | |
| | | /** |
| | | * 插屏2.0广告将要展示回调 |
| | | * 插屏2.0广告即将展示回调该函数 |
| | | */ |
| | | - (void)unifiedInterstitialWillPresentScreen:(GDTUnifiedInterstitialAd *)unifiedInterstitial; |
| | | |
| | | /** |
| | | * 插屏2.0广告视图展示成功回调 |
| | | * 插屏2.0广告展示成功回调该函数 |
| | | */ |
| | | - (void)unifiedInterstitialDidPresentScreen:(GDTUnifiedInterstitialAd *)unifiedInterstitial; |
| | | |
| | | /** |
| | | * 插屏2.0广告视图展示失败回调 |
| | | * 插屏2.0广告展示失败回调该函数 |
| | | */ |
| | | - (void)unifiedInterstitialFailToPresent:(GDTUnifiedInterstitialAd *)unifiedInterstitial error:(NSError *)error; |
| | | |
| | | /** |
| | | * 插屏2.0广告展示结束回调 |
| | | * 插屏2.0广告展示结束回调该函数 |
| | | */ |
| | | - (void)unifiedInterstitialDidDismissScreen:(GDTUnifiedInterstitialAd *)unifiedInterstitial; |
| | | |
| | | /** |
| | | * 当点击下载应用时会调用系统程序打开其它App或者Appstore时回调 |
| | | */ |
| | | - (void)unifiedInterstitialWillLeaveApplication:(GDTUnifiedInterstitialAd *)unifiedInterstitial; |
| | | |
| | | /** |
| | | * 插屏2.0广告曝光回调 |
| | | */ |
| | | - (void)unifiedInterstitialWillExposure:(GDTUnifiedInterstitialAd *)unifiedInterstitial; |
| | | |
| | | /** |
| | | * 插屏2.0广告点击回调 |
| | | */ |
| | | - (void)unifiedInterstitialClicked:(GDTUnifiedInterstitialAd *)unifiedInterstitial; |
| | | |
| | | /** |
| | | * 点击插屏2.0广告以后即将弹出全屏广告页 |
| | | */ |
| | | - (void)unifiedInterstitialAdWillPresentFullScreenModal:(GDTUnifiedInterstitialAd *)unifiedInterstitial; |
| | | |
| | | /** |
| | | * 点击插屏2.0广告以后弹出全屏广告页 |
| | | */ |
| | | - (void)unifiedInterstitialAdDidPresentFullScreenModal:(GDTUnifiedInterstitialAd *)unifiedInterstitial; |
| | | |
| | | /** |
| | | * 全屏广告页将要关闭 |
| | | */ |
| | | - (void)unifiedInterstitialAdWillDismissFullScreenModal:(GDTUnifiedInterstitialAd *)unifiedInterstitial; |
| | | |
| | | /** |
| | | * 全屏广告页被关闭 |
| | | */ |
| | | - (void)unifiedInterstitialAdDidDismissFullScreenModal:(GDTUnifiedInterstitialAd *)unifiedInterstitial; |
| | | |
| | | /** |
| | | * 插屏2.0视频广告 player 播放状态更新回调 |
| | | */ |
| | | - (void)unifiedInterstitialAd:(GDTUnifiedInterstitialAd *)unifiedInterstitial playerStatusChanged:(GDTMediaPlayerStatus)status; |
| | | |
| | | /** |
| | | * 插屏2.0视频广告详情页 WillPresent 回调 |
| | | */ |
| | | - (void)unifiedInterstitialAdViewWillPresentVideoVC:(GDTUnifiedInterstitialAd *)unifiedInterstitial; |
| | | |
| | | /** |
| | | * 插屏2.0视频广告详情页 DidPresent 回调 |
| | | */ |
| | | - (void)unifiedInterstitialAdViewDidPresentVideoVC:(GDTUnifiedInterstitialAd *)unifiedInterstitial; |
| | | |
| | | /** |
| | | * 插屏2.0视频广告详情页 WillDismiss 回调 |
| | | */ |
| | | - (void)unifiedInterstitialAdViewWillDismissVideoVC:(GDTUnifiedInterstitialAd *)unifiedInterstitial; |
| | | |
| | | /** |
| | | * 插屏2.0视频广告详情页 DidDismiss 回调 |
| | | */ |
| | | - (void)unifiedInterstitialAdViewDidDismissVideoVC:(GDTUnifiedInterstitialAd *)unifiedInterstitial; |
| | | |
| | | @end |
| | | |
| | | @interface GDTUnifiedInterstitialAd : NSObject |
| | | |
| | | /** |
| | | * 插屏2.0广告预加载是否完成 |
| | | */ |
| | | @property (nonatomic, readonly) BOOL isAdValid; |
| | | |
| | | /** |
| | | * 委托对象 |
| | | */ |
| | | @property (nonatomic, weak) id<GDTUnifiedInterstitialAdDelegate> delegate; |
| | | |
| | | @property (nonatomic, readonly) NSString *placementId; |
| | | |
| | | /** |
| | | * 构造方法 |
| | | * 详解:placementId - 广告位 ID |
| | | */ |
| | | - (instancetype)initWithPlacementId:(NSString *)placementId; |
| | | |
| | | /** |
| | | * 构造方法 |
| | | * 详解:appId - 媒体 ID |
| | | * placementId - 广告位 ID |
| | | */ |
| | | - (instancetype)initWithAppId:(NSString *)appId placementId:(NSString *)placementId GDT_DEPRECATED_MSG_ATTRIBUTE("接口即将废弃,请使用 initWithPlacementId:"); |
| | | |
| | | /** |
| | | * 广告发起请求方法 |
| | | * 详解:[必选]发起拉取广告请求 |
| | | */ |
| | | - (void)loadAd; |
| | | |
| | | /** |
| | | * 插屏全屏视频广告发起请求方法 |
| | | * 详解:[必选]发起拉取广告请求 |
| | | */ |
| | | - (void)loadFullScreenAd; |
| | | |
| | | |
| | | /** |
| | | * 广告展示方法 |
| | | * 详解:[必选]发起展示广告请求, 必须传入用于显示插播广告的UIViewController |
| | | */ |
| | | |
| | | - (void)presentAdFromRootViewController:(UIViewController *)rootViewController; |
| | | |
| | | /** |
| | | * 插屏视频全屏广告展示方法 |
| | | * 详解:[必选]发起展示广告请求, 必须传入用于显示插播广告的UIViewController |
| | | */ |
| | | - (void)presentFullScreenAdFromRootViewController:(UIViewController *)rootViewController; |
| | | |
| | | /** |
| | | 返回广告的eCPM,单位:分 |
| | | |
| | | @return 成功返回一个大于等于0的值,-1表示无权限或后台出现异常 |
| | | */ |
| | | - (NSInteger)eCPM; |
| | | |
| | | /** |
| | | 返回广告的eCPM等级 |
| | | |
| | | @return 成功返回一个包含数字的string,@""或nil表示无权限或后台异常 |
| | | */ |
| | | - (NSString *)eCPMLevel; |
| | | |
| | | /** |
| | | * 非 WiFi 网络,是否自动播放。默认 NO。loadAd 前设置。 |
| | | */ |
| | | |
| | | @property (nonatomic, assign) BOOL videoAutoPlayOnWWAN; |
| | | |
| | | /** |
| | | * 自动播放时,是否静音。默认 YES。loadAd 前设置。 |
| | | */ |
| | | @property (nonatomic, assign) BOOL videoMuted; |
| | | |
| | | |
| | | /** |
| | | * 视频详情页播放时是否静音。默认NO。loadAd 前设置。 |
| | | */ |
| | | @property (nonatomic, assign) BOOL detailPageVideoMuted; |
| | | |
| | | /** |
| | | 请求视频的时长下限,视频时长有效值范围为[5,60]。 |
| | | 以下两种情况会使用系统默认的最小值设置,1:不设置 2:minVideoDuration大于maxVideoDuration |
| | | */ |
| | | @property (nonatomic) NSInteger minVideoDuration; |
| | | |
| | | /** |
| | | 请求视频的时长上限,视频时长有效值范围为[5,60]。 |
| | | */ |
| | | @property (nonatomic) NSInteger maxVideoDuration; |
| | | |
| | | /** |
| | | * 是否是视频插屏2.0广告 |
| | | */ |
| | | @property (nonatomic, assign, readonly) BOOL isVideoAd; |
| | | |
| | | /** |
| | | * 视频插屏2.0广告时长,单位 ms |
| | | */ |
| | | - (CGFloat)videoDuration; |
| | | |
| | | /** |
| | | * 视频插屏广告已播放时长,单位 ms |
| | | */ |
| | | - (CGFloat)videoPlayTime; |
| | | |
| | | /** |
| | | 返回广告平台名称 |
| | | |
| | | @return 当使用流量分配功能时,用于区分广告平台;未使用时为空字符串 |
| | | */ |
| | | - (NSString *)adNetworkName; |
| | | |
| | | @end |
| | | |
| | | NS_ASSUME_NONNULL_END |
New file |
| | |
| | | // |
| | | // GDTUnifiedNativeAd.h |
| | | // GDTMobSDK |
| | | // |
| | | // Created by nimomeng on 2018/10/10. |
| | | // Copyright © 2018 Tencent. All rights reserved. |
| | | // |
| | | |
| | | #import <Foundation/Foundation.h> |
| | | #import "GDTUnifiedNativeAdDataObject.h" |
| | | #import "GDTUnifiedNativeAdView.h" |
| | | NS_ASSUME_NONNULL_BEGIN |
| | | |
| | | @protocol GDTUnifiedNativeAdDelegate <NSObject> |
| | | |
| | | /** |
| | | 广告数据回调 |
| | | |
| | | @param unifiedNativeAdDataObjects 广告数据数组 |
| | | @param error 错误信息 |
| | | */ |
| | | - (void)gdt_unifiedNativeAdLoaded:(NSArray<GDTUnifiedNativeAdDataObject *> * _Nullable)unifiedNativeAdDataObjects error:(NSError * _Nullable)error; |
| | | @end |
| | | |
| | | @interface GDTUnifiedNativeAd : NSObject |
| | | @property (nonatomic, weak) id<GDTUnifiedNativeAdDelegate> delegate; |
| | | |
| | | /** |
| | | 请求视频的时长下限,视频时长有效值范围为[5,60]。 |
| | | 以下两种情况会使用系统默认的最小值设置,1:不设置 2:minVideoDuration大于maxVideoDuration |
| | | */ |
| | | @property (nonatomic) NSInteger minVideoDuration; |
| | | |
| | | /** |
| | | 请求视频的最大时长,视频时长有效值范围为[5,60]。 |
| | | */ |
| | | @property (nonatomic) NSInteger maxVideoDuration; |
| | | |
| | | /** |
| | | 可选属性,设置本次拉取的视频广告从用户角度看到的视频播放策略。 |
| | | |
| | | “用户角度”特指用户看到的情况,并非SDK是否自动播放,与自动播放策略 GDTVideoAutoPlayPolicy 的取值并非一一对应 |
| | | |
| | | 例如开发者设置了 GDTVideoAutoPlayPolicyNever 表示 SDK 不自动播放视频,但是开发者通过 GDTMediaView 的 play 方法播放视频,这在用户看来仍然是自动播放的。 |
| | | |
| | | 准确的设置 GDTVideoPlayPolicy 有助于提高视频广告的eCPM值,如果广告位仅支持图文广告,则无需调用。 |
| | | |
| | | 需要在 loadAd 前设置此属性。 |
| | | */ |
| | | @property (nonatomic, assign) GDTVideoPlayPolicy videoPlayPolicy; |
| | | |
| | | /** |
| | | 可选属性,设置本次拉取的视频广告封面是由SDK渲染还是开发者自行渲染。 |
| | | |
| | | SDK 渲染,指视频广告 containerView 直接在 feed 流等场景展示,用户可以直接看到渲染的视频广告。Demo 工程中的 “视频Feed” 就是 SDK 渲染。 |
| | | |
| | | 开发者自行渲染,指开发者获取到广告对象后,先用封面图字段在 feed 流中先渲染出一个封面图入口,用户点击封面图,再进入一个有 conainterView 的详细页,播放视频。Demo 工程中的 "竖版 Feed 视频" 就是开发者渲染的场景。 |
| | | */ |
| | | @property (nonatomic, assign) GDTVideoRenderType videoRenderType; |
| | | |
| | | /** |
| | | 构造方法 |
| | | |
| | | @param placementId 广告位ID |
| | | @return GDTUnifiedNativeAd 实例 |
| | | */ |
| | | - (instancetype)initWithPlacementId:(NSString *)placementId; |
| | | |
| | | /** |
| | | 构造方法 |
| | | |
| | | @param appId 媒体ID |
| | | @param placementId 广告位ID |
| | | @return GDTUnifiedNativeAd 实例 |
| | | */ |
| | | - (instancetype)initWithAppId:(NSString *)appId placementId:(NSString *)placementId GDT_DEPRECATED_MSG_ATTRIBUTE("接口即将废弃,请使用 initWithPlacementId:"); |
| | | |
| | | /** |
| | | 加载广告 |
| | | */ |
| | | - (void)loadAd; |
| | | |
| | | /** |
| | | 加载广告 |
| | | |
| | | @param adCount 加载条数 |
| | | */ |
| | | - (void)loadAdWithAdCount:(NSInteger)adCount; |
| | | |
| | | /** |
| | | 返回广告平台名称 |
| | | |
| | | @return 当使用流量分配功能时,用于区分广告平台;未使用时为空字符串 |
| | | */ |
| | | - (NSString *)adNetworkName; |
| | | |
| | | /** |
| | | * 当需要支持 VAST 广告时,需流量自行配置 adapter 的 vastClassName |
| | | */ |
| | | - (void)setVastClassName:(NSString *)vastClassName; |
| | | |
| | | @end |
| | | NS_ASSUME_NONNULL_END |
New file |
| | |
| | | // |
| | | // GDTUnifiedNativeAdDataObject.h |
| | | // GDTMobSDK |
| | | // |
| | | // Created by nimomeng on 2018/10/10. |
| | | // Copyright © 2018 Tencent. All rights reserved. |
| | | // |
| | | |
| | | #import <Foundation/Foundation.h> |
| | | #import <UIKit/UIKit.h> |
| | | #import "GDTVideoConfig.h" |
| | | |
| | | typedef NS_ENUM(NSInteger, GDTVastAdEventType) { |
| | | GDTVastAdEventTypeUnknow, |
| | | GDTVastAdEventTypeLoaded, |
| | | GDTVastAdEventTypeStarted, |
| | | GDTVastAdEventTypeFirstQuartile, |
| | | GDTVastAdEventTypeMidPoint, |
| | | GDTVastAdEventTypeThirdQuartile, |
| | | GDTVastAdEventTypeComplete, |
| | | GDTVastAdEventTypeAllAdsComplete, |
| | | GDTVastAdEventTypeExposed, |
| | | GDTVastAdEventTypeClicked, |
| | | }; |
| | | |
| | | |
| | | @interface GDTUnifiedNativeAdDataObject : NSObject |
| | | |
| | | /** |
| | | 广告标题 |
| | | */ |
| | | @property (nonatomic, copy, readonly) NSString *title; |
| | | |
| | | /** |
| | | 广告描述 |
| | | */ |
| | | @property (nonatomic, copy, readonly) NSString *desc; |
| | | |
| | | /** |
| | | 广告大图Url |
| | | */ |
| | | @property (nonatomic, copy, readonly) NSString *imageUrl; |
| | | |
| | | /** |
| | | 素材宽度,单图广告代表大图 imageUrl 宽度、多图广告代表小图 mediaUrlList 宽度 |
| | | */ |
| | | @property (nonatomic, readonly) NSInteger imageWidth; |
| | | |
| | | /** |
| | | 素材高度,单图广告代表大图 imageUrl 高度、多图广告代表小图 mediaUrlList 高度 |
| | | */ |
| | | @property (nonatomic, readonly) NSInteger imageHeight; |
| | | |
| | | /** |
| | | 应用类广告App 图标Url |
| | | */ |
| | | @property (nonatomic, copy, readonly) NSString *iconUrl; |
| | | |
| | | /** |
| | | 三小图广告的图片Url集合 |
| | | */ |
| | | @property (nonatomic, copy, readonly) NSArray *mediaUrlList; |
| | | |
| | | /** |
| | | 应用类广告的星级(5星制度) |
| | | */ |
| | | @property (nonatomic, readonly) CGFloat appRating; |
| | | |
| | | /** |
| | | 应用类广告的价格 |
| | | */ |
| | | @property (nonatomic, strong, readonly) NSNumber *appPrice; |
| | | |
| | | /** |
| | | 是否为应用类广告 |
| | | */ |
| | | @property (nonatomic, readonly) BOOL isAppAd; |
| | | |
| | | /** |
| | | 是否为视频广告 |
| | | */ |
| | | @property (nonatomic, readonly) BOOL isVideoAd; |
| | | |
| | | /** |
| | | 是否为三小图广告 |
| | | */ |
| | | @property (nonatomic, readonly) BOOL isThreeImgsAd; |
| | | |
| | | /** |
| | | 返回广告的eCPM,单位:分 |
| | | |
| | | @return 成功返回一个大于等于0的值,-1表示无权限或后台出现异常 |
| | | */ |
| | | @property (nonatomic, readonly) NSInteger eCPM; |
| | | |
| | | /** |
| | | 返回广告的eCPM等级 |
| | | |
| | | @return 成功返回一个包含数字的string,@""或nil表示无权限或后台异常 |
| | | */ |
| | | @property (nonatomic, readonly) NSString *eCPMLevel; |
| | | |
| | | /** |
| | | 广告对应的CTA文案,自定义CTA视图时建议使用此字段 |
| | | 广告对应的callToAction文案,比如“立即预约”或“电话咨询”, 自定义callToAction视图时建议使用此字段 |
| | | |
| | | 该字段在部分广告类型中可能为空 |
| | | */ |
| | | @property (nonatomic, readonly) NSString *callToAction; |
| | | |
| | | /** |
| | | 返回广告是否可以跳过,用于做前贴片场景 |
| | | |
| | | @return YES 表示可跳过、NO 表示不可跳过 |
| | | */ |
| | | @property (nonatomic, readonly) BOOL skippable; |
| | | |
| | | /** |
| | | 视频广告播放配置 |
| | | */ |
| | | @property (nonatomic, strong) GDTVideoConfig *videoConfig; |
| | | |
| | | /** |
| | | * 视频广告时长,单位 ms |
| | | */ |
| | | @property (nonatomic, readonly) CGFloat duration; |
| | | |
| | | /** |
| | | * VAST Tag Url,可能为空。 |
| | | */ |
| | | @property (nonatomic, copy, readonly) NSString *vastTagUrl; |
| | | |
| | | /** |
| | | * VAST Content,可能为空。 |
| | | */ |
| | | @property (nonatomic, copy, readonly) NSString *vastContent; |
| | | |
| | | /** |
| | | * 是否为 VAST 广告 |
| | | */ |
| | | @property (nonatomic, assign, readonly) BOOL isVastAd; |
| | | |
| | | /** |
| | | 判断两个自渲染2.0广告数据是否相等 |
| | | |
| | | @param dataObject 需要对比的自渲染2.0广告数据对象 |
| | | @return YES or NO |
| | | */ |
| | | - (BOOL)equalsAdData:(GDTUnifiedNativeAdDataObject *)dataObject; |
| | | |
| | | @end |
New file |
| | |
| | | // |
| | | // GDTUnifiedNativeAdView.h |
| | | // GDTMobSDK |
| | | // |
| | | // Created by nimomeng on 2018/10/10. |
| | | // Copyright © 2018 Tencent. All rights reserved. |
| | | // |
| | | |
| | | #import <UIKit/UIKit.h> |
| | | #import "GDTLogoView.h" |
| | | #import "GDTMediaView.h" |
| | | #import "GDTUnifiedNativeAdDataObject.h" |
| | | #import "GDTSDKDefines.h" |
| | | |
| | | @class GDTUnifiedNativeAdView; |
| | | |
| | | //视频广告时长Key |
| | | extern NSString* const kGDTUnifiedNativeAdKeyVideoDuration; |
| | | |
| | | @protocol GDTUnifiedNativeAdViewDelegate <NSObject> |
| | | |
| | | @optional |
| | | /** |
| | | 广告曝光回调 |
| | | |
| | | @param unifiedNativeAdView GDTUnifiedNativeAdView 实例 |
| | | */ |
| | | - (void)gdt_unifiedNativeAdViewWillExpose:(GDTUnifiedNativeAdView *)unifiedNativeAdView; |
| | | |
| | | |
| | | /** |
| | | 广告点击回调 |
| | | |
| | | @param unifiedNativeAdView GDTUnifiedNativeAdView 实例 |
| | | */ |
| | | - (void)gdt_unifiedNativeAdViewDidClick:(GDTUnifiedNativeAdView *)unifiedNativeAdView; |
| | | |
| | | |
| | | /** |
| | | 广告详情页关闭回调 |
| | | |
| | | @param unifiedNativeAdView GDTUnifiedNativeAdView 实例 |
| | | */ |
| | | - (void)gdt_unifiedNativeAdDetailViewClosed:(GDTUnifiedNativeAdView *)unifiedNativeAdView; |
| | | |
| | | |
| | | /** |
| | | 当点击应用下载或者广告调用系统程序打开时调用 |
| | | |
| | | @param unifiedNativeAdView GDTUnifiedNativeAdView 实例 |
| | | */ |
| | | - (void)gdt_unifiedNativeAdViewApplicationWillEnterBackground:(GDTUnifiedNativeAdView *)unifiedNativeAdView; |
| | | |
| | | |
| | | /** |
| | | 广告详情页面即将展示回调 |
| | | |
| | | @param unifiedNativeAdView GDTUnifiedNativeAdView 实例 |
| | | */ |
| | | - (void)gdt_unifiedNativeAdDetailViewWillPresentScreen:(GDTUnifiedNativeAdView *)unifiedNativeAdView; |
| | | |
| | | |
| | | /** |
| | | 视频广告播放状态更改回调 |
| | | |
| | | @param nativeExpressAdView GDTUnifiedNativeAdView 实例 |
| | | @param status 视频广告播放状态 |
| | | @param userInfo 视频广告信息 |
| | | */ |
| | | - (void)gdt_unifiedNativeAdView:(GDTUnifiedNativeAdView *)unifiedNativeAdView playerStatusChanged:(GDTMediaPlayerStatus)status userInfo:(NSDictionary *)userInfo; |
| | | @end |
| | | |
| | | @interface GDTUnifiedNativeAdView:UIView |
| | | |
| | | /** |
| | | 绑定的数据对象 |
| | | */ |
| | | @property (nonatomic, strong, readonly) GDTUnifiedNativeAdDataObject *dataObject; |
| | | |
| | | /** |
| | | 视频广告的媒体View,绑定数据对象后自动生成,可自定义布局 |
| | | */ |
| | | @property (nonatomic, strong, readonly) GDTMediaView *mediaView; |
| | | |
| | | /** |
| | | 腾讯广告 LogoView,自动生成,可自定义布局 |
| | | */ |
| | | @property (nonatomic, strong, readonly) GDTLogoView *logoView; |
| | | |
| | | /** |
| | | 广告 View 时间回调对象 |
| | | */ |
| | | @property (nonatomic, weak) id<GDTUnifiedNativeAdViewDelegate> delegate; |
| | | |
| | | /* |
| | | * viewControllerForPresentingModalView |
| | | * 详解:开发者需传入用来弹出目标页的ViewController,一般为当前ViewController |
| | | */ |
| | | @property (nonatomic, weak) UIViewController *viewController; |
| | | |
| | | /** |
| | | 自渲染2.0视图注册方法 |
| | | |
| | | @param dataObject 数据对象,必传字段 |
| | | @param clickableViews 可点击的视图数组,此数组内的广告元素才可以响应广告对应的点击事件 |
| | | */ |
| | | - (void)registerDataObject:(GDTUnifiedNativeAdDataObject *)dataObject |
| | | clickableViews:(NSArray<UIView *> *)clickableViews; |
| | | |
| | | |
| | | /** |
| | | 自渲染2.0视图注册方法 |
| | | @param dataObject 数据对象,必传字段 |
| | | @param clickableViews 可点击的视图数组,此数组内的广告元素才可以响应广告对应的点击事件 |
| | | @param customClickableViews 可点击的视图数组,与clickableViews的区别是:在视频广告中当dataObject中的videoConfig的detailPageEnable为YES时,点击后直接进落地页而非视频详情页,除此条件外点击行为与clickableViews保持一致 |
| | | */ |
| | | - (void)registerDataObject:(GDTUnifiedNativeAdDataObject *)dataObject |
| | | clickableViews:(NSArray<UIView *> *)clickableViews customClickableViews:(NSArray <UIView *> *)customClickableViews; |
| | | |
| | | /** |
| | | 注册可点击的callToAction视图的方法 |
| | | 建议开发者使用GDTUnifiedNativeAdDataObject中的callToAction字段来创建视图,并取代自定义的下载或打开等button, |
| | | 调用此方法之前必须先调用registerDataObject:clickableViews |
| | | @param callToActionView CTA视图, 系统自动处理点击事件 |
| | | */ |
| | | - (void)registerClickableCallToActionView:(UIView *)callToActionView; |
| | | |
| | | /** |
| | | 注销数据对象,在 tableView、collectionView 等场景需要复用 GDTUnifiedNativeAdView 时, |
| | | 需要在合适的时机,例如 cell 的 prepareForReuse 方法内执行 unregisterDataObject 方法, |
| | | 将广告对象与 GDTUnifiedNativeAdView 解绑,具体可参考示例 demo 的 UnifiedNativeAdBaseTableViewCell 类 |
| | | */ |
| | | - (void)unregisterDataObject; |
| | | |
| | | //#pragma mark - DEPRECATED |
| | | ///** |
| | | // 此方法已经废弃 |
| | | // 自渲染2.0视图注册方法 |
| | | // |
| | | // @param dataObject 数据对象,必传字段 |
| | | // @param logoView logo视图 |
| | | // @param viewController 所在ViewController,必传字段。支持在register之后对其进行修改 |
| | | // @param clickableViews 可点击的视图数组,此数组内的广告元素才可以响应广告对应的点击事件 |
| | | // */ |
| | | //- (void)registerDataObject:(GDTUnifiedNativeAdDataObject *)dataObject |
| | | // logoView:(GDTLogoView *)logoView |
| | | // viewController:(UIViewController *)viewController |
| | | // clickableViews:(NSArray<UIView *> *)clickableViews GDT_DEPRECATED_MSG_ATTRIBUTE("use registerDataObject:clickableViews: instead."); |
| | | // |
| | | // |
| | | ///** |
| | | // 此方法已经废弃 |
| | | // 自渲染2.0视图注册方法 |
| | | // |
| | | // @param dataObject 数据对象,必传字段 |
| | | // @param mediaView 媒体对象视图,此处放视频播放器的容器视图 |
| | | // @param logoView logo视图 |
| | | // @param viewController 所在ViewController,必传字段。支持在register之后对其进行修改 |
| | | // @param clickableViews 可点击的视图数组,此数组内的广告元素才可以响应广告对应的点击事件 |
| | | // */ |
| | | //- (void)registerDataObject:(GDTUnifiedNativeAdDataObject *)dataObject |
| | | // mediaView:(GDTMediaView *)mediaView |
| | | // logoView:(GDTLogoView *)logoView |
| | | // viewController:(UIViewController *)viewController |
| | | // clickableViews:(NSArray<UIView *> *)clickableViews GDT_DEPRECATED_MSG_ATTRIBUTE("use registerDataObject:clickableViews: instead."); |
| | | @end |
| | | |
| | | |
| | | |
New file |
| | |
| | | // |
| | | // GDTVideoConfig.h |
| | | // GDTMobApp |
| | | // |
| | | // Created by royqpwang on 2019/5/16. |
| | | // Copyright © 2019 Tencent. All rights reserved. |
| | | // |
| | | |
| | | #import <Foundation/Foundation.h> |
| | | |
| | | typedef NS_ENUM(NSInteger, GDTVideoAutoPlayPolicy) { |
| | | GDTVideoAutoPlayPolicyWIFI = 0, // WIFI 下自动播放 |
| | | GDTVideoAutoPlayPolicyAlways = 1, // 总是自动播放,无论网络条件 |
| | | GDTVideoAutoPlayPolicyNever = 2, // 从不自动播放,无论网络条件 |
| | | }; |
| | | |
| | | NS_ASSUME_NONNULL_BEGIN |
| | | |
| | | @interface GDTVideoConfig : NSObject |
| | | |
| | | /** |
| | | 视频自动播放策略,默认 GDTVideoAutoPlayPolicyAlways, |
| | | 选择 GDTVideoAutoPlayPolicyNever 策略时,需要开发者调用 GDTMediaView 的 play\pause 方法触发视频播、暂停, |
| | | 或者开启 userControlEnable 设置,让用户点击 MediaView 控制播放状态 |
| | | */ |
| | | @property (nonatomic, assign) GDTVideoAutoPlayPolicy autoPlayPolicy; |
| | | |
| | | /** |
| | | 是否静音播放视频广告,视频初始状态是否静音,默认 YES, |
| | | 可通过 GDTMediaView muteEnable: 方法实时控制播放器j静音状态, |
| | | */ |
| | | @property (nonatomic, assign) BOOL videoMuted; |
| | | |
| | | /** |
| | | 视频详情页播放时是否静音,默认NO, |
| | | */ |
| | | @property (nonatomic, assign) BOOL detailPageVideoMuted; |
| | | |
| | | /** |
| | | 是否启动自动续播功能,当在 tableView 等场景播放器被销毁时,广告展示时继续从上次播放位置续播,默认 NO |
| | | */ |
| | | @property (nonatomic, assign) BOOL autoResumeEnable; |
| | | |
| | | /** |
| | | 广告发生点击行为时,是否展示视频详情页 |
| | | 设为 NO 时,用户点击 clickableViews 会直接打开 App Store 或者广告落地页 |
| | | */ |
| | | @property (nonatomic, assign) BOOL detailPageEnable; |
| | | |
| | | /** |
| | | 是否支持用户点击 MediaView 改变视频播放暂停状态,默认 NO |
| | | 设为 YES 时,用户点击会切换播放器播放、暂停状态 |
| | | */ |
| | | @property (nonatomic, assign) BOOL userControlEnable; |
| | | |
| | | /** |
| | | 是否展示播放进度条,默认 YES |
| | | */ |
| | | @property (nonatomic, assign) BOOL progressViewEnable; |
| | | |
| | | /** |
| | | 是否展示播放器封面图,默认 YES |
| | | */ |
| | | @property (nonatomic, assign) BOOL coverImageEnable; |
| | | |
| | | @end |
| | | |
| | | NS_ASSUME_NONNULL_END |
| | |
| | | |
| | | - (void)viewWillAppear:(BOOL)animated{ |
| | | [super viewWillAppear:animated]; |
| | | [MobClick beginLogPageView:@"帮助与反馈"]; |
| | | //[MobClick beginLogPageView:@"帮助与反馈"]; |
| | | } |
| | | - (void)viewWillDisappear:(BOOL)animated{ |
| | | [super viewWillDisappear:animated]; |
| | | [MobClick endLogPageView:@"帮助与反馈"]; |
| | | //[MobClick endLogPageView:@"帮助与反馈"]; |
| | | } |
| | | |
| | | -(void)initScene{ |
| | |
| | | |
| | | - (void)viewDidLoad { |
| | | [super viewDidLoad]; |
| | | [MobClick beginLogPageView:@"进入单个明星"]; |
| | | //[MobClick beginLogPageView:@"进入单个明星"]; |
| | | //初始化界面 |
| | | [self initScene]; |
| | | } |
| | | |
| | | -(void)dealloc{ |
| | | [MobClick beginLogPageView:@"退出单个明星"]; |
| | | //[MobClick beginLogPageView:@"退出单个明星"]; |
| | | } |
| | | |
| | | -(void)initScene{ |
| | |
| | | -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{ |
| | | NSDictionary * dic = movelist[indexPath.row]; |
| | | XYRDetailViewController *play=[[XYRDetailViewController alloc]init]; |
| | | play.modalPresentationStyle = 0; |
| | | play.Model = [XYRVideoInfoModel yy_modelWithDictionary:dic]; |
| | | [self presentViewController:play animated:YES completion:^{ |
| | | |
| | |
| | | <key>CFBundlePackageType</key> |
| | | <string>APPL</string> |
| | | <key>CFBundleShortVersionString</key> |
| | | <string>3.0.9</string> |
| | | <string>$(MARKETING_VERSION)</string> |
| | | <key>CFBundleSignature</key> |
| | | <string>????</string> |
| | | <key>CFBundleURLTypes</key> |
| | |
| | | </dict> |
| | | </array> |
| | | <key>CFBundleVersion</key> |
| | | <string>74</string> |
| | | <string>$(CURRENT_PROJECT_VERSION)</string> |
| | | <key>LSApplicationQueriesSchemes</key> |
| | | <array> |
| | | <string>tmall</string> |
| | |
| | | */ |
| | | -(void)creatData{ |
| | | if (!_iconArr) { |
| | | _iconArr=[NSArray arrayWithObjects:@"我的收藏",@"观看记录",@"我的关注",@"我的消息",@"分享出去",@"帮助和反馈",@"隐私政策",@"设置", nil]; |
| | | _iconArr=[NSArray arrayWithObjects:@"我的收藏",@"观看记录",@"我的关注",@"我的消息",@"帮助和反馈",@"隐私政策",@"设置", nil]; |
| | | } |
| | | if (!_dataArr) { |
| | | _dataArr=[NSArray arrayWithObjects:@"我的收藏",@"观看记录",@"我的关注",@"我的消息",@"分享软件",@"帮助与反馈",@"隐私政策",@"设置", nil]; |
| | | _dataArr=[NSArray arrayWithObjects:@"我的收藏",@"观看记录",@"我的关注",@"我的消息",@"帮助与反馈",@"隐私政策",@"设置", nil]; |
| | | } |
| | | } |
| | | /** |
| | |
| | | |
| | | switch (indexPath.row) { |
| | | case 0:{ |
| | | // if([[NSUserDefaults standardUserDefaults] boolForKey:@"userOnLine"]){ |
| | | // if([[NSUserDefaults standardUserDefaults] boolForKey:@"userOnLine"]){ |
| | | // |
| | | CollectionController * cc = [CollectionController new]; |
| | | [cc setHidesBottomBarWhenPushed:YES]; |
| | |
| | | } |
| | | } |
| | | break; |
| | | case 4:{//分享 |
| | | [self shareAPP]; |
| | | } |
| | | break; |
| | | // case 5:{//发布东西 |
| | | // PublishGoodsViewController *PublishGoodsVC=[[PublishGoodsViewController alloc] init]; |
| | | // [nav pushViewController:PublishGoodsVC animated:YES]; |
| | | // } |
| | | // break; |
| | | case 5:{ |
| | | |
| | | case 4:{ |
| | | //帮助与反馈 |
| | | HelpViewController *Help = [HelpViewController new]; |
| | | [Help setHidesBottomBarWhenPushed:YES]; |
| | |
| | | } |
| | | break; |
| | | |
| | | case 6:{ |
| | | case 5:{ |
| | | NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"%@/api_control_ios.jsp",iconImageUrl]]; |
| | | SFSafariViewController *safariVC = [[SFSafariViewController alloc] initWithURL:url]; |
| | | // safariVC.delegate = self; |
| | |
| | | // safariVC.hidesBottomBarWhenPushed = YES; |
| | | // 建议 |
| | | // [self.navigationController pushViewController:safariVC animated:YES]; |
| | | safariVC.modalPresentationStyle = 0; |
| | | [self presentViewController:safariVC animated:YES completion:nil]; |
| | | |
| | | } |
| | | break; |
| | | |
| | | case 7:{ |
| | | case 6:{ |
| | | //设置 |
| | | SettingController * setting = [SettingController new]; |
| | | [setting setHidesBottomBarWhenPushed:YES]; |
| | |
| | | [self.view addSubview:shareView]; |
| | | } |
| | | #pragma mark -HXEasyCustomShareViewDelegate |
| | | - (void)easyCustomShareViewButtonAction:(HXEasyCustomShareView *)shareView title:(NSString *)title { |
| | | if ([title isEqualToString:@"微信"]) { |
| | | [self shareWebPageToPlatformType:UMSocialPlatformType_WechatSession]; |
| | | }else if ([title isEqualToString:@"朋友圈"]) { |
| | | [self shareWebPageToPlatformType:UMSocialPlatformType_WechatTimeLine]; |
| | | }else if ([title isEqualToString:@"QQ"]) { |
| | | [self shareWebPageToPlatformType:UMSocialPlatformType_QQ]; |
| | | }else if ([title isEqualToString:@"新浪微博"]) { |
| | | [self shareWebPageToPlatformType:UMSocialPlatformType_Sina]; |
| | | }else if ([title isEqualToString:@"QQ空间"]) { |
| | | [self shareWebPageToPlatformType:UMSocialPlatformType_Qzone]; |
| | | }else{ |
| | | //到这里就错了 |
| | | } |
| | | [shareView tappedCancel]; |
| | | } |
| | | //- (void)easyCustomShareViewButtonAction:(HXEasyCustomShareView *)shareView title:(NSString *)title { |
| | | // if ([title isEqualToString:@"微信"]) { |
| | | // [self shareWebPageToPlatformType:UMSocialPlatformType_WechatSession]; |
| | | // }else if ([title isEqualToString:@"朋友圈"]) { |
| | | // [self shareWebPageToPlatformType:UMSocialPlatformType_WechatTimeLine]; |
| | | // }else if ([title isEqualToString:@"QQ"]) { |
| | | // [self shareWebPageToPlatformType:UMSocialPlatformType_QQ]; |
| | | // }else if ([title isEqualToString:@"新浪微博"]) { |
| | | // [self shareWebPageToPlatformType:UMSocialPlatformType_Sina]; |
| | | // }else if ([title isEqualToString:@"QQ空间"]) { |
| | | // [self shareWebPageToPlatformType:UMSocialPlatformType_Qzone]; |
| | | // }else{ |
| | | // //到这里就错了 |
| | | // } |
| | | // [shareView tappedCancel]; |
| | | //} |
| | | |
| | | /** |
| | | 分享 |
| | | */ |
| | | - (void)shareWebPageToPlatformType:(UMSocialPlatformType)platformType{ |
| | | |
| | | //创建分享消息对象 |
| | | UMSocialMessageObject *messageObject = [UMSocialMessageObject messageObject]; |
| | | |
| | | //创建网页内容对象 |
| | | UMShareWebpageObject *shareObject = [UMShareWebpageObject shareObjectWithTitle:@"布丸影视大全" descr:[NSString stringWithFormat:@"%@!%@",[[NSUserDefaults standardUserDefaults] objectForKey:@"ShareContent"],[[NSUserDefaults standardUserDefaults] objectForKey:@"ShareUrl"]] thumImage:[UIImage imageNamed:@"分享图标"]]; |
| | | NSLog(@"%@---%@",[[NSUserDefaults standardUserDefaults] objectForKey:@"ShareContent"],[[NSUserDefaults standardUserDefaults] objectForKey:@"ShareUrl"]); |
| | | //设置网页地址 |
| | | shareObject.webpageUrl =[[NSUserDefaults standardUserDefaults] objectForKey:@"ShareUrl"]; |
| | | NSLog(@"%@",[[NSUserDefaults standardUserDefaults] objectForKey:@"ShareUrl"]); |
| | | //分享消息对象设置分享内容对象 |
| | | messageObject.shareObject = shareObject; |
| | | NSLog(@"%@",shareObject); |
| | | //调用分享接口 |
| | | [[UMSocialManager defaultManager] shareToPlatform:platformType messageObject:messageObject currentViewController:self completion:^(id data, NSError *error) { |
| | | if (error) { |
| | | [SVProgressHUD showErrorWithStatus:@"分享失败!"]; |
| | | NSLog(@"************Share fail with error %@*********",error); |
| | | }else{ |
| | | NSLog(@"response data is %@",data); |
| | | } |
| | | }]; |
| | | } |
| | | //- (void)shareWebPageToPlatformType:(UMSocialPlatformType)platformType{ |
| | | // |
| | | // //创建分享消息对象 |
| | | // UMSocialMessageObject *messageObject = [UMSocialMessageObject messageObject]; |
| | | // |
| | | // //创建网页内容对象 |
| | | // UMShareWebpageObject *shareObject = [UMShareWebpageObject shareObjectWithTitle:@"布丸影视大全" descr:[NSString stringWithFormat:@"%@!%@",[[NSUserDefaults standardUserDefaults] objectForKey:@"ShareContent"],[[NSUserDefaults standardUserDefaults] objectForKey:@"ShareUrl"]] thumImage:[UIImage imageNamed:@"分享图标"]]; |
| | | // NSLog(@"%@---%@",[[NSUserDefaults standardUserDefaults] objectForKey:@"ShareContent"],[[NSUserDefaults standardUserDefaults] objectForKey:@"ShareUrl"]); |
| | | // //设置网页地址 |
| | | // shareObject.webpageUrl =[[NSUserDefaults standardUserDefaults] objectForKey:@"ShareUrl"]; |
| | | // NSLog(@"%@",[[NSUserDefaults standardUserDefaults] objectForKey:@"ShareUrl"]); |
| | | // //分享消息对象设置分享内容对象 |
| | | // messageObject.shareObject = shareObject; |
| | | // NSLog(@"%@",shareObject); |
| | | // //调用分享接口 |
| | | // [[UMSocialManager defaultManager] shareToPlatform:platformType messageObject:messageObject currentViewController:self completion:^(id data, NSError *error) { |
| | | // if (error) { |
| | | // [SVProgressHUD showErrorWithStatus:@"分享失败!"]; |
| | | // NSLog(@"************Share fail with error %@*********",error); |
| | | // }else{ |
| | | // NSLog(@"response data is %@",data); |
| | | // } |
| | | // }]; |
| | | //} |
| | | |
| | | - (void)didReceiveMemoryWarning { |
| | | [super didReceiveMemoryWarning]; |
| | |
| | | - (void)viewWillAppear:(BOOL)animated |
| | | { |
| | | [super viewWillAppear:animated]; |
| | | [MobClick beginLogPageView:@"登录界面"]; |
| | | //[MobClick beginLogPageView:@"登录界面"]; |
| | | } |
| | | |
| | | - (void)viewWillDisappear:(BOOL)animated |
| | | { |
| | | [super viewWillDisappear:animated]; |
| | | [MobClick endLogPageView:@"登录界面"]; |
| | | //[MobClick endLogPageView:@"登录界面"]; |
| | | } |
| | | |
| | | /** |
| | |
| | | [LoginBtn addTarget:self action:@selector(LoginClick) forControlEvents:UIControlEventTouchUpInside]; |
| | | [self.view addSubview:LoginBtn]; |
| | | |
| | | //第三方登录 |
| | | UIView * thirdView=[[UIView alloc] initWithFrame:CGRectMake(0, KScreenH-170, KScreenW, 170)]; |
| | | thirdView.backgroundColor=KGlobalLightGreyColor_255; |
| | | [self.view addSubview:thirdView]; |
| | | |
| | | //第三方登录的标头 |
| | | UIImageView *thirdtitle=[[UIImageView alloc] initWithFrame:CGRectMake((KScreenW-210)/2, 20, 210, 23)]; |
| | | thirdtitle.image=[UIImage imageNamed:@"三方登录标头"]; |
| | | [thirdView addSubview:thirdtitle]; |
| | | |
| | | //QQ登录 |
| | | UIButton * QQLoginButton=[[UIButton alloc] initWithFrame:CGRectMake(KScreenW/2-30, thirdView.frame.size.height/2-30, 60, 60)]; |
| | | [QQLoginButton setBackgroundImage:[UIImage imageNamed:@"QQLogin"] forState:UIControlStateNormal]; |
| | | [QQLoginButton addTarget:self action:@selector(ClickQQ:) forControlEvents:UIControlEventTouchUpInside]; |
| | | [thirdView addSubview:QQLoginButton]; |
| | | |
| | | UILabel * QQLabel=[[UILabel alloc] initWithFrame:CGRectMake(KScreenW/2-30, thirdView.frame.size.height/2+30, 60, 40)]; |
| | | QQLabel.textAlignment = NSTextAlignmentCenter; |
| | | QQLabel.text=@"QQ"; |
| | | QQLabel.font=[UIFont systemFontOfSize:17]; |
| | | [thirdView addSubview:QQLabel]; |
| | | |
| | | if (![[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:@"mqq://"]]) { |
| | | thirdView.hidden = YES; |
| | | }else{ |
| | | thirdView.hidden = NO; |
| | | |
| | | } |
| | | // //第三方登录 |
| | | // UIView * thirdView=[[UIView alloc] initWithFrame:CGRectMake(0, KScreenH-170, KScreenW, 170)]; |
| | | // thirdView.backgroundColor=KGlobalLightGreyColor_255; |
| | | // [self.view addSubview:thirdView]; |
| | | // |
| | | // //第三方登录的标头 |
| | | // UIImageView *thirdtitle=[[UIImageView alloc] initWithFrame:CGRectMake((KScreenW-210)/2, 20, 210, 23)]; |
| | | // thirdtitle.image=[UIImage imageNamed:@"三方登录标头"]; |
| | | // [thirdView addSubview:thirdtitle]; |
| | | // |
| | | // //QQ登录 |
| | | // UIButton * QQLoginButton=[[UIButton alloc] initWithFrame:CGRectMake(KScreenW/2-30, thirdView.frame.size.height/2-30, 60, 60)]; |
| | | // [QQLoginButton setBackgroundImage:[UIImage imageNamed:@"QQLogin"] forState:UIControlStateNormal]; |
| | | // [QQLoginButton addTarget:self action:@selector(ClickQQ:) forControlEvents:UIControlEventTouchUpInside]; |
| | | // [thirdView addSubview:QQLoginButton]; |
| | | // |
| | | // UILabel * QQLabel=[[UILabel alloc] initWithFrame:CGRectMake(KScreenW/2-30, thirdView.frame.size.height/2+30, 60, 40)]; |
| | | // QQLabel.textAlignment = NSTextAlignmentCenter; |
| | | // QQLabel.text=@"QQ"; |
| | | // QQLabel.font=[UIFont systemFontOfSize:17]; |
| | | // [thirdView addSubview:QQLabel]; |
| | | // |
| | | // if (![[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:@"mqq://"]]) { |
| | | // thirdView.hidden = YES; |
| | | // }else{ |
| | | // thirdView.hidden = NO; |
| | | // |
| | | // } |
| | | |
| | | } |
| | | |
| | |
| | | * |
| | | * @param sender QQ登录的按钮 |
| | | */ |
| | | -(void)ClickQQ:(UIButton*)sender{ |
| | | |
| | | if (![[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:@"mqq://"]]){ |
| | | [SVProgressHUD showInfoWithStatus:@"您还没有安装QQ哦"]; |
| | | |
| | | return; |
| | | } |
| | | |
| | | [[UMSocialManager defaultManager] getUserInfoWithPlatform:UMSocialPlatformType_QQ currentViewController:nil completion:^(id result, NSError *error) { |
| | | if (error) { |
| | | |
| | | }else{ |
| | | //提示用户,正在登陆中 |
| | | [SVProgressHUD showWithStatus:@"拼命登陆中..."]; |
| | | |
| | | UMSocialUserInfoResponse *snsAccount = result; |
| | | |
| | | [[YTHNetInterface startInterface] getThirdPartyWithWithUid:[YTHsharedManger startManger].Uid withOpenId:snsAccount.openid WithName:snsAccount.name WithPortrait:snsAccount.iconurl WithLoginType:@"1" withSystem:@"1" withBlock:^(BOOL isSuccessful, id result, NSString *error) { |
| | | if (isSuccessful) { |
| | | [SVProgressHUD dismiss]; |
| | | //LoginUid的设置在YTHNetInterface中,点击上面的的请求函数,就可以看见! |
| | | [[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"userOnLine"]; |
| | | [self getInfoFromInternet]; |
| | | if (_ispresent) { |
| | | [self presentBack]; |
| | | }else{ |
| | | [self back]; |
| | | } |
| | | }else{ |
| | | //通知用户登录失败 |
| | | [SVProgressHUD showErrorWithStatus:@"登陆失败!"]; |
| | | } |
| | | }]; |
| | | } |
| | | }]; |
| | | } |
| | | //-(void)ClickQQ:(UIButton*)sender{ |
| | | // |
| | | // if (![[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:@"mqq://"]]){ |
| | | // [SVProgressHUD showInfoWithStatus:@"您还没有安装QQ哦"]; |
| | | // |
| | | // return; |
| | | // } |
| | | // |
| | | // [[UMSocialManager defaultManager] getUserInfoWithPlatform:UMSocialPlatformType_QQ currentViewController:nil completion:^(id result, NSError *error) { |
| | | // if (error) { |
| | | // |
| | | // }else{ |
| | | // //提示用户,正在登陆中 |
| | | // [SVProgressHUD showWithStatus:@"拼命登陆中..."]; |
| | | // |
| | | // UMSocialUserInfoResponse *snsAccount = result; |
| | | // |
| | | // [[YTHNetInterface startInterface] getThirdPartyWithWithUid:[YTHsharedManger startManger].Uid withOpenId:snsAccount.openid WithName:snsAccount.name WithPortrait:snsAccount.iconurl WithLoginType:@"1" withSystem:@"1" withBlock:^(BOOL isSuccessful, id result, NSString *error) { |
| | | // if (isSuccessful) { |
| | | // [SVProgressHUD dismiss]; |
| | | // //LoginUid的设置在YTHNetInterface中,点击上面的的请求函数,就可以看见! |
| | | // [[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"userOnLine"]; |
| | | // [self getInfoFromInternet]; |
| | | // if (_ispresent) { |
| | | // [self presentBack]; |
| | | // }else{ |
| | | // [self back]; |
| | | // } |
| | | // }else{ |
| | | // //通知用户登录失败 |
| | | // [SVProgressHUD showErrorWithStatus:@"登陆失败!"]; |
| | | // } |
| | | // }]; |
| | | // } |
| | | // }]; |
| | | //} |
| | | |
| | | /** |
| | | 从网络获取数据 |
| | |
| | | [tableView deselectRowAtIndexPath:indexPath animated:YES]; |
| | | XYRDetailViewController *play=[[XYRDetailViewController alloc]init]; |
| | | NSDictionary *dic = historyListDataArray[indexPath.row]; |
| | | play.modalPresentationStyle = 0; |
| | | play.Model = [XYRVideoInfoModel yy_modelWithDictionary:dic]; |
| | | [self presentViewController:play animated:YES completion:^{ |
| | | |
New file |
| | |
| | | // |
| | | // MJRefreshAutoFooter.h |
| | | // MJRefreshExample |
| | | // |
| | | // Created by MJ Lee on 15/4/24. |
| | | // Copyright (c) 2015年 小码哥. All rights reserved. |
| | | // |
| | | |
| | | #import "MJRefreshFooter.h" |
| | | |
| | | NS_ASSUME_NONNULL_BEGIN |
| | | |
| | | @interface MJRefreshAutoFooter : MJRefreshFooter |
| | | /** 是否自动刷新(默认为YES) */ |
| | | @property (assign, nonatomic, getter=isAutomaticallyRefresh) BOOL automaticallyRefresh; |
| | | |
| | | /** 当底部控件出现多少时就自动刷新(默认为1.0,也就是底部控件完全出现时,才会自动刷新) */ |
| | | @property (assign, nonatomic) CGFloat appearencePercentTriggerAutoRefresh MJRefreshDeprecated("请使用triggerAutomaticallyRefreshPercent属性"); |
| | | |
| | | /** 当底部控件出现多少时就自动刷新(默认为1.0,也就是底部控件完全出现时,才会自动刷新) */ |
| | | @property (assign, nonatomic) CGFloat triggerAutomaticallyRefreshPercent; |
| | | |
| | | /** 自动触发次数, 默认为 1, 仅在拖拽 ScrollView 时才生效, |
| | | |
| | | 如果为 -1, 则为无限触发 |
| | | */ |
| | | @property (nonatomic) NSInteger autoTriggerTimes; |
| | | @end |
| | | |
| | | NS_ASSUME_NONNULL_END |
New file |
| | |
| | | // |
| | | // MJRefreshAutoFooter.m |
| | | // MJRefreshExample |
| | | // |
| | | // Created by MJ Lee on 15/4/24. |
| | | // Copyright (c) 2015年 小码哥. All rights reserved. |
| | | // |
| | | |
| | | #import "MJRefreshAutoFooter.h" |
| | | |
| | | @interface MJRefreshAutoFooter() |
| | | /** 一个新的拖拽 */ |
| | | @property (nonatomic) BOOL triggerByDrag; |
| | | @property (nonatomic) NSInteger leftTriggerTimes; |
| | | @end |
| | | |
| | | @implementation MJRefreshAutoFooter |
| | | |
| | | #pragma mark - 初始化 |
| | | - (void)willMoveToSuperview:(UIView *)newSuperview |
| | | { |
| | | [super willMoveToSuperview:newSuperview]; |
| | | |
| | | if (newSuperview) { // 新的父控件 |
| | | if (self.hidden == NO) { |
| | | self.scrollView.mj_insetB += self.mj_h; |
| | | } |
| | | |
| | | // 设置位置 |
| | | self.mj_y = _scrollView.mj_contentH; |
| | | } else { // 被移除了 |
| | | if (self.hidden == NO) { |
| | | self.scrollView.mj_insetB -= self.mj_h; |
| | | } |
| | | } |
| | | } |
| | | |
| | | #pragma mark - 过期方法 |
| | | - (void)setAppearencePercentTriggerAutoRefresh:(CGFloat)appearencePercentTriggerAutoRefresh |
| | | { |
| | | self.triggerAutomaticallyRefreshPercent = appearencePercentTriggerAutoRefresh; |
| | | } |
| | | |
| | | - (CGFloat)appearencePercentTriggerAutoRefresh |
| | | { |
| | | return self.triggerAutomaticallyRefreshPercent; |
| | | } |
| | | |
| | | #pragma mark - 实现父类的方法 |
| | | - (void)prepare |
| | | { |
| | | [super prepare]; |
| | | |
| | | // 默认底部控件100%出现时才会自动刷新 |
| | | self.triggerAutomaticallyRefreshPercent = 1.0; |
| | | |
| | | // 设置为默认状态 |
| | | self.automaticallyRefresh = YES; |
| | | |
| | | self.autoTriggerTimes = 1; |
| | | } |
| | | |
| | | - (void)scrollViewContentSizeDidChange:(NSDictionary *)change |
| | | { |
| | | [super scrollViewContentSizeDidChange:change]; |
| | | |
| | | // 设置位置 |
| | | self.mj_y = self.scrollView.mj_contentH + self.ignoredScrollViewContentInsetBottom; |
| | | } |
| | | |
| | | - (void)scrollViewContentOffsetDidChange:(NSDictionary *)change |
| | | { |
| | | [super scrollViewContentOffsetDidChange:change]; |
| | | |
| | | if (self.state != MJRefreshStateIdle || !self.automaticallyRefresh || self.mj_y == 0) return; |
| | | |
| | | if (_scrollView.mj_insetT + _scrollView.mj_contentH > _scrollView.mj_h) { // 内容超过一个屏幕 |
| | | // 这里的_scrollView.mj_contentH替换掉self.mj_y更为合理 |
| | | if (_scrollView.mj_offsetY >= _scrollView.mj_contentH - _scrollView.mj_h + self.mj_h * self.triggerAutomaticallyRefreshPercent + _scrollView.mj_insetB - self.mj_h) { |
| | | // 防止手松开时连续调用 |
| | | CGPoint old = [change[@"old"] CGPointValue]; |
| | | CGPoint new = [change[@"new"] CGPointValue]; |
| | | if (new.y <= old.y) return; |
| | | |
| | | if (_scrollView.isDragging) { |
| | | self.triggerByDrag = YES; |
| | | } |
| | | // 当底部刷新控件完全出现时,才刷新 |
| | | [self beginRefreshing]; |
| | | } |
| | | } |
| | | } |
| | | |
| | | - (void)scrollViewPanStateDidChange:(NSDictionary *)change |
| | | { |
| | | [super scrollViewPanStateDidChange:change]; |
| | | |
| | | if (self.state != MJRefreshStateIdle) return; |
| | | |
| | | UIGestureRecognizerState panState = _scrollView.panGestureRecognizer.state; |
| | | |
| | | switch (panState) { |
| | | // 手松开 |
| | | case UIGestureRecognizerStateEnded: { |
| | | if (_scrollView.mj_insetT + _scrollView.mj_contentH <= _scrollView.mj_h) { // 不够一个屏幕 |
| | | if (_scrollView.mj_offsetY >= - _scrollView.mj_insetT) { // 向上拽 |
| | | self.triggerByDrag = YES; |
| | | [self beginRefreshing]; |
| | | } |
| | | } else { // 超出一个屏幕 |
| | | if (_scrollView.mj_offsetY >= _scrollView.mj_contentH + _scrollView.mj_insetB - _scrollView.mj_h) { |
| | | self.triggerByDrag = YES; |
| | | [self beginRefreshing]; |
| | | } |
| | | } |
| | | } |
| | | break; |
| | | |
| | | case UIGestureRecognizerStateBegan: { |
| | | [self resetTriggerTimes]; |
| | | } |
| | | break; |
| | | |
| | | default: |
| | | break; |
| | | } |
| | | } |
| | | |
| | | - (BOOL)unlimitedTrigger { |
| | | return self.leftTriggerTimes == -1; |
| | | } |
| | | |
| | | - (void)beginRefreshing |
| | | { |
| | | if (self.triggerByDrag && self.leftTriggerTimes <= 0 && !self.unlimitedTrigger) { |
| | | return; |
| | | } |
| | | |
| | | [super beginRefreshing]; |
| | | } |
| | | |
| | | - (void)setState:(MJRefreshState)state |
| | | { |
| | | MJRefreshCheckState |
| | | |
| | | if (state == MJRefreshStateRefreshing) { |
| | | [self executeRefreshingCallback]; |
| | | } else if (state == MJRefreshStateNoMoreData || state == MJRefreshStateIdle) { |
| | | if (self.triggerByDrag) { |
| | | if (!self.unlimitedTrigger) { |
| | | self.leftTriggerTimes -= 1; |
| | | } |
| | | self.triggerByDrag = NO; |
| | | } |
| | | |
| | | if (MJRefreshStateRefreshing == oldState) { |
| | | if (self.scrollView.pagingEnabled) { |
| | | CGPoint offset = self.scrollView.contentOffset; |
| | | offset.y -= self.scrollView.mj_insetB; |
| | | [UIView animateWithDuration:MJRefreshSlowAnimationDuration animations:^{ |
| | | self.scrollView.contentOffset = offset; |
| | | |
| | | if (self.endRefreshingAnimationBeginAction) { |
| | | self.endRefreshingAnimationBeginAction(); |
| | | } |
| | | } completion:^(BOOL finished) { |
| | | if (self.endRefreshingCompletionBlock) { |
| | | self.endRefreshingCompletionBlock(); |
| | | } |
| | | }]; |
| | | return; |
| | | } |
| | | |
| | | if (self.endRefreshingCompletionBlock) { |
| | | self.endRefreshingCompletionBlock(); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | - (void)resetTriggerTimes { |
| | | self.leftTriggerTimes = self.autoTriggerTimes; |
| | | } |
| | | |
| | | - (void)setHidden:(BOOL)hidden |
| | | { |
| | | BOOL lastHidden = self.isHidden; |
| | | |
| | | [super setHidden:hidden]; |
| | | |
| | | if (!lastHidden && hidden) { |
| | | self.state = MJRefreshStateIdle; |
| | | |
| | | self.scrollView.mj_insetB -= self.mj_h; |
| | | } else if (lastHidden && !hidden) { |
| | | self.scrollView.mj_insetB += self.mj_h; |
| | | |
| | | // 设置位置 |
| | | self.mj_y = _scrollView.mj_contentH; |
| | | } |
| | | } |
| | | |
| | | - (void)setAutoTriggerTimes:(NSInteger)autoTriggerTimes { |
| | | _autoTriggerTimes = autoTriggerTimes; |
| | | self.leftTriggerTimes = autoTriggerTimes; |
| | | } |
| | | @end |
New file |
| | |
| | | // |
| | | // MJRefreshBackFooter.h |
| | | // MJRefreshExample |
| | | // |
| | | // Created by MJ Lee on 15/4/24. |
| | | // Copyright (c) 2015年 小码哥. All rights reserved. |
| | | // |
| | | |
| | | #import "MJRefreshFooter.h" |
| | | |
| | | NS_ASSUME_NONNULL_BEGIN |
| | | |
| | | @interface MJRefreshBackFooter : MJRefreshFooter |
| | | |
| | | @end |
| | | |
| | | NS_ASSUME_NONNULL_END |
New file |
| | |
| | | // |
| | | // MJRefreshBackFooter.m |
| | | // MJRefreshExample |
| | | // |
| | | // Created by MJ Lee on 15/4/24. |
| | | // Copyright (c) 2015年 小码哥. All rights reserved. |
| | | // |
| | | |
| | | #import "MJRefreshBackFooter.h" |
| | | |
| | | @interface MJRefreshBackFooter() |
| | | @property (assign, nonatomic) NSInteger lastRefreshCount; |
| | | @property (assign, nonatomic) CGFloat lastBottomDelta; |
| | | @end |
| | | |
| | | @implementation MJRefreshBackFooter |
| | | |
| | | #pragma mark - 初始化 |
| | | - (void)willMoveToSuperview:(UIView *)newSuperview |
| | | { |
| | | [super willMoveToSuperview:newSuperview]; |
| | | |
| | | [self scrollViewContentSizeDidChange:nil]; |
| | | } |
| | | |
| | | #pragma mark - 实现父类的方法 |
| | | - (void)scrollViewContentOffsetDidChange:(NSDictionary *)change |
| | | { |
| | | [super scrollViewContentOffsetDidChange:change]; |
| | | |
| | | // 如果正在刷新,直接返回 |
| | | if (self.state == MJRefreshStateRefreshing) return; |
| | | |
| | | _scrollViewOriginalInset = self.scrollView.mj_inset; |
| | | |
| | | // 当前的contentOffset |
| | | CGFloat currentOffsetY = self.scrollView.mj_offsetY; |
| | | // 尾部控件刚好出现的offsetY |
| | | CGFloat happenOffsetY = [self happenOffsetY]; |
| | | // 如果是向下滚动到看不见尾部控件,直接返回 |
| | | if (currentOffsetY <= happenOffsetY) return; |
| | | |
| | | CGFloat pullingPercent = (currentOffsetY - happenOffsetY) / self.mj_h; |
| | | |
| | | // 如果已全部加载,仅设置pullingPercent,然后返回 |
| | | if (self.state == MJRefreshStateNoMoreData) { |
| | | self.pullingPercent = pullingPercent; |
| | | return; |
| | | } |
| | | |
| | | if (self.scrollView.isDragging) { |
| | | self.pullingPercent = pullingPercent; |
| | | // 普通 和 即将刷新 的临界点 |
| | | CGFloat normal2pullingOffsetY = happenOffsetY + self.mj_h; |
| | | |
| | | if (self.state == MJRefreshStateIdle && currentOffsetY > normal2pullingOffsetY) { |
| | | // 转为即将刷新状态 |
| | | self.state = MJRefreshStatePulling; |
| | | } else if (self.state == MJRefreshStatePulling && currentOffsetY <= normal2pullingOffsetY) { |
| | | // 转为普通状态 |
| | | self.state = MJRefreshStateIdle; |
| | | } |
| | | } else if (self.state == MJRefreshStatePulling) {// 即将刷新 && 手松开 |
| | | // 开始刷新 |
| | | [self beginRefreshing]; |
| | | } else if (pullingPercent < 1) { |
| | | self.pullingPercent = pullingPercent; |
| | | } |
| | | } |
| | | |
| | | - (void)scrollViewContentSizeDidChange:(NSDictionary *)change |
| | | { |
| | | [super scrollViewContentSizeDidChange:change]; |
| | | |
| | | // 内容的高度 |
| | | CGFloat contentHeight = self.scrollView.mj_contentH + self.ignoredScrollViewContentInsetBottom; |
| | | // 表格的高度 |
| | | CGFloat scrollHeight = self.scrollView.mj_h - self.scrollViewOriginalInset.top - self.scrollViewOriginalInset.bottom + self.ignoredScrollViewContentInsetBottom; |
| | | // 设置位置和尺寸 |
| | | self.mj_y = MAX(contentHeight, scrollHeight); |
| | | } |
| | | |
| | | - (void)setState:(MJRefreshState)state |
| | | { |
| | | MJRefreshCheckState |
| | | |
| | | // 根据状态来设置属性 |
| | | if (state == MJRefreshStateNoMoreData || state == MJRefreshStateIdle) { |
| | | // 刷新完毕 |
| | | if (MJRefreshStateRefreshing == oldState) { |
| | | [UIView animateWithDuration:MJRefreshSlowAnimationDuration animations:^{ |
| | | if (self.endRefreshingAnimationBeginAction) { |
| | | self.endRefreshingAnimationBeginAction(); |
| | | } |
| | | |
| | | self.scrollView.mj_insetB -= self.lastBottomDelta; |
| | | // 自动调整透明度 |
| | | if (self.isAutomaticallyChangeAlpha) self.alpha = 0.0; |
| | | } completion:^(BOOL finished) { |
| | | self.pullingPercent = 0.0; |
| | | |
| | | if (self.endRefreshingCompletionBlock) { |
| | | self.endRefreshingCompletionBlock(); |
| | | } |
| | | }]; |
| | | } |
| | | |
| | | CGFloat deltaH = [self heightForContentBreakView]; |
| | | // 刚刷新完毕 |
| | | if (MJRefreshStateRefreshing == oldState && deltaH > 0 && self.scrollView.mj_totalDataCount != self.lastRefreshCount) { |
| | | self.scrollView.mj_offsetY = self.scrollView.mj_offsetY; |
| | | } |
| | | } else if (state == MJRefreshStateRefreshing) { |
| | | // 记录刷新前的数量 |
| | | self.lastRefreshCount = self.scrollView.mj_totalDataCount; |
| | | |
| | | [UIView animateWithDuration:MJRefreshFastAnimationDuration animations:^{ |
| | | CGFloat bottom = self.mj_h + self.scrollViewOriginalInset.bottom; |
| | | CGFloat deltaH = [self heightForContentBreakView]; |
| | | if (deltaH < 0) { // 如果内容高度小于view的高度 |
| | | bottom -= deltaH; |
| | | } |
| | | self.lastBottomDelta = bottom - self.scrollView.mj_insetB; |
| | | self.scrollView.mj_insetB = bottom; |
| | | self.scrollView.mj_offsetY = [self happenOffsetY] + self.mj_h; |
| | | } completion:^(BOOL finished) { |
| | | [self executeRefreshingCallback]; |
| | | }]; |
| | | } |
| | | } |
| | | #pragma mark - 私有方法 |
| | | #pragma mark 获得scrollView的内容 超出 view 的高度 |
| | | - (CGFloat)heightForContentBreakView |
| | | { |
| | | CGFloat h = self.scrollView.frame.size.height - self.scrollViewOriginalInset.bottom - self.scrollViewOriginalInset.top; |
| | | return self.scrollView.contentSize.height - h; |
| | | } |
| | | |
| | | #pragma mark 刚好看到上拉刷新控件时的contentOffset.y |
| | | - (CGFloat)happenOffsetY |
| | | { |
| | | CGFloat deltaH = [self heightForContentBreakView]; |
| | | if (deltaH > 0) { |
| | | return deltaH - self.scrollViewOriginalInset.top; |
| | | } else { |
| | | return - self.scrollViewOriginalInset.top; |
| | | } |
| | | } |
| | | @end |
New file |
| | |
| | | // 代码地址: https://github.com/CoderMJLee/MJRefresh |
| | | // 代码地址: http://code4app.com/ios/%E5%BF%AB%E9%80%9F%E9%9B%86%E6%88%90%E4%B8%8B%E6%8B%89%E4%B8%8A%E6%8B%89%E5%88%B7%E6%96%B0/52326ce26803fabc46000000 |
| | | // MJRefreshComponent.h |
| | | // MJRefreshExample |
| | | // |
| | | // Created by MJ Lee on 15/3/4. |
| | | // Copyright (c) 2015年 小码哥. All rights reserved. |
| | | // 刷新控件的基类 |
| | | |
| | | #import <UIKit/UIKit.h> |
| | | #import "MJRefreshConst.h" |
| | | #import "UIView+MJExtension.h" |
| | | #import "UIScrollView+MJExtension.h" |
| | | #import "UIScrollView+MJRefresh.h" |
| | | #import "NSBundle+MJRefresh.h" |
| | | |
| | | NS_ASSUME_NONNULL_BEGIN |
| | | |
| | | /** 刷新控件的状态 */ |
| | | typedef NS_ENUM(NSInteger, MJRefreshState) { |
| | | /** 普通闲置状态 */ |
| | | MJRefreshStateIdle = 1, |
| | | /** 松开就可以进行刷新的状态 */ |
| | | MJRefreshStatePulling, |
| | | /** 正在刷新中的状态 */ |
| | | MJRefreshStateRefreshing, |
| | | /** 即将刷新的状态 */ |
| | | MJRefreshStateWillRefresh, |
| | | /** 所有数据加载完毕,没有更多的数据了 */ |
| | | MJRefreshStateNoMoreData |
| | | }; |
| | | |
| | | /** 进入刷新状态的回调 */ |
| | | typedef void (^MJRefreshComponentRefreshingBlock)(void) MJRefreshDeprecated("first deprecated in 3.3.0 - Use `MJRefreshComponentAction` instead"); |
| | | /** 开始刷新后的回调(进入刷新状态后的回调) */ |
| | | typedef void (^MJRefreshComponentBeginRefreshingCompletionBlock)(void) MJRefreshDeprecated("first deprecated in 3.3.0 - Use `MJRefreshComponentAction` instead"); |
| | | /** 结束刷新后的回调 */ |
| | | typedef void (^MJRefreshComponentEndRefreshingCompletionBlock)(void) MJRefreshDeprecated("first deprecated in 3.3.0 - Use `MJRefreshComponentAction` instead"); |
| | | |
| | | /** 刷新用到的回调类型 */ |
| | | typedef void (^MJRefreshComponentAction)(void); |
| | | |
| | | /** 刷新控件的基类 */ |
| | | @interface MJRefreshComponent : UIView |
| | | { |
| | | /** 记录scrollView刚开始的inset */ |
| | | UIEdgeInsets _scrollViewOriginalInset; |
| | | /** 父控件 */ |
| | | __weak UIScrollView *_scrollView; |
| | | } |
| | | #pragma mark - 刷新回调 |
| | | /** 正在刷新的回调 */ |
| | | @property (copy, nonatomic, nullable) MJRefreshComponentAction refreshingBlock; |
| | | /** 设置回调对象和回调方法 */ |
| | | - (void)setRefreshingTarget:(id)target refreshingAction:(SEL)action; |
| | | |
| | | /** 回调对象 */ |
| | | @property (weak, nonatomic) id refreshingTarget; |
| | | /** 回调方法 */ |
| | | @property (assign, nonatomic) SEL refreshingAction; |
| | | /** 触发回调(交给子类去调用) */ |
| | | - (void)executeRefreshingCallback; |
| | | |
| | | #pragma mark - 刷新状态控制 |
| | | /** 进入刷新状态 */ |
| | | - (void)beginRefreshing; |
| | | - (void)beginRefreshingWithCompletionBlock:(void (^)(void))completionBlock; |
| | | /** 开始刷新后的回调(进入刷新状态后的回调) */ |
| | | @property (copy, nonatomic, nullable) MJRefreshComponentAction beginRefreshingCompletionBlock; |
| | | /** 带动画的结束刷新的回调 */ |
| | | @property (copy, nonatomic, nullable) MJRefreshComponentAction endRefreshingAnimateCompletionBlock MJRefreshDeprecated("first deprecated in 3.3.0 - Use `endRefreshingAnimationBeginAction` instead"); |
| | | @property (copy, nonatomic, nullable) MJRefreshComponentAction endRefreshingAnimationBeginAction; |
| | | /** 结束刷新的回调 */ |
| | | @property (copy, nonatomic, nullable) MJRefreshComponentAction endRefreshingCompletionBlock; |
| | | /** 结束刷新状态 */ |
| | | - (void)endRefreshing; |
| | | - (void)endRefreshingWithCompletionBlock:(void (^)(void))completionBlock; |
| | | /** 是否正在刷新 */ |
| | | @property (assign, nonatomic, readonly, getter=isRefreshing) BOOL refreshing; |
| | | |
| | | /** 刷新状态 一般交给子类内部实现 */ |
| | | @property (assign, nonatomic) MJRefreshState state; |
| | | |
| | | #pragma mark - 交给子类去访问 |
| | | /** 记录scrollView刚开始的inset */ |
| | | @property (assign, nonatomic, readonly) UIEdgeInsets scrollViewOriginalInset; |
| | | /** 父控件 */ |
| | | @property (weak, nonatomic, readonly) UIScrollView *scrollView; |
| | | |
| | | #pragma mark - 交给子类们去实现 |
| | | /** 初始化 */ |
| | | - (void)prepare NS_REQUIRES_SUPER; |
| | | /** 摆放子控件frame */ |
| | | - (void)placeSubviews NS_REQUIRES_SUPER; |
| | | /** 当scrollView的contentOffset发生改变的时候调用 */ |
| | | - (void)scrollViewContentOffsetDidChange:(nullable NSDictionary *)change NS_REQUIRES_SUPER; |
| | | /** 当scrollView的contentSize发生改变的时候调用 */ |
| | | - (void)scrollViewContentSizeDidChange:(nullable NSDictionary *)change NS_REQUIRES_SUPER; |
| | | /** 当scrollView的拖拽状态发生改变的时候调用 */ |
| | | - (void)scrollViewPanStateDidChange:(nullable NSDictionary *)change NS_REQUIRES_SUPER; |
| | | |
| | | |
| | | #pragma mark - 其他 |
| | | /** 拉拽的百分比(交给子类重写) */ |
| | | @property (assign, nonatomic) CGFloat pullingPercent; |
| | | /** 根据拖拽比例自动切换透明度 */ |
| | | @property (assign, nonatomic, getter=isAutoChangeAlpha) BOOL autoChangeAlpha MJRefreshDeprecated("请使用automaticallyChangeAlpha属性"); |
| | | /** 根据拖拽比例自动切换透明度 */ |
| | | @property (assign, nonatomic, getter=isAutomaticallyChangeAlpha) BOOL automaticallyChangeAlpha; |
| | | @end |
| | | |
| | | @interface UILabel(MJRefresh) |
| | | + (instancetype)mj_label; |
| | | - (CGFloat)mj_textWidth; |
| | | @end |
| | | |
| | | |
| | | NS_ASSUME_NONNULL_END |
New file |
| | |
| | | // 代码地址: https://github.com/CoderMJLee/MJRefresh |
| | | // 代码地址: http://code4app.com/ios/%E5%BF%AB%E9%80%9F%E9%9B%86%E6%88%90%E4%B8%8B%E6%8B%89%E4%B8%8A%E6%8B%89%E5%88%B7%E6%96%B0/52326ce26803fabc46000000 |
| | | // MJRefreshComponent.m |
| | | // MJRefreshExample |
| | | // |
| | | // Created by MJ Lee on 15/3/4. |
| | | // Copyright (c) 2015年 小码哥. All rights reserved. |
| | | // |
| | | |
| | | #import "MJRefreshComponent.h" |
| | | #import "MJRefreshConst.h" |
| | | |
| | | @interface MJRefreshComponent() |
| | | @property (strong, nonatomic) UIPanGestureRecognizer *pan; |
| | | @end |
| | | |
| | | @implementation MJRefreshComponent |
| | | #pragma mark - 初始化 |
| | | - (instancetype)initWithFrame:(CGRect)frame |
| | | { |
| | | if (self = [super initWithFrame:frame]) { |
| | | // 准备工作 |
| | | [self prepare]; |
| | | |
| | | // 默认是普通状态 |
| | | self.state = MJRefreshStateIdle; |
| | | } |
| | | return self; |
| | | } |
| | | |
| | | - (void)prepare |
| | | { |
| | | // 基本属性 |
| | | self.autoresizingMask = UIViewAutoresizingFlexibleWidth; |
| | | self.backgroundColor = [UIColor clearColor]; |
| | | } |
| | | |
| | | - (void)layoutSubviews |
| | | { |
| | | [self placeSubviews]; |
| | | |
| | | [super layoutSubviews]; |
| | | } |
| | | |
| | | - (void)placeSubviews{} |
| | | |
| | | - (void)willMoveToSuperview:(UIView *)newSuperview |
| | | { |
| | | [super willMoveToSuperview:newSuperview]; |
| | | |
| | | // 如果不是UIScrollView,不做任何事情 |
| | | if (newSuperview && ![newSuperview isKindOfClass:[UIScrollView class]]) return; |
| | | |
| | | // 旧的父控件移除监听 |
| | | [self removeObservers]; |
| | | |
| | | if (newSuperview) { // 新的父控件 |
| | | // 记录UIScrollView |
| | | _scrollView = (UIScrollView *)newSuperview; |
| | | |
| | | // 设置宽度 |
| | | self.mj_w = _scrollView.mj_w; |
| | | // 设置位置 |
| | | self.mj_x = -_scrollView.mj_insetL; |
| | | |
| | | // 设置永远支持垂直弹簧效果 |
| | | _scrollView.alwaysBounceVertical = YES; |
| | | // 记录UIScrollView最开始的contentInset |
| | | _scrollViewOriginalInset = _scrollView.mj_inset; |
| | | |
| | | // 添加监听 |
| | | [self addObservers]; |
| | | } |
| | | } |
| | | |
| | | - (void)drawRect:(CGRect)rect |
| | | { |
| | | [super drawRect:rect]; |
| | | |
| | | if (self.state == MJRefreshStateWillRefresh) { |
| | | // 预防view还没显示出来就调用了beginRefreshing |
| | | self.state = MJRefreshStateRefreshing; |
| | | } |
| | | } |
| | | |
| | | #pragma mark - KVO监听 |
| | | - (void)addObservers |
| | | { |
| | | NSKeyValueObservingOptions options = NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld; |
| | | [self.scrollView addObserver:self forKeyPath:MJRefreshKeyPathContentOffset options:options context:nil]; |
| | | [self.scrollView addObserver:self forKeyPath:MJRefreshKeyPathContentSize options:options context:nil]; |
| | | self.pan = self.scrollView.panGestureRecognizer; |
| | | [self.pan addObserver:self forKeyPath:MJRefreshKeyPathPanState options:options context:nil]; |
| | | } |
| | | |
| | | - (void)removeObservers |
| | | { |
| | | [self.superview removeObserver:self forKeyPath:MJRefreshKeyPathContentOffset]; |
| | | [self.superview removeObserver:self forKeyPath:MJRefreshKeyPathContentSize]; |
| | | [self.pan removeObserver:self forKeyPath:MJRefreshKeyPathPanState]; |
| | | self.pan = nil; |
| | | } |
| | | |
| | | - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context |
| | | { |
| | | // 遇到这些情况就直接返回 |
| | | if (!self.userInteractionEnabled) return; |
| | | |
| | | // 这个就算看不见也需要处理 |
| | | if ([keyPath isEqualToString:MJRefreshKeyPathContentSize]) { |
| | | [self scrollViewContentSizeDidChange:change]; |
| | | } |
| | | |
| | | // 看不见 |
| | | if (self.hidden) return; |
| | | if ([keyPath isEqualToString:MJRefreshKeyPathContentOffset]) { |
| | | [self scrollViewContentOffsetDidChange:change]; |
| | | } else if ([keyPath isEqualToString:MJRefreshKeyPathPanState]) { |
| | | [self scrollViewPanStateDidChange:change]; |
| | | } |
| | | } |
| | | |
| | | - (void)scrollViewContentOffsetDidChange:(NSDictionary *)change{} |
| | | - (void)scrollViewContentSizeDidChange:(NSDictionary *)change{} |
| | | - (void)scrollViewPanStateDidChange:(NSDictionary *)change{} |
| | | |
| | | #pragma mark - 公共方法 |
| | | #pragma mark 设置回调对象和回调方法 |
| | | - (void)setRefreshingTarget:(id)target refreshingAction:(SEL)action |
| | | { |
| | | self.refreshingTarget = target; |
| | | self.refreshingAction = action; |
| | | } |
| | | |
| | | - (void)setState:(MJRefreshState)state |
| | | { |
| | | _state = state; |
| | | |
| | | // 加入主队列的目的是等setState:方法调用完毕、设置完文字后再去布局子控件 |
| | | MJRefreshDispatchAsyncOnMainQueue([self setNeedsLayout];) |
| | | } |
| | | |
| | | #pragma mark 进入刷新状态 |
| | | - (void)beginRefreshing |
| | | { |
| | | [UIView animateWithDuration:MJRefreshFastAnimationDuration animations:^{ |
| | | self.alpha = 1.0; |
| | | }]; |
| | | self.pullingPercent = 1.0; |
| | | // 只要正在刷新,就完全显示 |
| | | if (self.window) { |
| | | self.state = MJRefreshStateRefreshing; |
| | | } else { |
| | | // 预防正在刷新中时,调用本方法使得header inset回置失败 |
| | | if (self.state != MJRefreshStateRefreshing) { |
| | | self.state = MJRefreshStateWillRefresh; |
| | | // 刷新(预防从另一个控制器回到这个控制器的情况,回来要重新刷新一下) |
| | | [self setNeedsDisplay]; |
| | | } |
| | | } |
| | | } |
| | | |
| | | - (void)beginRefreshingWithCompletionBlock:(void (^)(void))completionBlock |
| | | { |
| | | self.beginRefreshingCompletionBlock = completionBlock; |
| | | |
| | | [self beginRefreshing]; |
| | | } |
| | | |
| | | #pragma mark 结束刷新状态 |
| | | - (void)endRefreshing |
| | | { |
| | | MJRefreshDispatchAsyncOnMainQueue(self.state = MJRefreshStateIdle;) |
| | | } |
| | | |
| | | - (void)endRefreshingWithCompletionBlock:(void (^)(void))completionBlock |
| | | { |
| | | self.endRefreshingCompletionBlock = completionBlock; |
| | | |
| | | [self endRefreshing]; |
| | | } |
| | | |
| | | #pragma mark 是否正在刷新 |
| | | - (BOOL)isRefreshing |
| | | { |
| | | return self.state == MJRefreshStateRefreshing || self.state == MJRefreshStateWillRefresh; |
| | | } |
| | | |
| | | #pragma mark 自动切换透明度 |
| | | - (void)setAutoChangeAlpha:(BOOL)autoChangeAlpha |
| | | { |
| | | self.automaticallyChangeAlpha = autoChangeAlpha; |
| | | } |
| | | |
| | | - (BOOL)isAutoChangeAlpha |
| | | { |
| | | return self.isAutomaticallyChangeAlpha; |
| | | } |
| | | |
| | | - (void)setAutomaticallyChangeAlpha:(BOOL)automaticallyChangeAlpha |
| | | { |
| | | _automaticallyChangeAlpha = automaticallyChangeAlpha; |
| | | |
| | | if (self.isRefreshing) return; |
| | | |
| | | if (automaticallyChangeAlpha) { |
| | | self.alpha = self.pullingPercent; |
| | | } else { |
| | | self.alpha = 1.0; |
| | | } |
| | | } |
| | | |
| | | #pragma mark 根据拖拽进度设置透明度 |
| | | - (void)setPullingPercent:(CGFloat)pullingPercent |
| | | { |
| | | _pullingPercent = pullingPercent; |
| | | |
| | | if (self.isRefreshing) return; |
| | | |
| | | if (self.isAutomaticallyChangeAlpha) { |
| | | self.alpha = pullingPercent; |
| | | } |
| | | } |
| | | |
| | | #pragma mark - 内部方法 |
| | | - (void)executeRefreshingCallback |
| | | { |
| | | MJRefreshDispatchAsyncOnMainQueue({ |
| | | if (self.refreshingBlock) { |
| | | self.refreshingBlock(); |
| | | } |
| | | if ([self.refreshingTarget respondsToSelector:self.refreshingAction]) { |
| | | MJRefreshMsgSend(MJRefreshMsgTarget(self.refreshingTarget), self.refreshingAction, self); |
| | | } |
| | | if (self.beginRefreshingCompletionBlock) { |
| | | self.beginRefreshingCompletionBlock(); |
| | | } |
| | | }) |
| | | } |
| | | |
| | | #pragma mark - <<< Deprecation compatible function >>> - |
| | | - (void)setEndRefreshingAnimateCompletionBlock:(MJRefreshComponentEndRefreshingCompletionBlock)endRefreshingAnimateCompletionBlock { |
| | | _endRefreshingAnimationBeginAction = endRefreshingAnimateCompletionBlock; |
| | | } |
| | | @end |
| | | |
| | | @implementation UILabel(MJRefresh) |
| | | + (instancetype)mj_label |
| | | { |
| | | UILabel *label = [[self alloc] init]; |
| | | label.font = MJRefreshLabelFont; |
| | | label.textColor = MJRefreshLabelTextColor; |
| | | label.autoresizingMask = UIViewAutoresizingFlexibleWidth; |
| | | label.textAlignment = NSTextAlignmentCenter; |
| | | label.backgroundColor = [UIColor clearColor]; |
| | | return label; |
| | | } |
| | | |
| | | - (CGFloat)mj_textWidth { |
| | | CGFloat stringWidth = 0; |
| | | CGSize size = CGSizeMake(MAXFLOAT, MAXFLOAT); |
| | | |
| | | if (self.attributedText) { |
| | | if (self.attributedText.length == 0) { return 0; } |
| | | stringWidth = [self.attributedText boundingRectWithSize:size |
| | | options:NSStringDrawingUsesLineFragmentOrigin |
| | | context:nil].size.width; |
| | | } else { |
| | | if (self.text.length == 0) { return 0; } |
| | | NSAssert(self.font != nil, @"请检查 mj_label's `font` 是否设置正确"); |
| | | stringWidth = [self.text boundingRectWithSize:size |
| | | options:NSStringDrawingUsesLineFragmentOrigin |
| | | attributes:@{NSFontAttributeName:self.font} |
| | | context:nil].size.width; |
| | | } |
| | | return stringWidth; |
| | | } |
| | | @end |
New file |
| | |
| | | // 代码地址: https://github.com/CoderMJLee/MJRefresh |
| | | // 代码地址: http://code4app.com/ios/%E5%BF%AB%E9%80%9F%E9%9B%86%E6%88%90%E4%B8%8B%E6%8B%89%E4%B8%8A%E6%8B%89%E5%88%B7%E6%96%B0/52326ce26803fabc46000000 |
| | | // MJRefreshFooter.h |
| | | // MJRefreshExample |
| | | // |
| | | // Created by MJ Lee on 15/3/5. |
| | | // Copyright (c) 2015年 小码哥. All rights reserved. |
| | | // 上拉刷新控件 |
| | | |
| | | #import "MJRefreshComponent.h" |
| | | |
| | | NS_ASSUME_NONNULL_BEGIN |
| | | |
| | | @interface MJRefreshFooter : MJRefreshComponent |
| | | /** 创建footer */ |
| | | + (instancetype)footerWithRefreshingBlock:(MJRefreshComponentAction)refreshingBlock; |
| | | /** 创建footer */ |
| | | + (instancetype)footerWithRefreshingTarget:(id)target refreshingAction:(SEL)action; |
| | | |
| | | /** 提示没有更多的数据 */ |
| | | - (void)endRefreshingWithNoMoreData; |
| | | - (void)noticeNoMoreData MJRefreshDeprecated("使用endRefreshingWithNoMoreData"); |
| | | |
| | | /** 重置没有更多的数据(消除没有更多数据的状态) */ |
| | | - (void)resetNoMoreData; |
| | | |
| | | /** 忽略多少scrollView的contentInset的bottom */ |
| | | @property (assign, nonatomic) CGFloat ignoredScrollViewContentInsetBottom; |
| | | |
| | | /** 自动根据有无数据来显示和隐藏(有数据就显示,没有数据隐藏。默认是NO) */ |
| | | @property (assign, nonatomic, getter=isAutomaticallyHidden) BOOL automaticallyHidden MJRefreshDeprecated("已废弃此属性,开发者请自行控制footer的显示和隐藏"); |
| | | @end |
| | | |
| | | NS_ASSUME_NONNULL_END |
New file |
| | |
| | | // 代码地址: https://github.com/CoderMJLee/MJRefresh |
| | | // 代码地址: http://code4app.com/ios/%E5%BF%AB%E9%80%9F%E9%9B%86%E6%88%90%E4%B8%8B%E6%8B%89%E4%B8%8A%E6%8B%89%E5%88%B7%E6%96%B0/52326ce26803fabc46000000 |
| | | // MJRefreshFooter.m |
| | | // MJRefreshExample |
| | | // |
| | | // Created by MJ Lee on 15/3/5. |
| | | // Copyright (c) 2015年 小码哥. All rights reserved. |
| | | // |
| | | |
| | | #import "MJRefreshFooter.h" |
| | | #include "UIScrollView+MJRefresh.h" |
| | | |
| | | @interface MJRefreshFooter() |
| | | |
| | | @end |
| | | |
| | | @implementation MJRefreshFooter |
| | | #pragma mark - 构造方法 |
| | | + (instancetype)footerWithRefreshingBlock:(MJRefreshComponentAction)refreshingBlock |
| | | { |
| | | MJRefreshFooter *cmp = [[self alloc] init]; |
| | | cmp.refreshingBlock = refreshingBlock; |
| | | return cmp; |
| | | } |
| | | + (instancetype)footerWithRefreshingTarget:(id)target refreshingAction:(SEL)action |
| | | { |
| | | MJRefreshFooter *cmp = [[self alloc] init]; |
| | | [cmp setRefreshingTarget:target refreshingAction:action]; |
| | | return cmp; |
| | | } |
| | | |
| | | #pragma mark - 重写父类的方法 |
| | | - (void)prepare |
| | | { |
| | | [super prepare]; |
| | | |
| | | // 设置自己的高度 |
| | | self.mj_h = MJRefreshFooterHeight; |
| | | |
| | | // 默认不会自动隐藏 |
| | | // self.automaticallyHidden = NO; |
| | | } |
| | | |
| | | #pragma mark - 公共方法 |
| | | - (void)endRefreshingWithNoMoreData |
| | | { |
| | | MJRefreshDispatchAsyncOnMainQueue(self.state = MJRefreshStateNoMoreData;) |
| | | } |
| | | |
| | | - (void)noticeNoMoreData |
| | | { |
| | | [self endRefreshingWithNoMoreData]; |
| | | } |
| | | |
| | | - (void)resetNoMoreData |
| | | { |
| | | MJRefreshDispatchAsyncOnMainQueue(self.state = MJRefreshStateIdle;) |
| | | } |
| | | |
| | | - (void)setAutomaticallyHidden:(BOOL)automaticallyHidden |
| | | { |
| | | _automaticallyHidden = automaticallyHidden; |
| | | } |
| | | @end |
New file |
| | |
| | | // 代码地址: https://github.com/CoderMJLee/MJRefresh |
| | | // 代码地址: http://code4app.com/ios/%E5%BF%AB%E9%80%9F%E9%9B%86%E6%88%90%E4%B8%8B%E6%8B%89%E4%B8%8A%E6%8B%89%E5%88%B7%E6%96%B0/52326ce26803fabc46000000 |
| | | // MJRefreshHeader.h |
| | | // MJRefreshExample |
| | | // |
| | | // Created by MJ Lee on 15/3/4. |
| | | // Copyright (c) 2015年 小码哥. All rights reserved. |
| | | // 下拉刷新控件:负责监控用户下拉的状态 |
| | | |
| | | #import "MJRefreshComponent.h" |
| | | |
| | | NS_ASSUME_NONNULL_BEGIN |
| | | |
| | | @interface MJRefreshHeader : MJRefreshComponent |
| | | /** 创建header */ |
| | | + (instancetype)headerWithRefreshingBlock:(MJRefreshComponentAction)refreshingBlock; |
| | | /** 创建header */ |
| | | + (instancetype)headerWithRefreshingTarget:(id)target refreshingAction:(SEL)action; |
| | | |
| | | /** 这个key用来存储上一次下拉刷新成功的时间 */ |
| | | @property (copy, nonatomic) NSString *lastUpdatedTimeKey; |
| | | /** 上一次下拉刷新成功的时间 */ |
| | | @property (strong, nonatomic, readonly, nullable) NSDate *lastUpdatedTime; |
| | | |
| | | /** 忽略多少scrollView的contentInset的top */ |
| | | @property (assign, nonatomic) CGFloat ignoredScrollViewContentInsetTop; |
| | | |
| | | /** 默认是关闭状态, 如果遇到 CollectionView 的动画异常问题可以尝试打开 */ |
| | | @property (nonatomic) BOOL isCollectionViewAnimationBug; |
| | | @end |
| | | |
| | | NS_ASSUME_NONNULL_END |
New file |
| | |
| | | // 代码地址: https://github.com/CoderMJLee/MJRefresh |
| | | // 代码地址: http://code4app.com/ios/%E5%BF%AB%E9%80%9F%E9%9B%86%E6%88%90%E4%B8%8B%E6%8B%89%E4%B8%8A%E6%8B%89%E5%88%B7%E6%96%B0/52326ce26803fabc46000000 |
| | | // MJRefreshHeader.m |
| | | // MJRefreshExample |
| | | // |
| | | // Created by MJ Lee on 15/3/4. |
| | | // Copyright (c) 2015年 小码哥. All rights reserved. |
| | | // |
| | | |
| | | #import "MJRefreshHeader.h" |
| | | |
| | | NSString * const MJRefreshHeaderRefreshing2IdleBoundsKey = @"MJRefreshHeaderRefreshing2IdleBounds"; |
| | | NSString * const MJRefreshHeaderRefreshingBoundsKey = @"MJRefreshHeaderRefreshingBounds"; |
| | | |
| | | @interface MJRefreshHeader() <CAAnimationDelegate> |
| | | @property (assign, nonatomic) CGFloat insetTDelta; |
| | | @end |
| | | |
| | | @implementation MJRefreshHeader |
| | | #pragma mark - 构造方法 |
| | | + (instancetype)headerWithRefreshingBlock:(MJRefreshComponentAction)refreshingBlock |
| | | { |
| | | MJRefreshHeader *cmp = [[self alloc] init]; |
| | | cmp.refreshingBlock = refreshingBlock; |
| | | return cmp; |
| | | } |
| | | + (instancetype)headerWithRefreshingTarget:(id)target refreshingAction:(SEL)action |
| | | { |
| | | MJRefreshHeader *cmp = [[self alloc] init]; |
| | | [cmp setRefreshingTarget:target refreshingAction:action]; |
| | | return cmp; |
| | | } |
| | | |
| | | #pragma mark - 覆盖父类的方法 |
| | | - (void)prepare |
| | | { |
| | | [super prepare]; |
| | | |
| | | // 设置key |
| | | self.lastUpdatedTimeKey = MJRefreshHeaderLastUpdatedTimeKey; |
| | | |
| | | // 设置高度 |
| | | self.mj_h = MJRefreshHeaderHeight; |
| | | } |
| | | |
| | | - (void)placeSubviews |
| | | { |
| | | [super placeSubviews]; |
| | | |
| | | // 设置y值(当自己的高度发生改变了,肯定要重新调整Y值,所以放到placeSubviews方法中设置y值) |
| | | self.mj_y = - self.mj_h - self.ignoredScrollViewContentInsetTop; |
| | | } |
| | | |
| | | - (void)resetInset { |
| | | if (@available(iOS 11.0, *)) { |
| | | } else { |
| | | // 如果 iOS 10 及以下系统在刷新时, push 新的 VC, 等待刷新完成后回来, 会导致顶部 Insets.top 异常, 不能 resetInset, 检查一下这种特殊情况 |
| | | if (!self.window) { return; } |
| | | } |
| | | |
| | | // sectionheader停留解决 |
| | | CGFloat insetT = - self.scrollView.mj_offsetY > _scrollViewOriginalInset.top ? - self.scrollView.mj_offsetY : _scrollViewOriginalInset.top; |
| | | insetT = insetT > self.mj_h + _scrollViewOriginalInset.top ? self.mj_h + _scrollViewOriginalInset.top : insetT; |
| | | self.insetTDelta = _scrollViewOriginalInset.top - insetT; |
| | | // 避免 CollectionView 在使用根据 Autolayout 和 内容自动伸缩 Cell, 刷新时导致的 Layout 异常渲染问题 |
| | | if (self.scrollView.mj_insetT != insetT) { |
| | | self.scrollView.mj_insetT = insetT; |
| | | } |
| | | } |
| | | |
| | | - (void)scrollViewContentOffsetDidChange:(NSDictionary *)change |
| | | { |
| | | [super scrollViewContentOffsetDidChange:change]; |
| | | |
| | | // 在刷新的refreshing状态 |
| | | if (self.state == MJRefreshStateRefreshing) { |
| | | [self resetInset]; |
| | | return; |
| | | } |
| | | |
| | | // 跳转到下一个控制器时,contentInset可能会变 |
| | | _scrollViewOriginalInset = self.scrollView.mj_inset; |
| | | |
| | | // 当前的contentOffset |
| | | CGFloat offsetY = self.scrollView.mj_offsetY; |
| | | // 头部控件刚好出现的offsetY |
| | | CGFloat happenOffsetY = - self.scrollViewOriginalInset.top; |
| | | |
| | | // 如果是向上滚动到看不见头部控件,直接返回 |
| | | // >= -> > |
| | | if (offsetY > happenOffsetY) return; |
| | | |
| | | // 普通 和 即将刷新 的临界点 |
| | | CGFloat normal2pullingOffsetY = happenOffsetY - self.mj_h; |
| | | CGFloat pullingPercent = (happenOffsetY - offsetY) / self.mj_h; |
| | | |
| | | if (self.scrollView.isDragging) { // 如果正在拖拽 |
| | | self.pullingPercent = pullingPercent; |
| | | if (self.state == MJRefreshStateIdle && offsetY < normal2pullingOffsetY) { |
| | | // 转为即将刷新状态 |
| | | self.state = MJRefreshStatePulling; |
| | | } else if (self.state == MJRefreshStatePulling && offsetY >= normal2pullingOffsetY) { |
| | | // 转为普通状态 |
| | | self.state = MJRefreshStateIdle; |
| | | } |
| | | } else if (self.state == MJRefreshStatePulling) {// 即将刷新 && 手松开 |
| | | // 开始刷新 |
| | | [self beginRefreshing]; |
| | | } else if (pullingPercent < 1) { |
| | | self.pullingPercent = pullingPercent; |
| | | } |
| | | } |
| | | |
| | | - (void)setState:(MJRefreshState)state |
| | | { |
| | | MJRefreshCheckState |
| | | |
| | | // 根据状态做事情 |
| | | if (state == MJRefreshStateIdle) { |
| | | if (oldState != MJRefreshStateRefreshing) return; |
| | | |
| | | [self headerEndingAction]; |
| | | } else if (state == MJRefreshStateRefreshing) { |
| | | [self headerRefreshingAction]; |
| | | } |
| | | } |
| | | |
| | | - (void)headerEndingAction { |
| | | // 保存刷新时间 |
| | | [[NSUserDefaults standardUserDefaults] setObject:[NSDate date] forKey:self.lastUpdatedTimeKey]; |
| | | [[NSUserDefaults standardUserDefaults] synchronize]; |
| | | |
| | | // 默认使用 UIViewAnimation 动画 |
| | | if (!self.isCollectionViewAnimationBug) { |
| | | // 恢复inset和offset |
| | | [UIView animateWithDuration:MJRefreshSlowAnimationDuration animations:^{ |
| | | self.scrollView.mj_insetT += self.insetTDelta; |
| | | |
| | | if (self.endRefreshingAnimationBeginAction) { |
| | | self.endRefreshingAnimationBeginAction(); |
| | | } |
| | | // 自动调整透明度 |
| | | if (self.isAutomaticallyChangeAlpha) self.alpha = 0.0; |
| | | } completion:^(BOOL finished) { |
| | | self.pullingPercent = 0.0; |
| | | |
| | | if (self.endRefreshingCompletionBlock) { |
| | | self.endRefreshingCompletionBlock(); |
| | | } |
| | | }]; |
| | | |
| | | return; |
| | | } |
| | | |
| | | /** |
| | | 这个解决方法的思路出自 https://github.com/CoderMJLee/MJRefresh/pull/844 |
| | | 修改了用+ [UIView animateWithDuration: animations:]实现的修改contentInset的动画 |
| | | fix issue#225 https://github.com/CoderMJLee/MJRefresh/issues/225 |
| | | 另一种解法 pull#737 https://github.com/CoderMJLee/MJRefresh/pull/737 |
| | | |
| | | 同时, 处理了 Refreshing 中的动画替换. |
| | | */ |
| | | |
| | | // 由于修改 Inset 会导致 self.pullingPercent 联动设置 self.alpha, 故提前获取 alpha 值, 后续用于还原 alpha 动画 |
| | | CGFloat viewAlpha = self.alpha; |
| | | |
| | | self.scrollView.mj_insetT += self.insetTDelta; |
| | | // 禁用交互, 如果不禁用可能会引起渲染问题. |
| | | self.scrollView.userInteractionEnabled = NO; |
| | | |
| | | //CAAnimation keyPath 不支持 contentInset 用Bounds的动画代替 |
| | | CABasicAnimation *boundsAnimation = [CABasicAnimation animationWithKeyPath:@"bounds"]; |
| | | boundsAnimation.fromValue = [NSValue valueWithCGRect:CGRectOffset(self.scrollView.bounds, 0, self.insetTDelta)]; |
| | | boundsAnimation.duration = MJRefreshSlowAnimationDuration; |
| | | //在delegate里移除 |
| | | boundsAnimation.removedOnCompletion = NO; |
| | | boundsAnimation.fillMode = kCAFillModeBoth; |
| | | boundsAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; |
| | | boundsAnimation.delegate = self; |
| | | [boundsAnimation setValue:MJRefreshHeaderRefreshing2IdleBoundsKey forKey:@"identity"]; |
| | | |
| | | [self.scrollView.layer addAnimation:boundsAnimation forKey:MJRefreshHeaderRefreshing2IdleBoundsKey]; |
| | | |
| | | if (self.endRefreshingAnimationBeginAction) { |
| | | self.endRefreshingAnimationBeginAction(); |
| | | } |
| | | // 自动调整透明度的动画 |
| | | if (self.isAutomaticallyChangeAlpha) { |
| | | CABasicAnimation *opacityAnimation = [CABasicAnimation animationWithKeyPath:@"opacity"]; |
| | | opacityAnimation.fromValue = @(viewAlpha); |
| | | opacityAnimation.toValue = @(0.0); |
| | | opacityAnimation.duration = MJRefreshSlowAnimationDuration; |
| | | opacityAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; |
| | | [self.layer addAnimation:opacityAnimation forKey:@"MJRefreshHeaderRefreshing2IdleOpacity"]; |
| | | |
| | | // 由于修改了 inset 导致, pullingPercent 被设置值, alpha 已经被提前修改为 0 了. 所以这里不用置 0, 但为了代码的严谨性, 不依赖其他的特殊实现方式, 这里还是置 0. |
| | | self.alpha = 0; |
| | | } |
| | | } |
| | | |
| | | - (void)headerRefreshingAction { |
| | | // 默认使用 UIViewAnimation 动画 |
| | | if (!self.isCollectionViewAnimationBug) { |
| | | MJRefreshDispatchAsyncOnMainQueue({ |
| | | [UIView animateWithDuration:MJRefreshFastAnimationDuration animations:^{ |
| | | if (self.scrollView.panGestureRecognizer.state != UIGestureRecognizerStateCancelled) { |
| | | CGFloat top = self.scrollViewOriginalInset.top + self.mj_h; |
| | | // 增加滚动区域top |
| | | self.scrollView.mj_insetT = top; |
| | | // 设置滚动位置 |
| | | CGPoint offset = self.scrollView.contentOffset; |
| | | offset.y = -top; |
| | | [self.scrollView setContentOffset:offset animated:NO]; |
| | | } |
| | | } completion:^(BOOL finished) { |
| | | [self executeRefreshingCallback]; |
| | | }]; |
| | | }) |
| | | return; |
| | | } |
| | | |
| | | if (self.scrollView.panGestureRecognizer.state != UIGestureRecognizerStateCancelled) { |
| | | CGFloat top = self.scrollViewOriginalInset.top + self.mj_h; |
| | | // 禁用交互, 如果不禁用可能会引起渲染问题. |
| | | self.scrollView.userInteractionEnabled = NO; |
| | | |
| | | // CAAnimation keyPath不支持 contentOffset 用Bounds的动画代替 |
| | | CABasicAnimation *boundsAnimation = [CABasicAnimation animationWithKeyPath:@"bounds"]; |
| | | CGRect bounds = self.scrollView.bounds; |
| | | bounds.origin.y = -top; |
| | | boundsAnimation.fromValue = [NSValue valueWithCGRect:self.scrollView.bounds]; |
| | | boundsAnimation.toValue = [NSValue valueWithCGRect:bounds]; |
| | | boundsAnimation.duration = MJRefreshFastAnimationDuration; |
| | | //在delegate里移除 |
| | | boundsAnimation.removedOnCompletion = NO; |
| | | boundsAnimation.fillMode = kCAFillModeBoth; |
| | | boundsAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; |
| | | boundsAnimation.delegate = self; |
| | | [boundsAnimation setValue:MJRefreshHeaderRefreshingBoundsKey forKey:@"identity"]; |
| | | [self.scrollView.layer addAnimation:boundsAnimation forKey:MJRefreshHeaderRefreshingBoundsKey]; |
| | | } else { |
| | | [self executeRefreshingCallback]; |
| | | } |
| | | } |
| | | |
| | | #pragma mark - CAAnimationDelegate |
| | | - (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag { |
| | | NSString *identity = [anim valueForKey:@"identity"]; |
| | | if ([identity isEqualToString:MJRefreshHeaderRefreshing2IdleBoundsKey]) { |
| | | self.pullingPercent = 0.0; |
| | | self.scrollView.userInteractionEnabled = YES; |
| | | if (self.endRefreshingCompletionBlock) { |
| | | self.endRefreshingCompletionBlock(); |
| | | } |
| | | } else if ([identity isEqualToString:MJRefreshHeaderRefreshingBoundsKey]) { |
| | | // 避免出现 end 先于 Refreshing 状态 |
| | | if (self.state != MJRefreshStateIdle) { |
| | | CGFloat top = self.scrollViewOriginalInset.top + self.mj_h; |
| | | self.scrollView.mj_insetT = top; |
| | | // 设置最终滚动位置 |
| | | CGPoint offset = self.scrollView.contentOffset; |
| | | offset.y = -top; |
| | | [self.scrollView setContentOffset:offset animated:NO]; |
| | | } |
| | | self.scrollView.userInteractionEnabled = YES; |
| | | [self executeRefreshingCallback]; |
| | | } |
| | | |
| | | if ([self.scrollView.layer animationForKey:MJRefreshHeaderRefreshing2IdleBoundsKey]) { |
| | | [self.scrollView.layer removeAnimationForKey:MJRefreshHeaderRefreshing2IdleBoundsKey]; |
| | | } |
| | | |
| | | if ([self.scrollView.layer animationForKey:MJRefreshHeaderRefreshingBoundsKey]) { |
| | | [self.scrollView.layer removeAnimationForKey:MJRefreshHeaderRefreshingBoundsKey]; |
| | | } |
| | | } |
| | | |
| | | #pragma mark - 公共方法 |
| | | - (NSDate *)lastUpdatedTime |
| | | { |
| | | return [[NSUserDefaults standardUserDefaults] objectForKey:self.lastUpdatedTimeKey]; |
| | | } |
| | | |
| | | - (void)setIgnoredScrollViewContentInsetTop:(CGFloat)ignoredScrollViewContentInsetTop { |
| | | _ignoredScrollViewContentInsetTop = ignoredScrollViewContentInsetTop; |
| | | |
| | | self.mj_y = - self.mj_h - _ignoredScrollViewContentInsetTop; |
| | | } |
| | | |
| | | @end |
New file |
| | |
| | | // |
| | | // MJRefreshTrailer.h |
| | | // MJRefresh |
| | | // |
| | | // Created by kinarobin on 2020/5/3. |
| | | // Copyright © 2020 小码哥. All rights reserved. |
| | | // |
| | | |
| | | #import "MJRefreshComponent.h" |
| | | |
| | | NS_ASSUME_NONNULL_BEGIN |
| | | |
| | | @interface MJRefreshTrailer : MJRefreshComponent |
| | | |
| | | /** 创建trailer*/ |
| | | + (instancetype)trailerWithRefreshingBlock:(MJRefreshComponentAction)refreshingBlock; |
| | | /** 创建trailer */ |
| | | + (instancetype)trailerWithRefreshingTarget:(id)target refreshingAction:(SEL)action; |
| | | |
| | | /** 忽略多少scrollView的contentInset的right */ |
| | | @property (assign, nonatomic) CGFloat ignoredScrollViewContentInsetRight; |
| | | |
| | | |
| | | @end |
| | | |
| | | NS_ASSUME_NONNULL_END |
New file |
| | |
| | | // |
| | | // MJRefreshTrailer.m |
| | | // MJRefresh |
| | | // |
| | | // Created by kinarobin on 2020/5/3. |
| | | // Copyright © 2020 小码哥. All rights reserved. |
| | | // |
| | | |
| | | #import "MJRefreshTrailer.h" |
| | | |
| | | @interface MJRefreshTrailer() |
| | | @property (assign, nonatomic) NSInteger lastRefreshCount; |
| | | @property (assign, nonatomic) CGFloat lastRightDelta; |
| | | @end |
| | | |
| | | @implementation MJRefreshTrailer |
| | | |
| | | #pragma mark - 构造方法 |
| | | + (instancetype)trailerWithRefreshingBlock:(MJRefreshComponentAction)refreshingBlock { |
| | | MJRefreshTrailer *cmp = [[self alloc] init]; |
| | | cmp.refreshingBlock = refreshingBlock; |
| | | return cmp; |
| | | } |
| | | |
| | | + (instancetype)trailerWithRefreshingTarget:(id)target refreshingAction:(SEL)action { |
| | | MJRefreshTrailer *cmp = [[self alloc] init]; |
| | | [cmp setRefreshingTarget:target refreshingAction:action]; |
| | | return cmp; |
| | | } |
| | | |
| | | - (void)scrollViewContentOffsetDidChange:(NSDictionary *)change { |
| | | [super scrollViewContentOffsetDidChange:change]; |
| | | |
| | | // 如果正在刷新,直接返回 |
| | | if (self.state == MJRefreshStateRefreshing) return; |
| | | |
| | | _scrollViewOriginalInset = self.scrollView.mj_inset; |
| | | |
| | | // 当前的contentOffset |
| | | CGFloat currentOffsetX = self.scrollView.mj_offsetX; |
| | | // 尾部控件刚好出现的offsetX |
| | | CGFloat happenOffsetX = [self happenOffsetX]; |
| | | // 如果是向右滚动到看不见右边控件,直接返回 |
| | | if (currentOffsetX <= happenOffsetX) return; |
| | | |
| | | CGFloat pullingPercent = (currentOffsetX - happenOffsetX) / self.mj_w; |
| | | |
| | | // 如果已全部加载,仅设置pullingPercent,然后返回 |
| | | if (self.state == MJRefreshStateNoMoreData) { |
| | | self.pullingPercent = pullingPercent; |
| | | return; |
| | | } |
| | | |
| | | if (self.scrollView.isDragging) { |
| | | self.pullingPercent = pullingPercent; |
| | | // 普通 和 即将刷新 的临界点 |
| | | CGFloat normal2pullingOffsetX = happenOffsetX + self.mj_w; |
| | | |
| | | if (self.state == MJRefreshStateIdle && currentOffsetX > normal2pullingOffsetX) { |
| | | self.state = MJRefreshStatePulling; |
| | | } else if (self.state == MJRefreshStatePulling && currentOffsetX <= normal2pullingOffsetX) { |
| | | // 转为普通状态 |
| | | self.state = MJRefreshStateIdle; |
| | | } |
| | | } else if (self.state == MJRefreshStatePulling) {// 即将刷新 && 手松开 |
| | | // 开始刷新 |
| | | [self beginRefreshing]; |
| | | } else if (pullingPercent < 1) { |
| | | self.pullingPercent = pullingPercent; |
| | | } |
| | | } |
| | | |
| | | - (void)setState:(MJRefreshState)state { |
| | | MJRefreshCheckState |
| | | // 根据状态来设置属性 |
| | | if (state == MJRefreshStateNoMoreData || state == MJRefreshStateIdle) { |
| | | // 刷新完毕 |
| | | if (MJRefreshStateRefreshing == oldState) { |
| | | [UIView animateWithDuration:MJRefreshSlowAnimationDuration animations:^{ |
| | | if (self.endRefreshingAnimationBeginAction) { |
| | | self.endRefreshingAnimationBeginAction(); |
| | | } |
| | | |
| | | self.scrollView.mj_insetR -= self.lastRightDelta; |
| | | // 自动调整透明度 |
| | | if (self.isAutomaticallyChangeAlpha) self.alpha = 0.0; |
| | | } completion:^(BOOL finished) { |
| | | self.pullingPercent = 0.0; |
| | | |
| | | if (self.endRefreshingCompletionBlock) { |
| | | self.endRefreshingCompletionBlock(); |
| | | } |
| | | }]; |
| | | } |
| | | |
| | | CGFloat deltaW = [self widthForContentBreakView]; |
| | | // 刚刷新完毕 |
| | | if (MJRefreshStateRefreshing == oldState && deltaW > 0 && self.scrollView.mj_totalDataCount != self.lastRefreshCount) { |
| | | self.scrollView.mj_offsetX = self.scrollView.mj_offsetX; |
| | | } |
| | | } else if (state == MJRefreshStateRefreshing) { |
| | | // 记录刷新前的数量 |
| | | self.lastRefreshCount = self.scrollView.mj_totalDataCount; |
| | | |
| | | [UIView animateWithDuration:MJRefreshFastAnimationDuration animations:^{ |
| | | CGFloat right = self.mj_w + self.scrollViewOriginalInset.right; |
| | | CGFloat deltaW = [self widthForContentBreakView]; |
| | | if (deltaW < 0) { // 如果内容宽度小于view的宽度 |
| | | right -= deltaW; |
| | | } |
| | | self.lastRightDelta = right - self.scrollView.mj_insetR; |
| | | self.scrollView.mj_insetR = right; |
| | | |
| | | // 设置滚动位置 |
| | | CGPoint offset = self.scrollView.contentOffset; |
| | | offset.x = [self happenOffsetX] + self.mj_w; |
| | | [self.scrollView setContentOffset:offset animated:NO]; |
| | | } completion:^(BOOL finished) { |
| | | [self executeRefreshingCallback]; |
| | | }]; |
| | | } |
| | | } |
| | | |
| | | - (void)scrollViewContentSizeDidChange:(NSDictionary *)change { |
| | | [super scrollViewContentSizeDidChange:change]; |
| | | |
| | | // 内容的宽度 |
| | | CGFloat contentWidth = self.scrollView.mj_contentW + self.ignoredScrollViewContentInsetRight; |
| | | // 表格的宽度 |
| | | CGFloat scrollWidth = self.scrollView.mj_w - self.scrollViewOriginalInset.left - self.scrollViewOriginalInset.right + self.ignoredScrollViewContentInsetRight; |
| | | // 设置位置和尺寸 |
| | | self.mj_x = MAX(contentWidth, scrollWidth); |
| | | } |
| | | |
| | | - (void)placeSubviews { |
| | | [super placeSubviews]; |
| | | |
| | | self.mj_h = _scrollView.mj_h; |
| | | // 设置自己的宽度 |
| | | self.mj_w = MJRefreshTrailWidth; |
| | | } |
| | | |
| | | - (void)willMoveToSuperview:(UIView *)newSuperview { |
| | | [super willMoveToSuperview:newSuperview]; |
| | | |
| | | if (newSuperview) { |
| | | // 设置支持水平弹簧效果 |
| | | _scrollView.alwaysBounceHorizontal = YES; |
| | | _scrollView.alwaysBounceVertical = NO; |
| | | } |
| | | } |
| | | |
| | | #pragma mark 刚好看到上拉刷新控件时的contentOffset.x |
| | | - (CGFloat)happenOffsetX { |
| | | CGFloat deltaW = [self widthForContentBreakView]; |
| | | if (deltaW > 0) { |
| | | return deltaW - self.scrollViewOriginalInset.left; |
| | | } else { |
| | | return - self.scrollViewOriginalInset.left; |
| | | } |
| | | } |
| | | |
| | | #pragma mark 获得scrollView的内容 超出 view 的宽度 |
| | | - (CGFloat)widthForContentBreakView { |
| | | CGFloat w = self.scrollView.frame.size.width - self.scrollViewOriginalInset.right - self.scrollViewOriginalInset.left; |
| | | return self.scrollView.contentSize.width - w; |
| | | } |
| | | |
| | | @end |
New file |
| | |
| | | // |
| | | // MJRefreshAutoGifFooter.h |
| | | // MJRefreshExample |
| | | // |
| | | // Created by MJ Lee on 15/4/24. |
| | | // Copyright (c) 2015年 小码哥. All rights reserved. |
| | | // |
| | | |
| | | #import "MJRefreshAutoStateFooter.h" |
| | | |
| | | NS_ASSUME_NONNULL_BEGIN |
| | | |
| | | @interface MJRefreshAutoGifFooter : MJRefreshAutoStateFooter |
| | | @property (weak, nonatomic, readonly) UIImageView *gifView; |
| | | |
| | | /** 设置state状态下的动画图片images 动画持续时间duration*/ |
| | | - (void)setImages:(NSArray *)images duration:(NSTimeInterval)duration forState:(MJRefreshState)state; |
| | | - (void)setImages:(NSArray *)images forState:(MJRefreshState)state; |
| | | @end |
| | | |
| | | NS_ASSUME_NONNULL_END |
New file |
| | |
| | | // |
| | | // MJRefreshAutoGifFooter.m |
| | | // MJRefreshExample |
| | | // |
| | | // Created by MJ Lee on 15/4/24. |
| | | // Copyright (c) 2015年 小码哥. All rights reserved. |
| | | // |
| | | |
| | | #import "MJRefreshAutoGifFooter.h" |
| | | |
| | | @interface MJRefreshAutoGifFooter() |
| | | { |
| | | __unsafe_unretained UIImageView *_gifView; |
| | | } |
| | | /** 所有状态对应的动画图片 */ |
| | | @property (strong, nonatomic) NSMutableDictionary *stateImages; |
| | | /** 所有状态对应的动画时间 */ |
| | | @property (strong, nonatomic) NSMutableDictionary *stateDurations; |
| | | @end |
| | | |
| | | @implementation MJRefreshAutoGifFooter |
| | | #pragma mark - 懒加载 |
| | | - (UIImageView *)gifView |
| | | { |
| | | if (!_gifView) { |
| | | UIImageView *gifView = [[UIImageView alloc] init]; |
| | | [self addSubview:_gifView = gifView]; |
| | | } |
| | | return _gifView; |
| | | } |
| | | |
| | | - (NSMutableDictionary *)stateImages |
| | | { |
| | | if (!_stateImages) { |
| | | self.stateImages = [NSMutableDictionary dictionary]; |
| | | } |
| | | return _stateImages; |
| | | } |
| | | |
| | | - (NSMutableDictionary *)stateDurations |
| | | { |
| | | if (!_stateDurations) { |
| | | self.stateDurations = [NSMutableDictionary dictionary]; |
| | | } |
| | | return _stateDurations; |
| | | } |
| | | |
| | | #pragma mark - 公共方法 |
| | | - (void)setImages:(NSArray *)images duration:(NSTimeInterval)duration forState:(MJRefreshState)state |
| | | { |
| | | if (images == nil) return; |
| | | |
| | | self.stateImages[@(state)] = images; |
| | | self.stateDurations[@(state)] = @(duration); |
| | | |
| | | /* 根据图片设置控件的高度 */ |
| | | UIImage *image = [images firstObject]; |
| | | if (image.size.height > self.mj_h) { |
| | | self.mj_h = image.size.height; |
| | | } |
| | | } |
| | | |
| | | - (void)setImages:(NSArray *)images forState:(MJRefreshState)state |
| | | { |
| | | [self setImages:images duration:images.count * 0.1 forState:state]; |
| | | } |
| | | |
| | | #pragma mark - 实现父类的方法 |
| | | - (void)prepare |
| | | { |
| | | [super prepare]; |
| | | |
| | | // 初始化间距 |
| | | self.labelLeftInset = 20; |
| | | } |
| | | |
| | | - (void)placeSubviews |
| | | { |
| | | [super placeSubviews]; |
| | | |
| | | if (self.gifView.constraints.count) return; |
| | | |
| | | self.gifView.frame = self.bounds; |
| | | if (self.isRefreshingTitleHidden) { |
| | | self.gifView.contentMode = UIViewContentModeCenter; |
| | | } else { |
| | | self.gifView.contentMode = UIViewContentModeRight; |
| | | self.gifView.mj_w = self.mj_w * 0.5 - self.labelLeftInset - self.stateLabel.mj_textWidth * 0.5; |
| | | } |
| | | } |
| | | |
| | | - (void)setState:(MJRefreshState)state |
| | | { |
| | | MJRefreshCheckState |
| | | |
| | | // 根据状态做事情 |
| | | if (state == MJRefreshStateRefreshing) { |
| | | NSArray *images = self.stateImages[@(state)]; |
| | | if (images.count == 0) return; |
| | | [self.gifView stopAnimating]; |
| | | |
| | | self.gifView.hidden = NO; |
| | | if (images.count == 1) { // 单张图片 |
| | | self.gifView.image = [images lastObject]; |
| | | } else { // 多张图片 |
| | | self.gifView.animationImages = images; |
| | | self.gifView.animationDuration = [self.stateDurations[@(state)] doubleValue]; |
| | | [self.gifView startAnimating]; |
| | | } |
| | | } else if (state == MJRefreshStateNoMoreData || state == MJRefreshStateIdle) { |
| | | [self.gifView stopAnimating]; |
| | | self.gifView.hidden = YES; |
| | | } |
| | | } |
| | | @end |
| | | |
New file |
| | |
| | | // |
| | | // MJRefreshAutoNormalFooter.h |
| | | // MJRefreshExample |
| | | // |
| | | // Created by MJ Lee on 15/4/24. |
| | | // Copyright (c) 2015年 小码哥. All rights reserved. |
| | | // |
| | | |
| | | #import "MJRefreshAutoStateFooter.h" |
| | | |
| | | NS_ASSUME_NONNULL_BEGIN |
| | | |
| | | @interface MJRefreshAutoNormalFooter : MJRefreshAutoStateFooter |
| | | @property (weak, nonatomic, readonly) UIActivityIndicatorView *loadingView; |
| | | |
| | | /** 菊花的样式 */ |
| | | @property (assign, nonatomic) UIActivityIndicatorViewStyle activityIndicatorViewStyle MJRefreshDeprecated("first deprecated in 3.2.2 - Use `loadingView` property"); |
| | | @end |
| | | |
| | | |
| | | NS_ASSUME_NONNULL_END |
New file |
| | |
| | | // |
| | | // MJRefreshAutoNormalFooter.m |
| | | // MJRefreshExample |
| | | // |
| | | // Created by MJ Lee on 15/4/24. |
| | | // Copyright (c) 2015年 小码哥. All rights reserved. |
| | | // |
| | | |
| | | #import "MJRefreshAutoNormalFooter.h" |
| | | |
| | | @interface MJRefreshAutoNormalFooter() |
| | | @property (weak, nonatomic) UIActivityIndicatorView *loadingView; |
| | | @end |
| | | |
| | | @implementation MJRefreshAutoNormalFooter |
| | | #pragma mark - 懒加载子控件 |
| | | - (UIActivityIndicatorView *)loadingView |
| | | { |
| | | if (!_loadingView) { |
| | | UIActivityIndicatorView *loadingView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:_activityIndicatorViewStyle]; |
| | | loadingView.hidesWhenStopped = YES; |
| | | [self addSubview:_loadingView = loadingView]; |
| | | } |
| | | return _loadingView; |
| | | } |
| | | |
| | | - (void)setActivityIndicatorViewStyle:(UIActivityIndicatorViewStyle)activityIndicatorViewStyle |
| | | { |
| | | _activityIndicatorViewStyle = activityIndicatorViewStyle; |
| | | |
| | | [self.loadingView removeFromSuperview]; |
| | | self.loadingView = nil; |
| | | [self setNeedsLayout]; |
| | | } |
| | | #pragma mark - 重写父类的方法 |
| | | - (void)prepare |
| | | { |
| | | [super prepare]; |
| | | |
| | | #if __IPHONE_OS_VERSION_MAX_ALLOWED >= 130000 |
| | | if (@available(iOS 13.0, *)) { |
| | | _activityIndicatorViewStyle = UIActivityIndicatorViewStyleMedium; |
| | | return; |
| | | } |
| | | #endif |
| | | |
| | | _activityIndicatorViewStyle = UIActivityIndicatorViewStyleGray; |
| | | } |
| | | |
| | | - (void)placeSubviews |
| | | { |
| | | [super placeSubviews]; |
| | | |
| | | if (self.loadingView.constraints.count) return; |
| | | |
| | | // 圈圈 |
| | | CGFloat loadingCenterX = self.mj_w * 0.5; |
| | | if (!self.isRefreshingTitleHidden) { |
| | | loadingCenterX -= self.stateLabel.mj_textWidth * 0.5 + self.labelLeftInset; |
| | | } |
| | | CGFloat loadingCenterY = self.mj_h * 0.5; |
| | | self.loadingView.center = CGPointMake(loadingCenterX, loadingCenterY); |
| | | } |
| | | |
| | | - (void)setState:(MJRefreshState)state |
| | | { |
| | | MJRefreshCheckState |
| | | |
| | | // 根据状态做事情 |
| | | if (state == MJRefreshStateNoMoreData || state == MJRefreshStateIdle) { |
| | | [self.loadingView stopAnimating]; |
| | | } else if (state == MJRefreshStateRefreshing) { |
| | | [self.loadingView startAnimating]; |
| | | } |
| | | } |
| | | |
| | | @end |
New file |
| | |
| | | // |
| | | // MJRefreshAutoStateFooter.h |
| | | // MJRefreshExample |
| | | // |
| | | // Created by MJ Lee on 15/6/13. |
| | | // Copyright © 2015年 小码哥. All rights reserved. |
| | | // |
| | | |
| | | #import "MJRefreshAutoFooter.h" |
| | | |
| | | NS_ASSUME_NONNULL_BEGIN |
| | | |
| | | @interface MJRefreshAutoStateFooter : MJRefreshAutoFooter |
| | | /** 文字距离圈圈、箭头的距离 */ |
| | | @property (assign, nonatomic) CGFloat labelLeftInset; |
| | | /** 显示刷新状态的label */ |
| | | @property (weak, nonatomic, readonly) UILabel *stateLabel; |
| | | |
| | | /** 设置state状态下的文字 */ |
| | | - (void)setTitle:(NSString *)title forState:(MJRefreshState)state; |
| | | |
| | | /** 隐藏刷新状态的文字 */ |
| | | @property (assign, nonatomic, getter=isRefreshingTitleHidden) BOOL refreshingTitleHidden; |
| | | @end |
| | | |
| | | NS_ASSUME_NONNULL_END |
New file |
| | |
| | | // |
| | | // MJRefreshAutoStateFooter.m |
| | | // MJRefreshExample |
| | | // |
| | | // Created by MJ Lee on 15/6/13. |
| | | // Copyright © 2015年 小码哥. All rights reserved. |
| | | // |
| | | |
| | | #import "MJRefreshAutoStateFooter.h" |
| | | |
| | | @interface MJRefreshAutoStateFooter() |
| | | { |
| | | /** 显示刷新状态的label */ |
| | | __unsafe_unretained UILabel *_stateLabel; |
| | | } |
| | | /** 所有状态对应的文字 */ |
| | | @property (strong, nonatomic) NSMutableDictionary *stateTitles; |
| | | @end |
| | | |
| | | @implementation MJRefreshAutoStateFooter |
| | | #pragma mark - 懒加载 |
| | | - (NSMutableDictionary *)stateTitles |
| | | { |
| | | if (!_stateTitles) { |
| | | self.stateTitles = [NSMutableDictionary dictionary]; |
| | | } |
| | | return _stateTitles; |
| | | } |
| | | |
| | | - (UILabel *)stateLabel |
| | | { |
| | | if (!_stateLabel) { |
| | | [self addSubview:_stateLabel = [UILabel mj_label]]; |
| | | } |
| | | return _stateLabel; |
| | | } |
| | | |
| | | #pragma mark - 公共方法 |
| | | - (void)setTitle:(NSString *)title forState:(MJRefreshState)state |
| | | { |
| | | if (title == nil) return; |
| | | self.stateTitles[@(state)] = title; |
| | | self.stateLabel.text = self.stateTitles[@(self.state)]; |
| | | } |
| | | |
| | | #pragma mark - 私有方法 |
| | | - (void)stateLabelClick |
| | | { |
| | | if (self.state == MJRefreshStateIdle) { |
| | | [self beginRefreshing]; |
| | | } |
| | | } |
| | | |
| | | #pragma mark - 重写父类的方法 |
| | | - (void)prepare |
| | | { |
| | | [super prepare]; |
| | | |
| | | // 初始化间距 |
| | | self.labelLeftInset = MJRefreshLabelLeftInset; |
| | | |
| | | // 初始化文字 |
| | | [self setTitle:[NSBundle mj_localizedStringForKey:MJRefreshAutoFooterIdleText] forState:MJRefreshStateIdle]; |
| | | [self setTitle:[NSBundle mj_localizedStringForKey:MJRefreshAutoFooterRefreshingText] forState:MJRefreshStateRefreshing]; |
| | | [self setTitle:[NSBundle mj_localizedStringForKey:MJRefreshAutoFooterNoMoreDataText] forState:MJRefreshStateNoMoreData]; |
| | | |
| | | // 监听label |
| | | self.stateLabel.userInteractionEnabled = YES; |
| | | [self.stateLabel addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(stateLabelClick)]]; |
| | | } |
| | | |
| | | - (void)placeSubviews |
| | | { |
| | | [super placeSubviews]; |
| | | |
| | | if (self.stateLabel.constraints.count) return; |
| | | |
| | | // 状态标签 |
| | | self.stateLabel.frame = self.bounds; |
| | | } |
| | | |
| | | - (void)setState:(MJRefreshState)state |
| | | { |
| | | MJRefreshCheckState |
| | | |
| | | if (self.isRefreshingTitleHidden && state == MJRefreshStateRefreshing) { |
| | | self.stateLabel.text = nil; |
| | | } else { |
| | | self.stateLabel.text = self.stateTitles[@(state)]; |
| | | } |
| | | } |
| | | @end |
New file |
| | |
| | | // |
| | | // MJRefreshBackGifFooter.h |
| | | // MJRefreshExample |
| | | // |
| | | // Created by MJ Lee on 15/4/24. |
| | | // Copyright (c) 2015年 小码哥. All rights reserved. |
| | | // |
| | | |
| | | #import "MJRefreshBackStateFooter.h" |
| | | |
| | | NS_ASSUME_NONNULL_BEGIN |
| | | |
| | | @interface MJRefreshBackGifFooter : MJRefreshBackStateFooter |
| | | @property (weak, nonatomic, readonly) UIImageView *gifView; |
| | | |
| | | /** 设置state状态下的动画图片images 动画持续时间duration*/ |
| | | - (void)setImages:(NSArray *)images duration:(NSTimeInterval)duration forState:(MJRefreshState)state; |
| | | - (void)setImages:(NSArray *)images forState:(MJRefreshState)state; |
| | | @end |
| | | |
| | | NS_ASSUME_NONNULL_END |
New file |
| | |
| | | // |
| | | // MJRefreshBackGifFooter.m |
| | | // MJRefreshExample |
| | | // |
| | | // Created by MJ Lee on 15/4/24. |
| | | // Copyright (c) 2015年 小码哥. All rights reserved. |
| | | // |
| | | |
| | | #import "MJRefreshBackGifFooter.h" |
| | | |
| | | @interface MJRefreshBackGifFooter() |
| | | { |
| | | __unsafe_unretained UIImageView *_gifView; |
| | | } |
| | | /** 所有状态对应的动画图片 */ |
| | | @property (strong, nonatomic) NSMutableDictionary *stateImages; |
| | | /** 所有状态对应的动画时间 */ |
| | | @property (strong, nonatomic) NSMutableDictionary *stateDurations; |
| | | @end |
| | | |
| | | @implementation MJRefreshBackGifFooter |
| | | #pragma mark - 懒加载 |
| | | - (UIImageView *)gifView |
| | | { |
| | | if (!_gifView) { |
| | | UIImageView *gifView = [[UIImageView alloc] init]; |
| | | [self addSubview:_gifView = gifView]; |
| | | } |
| | | return _gifView; |
| | | } |
| | | |
| | | - (NSMutableDictionary *)stateImages |
| | | { |
| | | if (!_stateImages) { |
| | | self.stateImages = [NSMutableDictionary dictionary]; |
| | | } |
| | | return _stateImages; |
| | | } |
| | | |
| | | - (NSMutableDictionary *)stateDurations |
| | | { |
| | | if (!_stateDurations) { |
| | | self.stateDurations = [NSMutableDictionary dictionary]; |
| | | } |
| | | return _stateDurations; |
| | | } |
| | | |
| | | #pragma mark - 公共方法 |
| | | - (void)setImages:(NSArray *)images duration:(NSTimeInterval)duration forState:(MJRefreshState)state |
| | | { |
| | | if (images == nil) return; |
| | | |
| | | self.stateImages[@(state)] = images; |
| | | self.stateDurations[@(state)] = @(duration); |
| | | |
| | | /* 根据图片设置控件的高度 */ |
| | | UIImage *image = [images firstObject]; |
| | | if (image.size.height > self.mj_h) { |
| | | self.mj_h = image.size.height; |
| | | } |
| | | } |
| | | |
| | | - (void)setImages:(NSArray *)images forState:(MJRefreshState)state |
| | | { |
| | | [self setImages:images duration:images.count * 0.1 forState:state]; |
| | | } |
| | | |
| | | #pragma mark - 实现父类的方法 |
| | | - (void)prepare |
| | | { |
| | | [super prepare]; |
| | | |
| | | // 初始化间距 |
| | | self.labelLeftInset = 20; |
| | | } |
| | | |
| | | - (void)setPullingPercent:(CGFloat)pullingPercent |
| | | { |
| | | [super setPullingPercent:pullingPercent]; |
| | | NSArray *images = self.stateImages[@(MJRefreshStateIdle)]; |
| | | if (self.state != MJRefreshStateIdle || images.count == 0) return; |
| | | [self.gifView stopAnimating]; |
| | | NSUInteger index = images.count * pullingPercent; |
| | | if (index >= images.count) index = images.count - 1; |
| | | self.gifView.image = images[index]; |
| | | } |
| | | |
| | | - (void)placeSubviews |
| | | { |
| | | [super placeSubviews]; |
| | | |
| | | if (self.gifView.constraints.count) return; |
| | | |
| | | self.gifView.frame = self.bounds; |
| | | if (self.stateLabel.hidden) { |
| | | self.gifView.contentMode = UIViewContentModeCenter; |
| | | } else { |
| | | self.gifView.contentMode = UIViewContentModeRight; |
| | | self.gifView.mj_w = self.mj_w * 0.5 - self.labelLeftInset - self.stateLabel.mj_textWidth * 0.5; |
| | | } |
| | | } |
| | | |
| | | - (void)setState:(MJRefreshState)state |
| | | { |
| | | MJRefreshCheckState |
| | | |
| | | // 根据状态做事情 |
| | | if (state == MJRefreshStatePulling || state == MJRefreshStateRefreshing) { |
| | | NSArray *images = self.stateImages[@(state)]; |
| | | if (images.count == 0) return; |
| | | |
| | | self.gifView.hidden = NO; |
| | | [self.gifView stopAnimating]; |
| | | if (images.count == 1) { // 单张图片 |
| | | self.gifView.image = [images lastObject]; |
| | | } else { // 多张图片 |
| | | self.gifView.animationImages = images; |
| | | self.gifView.animationDuration = [self.stateDurations[@(state)] doubleValue]; |
| | | [self.gifView startAnimating]; |
| | | } |
| | | } else if (state == MJRefreshStateIdle) { |
| | | self.gifView.hidden = NO; |
| | | } else if (state == MJRefreshStateNoMoreData) { |
| | | self.gifView.hidden = YES; |
| | | } |
| | | } |
| | | @end |
New file |
| | |
| | | // |
| | | // MJRefreshBackNormalFooter.h |
| | | // MJRefreshExample |
| | | // |
| | | // Created by MJ Lee on 15/4/24. |
| | | // Copyright (c) 2015年 小码哥. All rights reserved. |
| | | // |
| | | |
| | | #import "MJRefreshBackStateFooter.h" |
| | | |
| | | NS_ASSUME_NONNULL_BEGIN |
| | | |
| | | @interface MJRefreshBackNormalFooter : MJRefreshBackStateFooter |
| | | @property (weak, nonatomic, readonly) UIImageView *arrowView; |
| | | @property (weak, nonatomic, readonly) UIActivityIndicatorView *loadingView; |
| | | |
| | | /** 菊花的样式 */ |
| | | @property (assign, nonatomic) UIActivityIndicatorViewStyle activityIndicatorViewStyle MJRefreshDeprecated("first deprecated in 3.2.2 - Use `loadingView` property"); |
| | | @end |
| | | |
| | | NS_ASSUME_NONNULL_END |
New file |
| | |
| | | // |
| | | // MJRefreshBackNormalFooter.m |
| | | // MJRefreshExample |
| | | // |
| | | // Created by MJ Lee on 15/4/24. |
| | | // Copyright (c) 2015年 小码哥. All rights reserved. |
| | | // |
| | | |
| | | #import "MJRefreshBackNormalFooter.h" |
| | | #import "NSBundle+MJRefresh.h" |
| | | |
| | | @interface MJRefreshBackNormalFooter() |
| | | { |
| | | __unsafe_unretained UIImageView *_arrowView; |
| | | } |
| | | @property (weak, nonatomic) UIActivityIndicatorView *loadingView; |
| | | @end |
| | | |
| | | @implementation MJRefreshBackNormalFooter |
| | | #pragma mark - 懒加载子控件 |
| | | - (UIImageView *)arrowView |
| | | { |
| | | if (!_arrowView) { |
| | | UIImageView *arrowView = [[UIImageView alloc] initWithImage:[NSBundle mj_arrowImage]]; |
| | | [self addSubview:_arrowView = arrowView]; |
| | | } |
| | | return _arrowView; |
| | | } |
| | | |
| | | |
| | | - (UIActivityIndicatorView *)loadingView |
| | | { |
| | | if (!_loadingView) { |
| | | UIActivityIndicatorView *loadingView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:_activityIndicatorViewStyle]; |
| | | loadingView.hidesWhenStopped = YES; |
| | | [self addSubview:_loadingView = loadingView]; |
| | | } |
| | | return _loadingView; |
| | | } |
| | | |
| | | - (void)setActivityIndicatorViewStyle:(UIActivityIndicatorViewStyle)activityIndicatorViewStyle |
| | | { |
| | | _activityIndicatorViewStyle = activityIndicatorViewStyle; |
| | | |
| | | [self.loadingView removeFromSuperview]; |
| | | self.loadingView = nil; |
| | | [self setNeedsLayout]; |
| | | } |
| | | #pragma mark - 重写父类的方法 |
| | | - (void)prepare |
| | | { |
| | | [super prepare]; |
| | | |
| | | #if __IPHONE_OS_VERSION_MAX_ALLOWED >= 130000 |
| | | if (@available(iOS 13.0, *)) { |
| | | _activityIndicatorViewStyle = UIActivityIndicatorViewStyleMedium; |
| | | return; |
| | | } |
| | | #endif |
| | | |
| | | _activityIndicatorViewStyle = UIActivityIndicatorViewStyleGray; |
| | | } |
| | | |
| | | - (void)placeSubviews |
| | | { |
| | | [super placeSubviews]; |
| | | |
| | | // 箭头的中心点 |
| | | CGFloat arrowCenterX = self.mj_w * 0.5; |
| | | if (!self.stateLabel.hidden) { |
| | | arrowCenterX -= self.labelLeftInset + self.stateLabel.mj_textWidth * 0.5; |
| | | } |
| | | CGFloat arrowCenterY = self.mj_h * 0.5; |
| | | CGPoint arrowCenter = CGPointMake(arrowCenterX, arrowCenterY); |
| | | |
| | | // 箭头 |
| | | if (self.arrowView.constraints.count == 0) { |
| | | self.arrowView.mj_size = self.arrowView.image.size; |
| | | self.arrowView.center = arrowCenter; |
| | | } |
| | | |
| | | // 圈圈 |
| | | if (self.loadingView.constraints.count == 0) { |
| | | self.loadingView.center = arrowCenter; |
| | | } |
| | | |
| | | self.arrowView.tintColor = self.stateLabel.textColor; |
| | | } |
| | | |
| | | - (void)setState:(MJRefreshState)state |
| | | { |
| | | MJRefreshCheckState |
| | | |
| | | // 根据状态做事情 |
| | | if (state == MJRefreshStateIdle) { |
| | | if (oldState == MJRefreshStateRefreshing) { |
| | | self.arrowView.transform = CGAffineTransformMakeRotation(0.000001 - M_PI); |
| | | [UIView animateWithDuration:MJRefreshSlowAnimationDuration animations:^{ |
| | | self.loadingView.alpha = 0.0; |
| | | } completion:^(BOOL finished) { |
| | | // 防止动画结束后,状态已经不是MJRefreshStateIdle |
| | | if (self.state != MJRefreshStateIdle) return; |
| | | |
| | | self.loadingView.alpha = 1.0; |
| | | [self.loadingView stopAnimating]; |
| | | |
| | | self.arrowView.hidden = NO; |
| | | }]; |
| | | } else { |
| | | self.arrowView.hidden = NO; |
| | | [self.loadingView stopAnimating]; |
| | | [UIView animateWithDuration:MJRefreshFastAnimationDuration animations:^{ |
| | | self.arrowView.transform = CGAffineTransformMakeRotation(0.000001 - M_PI); |
| | | }]; |
| | | } |
| | | } else if (state == MJRefreshStatePulling) { |
| | | self.arrowView.hidden = NO; |
| | | [self.loadingView stopAnimating]; |
| | | [UIView animateWithDuration:MJRefreshFastAnimationDuration animations:^{ |
| | | self.arrowView.transform = CGAffineTransformIdentity; |
| | | }]; |
| | | } else if (state == MJRefreshStateRefreshing) { |
| | | self.arrowView.hidden = YES; |
| | | [self.loadingView startAnimating]; |
| | | } else if (state == MJRefreshStateNoMoreData) { |
| | | self.arrowView.hidden = YES; |
| | | [self.loadingView stopAnimating]; |
| | | } |
| | | } |
| | | |
| | | @end |
New file |
| | |
| | | // |
| | | // MJRefreshBackStateFooter.h |
| | | // MJRefreshExample |
| | | // |
| | | // Created by MJ Lee on 15/6/13. |
| | | // Copyright © 2015年 小码哥. All rights reserved. |
| | | // |
| | | |
| | | #import "MJRefreshBackFooter.h" |
| | | |
| | | NS_ASSUME_NONNULL_BEGIN |
| | | |
| | | @interface MJRefreshBackStateFooter : MJRefreshBackFooter |
| | | /** 文字距离圈圈、箭头的距离 */ |
| | | @property (assign, nonatomic) CGFloat labelLeftInset; |
| | | /** 显示刷新状态的label */ |
| | | @property (weak, nonatomic, readonly) UILabel *stateLabel; |
| | | /** 设置state状态下的文字 */ |
| | | - (void)setTitle:(NSString *)title forState:(MJRefreshState)state; |
| | | |
| | | /** 获取state状态下的title */ |
| | | - (NSString *)titleForState:(MJRefreshState)state; |
| | | @end |
| | | |
| | | NS_ASSUME_NONNULL_END |
New file |
| | |
| | | // |
| | | // MJRefreshGifHeader.h |
| | | // MJRefreshExample |
| | | // |
| | | // Created by MJ Lee on 15/4/24. |
| | | // Copyright (c) 2015年 小码哥. All rights reserved. |
| | | // |
| | | |
| | | #import "MJRefreshStateHeader.h" |
| | | |
| | | NS_ASSUME_NONNULL_BEGIN |
| | | |
| | | @interface MJRefreshGifHeader : MJRefreshStateHeader |
| | | @property (weak, nonatomic, readonly) UIImageView *gifView; |
| | | |
| | | /** 设置state状态下的动画图片images 动画持续时间duration*/ |
| | | - (void)setImages:(NSArray *)images duration:(NSTimeInterval)duration forState:(MJRefreshState)state; |
| | | - (void)setImages:(NSArray *)images forState:(MJRefreshState)state; |
| | | @end |
| | | |
| | | NS_ASSUME_NONNULL_END |
New file |
| | |
| | | // |
| | | // MJRefreshGifHeader.m |
| | | // MJRefreshExample |
| | | // |
| | | // Created by MJ Lee on 15/4/24. |
| | | // Copyright (c) 2015年 小码哥. All rights reserved. |
| | | // |
| | | |
| | | #import "MJRefreshGifHeader.h" |
| | | |
| | | @interface MJRefreshGifHeader() |
| | | { |
| | | __unsafe_unretained UIImageView *_gifView; |
| | | } |
| | | /** 所有状态对应的动画图片 */ |
| | | @property (strong, nonatomic) NSMutableDictionary *stateImages; |
| | | /** 所有状态对应的动画时间 */ |
| | | @property (strong, nonatomic) NSMutableDictionary *stateDurations; |
| | | @end |
| | | |
| | | @implementation MJRefreshGifHeader |
| | | #pragma mark - 懒加载 |
| | | - (UIImageView *)gifView |
| | | { |
| | | if (!_gifView) { |
| | | UIImageView *gifView = [[UIImageView alloc] init]; |
| | | [self addSubview:_gifView = gifView]; |
| | | } |
| | | return _gifView; |
| | | } |
| | | |
| | | - (NSMutableDictionary *)stateImages |
| | | { |
| | | if (!_stateImages) { |
| | | self.stateImages = [NSMutableDictionary dictionary]; |
| | | } |
| | | return _stateImages; |
| | | } |
| | | |
| | | - (NSMutableDictionary *)stateDurations |
| | | { |
| | | if (!_stateDurations) { |
| | | self.stateDurations = [NSMutableDictionary dictionary]; |
| | | } |
| | | return _stateDurations; |
| | | } |
| | | |
| | | #pragma mark - 公共方法 |
| | | - (void)setImages:(NSArray *)images duration:(NSTimeInterval)duration forState:(MJRefreshState)state |
| | | { |
| | | if (images == nil) return; |
| | | |
| | | self.stateImages[@(state)] = images; |
| | | self.stateDurations[@(state)] = @(duration); |
| | | |
| | | /* 根据图片设置控件的高度 */ |
| | | UIImage *image = [images firstObject]; |
| | | if (image.size.height > self.mj_h) { |
| | | self.mj_h = image.size.height; |
| | | } |
| | | } |
| | | |
| | | - (void)setImages:(NSArray *)images forState:(MJRefreshState)state |
| | | { |
| | | [self setImages:images duration:images.count * 0.1 forState:state]; |
| | | } |
| | | |
| | | #pragma mark - 实现父类的方法 |
| | | - (void)prepare |
| | | { |
| | | [super prepare]; |
| | | |
| | | // 初始化间距 |
| | | self.labelLeftInset = 20; |
| | | } |
| | | |
| | | - (void)setPullingPercent:(CGFloat)pullingPercent |
| | | { |
| | | [super setPullingPercent:pullingPercent]; |
| | | NSArray *images = self.stateImages[@(MJRefreshStateIdle)]; |
| | | if (self.state != MJRefreshStateIdle || images.count == 0) return; |
| | | // 停止动画 |
| | | [self.gifView stopAnimating]; |
| | | // 设置当前需要显示的图片 |
| | | NSUInteger index = images.count * pullingPercent; |
| | | if (index >= images.count) index = images.count - 1; |
| | | self.gifView.image = images[index]; |
| | | } |
| | | |
| | | - (void)placeSubviews |
| | | { |
| | | [super placeSubviews]; |
| | | |
| | | if (self.gifView.constraints.count) return; |
| | | |
| | | self.gifView.frame = self.bounds; |
| | | if (self.stateLabel.hidden && self.lastUpdatedTimeLabel.hidden) { |
| | | self.gifView.contentMode = UIViewContentModeCenter; |
| | | } else { |
| | | self.gifView.contentMode = UIViewContentModeRight; |
| | | |
| | | CGFloat stateWidth = self.stateLabel.mj_textWidth; |
| | | CGFloat timeWidth = 0.0; |
| | | if (!self.lastUpdatedTimeLabel.hidden) { |
| | | timeWidth = self.lastUpdatedTimeLabel.mj_textWidth; |
| | | } |
| | | CGFloat textWidth = MAX(stateWidth, timeWidth); |
| | | self.gifView.mj_w = self.mj_w * 0.5 - textWidth * 0.5 - self.labelLeftInset; |
| | | } |
| | | } |
| | | |
| | | - (void)setState:(MJRefreshState)state |
| | | { |
| | | MJRefreshCheckState |
| | | |
| | | // 根据状态做事情 |
| | | if (state == MJRefreshStatePulling || state == MJRefreshStateRefreshing) { |
| | | NSArray *images = self.stateImages[@(state)]; |
| | | if (images.count == 0) return; |
| | | |
| | | [self.gifView stopAnimating]; |
| | | if (images.count == 1) { // 单张图片 |
| | | self.gifView.image = [images lastObject]; |
| | | } else { // 多张图片 |
| | | self.gifView.animationImages = images; |
| | | self.gifView.animationDuration = [self.stateDurations[@(state)] doubleValue]; |
| | | [self.gifView startAnimating]; |
| | | } |
| | | } else if (state == MJRefreshStateIdle) { |
| | | [self.gifView stopAnimating]; |
| | | } |
| | | } |
| | | @end |
New file |
| | |
| | | // |
| | | // MJRefreshNormalHeader.h |
| | | // MJRefreshExample |
| | | // |
| | | // Created by MJ Lee on 15/4/24. |
| | | // Copyright (c) 2015年 小码哥. All rights reserved. |
| | | // |
| | | |
| | | #import "MJRefreshStateHeader.h" |
| | | |
| | | NS_ASSUME_NONNULL_BEGIN |
| | | |
| | | @interface MJRefreshNormalHeader : MJRefreshStateHeader |
| | | @property (weak, nonatomic, readonly) UIImageView *arrowView; |
| | | @property (weak, nonatomic, readonly) UIActivityIndicatorView *loadingView; |
| | | |
| | | |
| | | /** 菊花的样式 */ |
| | | @property (assign, nonatomic) UIActivityIndicatorViewStyle activityIndicatorViewStyle MJRefreshDeprecated("first deprecated in 3.2.2 - Use `loadingView` property"); |
| | | @end |
| | | |
| | | NS_ASSUME_NONNULL_END |
New file |
| | |
| | | // |
| | | // MJRefreshNormalHeader.m |
| | | // MJRefreshExample |
| | | // |
| | | // Created by MJ Lee on 15/4/24. |
| | | // Copyright (c) 2015年 小码哥. All rights reserved. |
| | | // |
| | | |
| | | #import "MJRefreshNormalHeader.h" |
| | | #import "NSBundle+MJRefresh.h" |
| | | |
| | | @interface MJRefreshNormalHeader() |
| | | { |
| | | __unsafe_unretained UIImageView *_arrowView; |
| | | } |
| | | @property (weak, nonatomic) UIActivityIndicatorView *loadingView; |
| | | @end |
| | | |
| | | @implementation MJRefreshNormalHeader |
| | | #pragma mark - 懒加载子控件 |
| | | - (UIImageView *)arrowView |
| | | { |
| | | if (!_arrowView) { |
| | | UIImageView *arrowView = [[UIImageView alloc] initWithImage:[NSBundle mj_arrowImage]]; |
| | | [self addSubview:_arrowView = arrowView]; |
| | | } |
| | | return _arrowView; |
| | | } |
| | | |
| | | - (UIActivityIndicatorView *)loadingView |
| | | { |
| | | if (!_loadingView) { |
| | | UIActivityIndicatorView *loadingView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:_activityIndicatorViewStyle]; |
| | | loadingView.hidesWhenStopped = YES; |
| | | [self addSubview:_loadingView = loadingView]; |
| | | } |
| | | return _loadingView; |
| | | } |
| | | |
| | | #pragma mark - 公共方法 |
| | | - (void)setActivityIndicatorViewStyle:(UIActivityIndicatorViewStyle)activityIndicatorViewStyle |
| | | { |
| | | _activityIndicatorViewStyle = activityIndicatorViewStyle; |
| | | |
| | | [self.loadingView removeFromSuperview]; |
| | | self.loadingView = nil; |
| | | [self setNeedsLayout]; |
| | | } |
| | | |
| | | #pragma mark - 重写父类的方法 |
| | | - (void)prepare |
| | | { |
| | | [super prepare]; |
| | | |
| | | #if __IPHONE_OS_VERSION_MAX_ALLOWED >= 130000 |
| | | if (@available(iOS 13.0, *)) { |
| | | _activityIndicatorViewStyle = UIActivityIndicatorViewStyleMedium; |
| | | return; |
| | | } |
| | | #endif |
| | | |
| | | _activityIndicatorViewStyle = UIActivityIndicatorViewStyleGray; |
| | | } |
| | | |
| | | - (void)placeSubviews |
| | | { |
| | | [super placeSubviews]; |
| | | |
| | | // 箭头的中心点 |
| | | CGFloat arrowCenterX = self.mj_w * 0.5; |
| | | if (!self.stateLabel.hidden) { |
| | | CGFloat stateWidth = self.stateLabel.mj_textWidth; |
| | | CGFloat timeWidth = 0.0; |
| | | if (!self.lastUpdatedTimeLabel.hidden) { |
| | | timeWidth = self.lastUpdatedTimeLabel.mj_textWidth; |
| | | } |
| | | CGFloat textWidth = MAX(stateWidth, timeWidth); |
| | | arrowCenterX -= textWidth / 2 + self.labelLeftInset; |
| | | } |
| | | CGFloat arrowCenterY = self.mj_h * 0.5; |
| | | CGPoint arrowCenter = CGPointMake(arrowCenterX, arrowCenterY); |
| | | |
| | | // 箭头 |
| | | if (self.arrowView.constraints.count == 0) { |
| | | self.arrowView.mj_size = self.arrowView.image.size; |
| | | self.arrowView.center = arrowCenter; |
| | | } |
| | | |
| | | // 圈圈 |
| | | if (self.loadingView.constraints.count == 0) { |
| | | self.loadingView.center = arrowCenter; |
| | | } |
| | | |
| | | self.arrowView.tintColor = self.stateLabel.textColor; |
| | | } |
| | | |
| | | - (void)setState:(MJRefreshState)state |
| | | { |
| | | MJRefreshCheckState |
| | | |
| | | // 根据状态做事情 |
| | | if (state == MJRefreshStateIdle) { |
| | | if (oldState == MJRefreshStateRefreshing) { |
| | | self.arrowView.transform = CGAffineTransformIdentity; |
| | | |
| | | [UIView animateWithDuration:MJRefreshSlowAnimationDuration animations:^{ |
| | | self.loadingView.alpha = 0.0; |
| | | } completion:^(BOOL finished) { |
| | | // 如果执行完动画发现不是idle状态,就直接返回,进入其他状态 |
| | | if (self.state != MJRefreshStateIdle) return; |
| | | |
| | | self.loadingView.alpha = 1.0; |
| | | [self.loadingView stopAnimating]; |
| | | self.arrowView.hidden = NO; |
| | | }]; |
| | | } else { |
| | | [self.loadingView stopAnimating]; |
| | | self.arrowView.hidden = NO; |
| | | [UIView animateWithDuration:MJRefreshFastAnimationDuration animations:^{ |
| | | self.arrowView.transform = CGAffineTransformIdentity; |
| | | }]; |
| | | } |
| | | } else if (state == MJRefreshStatePulling) { |
| | | [self.loadingView stopAnimating]; |
| | | self.arrowView.hidden = NO; |
| | | [UIView animateWithDuration:MJRefreshFastAnimationDuration animations:^{ |
| | | self.arrowView.transform = CGAffineTransformMakeRotation(0.000001 - M_PI); |
| | | }]; |
| | | } else if (state == MJRefreshStateRefreshing) { |
| | | self.loadingView.alpha = 1.0; // 防止refreshing -> idle的动画完毕动作没有被执行 |
| | | [self.loadingView startAnimating]; |
| | | self.arrowView.hidden = YES; |
| | | } |
| | | } |
| | | @end |
New file |
| | |
| | | // |
| | | // MJRefreshStateHeader.h |
| | | // MJRefreshExample |
| | | // |
| | | // Created by MJ Lee on 15/4/24. |
| | | // Copyright (c) 2015年 小码哥. All rights reserved. |
| | | // |
| | | |
| | | #import "MJRefreshHeader.h" |
| | | |
| | | NS_ASSUME_NONNULL_BEGIN |
| | | |
| | | @interface MJRefreshStateHeader : MJRefreshHeader |
| | | #pragma mark - 刷新时间相关 |
| | | /** 利用这个block来决定显示的更新时间文字 */ |
| | | @property (copy, nonatomic, nullable) NSString *(^lastUpdatedTimeText)(NSDate * _Nullable lastUpdatedTime); |
| | | /** 显示上一次刷新时间的label */ |
| | | @property (weak, nonatomic, readonly) UILabel *lastUpdatedTimeLabel; |
| | | |
| | | #pragma mark - 状态相关 |
| | | /** 文字距离圈圈、箭头的距离 */ |
| | | @property (assign, nonatomic) CGFloat labelLeftInset; |
| | | /** 显示刷新状态的label */ |
| | | @property (weak, nonatomic, readonly) UILabel *stateLabel; |
| | | /** 设置state状态下的文字 */ |
| | | - (void)setTitle:(NSString *)title forState:(MJRefreshState)state; |
| | | @end |
| | | |
| | | NS_ASSUME_NONNULL_END |
New file |
| | |
| | | // |
| | | // MJRefreshStateHeader.m |
| | | // MJRefreshExample |
| | | // |
| | | // Created by MJ Lee on 15/4/24. |
| | | // Copyright (c) 2015年 小码哥. All rights reserved. |
| | | // |
| | | |
| | | #import "MJRefreshStateHeader.h" |
| | | |
| | | @interface MJRefreshStateHeader() |
| | | { |
| | | /** 显示上一次刷新时间的label */ |
| | | __unsafe_unretained UILabel *_lastUpdatedTimeLabel; |
| | | /** 显示刷新状态的label */ |
| | | __unsafe_unretained UILabel *_stateLabel; |
| | | } |
| | | /** 所有状态对应的文字 */ |
| | | @property (strong, nonatomic) NSMutableDictionary *stateTitles; |
| | | @end |
| | | |
| | | @implementation MJRefreshStateHeader |
| | | #pragma mark - 懒加载 |
| | | - (NSMutableDictionary *)stateTitles |
| | | { |
| | | if (!_stateTitles) { |
| | | self.stateTitles = [NSMutableDictionary dictionary]; |
| | | } |
| | | return _stateTitles; |
| | | } |
| | | |
| | | - (UILabel *)stateLabel |
| | | { |
| | | if (!_stateLabel) { |
| | | [self addSubview:_stateLabel = [UILabel mj_label]]; |
| | | } |
| | | return _stateLabel; |
| | | } |
| | | |
| | | - (UILabel *)lastUpdatedTimeLabel |
| | | { |
| | | if (!_lastUpdatedTimeLabel) { |
| | | [self addSubview:_lastUpdatedTimeLabel = [UILabel mj_label]]; |
| | | } |
| | | return _lastUpdatedTimeLabel; |
| | | } |
| | | |
| | | #pragma mark - 公共方法 |
| | | - (void)setTitle:(NSString *)title forState:(MJRefreshState)state |
| | | { |
| | | if (title == nil) return; |
| | | self.stateTitles[@(state)] = title; |
| | | self.stateLabel.text = self.stateTitles[@(self.state)]; |
| | | } |
| | | |
| | | #pragma mark key的处理 |
| | | - (void)setLastUpdatedTimeKey:(NSString *)lastUpdatedTimeKey |
| | | { |
| | | [super setLastUpdatedTimeKey:lastUpdatedTimeKey]; |
| | | |
| | | // 如果label隐藏了,就不用再处理 |
| | | if (self.lastUpdatedTimeLabel.hidden) return; |
| | | |
| | | NSDate *lastUpdatedTime = [[NSUserDefaults standardUserDefaults] objectForKey:lastUpdatedTimeKey]; |
| | | |
| | | // 如果有block |
| | | if (self.lastUpdatedTimeText) { |
| | | self.lastUpdatedTimeLabel.text = self.lastUpdatedTimeText(lastUpdatedTime); |
| | | return; |
| | | } |
| | | |
| | | if (lastUpdatedTime) { |
| | | // 1.获得年月日 |
| | | NSCalendar *calendar = [NSCalendar calendarWithIdentifier:NSCalendarIdentifierGregorian]; |
| | | NSUInteger unitFlags = NSCalendarUnitYear| NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute; |
| | | NSDateComponents *cmp1 = [calendar components:unitFlags fromDate:lastUpdatedTime]; |
| | | NSDateComponents *cmp2 = [calendar components:unitFlags fromDate:[NSDate date]]; |
| | | |
| | | // 2.格式化日期 |
| | | NSDateFormatter *formatter = [[NSDateFormatter alloc] init]; |
| | | BOOL isToday = NO; |
| | | if ([cmp1 day] == [cmp2 day]) { // 今天 |
| | | formatter.dateFormat = @" HH:mm"; |
| | | isToday = YES; |
| | | } else if ([cmp1 year] == [cmp2 year]) { // 今年 |
| | | formatter.dateFormat = @"MM-dd HH:mm"; |
| | | } else { |
| | | formatter.dateFormat = @"yyyy-MM-dd HH:mm"; |
| | | } |
| | | NSString *time = [formatter stringFromDate:lastUpdatedTime]; |
| | | |
| | | // 3.显示日期 |
| | | self.lastUpdatedTimeLabel.text = [NSString stringWithFormat:@"%@%@%@", |
| | | [NSBundle mj_localizedStringForKey:MJRefreshHeaderLastTimeText], |
| | | isToday ? [NSBundle mj_localizedStringForKey:MJRefreshHeaderDateTodayText] : @"", |
| | | time]; |
| | | } else { |
| | | self.lastUpdatedTimeLabel.text = [NSString stringWithFormat:@"%@%@", |
| | | [NSBundle mj_localizedStringForKey:MJRefreshHeaderLastTimeText], |
| | | [NSBundle mj_localizedStringForKey:MJRefreshHeaderNoneLastDateText]]; |
| | | } |
| | | } |
| | | |
| | | #pragma mark - 覆盖父类的方法 |
| | | - (void)prepare |
| | | { |
| | | [super prepare]; |
| | | |
| | | // 初始化间距 |
| | | self.labelLeftInset = MJRefreshLabelLeftInset; |
| | | |
| | | // 初始化文字 |
| | | [self setTitle:[NSBundle mj_localizedStringForKey:MJRefreshHeaderIdleText] forState:MJRefreshStateIdle]; |
| | | [self setTitle:[NSBundle mj_localizedStringForKey:MJRefreshHeaderPullingText] forState:MJRefreshStatePulling]; |
| | | [self setTitle:[NSBundle mj_localizedStringForKey:MJRefreshHeaderRefreshingText] forState:MJRefreshStateRefreshing]; |
| | | } |
| | | |
| | | - (void)placeSubviews |
| | | { |
| | | [super placeSubviews]; |
| | | |
| | | if (self.stateLabel.hidden) return; |
| | | |
| | | BOOL noConstrainsOnStatusLabel = self.stateLabel.constraints.count == 0; |
| | | |
| | | if (self.lastUpdatedTimeLabel.hidden) { |
| | | // 状态 |
| | | if (noConstrainsOnStatusLabel) self.stateLabel.frame = self.bounds; |
| | | } else { |
| | | CGFloat stateLabelH = self.mj_h * 0.5; |
| | | // 状态 |
| | | if (noConstrainsOnStatusLabel) { |
| | | self.stateLabel.mj_x = 0; |
| | | self.stateLabel.mj_y = 0; |
| | | self.stateLabel.mj_w = self.mj_w; |
| | | self.stateLabel.mj_h = stateLabelH; |
| | | } |
| | | |
| | | // 更新时间 |
| | | if (self.lastUpdatedTimeLabel.constraints.count == 0) { |
| | | self.lastUpdatedTimeLabel.mj_x = 0; |
| | | self.lastUpdatedTimeLabel.mj_y = stateLabelH; |
| | | self.lastUpdatedTimeLabel.mj_w = self.mj_w; |
| | | self.lastUpdatedTimeLabel.mj_h = self.mj_h - self.lastUpdatedTimeLabel.mj_y; |
| | | } |
| | | } |
| | | } |
| | | |
| | | - (void)setState:(MJRefreshState)state |
| | | { |
| | | MJRefreshCheckState |
| | | |
| | | // 设置状态文字 |
| | | self.stateLabel.text = self.stateTitles[@(state)]; |
| | | |
| | | // 重新设置key(重新显示时间) |
| | | self.lastUpdatedTimeKey = self.lastUpdatedTimeKey; |
| | | } |
| | | @end |
New file |
| | |
| | | // |
| | | // MJRefreshNormalTrailer.h |
| | | // MJRefreshExample |
| | | // |
| | | // Created by kinarobin on 2020/5/3. |
| | | // Copyright © 2020 小码哥. All rights reserved. |
| | | // |
| | | |
| | | #import "MJRefreshStateTrailer.h" |
| | | |
| | | NS_ASSUME_NONNULL_BEGIN |
| | | |
| | | @interface MJRefreshNormalTrailer : MJRefreshStateTrailer |
| | | |
| | | @property (weak, nonatomic, readonly) UIImageView *arrowView; |
| | | |
| | | @end |
| | | |
| | | NS_ASSUME_NONNULL_END |
New file |
| | |
| | | // |
| | | // MJRefreshNormalTrailer.m |
| | | // MJRefreshExample |
| | | // |
| | | // Created by kinarobin on 2020/5/3. |
| | | // Copyright © 2020 小码哥. All rights reserved. |
| | | // |
| | | |
| | | #import "MJRefreshNormalTrailer.h" |
| | | #import "NSBundle+MJRefresh.h" |
| | | |
| | | @interface MJRefreshNormalTrailer() { |
| | | __unsafe_unretained UIImageView *_arrowView; |
| | | } |
| | | @end |
| | | |
| | | @implementation MJRefreshNormalTrailer |
| | | #pragma mark - 懒加载子控件 |
| | | - (UIImageView *)arrowView { |
| | | if (!_arrowView) { |
| | | UIImageView *arrowView = [[UIImageView alloc] initWithImage:[NSBundle mj_trailArrowImage]]; |
| | | [self addSubview:_arrowView = arrowView]; |
| | | } |
| | | return _arrowView; |
| | | } |
| | | |
| | | - (void)placeSubviews { |
| | | [super placeSubviews]; |
| | | |
| | | CGSize arrowSize = self.arrowView.image.size; |
| | | // 箭头的中心点 |
| | | CGPoint selfCenter = CGPointMake(self.mj_w * 0.5, self.mj_h * 0.5); |
| | | CGPoint arrowCenter = CGPointMake(arrowSize.width * 0.5 + 5, self.mj_h * 0.5); |
| | | BOOL stateHidden = self.stateLabel.isHidden; |
| | | |
| | | if (self.arrowView.constraints.count == 0) { |
| | | self.arrowView.mj_size = self.arrowView.image.size; |
| | | self.arrowView.center = stateHidden ? selfCenter : arrowCenter ; |
| | | } |
| | | self.arrowView.tintColor = self.stateLabel.textColor; |
| | | |
| | | if (stateHidden) return; |
| | | |
| | | BOOL noConstrainsOnStatusLabel = self.stateLabel.constraints.count == 0; |
| | | CGFloat stateLabelW = ceil(self.stateLabel.font.pointSize); |
| | | // 状态 |
| | | if (noConstrainsOnStatusLabel) { |
| | | BOOL arrowHidden = self.arrowView.isHidden; |
| | | CGFloat stateCenterX = (self.mj_w + arrowSize.width) * 0.5; |
| | | self.stateLabel.center = arrowHidden ? selfCenter : CGPointMake(stateCenterX, self.mj_h * 0.5); |
| | | self.stateLabel.mj_size = CGSizeMake(stateLabelW, self.mj_h) ; |
| | | } |
| | | } |
| | | |
| | | - (void)setState:(MJRefreshState)state { |
| | | MJRefreshCheckState |
| | | // 根据状态做事情 |
| | | if (state == MJRefreshStateIdle) { |
| | | if (oldState == MJRefreshStateRefreshing) { |
| | | [UIView animateWithDuration:MJRefreshFastAnimationDuration animations:^{ |
| | | self.arrowView.transform = CGAffineTransformMakeRotation(M_PI); |
| | | } completion:^(BOOL finished) { |
| | | self.arrowView.transform = CGAffineTransformIdentity; |
| | | }]; |
| | | } else { |
| | | [UIView animateWithDuration:MJRefreshFastAnimationDuration animations:^{ |
| | | self.arrowView.transform = CGAffineTransformIdentity; |
| | | }]; |
| | | } |
| | | } else if (state == MJRefreshStatePulling) { |
| | | [UIView animateWithDuration:MJRefreshFastAnimationDuration animations:^{ |
| | | self.arrowView.transform = CGAffineTransformMakeRotation(M_PI); |
| | | }]; |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | @end |
New file |
| | |
| | | // |
| | | // MJRefreshStateTrailer.h |
| | | // MJRefreshExample |
| | | // |
| | | // Created by kinarobin on 2020/5/3. |
| | | // Copyright © 2020 小码哥. All rights reserved. |
| | | // |
| | | |
| | | #import "MJRefreshTrailer.h" |
| | | |
| | | NS_ASSUME_NONNULL_BEGIN |
| | | |
| | | |
| | | @interface MJRefreshStateTrailer : MJRefreshTrailer |
| | | |
| | | #pragma mark - 状态相关 |
| | | /** 显示刷新状态的label */ |
| | | @property (weak, nonatomic, readonly) UILabel *stateLabel; |
| | | /** 设置state状态下的文字 */ |
| | | - (void)setTitle:(NSString *)title forState:(MJRefreshState)state; |
| | | |
| | | @end |
| | | |
| | | NS_ASSUME_NONNULL_END |
New file |
| | |
| | | // |
| | | // MJRefreshStateTrailer.m |
| | | // MJRefreshExample |
| | | // |
| | | // Created by kinarobin on 2020/5/3. |
| | | // Copyright © 2020 小码哥. All rights reserved. |
| | | // |
| | | |
| | | #import "MJRefreshStateTrailer.h" |
| | | |
| | | @interface MJRefreshStateTrailer() { |
| | | /** 显示刷新状态的label */ |
| | | __unsafe_unretained UILabel *_stateLabel; |
| | | } |
| | | /** 所有状态对应的文字 */ |
| | | @property (strong, nonatomic) NSMutableDictionary *stateTitles; |
| | | @end |
| | | |
| | | @implementation MJRefreshStateTrailer |
| | | #pragma mark - 懒加载 |
| | | - (NSMutableDictionary *)stateTitles { |
| | | if (!_stateTitles) { |
| | | self.stateTitles = [NSMutableDictionary dictionary]; |
| | | } |
| | | return _stateTitles; |
| | | } |
| | | |
| | | - (UILabel *)stateLabel { |
| | | if (!_stateLabel) { |
| | | UILabel *stateLabel = [UILabel mj_label]; |
| | | stateLabel.numberOfLines = 0; |
| | | [self addSubview:_stateLabel = stateLabel]; |
| | | } |
| | | return _stateLabel; |
| | | } |
| | | |
| | | #pragma mark - 公共方法 |
| | | - (void)setTitle:(NSString *)title forState:(MJRefreshState)state { |
| | | if (title == nil) return; |
| | | self.stateTitles[@(state)] = title; |
| | | } |
| | | |
| | | #pragma mark - 覆盖父类的方法 |
| | | - (void)prepare { |
| | | [super prepare]; |
| | | |
| | | // 初始化文字 |
| | | [self setTitle:[NSBundle mj_localizedStringForKey:MJRefreshTrailerIdleText] forState:MJRefreshStateIdle]; |
| | | [self setTitle:[NSBundle mj_localizedStringForKey:MJRefreshTrailerPullingText] forState:MJRefreshStatePulling]; |
| | | [self setTitle:[NSBundle mj_localizedStringForKey:MJRefreshTrailerPullingText] forState:MJRefreshStateRefreshing]; |
| | | } |
| | | |
| | | - (void)setState:(MJRefreshState)state { |
| | | MJRefreshCheckState |
| | | // 设置状态文字 |
| | | self.stateLabel.text = self.stateTitles[@(state)]; |
| | | } |
| | | |
| | | - (void)placeSubviews { |
| | | [super placeSubviews]; |
| | | |
| | | if (self.stateLabel.hidden) return; |
| | | |
| | | BOOL noConstrainsOnStatusLabel = self.stateLabel.constraints.count == 0; |
| | | CGFloat stateLabelW = ceil(self.stateLabel.font.pointSize); |
| | | // 状态 |
| | | if (noConstrainsOnStatusLabel) { |
| | | self.stateLabel.center = CGPointMake(self.mj_w * 0.5, self.mj_h * 0.5); |
| | | self.stateLabel.mj_size = CGSizeMake(stateLabelW, self.mj_h) ; |
| | | } |
| | | } |
| | | |
| | | @end |
New file |
| | |
| | | "MJRefreshHeaderIdleText" = "아래로 당겨 새로고침"; |
| | | "MJRefreshHeaderPullingText" = "놓으면 새로고침"; |
| | | "MJRefreshHeaderRefreshingText" = "로딩중..."; |
| | | |
| | | "MJRefreshAutoFooterIdleText" = "탭 또는 위로 당겨 로드함"; |
| | | "MJRefreshAutoFooterRefreshingText" = "로딩중..."; |
| | | "MJRefreshAutoFooterNoMoreDataText" = "더이상 데이터 없음"; |
| | | |
| | | "MJRefreshBackFooterIdleText" = "위로 당겨 더 로드 가능"; |
| | | "MJRefreshBackFooterPullingText" = "놓으면 더 로드됨."; |
| | | "MJRefreshBackFooterRefreshingText" = "로딩중..."; |
| | | "MJRefreshBackFooterNoMoreDataText" = "더이상 데이터 없음"; |
| | | |
| | | "MJRefreshHeaderLastTimeText" = "마지막 업데이트: "; |
| | | "MJRefreshHeaderDateTodayText" = "오늘"; |
| | | "MJRefreshHeaderNoneLastDateText" = "기록 없음"; |
New file |
| | |
| | | "MJRefreshHeaderIdleText" = "下拉可以刷新"; |
| | | "MJRefreshHeaderPullingText" = "鬆開立即刷新"; |
| | | "MJRefreshHeaderRefreshingText" = "正在刷新數據中..."; |
| | | |
| | | "MJRefreshTrailerIdleText" = "滑動查看圖文詳情"; |
| | | "MJRefreshTrailerPullingText" = "釋放查看圖文詳情"; |
| | | |
| | | "MJRefreshAutoFooterIdleText" = "點擊或上拉加載更多"; |
| | | "MJRefreshAutoFooterRefreshingText" = "正在加載更多的數據..."; |
| | | "MJRefreshAutoFooterNoMoreDataText" = "已經全部加載完畢"; |
| | | |
| | | "MJRefreshBackFooterIdleText" = "上拉可以加載更多"; |
| | | "MJRefreshBackFooterPullingText" = "鬆開立即加載更多"; |
| | | "MJRefreshBackFooterRefreshingText" = "正在加載更多的數據..."; |
| | | "MJRefreshBackFooterNoMoreDataText" = "已經全部加載完畢"; |
| | | |
| | | "MJRefreshHeaderLastTimeText" = "最後更新:"; |
| | | "MJRefreshHeaderDateTodayText" = "今天"; |
| | | "MJRefreshHeaderNoneLastDateText" = "無記錄"; |
New file |
| | |
| | | // 代码地址: https://github.com/CoderMJLee/MJRefresh |
| | | // 代码地址: http://code4app.com/ios/%E5%BF%AB%E9%80%9F%E9%9B%86%E6%88%90%E4%B8%8B%E6%8B%89%E4%B8%8A%E6%8B%89%E5%88%B7%E6%96%B0/52326ce26803fabc46000000 |
| | | |
| | | #import "UIScrollView+MJRefresh.h" |
| | | #import "UIScrollView+MJExtension.h" |
| | | #import "UIView+MJExtension.h" |
| | | |
| | | #import "MJRefreshNormalHeader.h" |
| | | #import "MJRefreshGifHeader.h" |
| | | |
| | | #import "MJRefreshBackNormalFooter.h" |
| | | #import "MJRefreshBackGifFooter.h" |
| | | #import "MJRefreshAutoNormalFooter.h" |
| | | #import "MJRefreshAutoGifFooter.h" |
| | | |
| | | #import "MJRefreshNormalTrailer.h" |
New file |
| | |
| | | // |
| | | // MJRefreshConfig.h |
| | | // |
| | | // Created by Frank on 2018/11/27. |
| | | // Copyright © 2018 小码哥. All rights reserved. |
| | | // |
| | | |
| | | #import <Foundation/Foundation.h> |
| | | |
| | | NS_ASSUME_NONNULL_BEGIN |
| | | |
| | | @interface MJRefreshConfig : NSObject |
| | | |
| | | /** 默认使用的语言版本, 默认为 nil. 将随系统的语言自动改变 */ |
| | | @property (copy, nonatomic, nullable) NSString *languageCode; |
| | | |
| | | /** @return Singleton Config instance */ |
| | | + (instancetype)defaultConfig; |
| | | |
| | | - (instancetype)init NS_UNAVAILABLE; |
| | | + (instancetype)new NS_UNAVAILABLE; |
| | | |
| | | @end |
| | | |
| | | NS_ASSUME_NONNULL_END |
New file |
| | |
| | | // |
| | | // MJRefreshConfig.m |
| | | // |
| | | // Created by Frank on 2018/11/27. |
| | | // Copyright © 2018 小码哥. All rights reserved. |
| | | // |
| | | |
| | | #import "MJRefreshConfig.h" |
| | | |
| | | @implementation MJRefreshConfig |
| | | |
| | | static MJRefreshConfig *mj_RefreshConfig = nil; |
| | | |
| | | + (instancetype)defaultConfig { |
| | | static dispatch_once_t onceToken; |
| | | dispatch_once(&onceToken, ^{ |
| | | mj_RefreshConfig = [[self alloc] init]; |
| | | }); |
| | | return mj_RefreshConfig; |
| | | } |
| | | |
| | | |
| | | |
| | | @end |
New file |
| | |
| | | // 代码地址: https://github.com/CoderMJLee/MJRefresh |
| | | // 代码地址: http://code4app.com/ios/%E5%BF%AB%E9%80%9F%E9%9B%86%E6%88%90%E4%B8%8B%E6%8B%89%E4%B8%8A%E6%8B%89%E5%88%B7%E6%96%B0/52326ce26803fabc46000000 |
| | | #import <UIKit/UIKit.h> |
| | | #import <objc/message.h> |
| | | |
| | | // 弱引用 |
| | | #define MJWeakSelf __weak typeof(self) weakSelf = self; |
| | | |
| | | // 日志输出 |
| | | #ifdef DEBUG |
| | | #define MJRefreshLog(...) NSLog(__VA_ARGS__) |
| | | #else |
| | | #define MJRefreshLog(...) |
| | | #endif |
| | | |
| | | // 过期提醒 |
| | | #define MJRefreshDeprecated(DESCRIPTION) __attribute__((deprecated(DESCRIPTION))) |
| | | |
| | | // 运行时objc_msgSend |
| | | #define MJRefreshMsgSend(...) ((void (*)(void *, SEL, UIView *))objc_msgSend)(__VA_ARGS__) |
| | | #define MJRefreshMsgTarget(target) (__bridge void *)(target) |
| | | |
| | | // RGB颜色 |
| | | #define MJRefreshColor(r, g, b) [UIColor colorWithRed:(r)/255.0 green:(g)/255.0 blue:(b)/255.0 alpha:1.0] |
| | | |
| | | // 文字颜色 |
| | | #define MJRefreshLabelTextColor MJRefreshColor(90, 90, 90) |
| | | |
| | | // 字体大小 |
| | | #define MJRefreshLabelFont [UIFont boldSystemFontOfSize:14] |
| | | |
| | | // 常量 |
| | | UIKIT_EXTERN const CGFloat MJRefreshLabelLeftInset; |
| | | UIKIT_EXTERN const CGFloat MJRefreshHeaderHeight; |
| | | UIKIT_EXTERN const CGFloat MJRefreshFooterHeight; |
| | | UIKIT_EXTERN const CGFloat MJRefreshTrailWidth; |
| | | UIKIT_EXTERN const CGFloat MJRefreshFastAnimationDuration; |
| | | UIKIT_EXTERN const CGFloat MJRefreshSlowAnimationDuration; |
| | | |
| | | UIKIT_EXTERN NSString *const MJRefreshKeyPathContentOffset; |
| | | UIKIT_EXTERN NSString *const MJRefreshKeyPathContentSize; |
| | | UIKIT_EXTERN NSString *const MJRefreshKeyPathContentInset; |
| | | UIKIT_EXTERN NSString *const MJRefreshKeyPathPanState; |
| | | |
| | | UIKIT_EXTERN NSString *const MJRefreshHeaderLastUpdatedTimeKey; |
| | | |
| | | UIKIT_EXTERN NSString *const MJRefreshHeaderIdleText; |
| | | UIKIT_EXTERN NSString *const MJRefreshHeaderPullingText; |
| | | UIKIT_EXTERN NSString *const MJRefreshHeaderRefreshingText; |
| | | |
| | | UIKIT_EXTERN NSString *const MJRefreshTrailerIdleText; |
| | | UIKIT_EXTERN NSString *const MJRefreshTrailerPullingText; |
| | | |
| | | UIKIT_EXTERN NSString *const MJRefreshAutoFooterIdleText; |
| | | UIKIT_EXTERN NSString *const MJRefreshAutoFooterRefreshingText; |
| | | UIKIT_EXTERN NSString *const MJRefreshAutoFooterNoMoreDataText; |
| | | |
| | | UIKIT_EXTERN NSString *const MJRefreshBackFooterIdleText; |
| | | UIKIT_EXTERN NSString *const MJRefreshBackFooterPullingText; |
| | | UIKIT_EXTERN NSString *const MJRefreshBackFooterRefreshingText; |
| | | UIKIT_EXTERN NSString *const MJRefreshBackFooterNoMoreDataText; |
| | | |
| | | UIKIT_EXTERN NSString *const MJRefreshHeaderLastTimeText; |
| | | UIKIT_EXTERN NSString *const MJRefreshHeaderDateTodayText; |
| | | UIKIT_EXTERN NSString *const MJRefreshHeaderNoneLastDateText; |
| | | |
| | | // 状态检查 |
| | | #define MJRefreshCheckState \ |
| | | MJRefreshState oldState = self.state; \ |
| | | if (state == oldState) return; \ |
| | | [super setState:state]; |
| | | |
| | | // 异步主线程执行,不强持有Self |
| | | #define MJRefreshDispatchAsyncOnMainQueue(x) \ |
| | | __weak typeof(self) weakSelf = self; \ |
| | | dispatch_async(dispatch_get_main_queue(), ^{ \ |
| | | typeof(weakSelf) self = weakSelf; \ |
| | | {x} \ |
| | | }); |
New file |
| | |
| | | // 代码地址: https://github.com/CoderMJLee/MJRefresh |
| | | // 代码地址: http://code4app.com/ios/%E5%BF%AB%E9%80%9F%E9%9B%86%E6%88%90%E4%B8%8B%E6%8B%89%E4%B8%8A%E6%8B%89%E5%88%B7%E6%96%B0/52326ce26803fabc46000000 |
| | | #import <UIKit/UIKit.h> |
| | | |
| | | const CGFloat MJRefreshLabelLeftInset = 25; |
| | | const CGFloat MJRefreshHeaderHeight = 54.0; |
| | | const CGFloat MJRefreshFooterHeight = 44.0; |
| | | const CGFloat MJRefreshTrailWidth = 60.0; |
| | | const CGFloat MJRefreshFastAnimationDuration = 0.25; |
| | | const CGFloat MJRefreshSlowAnimationDuration = 0.4; |
| | | |
| | | NSString *const MJRefreshKeyPathContentOffset = @"contentOffset"; |
| | | NSString *const MJRefreshKeyPathContentInset = @"contentInset"; |
| | | NSString *const MJRefreshKeyPathContentSize = @"contentSize"; |
| | | NSString *const MJRefreshKeyPathPanState = @"state"; |
| | | |
| | | NSString *const MJRefreshHeaderLastUpdatedTimeKey = @"MJRefreshHeaderLastUpdatedTimeKey"; |
| | | |
| | | NSString *const MJRefreshHeaderIdleText = @"MJRefreshHeaderIdleText"; |
| | | NSString *const MJRefreshHeaderPullingText = @"MJRefreshHeaderPullingText"; |
| | | NSString *const MJRefreshHeaderRefreshingText = @"MJRefreshHeaderRefreshingText"; |
| | | |
| | | NSString *const MJRefreshTrailerIdleText = @"MJRefreshTrailerIdleText"; |
| | | NSString *const MJRefreshTrailerPullingText = @"MJRefreshTrailerPullingText"; |
| | | |
| | | NSString *const MJRefreshAutoFooterIdleText = @"MJRefreshAutoFooterIdleText"; |
| | | NSString *const MJRefreshAutoFooterRefreshingText = @"MJRefreshAutoFooterRefreshingText"; |
| | | NSString *const MJRefreshAutoFooterNoMoreDataText = @"MJRefreshAutoFooterNoMoreDataText"; |
| | | |
| | | NSString *const MJRefreshBackFooterIdleText = @"MJRefreshBackFooterIdleText"; |
| | | NSString *const MJRefreshBackFooterPullingText = @"MJRefreshBackFooterPullingText"; |
| | | NSString *const MJRefreshBackFooterRefreshingText = @"MJRefreshBackFooterRefreshingText"; |
| | | NSString *const MJRefreshBackFooterNoMoreDataText = @"MJRefreshBackFooterNoMoreDataText"; |
| | | |
| | | NSString *const MJRefreshHeaderLastTimeText = @"MJRefreshHeaderLastTimeText"; |
| | | NSString *const MJRefreshHeaderDateTodayText = @"MJRefreshHeaderDateTodayText"; |
| | | NSString *const MJRefreshHeaderNoneLastDateText = @"MJRefreshHeaderNoneLastDateText"; |
New file |
| | |
| | | // |
| | | // NSBundle+MJRefresh.h |
| | | // MJRefreshExample |
| | | // |
| | | // Created by MJ Lee on 16/6/13. |
| | | // Copyright © 2016年 小码哥. All rights reserved. |
| | | // |
| | | |
| | | #import <UIKit/UIKit.h> |
| | | |
| | | NS_ASSUME_NONNULL_BEGIN |
| | | |
| | | @interface NSBundle (MJRefresh) |
| | | + (instancetype)mj_refreshBundle; |
| | | + (UIImage *)mj_arrowImage; |
| | | + (UIImage *)mj_trailArrowImage; |
| | | + (NSString *)mj_localizedStringForKey:(NSString *)key value:(nullable NSString *)value; |
| | | + (NSString *)mj_localizedStringForKey:(NSString *)key; |
| | | @end |
| | | |
| | | NS_ASSUME_NONNULL_END |
New file |
| | |
| | | // |
| | | // NSBundle+MJRefresh.m |
| | | // MJRefreshExample |
| | | // |
| | | // Created by MJ Lee on 16/6/13. |
| | | // Copyright © 2016年 小码哥. All rights reserved. |
| | | // |
| | | |
| | | #import "NSBundle+MJRefresh.h" |
| | | #import "MJRefreshComponent.h" |
| | | #import "MJRefreshConfig.h" |
| | | |
| | | @implementation NSBundle (MJRefresh) |
| | | + (instancetype)mj_refreshBundle |
| | | { |
| | | static NSBundle *refreshBundle = nil; |
| | | if (refreshBundle == nil) { |
| | | // 这里不使用mainBundle是为了适配pod 1.x和0.x |
| | | refreshBundle = [NSBundle bundleWithPath:[[NSBundle bundleForClass:[MJRefreshComponent class]] pathForResource:@"MJRefresh" ofType:@"bundle"]]; |
| | | } |
| | | return refreshBundle; |
| | | } |
| | | |
| | | + (UIImage *)mj_arrowImage |
| | | { |
| | | static UIImage *arrowImage = nil; |
| | | if (arrowImage == nil) { |
| | | arrowImage = [[UIImage imageWithContentsOfFile:[[self mj_refreshBundle] pathForResource:@"arrow@2x" ofType:@"png"]] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]; |
| | | } |
| | | return arrowImage; |
| | | } |
| | | |
| | | + (UIImage *)mj_trailArrowImage { |
| | | static UIImage *arrowImage = nil; |
| | | if (arrowImage == nil) { |
| | | arrowImage = [[UIImage imageWithContentsOfFile:[[self mj_refreshBundle] pathForResource:@"trail_arrow@2x" ofType:@"png"]] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]; |
| | | } |
| | | return arrowImage; |
| | | } |
| | | |
| | | + (NSString *)mj_localizedStringForKey:(NSString *)key |
| | | { |
| | | return [self mj_localizedStringForKey:key value:nil]; |
| | | } |
| | | |
| | | + (NSString *)mj_localizedStringForKey:(NSString *)key value:(NSString *)value |
| | | { |
| | | static NSBundle *bundle = nil; |
| | | if (bundle == nil) { |
| | | NSString *language = MJRefreshConfig.defaultConfig.languageCode; |
| | | // 如果配置中没有配置语言 |
| | | if (!language) { |
| | | // (iOS获取的语言字符串比较不稳定)目前框架只处理en、zh-Hans、zh-Hant三种情况,其他按照系统默认处理 |
| | | language = [NSLocale preferredLanguages].firstObject; |
| | | } |
| | | |
| | | if ([language hasPrefix:@"en"]) { |
| | | language = @"en"; |
| | | } else if ([language hasPrefix:@"zh"]) { |
| | | if ([language rangeOfString:@"Hans"].location != NSNotFound) { |
| | | language = @"zh-Hans"; // 简体中文 |
| | | } else { // zh-Hant\zh-HK\zh-TW |
| | | language = @"zh-Hant"; // 繁體中文 |
| | | } |
| | | } else if ([language hasPrefix:@"ko"]) { |
| | | language = @"ko"; |
| | | } else if ([language hasPrefix:@"ru"]) { |
| | | language = @"ru"; |
| | | } else if ([language hasPrefix:@"uk"]) { |
| | | language = @"uk"; |
| | | } else { |
| | | language = @"en"; |
| | | } |
| | | |
| | | // 从MJRefresh.bundle中查找资源 |
| | | bundle = [NSBundle bundleWithPath:[[NSBundle mj_refreshBundle] pathForResource:language ofType:@"lproj"]]; |
| | | } |
| | | value = [bundle localizedStringForKey:key value:value table:nil]; |
| | | return [[NSBundle mainBundle] localizedStringForKey:key value:value table:nil]; |
| | | } |
| | | @end |
New file |
| | |
| | | // 代码地址: https://github.com/CoderMJLee/MJRefresh |
| | | // 代码地址: http://code4app.com/ios/%E5%BF%AB%E9%80%9F%E9%9B%86%E6%88%90%E4%B8%8B%E6%8B%89%E4%B8%8A%E6%8B%89%E5%88%B7%E6%96%B0/52326ce26803fabc46000000 |
| | | // UIScrollView+Extension.h |
| | | // MJRefreshExample |
| | | // |
| | | // Created by MJ Lee on 14-5-28. |
| | | // Copyright (c) 2014年 小码哥. All rights reserved. |
| | | // |
| | | |
| | | #import <UIKit/UIKit.h> |
| | | |
| | | NS_ASSUME_NONNULL_BEGIN |
| | | |
| | | @interface UIScrollView (MJExtension) |
| | | @property (readonly, nonatomic) UIEdgeInsets mj_inset; |
| | | |
| | | @property (assign, nonatomic) CGFloat mj_insetT; |
| | | @property (assign, nonatomic) CGFloat mj_insetB; |
| | | @property (assign, nonatomic) CGFloat mj_insetL; |
| | | @property (assign, nonatomic) CGFloat mj_insetR; |
| | | |
| | | @property (assign, nonatomic) CGFloat mj_offsetX; |
| | | @property (assign, nonatomic) CGFloat mj_offsetY; |
| | | |
| | | @property (assign, nonatomic) CGFloat mj_contentW; |
| | | @property (assign, nonatomic) CGFloat mj_contentH; |
| | | @end |
| | | |
| | | NS_ASSUME_NONNULL_END |
New file |
| | |
| | | // 代码地址: https://github.com/CoderMJLee/MJRefresh |
| | | // 代码地址: http://code4app.com/ios/%E5%BF%AB%E9%80%9F%E9%9B%86%E6%88%90%E4%B8%8B%E6%8B%89%E4%B8%8A%E6%8B%89%E5%88%B7%E6%96%B0/52326ce26803fabc46000000 |
| | | // UIScrollView+Extension.m |
| | | // MJRefreshExample |
| | | // |
| | | // Created by MJ Lee on 14-5-28. |
| | | // Copyright (c) 2014年 小码哥. All rights reserved. |
| | | // |
| | | |
| | | #import "UIScrollView+MJExtension.h" |
| | | #import <objc/runtime.h> |
| | | |
| | | #pragma clang diagnostic push |
| | | #pragma clang diagnostic ignored "-Wunguarded-availability-new" |
| | | |
| | | @implementation UIScrollView (MJExtension) |
| | | |
| | | static BOOL respondsToAdjustedContentInset_; |
| | | |
| | | + (void)initialize |
| | | { |
| | | static dispatch_once_t onceToken; |
| | | dispatch_once(&onceToken, ^{ |
| | | respondsToAdjustedContentInset_ = [self instancesRespondToSelector:@selector(adjustedContentInset)]; |
| | | }); |
| | | } |
| | | |
| | | - (UIEdgeInsets)mj_inset |
| | | { |
| | | #ifdef __IPHONE_11_0 |
| | | if (respondsToAdjustedContentInset_) { |
| | | return self.adjustedContentInset; |
| | | } |
| | | #endif |
| | | return self.contentInset; |
| | | } |
| | | |
| | | - (void)setMj_insetT:(CGFloat)mj_insetT |
| | | { |
| | | UIEdgeInsets inset = self.contentInset; |
| | | inset.top = mj_insetT; |
| | | #ifdef __IPHONE_11_0 |
| | | if (respondsToAdjustedContentInset_) { |
| | | inset.top -= (self.adjustedContentInset.top - self.contentInset.top); |
| | | } |
| | | #endif |
| | | self.contentInset = inset; |
| | | } |
| | | |
| | | - (CGFloat)mj_insetT |
| | | { |
| | | return self.mj_inset.top; |
| | | } |
| | | |
| | | - (void)setMj_insetB:(CGFloat)mj_insetB |
| | | { |
| | | UIEdgeInsets inset = self.contentInset; |
| | | inset.bottom = mj_insetB; |
| | | #ifdef __IPHONE_11_0 |
| | | if (respondsToAdjustedContentInset_) { |
| | | inset.bottom -= (self.adjustedContentInset.bottom - self.contentInset.bottom); |
| | | } |
| | | #endif |
| | | self.contentInset = inset; |
| | | } |
| | | |
| | | - (CGFloat)mj_insetB |
| | | { |
| | | return self.mj_inset.bottom; |
| | | } |
| | | |
| | | - (void)setMj_insetL:(CGFloat)mj_insetL |
| | | { |
| | | UIEdgeInsets inset = self.contentInset; |
| | | inset.left = mj_insetL; |
| | | #ifdef __IPHONE_11_0 |
| | | if (respondsToAdjustedContentInset_) { |
| | | inset.left -= (self.adjustedContentInset.left - self.contentInset.left); |
| | | } |
| | | #endif |
| | | self.contentInset = inset; |
| | | } |
| | | |
| | | - (CGFloat)mj_insetL |
| | | { |
| | | return self.mj_inset.left; |
| | | } |
| | | |
| | | - (void)setMj_insetR:(CGFloat)mj_insetR |
| | | { |
| | | UIEdgeInsets inset = self.contentInset; |
| | | inset.right = mj_insetR; |
| | | #ifdef __IPHONE_11_0 |
| | | if (respondsToAdjustedContentInset_) { |
| | | inset.right -= (self.adjustedContentInset.right - self.contentInset.right); |
| | | } |
| | | #endif |
| | | self.contentInset = inset; |
| | | } |
| | | |
| | | - (CGFloat)mj_insetR |
| | | { |
| | | return self.mj_inset.right; |
| | | } |
| | | |
| | | - (void)setMj_offsetX:(CGFloat)mj_offsetX |
| | | { |
| | | CGPoint offset = self.contentOffset; |
| | | offset.x = mj_offsetX; |
| | | self.contentOffset = offset; |
| | | } |
| | | |
| | | - (CGFloat)mj_offsetX |
| | | { |
| | | return self.contentOffset.x; |
| | | } |
| | | |
| | | - (void)setMj_offsetY:(CGFloat)mj_offsetY |
| | | { |
| | | CGPoint offset = self.contentOffset; |
| | | offset.y = mj_offsetY; |
| | | self.contentOffset = offset; |
| | | } |
| | | |
| | | - (CGFloat)mj_offsetY |
| | | { |
| | | return self.contentOffset.y; |
| | | } |
| | | |
| | | - (void)setMj_contentW:(CGFloat)mj_contentW |
| | | { |
| | | CGSize size = self.contentSize; |
| | | size.width = mj_contentW; |
| | | self.contentSize = size; |
| | | } |
| | | |
| | | - (CGFloat)mj_contentW |
| | | { |
| | | return self.contentSize.width; |
| | | } |
| | | |
| | | - (void)setMj_contentH:(CGFloat)mj_contentH |
| | | { |
| | | CGSize size = self.contentSize; |
| | | size.height = mj_contentH; |
| | | self.contentSize = size; |
| | | } |
| | | |
| | | - (CGFloat)mj_contentH |
| | | { |
| | | return self.contentSize.height; |
| | | } |
| | | @end |
| | | #pragma clang diagnostic pop |
New file |
| | |
| | | // 代码地址: https://github.com/CoderMJLee/MJRefresh |
| | | // 代码地址: http://code4app.com/ios/%E5%BF%AB%E9%80%9F%E9%9B%86%E6%88%90%E4%B8%8B%E6%8B%89%E4%B8%8A%E6%8B%89%E5%88%B7%E6%96%B0/52326ce26803fabc46000000 |
| | | // UIScrollView+MJRefresh.h |
| | | // MJRefreshExample |
| | | // |
| | | // Created by MJ Lee on 15/3/4. |
| | | // Copyright (c) 2015年 小码哥. All rights reserved. |
| | | // 给ScrollView增加下拉刷新、上拉刷新、 左滑刷新的功能 |
| | | |
| | | #import <UIKit/UIKit.h> |
| | | #import "MJRefreshConst.h" |
| | | |
| | | @class MJRefreshHeader, MJRefreshFooter, MJRefreshTrailer; |
| | | |
| | | NS_ASSUME_NONNULL_BEGIN |
| | | |
| | | @interface UIScrollView (MJRefresh) |
| | | /** 下拉刷新控件 */ |
| | | @property (strong, nonatomic, nullable) MJRefreshHeader *mj_header; |
| | | @property (strong, nonatomic, nullable) MJRefreshHeader *header MJRefreshDeprecated("使用mj_header"); |
| | | /** 上拉刷新控件 */ |
| | | @property (strong, nonatomic, nullable) MJRefreshFooter *mj_footer; |
| | | @property (strong, nonatomic, nullable) MJRefreshFooter *footer MJRefreshDeprecated("使用mj_footer"); |
| | | |
| | | /** 左滑刷新控件 */ |
| | | @property (strong, nonatomic, nullable) MJRefreshTrailer *mj_trailer; |
| | | |
| | | #pragma mark - other |
| | | - (NSInteger)mj_totalDataCount; |
| | | |
| | | @end |
| | | |
| | | NS_ASSUME_NONNULL_END |
New file |
| | |
| | | // 代码地址: https://github.com/CoderMJLee/MJRefresh |
| | | // 代码地址: http://code4app.com/ios/%E5%BF%AB%E9%80%9F%E9%9B%86%E6%88%90%E4%B8%8B%E6%8B%89%E4%B8%8A%E6%8B%89%E5%88%B7%E6%96%B0/52326ce26803fabc46000000 |
| | | // UIScrollView+MJRefresh.m |
| | | // MJRefreshExample |
| | | // |
| | | // Created by MJ Lee on 15/3/4. |
| | | // Copyright (c) 2015年 小码哥. All rights reserved. |
| | | // |
| | | |
| | | #import "UIScrollView+MJRefresh.h" |
| | | #import "MJRefreshHeader.h" |
| | | #import "MJRefreshFooter.h" |
| | | #import "MJRefreshTrailer.h" |
| | | #import <objc/runtime.h> |
| | | |
| | | @implementation UIScrollView (MJRefresh) |
| | | |
| | | #pragma mark - header |
| | | static const char MJRefreshHeaderKey = '\0'; |
| | | - (void)setMj_header:(MJRefreshHeader *)mj_header |
| | | { |
| | | if (mj_header != self.mj_header) { |
| | | // 删除旧的,添加新的 |
| | | [self.mj_header removeFromSuperview]; |
| | | [self insertSubview:mj_header atIndex:0]; |
| | | |
| | | // 存储新的 |
| | | objc_setAssociatedObject(self, &MJRefreshHeaderKey, |
| | | mj_header, OBJC_ASSOCIATION_RETAIN); |
| | | } |
| | | } |
| | | |
| | | - (MJRefreshHeader *)mj_header |
| | | { |
| | | return objc_getAssociatedObject(self, &MJRefreshHeaderKey); |
| | | } |
| | | |
| | | #pragma mark - footer |
| | | static const char MJRefreshFooterKey = '\0'; |
| | | - (void)setMj_footer:(MJRefreshFooter *)mj_footer |
| | | { |
| | | if (mj_footer != self.mj_footer) { |
| | | // 删除旧的,添加新的 |
| | | [self.mj_footer removeFromSuperview]; |
| | | [self insertSubview:mj_footer atIndex:0]; |
| | | |
| | | // 存储新的 |
| | | objc_setAssociatedObject(self, &MJRefreshFooterKey, |
| | | mj_footer, OBJC_ASSOCIATION_RETAIN); |
| | | } |
| | | } |
| | | |
| | | - (MJRefreshFooter *)mj_footer |
| | | { |
| | | return objc_getAssociatedObject(self, &MJRefreshFooterKey); |
| | | } |
| | | |
| | | #pragma mark - footer |
| | | static const char MJRefreshTrailerKey = '\0'; |
| | | - (void)setMj_trailer:(MJRefreshTrailer *)mj_trailer { |
| | | if (mj_trailer != self.mj_trailer) { |
| | | // 删除旧的,添加新的 |
| | | [self.mj_trailer removeFromSuperview]; |
| | | [self insertSubview:mj_trailer atIndex:0]; |
| | | |
| | | // 存储新的 |
| | | objc_setAssociatedObject(self, &MJRefreshTrailerKey, |
| | | mj_trailer, OBJC_ASSOCIATION_RETAIN); |
| | | } |
| | | } |
| | | |
| | | - (MJRefreshTrailer *)mj_trailer { |
| | | return objc_getAssociatedObject(self, &MJRefreshTrailerKey); |
| | | } |
| | | |
| | | #pragma mark - 过期 |
| | | - (void)setFooter:(MJRefreshFooter *)footer |
| | | { |
| | | self.mj_footer = footer; |
| | | } |
| | | |
| | | - (MJRefreshFooter *)footer |
| | | { |
| | | return self.mj_footer; |
| | | } |
| | | |
| | | - (void)setHeader:(MJRefreshHeader *)header |
| | | { |
| | | self.mj_header = header; |
| | | } |
| | | |
| | | - (MJRefreshHeader *)header |
| | | { |
| | | return self.mj_header; |
| | | } |
| | | |
| | | #pragma mark - other |
| | | - (NSInteger)mj_totalDataCount |
| | | { |
| | | NSInteger totalCount = 0; |
| | | if ([self isKindOfClass:[UITableView class]]) { |
| | | UITableView *tableView = (UITableView *)self; |
| | | |
| | | for (NSInteger section = 0; section < tableView.numberOfSections; section++) { |
| | | totalCount += [tableView numberOfRowsInSection:section]; |
| | | } |
| | | } else if ([self isKindOfClass:[UICollectionView class]]) { |
| | | UICollectionView *collectionView = (UICollectionView *)self; |
| | | |
| | | for (NSInteger section = 0; section < collectionView.numberOfSections; section++) { |
| | | totalCount += [collectionView numberOfItemsInSection:section]; |
| | | } |
| | | } |
| | | return totalCount; |
| | | } |
| | | |
| | | @end |
New file |
| | |
| | | // 代码地址: https://github.com/CoderMJLee/MJRefresh |
| | | // 代码地址: http://code4app.com/ios/%E5%BF%AB%E9%80%9F%E9%9B%86%E6%88%90%E4%B8%8B%E6%8B%89%E4%B8%8A%E6%8B%89%E5%88%B7%E6%96%B0/52326ce26803fabc46000000 |
| | | // UIView+Extension.h |
| | | // MJRefreshExample |
| | | // |
| | | // Created by MJ Lee on 14-5-28. |
| | | // Copyright (c) 2014年 小码哥. All rights reserved. |
| | | // |
| | | |
| | | #import <UIKit/UIKit.h> |
| | | |
| | | NS_ASSUME_NONNULL_BEGIN |
| | | |
| | | @interface UIView (MJExtension) |
| | | @property (assign, nonatomic) CGFloat mj_x; |
| | | @property (assign, nonatomic) CGFloat mj_y; |
| | | @property (assign, nonatomic) CGFloat mj_w; |
| | | @property (assign, nonatomic) CGFloat mj_h; |
| | | @property (assign, nonatomic) CGSize mj_size; |
| | | @property (assign, nonatomic) CGPoint mj_origin; |
| | | @end |
| | | |
| | | NS_ASSUME_NONNULL_END |
| | |
| | | [super viewWillAppear:animated]; |
| | | self.navigationController.navigationBarHidden = NO; |
| | | self.view.backgroundColor = kGlobalBackgroundColor; |
| | | [MobClick beginLogPageView:@"主四页"]; |
| | | //[MobClick beginLogPageView:@"主四页"]; |
| | | |
| | | //强制竖屏 |
| | | NSNumber *orientationUnknown = [NSNumber numberWithInt:UIInterfaceOrientationUnknown]; |
| | |
| | | |
| | | - (void)viewWillDisappear:(BOOL)animated{ |
| | | [super viewWillDisappear:animated]; |
| | | [MobClick endLogPageView:@"主四页"]; |
| | | //[MobClick endLogPageView:@"主四页"]; |
| | | } |
| | | |
| | | -(BOOL)shouldAutorotate{ |
| | |
| | | NSString *userInfo=[dic objectForKey:@"Params"]; |
| | | NSDictionary *Params = [self dictionaryWithJsonString:userInfo]; |
| | | XYRDetailViewController *play=[[XYRDetailViewController alloc]init]; |
| | | play.modalPresentationStyle = 0; |
| | | play.Model = [XYRVideoInfoModel yy_modelWithDictionary:Params]; |
| | | [self presentViewController:play animated:YES completion:^{ |
| | | |
| | |
| | | NSDictionary * dic = [ListDataArray[indexPath.section] objectForKey:@"VideoInfo"]; |
| | | NSLog(@"%ld",(long)indexPath.section); |
| | | XYRDetailViewController *play=[[XYRDetailViewController alloc]init]; |
| | | play.modalPresentationStyle = 0; |
| | | play.Model = [XYRVideoInfoModel yy_modelWithDictionary:dic]; |
| | | [self presentViewController:play animated:YES completion:^{ |
| | | |
| | |
| | | #define SuggestSearch @"suggestSearch" |
| | | |
| | | #pragma mark 搜索 |
| | | #define Search @"search" |
| | | #define Search @"searchNew" |
| | | |
| | | #pragma mark 热门搜索 |
| | | #define HotSearch @"getHotSearch" |
| | |
| | | |
| | | - (void)viewDidLoad { |
| | | [super viewDidLoad]; |
| | | [MobClick beginLogPageView:@"进入单个专题"]; |
| | | //[MobClick beginLogPageView:@"进入单个专题"]; |
| | | [self initScene]; |
| | | } |
| | | |
| | | -(void)dealloc{ |
| | | [MobClick beginLogPageView:@"退出单个专题"]; |
| | | //[MobClick beginLogPageView:@"退出单个专题"]; |
| | | } |
| | | |
| | | -(void)initScene{ |
| | |
| | | if(indexPath.section ==2){ |
| | | NSDictionary * dic = dataarr[indexPath.row]; |
| | | XYRDetailViewController *play=[[XYRDetailViewController alloc]init]; |
| | | play.modalPresentationStyle = 0; |
| | | play.Model = [XYRVideoInfoModel yy_modelWithDictionary:dic]; |
| | | [self presentViewController:play animated:YES completion:^{ |
| | | }]; |
New file |
| | |
| | | // |
| | | // SearchDetailListCell.h |
| | | // BuWanVideo2.0 |
| | | // |
| | | // Created by Aeline on 2020/9/19. |
| | | // Copyright © 2020 com.yeshi.buwansheque.ios. All rights reserved. |
| | | // |
| | | |
| | | #import <UIKit/UIKit.h> |
| | | #import "XYRVideoInfoModel.h" |
| | | |
| | | @protocol SearchDetailListCellDelegate <NSObject> |
| | | |
| | | - (void)playVideo:(XYRVideoInfoModel *_Nonnull)model; |
| | | |
| | | @end |
| | | |
| | | NS_ASSUME_NONNULL_BEGIN |
| | | |
| | | @interface SearchDetailListCell : UITableViewCell |
| | | |
| | | @property (nonatomic, nullable, strong) XYRVideoInfoModel *model; |
| | | |
| | | @property (nonatomic, weak) id<SearchDetailListCellDelegate>delegate; |
| | | |
| | | @end |
| | | |
| | | NS_ASSUME_NONNULL_END |
New file |
| | |
| | | // |
| | | // SearchDetailListCell.m |
| | | // BuWanVideo2.0 |
| | | // |
| | | // Created by Aeline on 2020/9/19. |
| | | // Copyright © 2020 com.yeshi.buwansheque.ios. All rights reserved. |
| | | // |
| | | |
| | | #import "SearchDetailListCell.h" |
| | | #import "UIImageView+YTH.h" |
| | | |
| | | @interface SearchDetailListCell () |
| | | |
| | | @property (nonatomic, nullable, strong) UIImageView *imageViewLogo; |
| | | |
| | | @property (nonatomic, nullable, strong) UILabel *labelTitle; |
| | | @property (nonatomic, nullable, strong) UILabel *labelTag; |
| | | @property (nonatomic, nullable, strong) UILabel *labelZY; |
| | | |
| | | @property (nonatomic, nullable, strong) UIButton *buttonPlay; |
| | | |
| | | @property (nonatomic, nullable, strong) UIView *viewLevel; |
| | | @end |
| | | |
| | | @implementation SearchDetailListCell |
| | | |
| | | - (void)awakeFromNib { |
| | | [super awakeFromNib]; |
| | | // Initialization code |
| | | } |
| | | |
| | | - (void)setSelected:(BOOL)selected animated:(BOOL)animated { |
| | | [super setSelected:selected animated:animated]; |
| | | |
| | | // Configure the view for the selected state |
| | | } |
| | | |
| | | - (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier { |
| | | self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; |
| | | if (self) { |
| | | self.contentView.backgroundColor = [UIColor whiteColor]; |
| | | self.selectionStyle = UITableViewCellSelectionStyleNone;//设置cell点击效果 |
| | | [self setupViewConfig]; |
| | | } |
| | | return self; |
| | | } |
| | | |
| | | - (void)setupViewConfig { |
| | | [self.contentView addSubview:self.imageViewLogo]; |
| | | [self.contentView addSubview:self.labelTitle]; |
| | | [self.contentView addSubview:self.labelTag]; |
| | | [self.contentView addSubview:self.labelZY]; |
| | | [self.contentView addSubview:self.buttonPlay]; |
| | | [self.contentView addSubview:self.viewLevel]; |
| | | } |
| | | |
| | | - (void)setModel:(XYRVideoInfoModel *)model { |
| | | _model = model; |
| | | if (model) { |
| | | [self.imageViewLogo setYthImageWithURL:model.Vpicture placeholderImage:nil]; |
| | | self.labelTitle.text = model.Name; |
| | | self.labelTag.text = model.Tag; |
| | | self.labelZY.text = model.MainActor; |
| | | |
| | | for (__strong UIView *view in [self.viewLevel subviews]) { |
| | | [view removeFromSuperview]; |
| | | view = nil; |
| | | } |
| | | for (int i = 0; i < model.VideoDetailList.count; i++) { |
| | | UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom]; |
| | | |
| | | [button setTitle:[NSString stringWithFormat:@"%@",model.VideoDetailList[i][@"Tag"]] forState:UIControlStateNormal]; |
| | | if (model.VideoDetailList.count > 5) { |
| | | if (i == 2) { |
| | | [button setTitle:@"..." forState:UIControlStateNormal]; |
| | | } |
| | | |
| | | if (i == 3) { |
| | | [button setTitle:[NSString stringWithFormat:@"%@",model.VideoDetailList[[model.VideoDetailList count] - 2][@"Tag"]] forState:UIControlStateNormal]; |
| | | } |
| | | |
| | | if (i == 4) { |
| | | [button setTitle:[NSString stringWithFormat:@"%@",model.VideoDetailList[[model.VideoDetailList count] - 1][@"Tag"]] forState:UIControlStateNormal]; |
| | | } |
| | | } |
| | | |
| | | [button setTitleColor:UIColorFromRGBValue(0x000000) forState:UIControlStateNormal]; |
| | | button.titleLabel.font = [UIFont systemFontOfSize:12]; |
| | | button.backgroundColor = UIColorFromRGBValue(0xD3D3D3); |
| | | button.layer.masksToBounds = YES; |
| | | button.layer.cornerRadius = 5; |
| | | button.tag = i; |
| | | [self.viewLevel addSubview:button]; |
| | | CGFloat width = (KScreenW - 60) / 5; |
| | | button.frame = CGRectMake(10 + 10 * i + width * i, 0, width, 29); |
| | | |
| | | [button addTarget:self action:@selector(touchIndex:) forControlEvents:UIControlEventTouchUpInside]; |
| | | } |
| | | } |
| | | } |
| | | |
| | | - (void)touchIndex:(UIButton *)button { |
| | | if (_delegate && [_delegate respondsToSelector:@selector(playVideo:)]) { |
| | | [_delegate playVideo:_model]; |
| | | } |
| | | } |
| | | |
| | | - (UIImageView *)imageViewLogo { |
| | | if (!_imageViewLogo) { |
| | | _imageViewLogo = [[UIImageView alloc] initWithFrame:CGRectMake(9, 15, 95, 131)]; |
| | | [_imageViewLogo setContentScaleFactor:[[UIScreen mainScreen] scale]]; |
| | | _imageViewLogo.contentMode = UIViewContentModeScaleAspectFill; |
| | | _imageViewLogo.clipsToBounds = YES; |
| | | _imageViewLogo.backgroundColor = UIColorFromRGBValue(0xf4f4f4); |
| | | } |
| | | return _imageViewLogo; |
| | | } |
| | | |
| | | - (UILabel *)labelTitle { |
| | | if (!_labelTitle) { |
| | | _labelTitle = [[UILabel alloc] initWithFrame:CGRectMake(CGRectGetMaxX(self.imageViewLogo.frame) + 17, 16, KScreenW - 121, 15)]; |
| | | _labelTitle.textColor = UIColorFromRGBValue(0x000000); |
| | | _labelTitle.textAlignment = NSTextAlignmentLeft; |
| | | _labelTitle.font = [UIFont systemFontOfSize:15]; |
| | | } |
| | | return _labelTitle; |
| | | } |
| | | |
| | | - (UILabel *)labelTag { |
| | | if (!_labelTag) { |
| | | _labelTag = [[UILabel alloc] initWithFrame:CGRectMake(CGRectGetMaxX(self.imageViewLogo.frame) + 17, CGRectGetMaxY(self.labelTitle.frame) + 7, KScreenW - 131, 15)]; |
| | | _labelTag.textColor = UIColorFromRGBValue(0xA3A3A3); |
| | | _labelTag.textAlignment = NSTextAlignmentLeft; |
| | | _labelTag.font = [UIFont systemFontOfSize:12]; |
| | | } |
| | | return _labelTag; |
| | | } |
| | | |
| | | - (UILabel *)labelZY { |
| | | if (!_labelZY) { |
| | | _labelZY = [[UILabel alloc] initWithFrame:CGRectMake(CGRectGetMaxX(self.imageViewLogo.frame) + 17, CGRectGetMaxY(self.labelTag.frame) + 15, KScreenW - 131, 30)]; |
| | | _labelZY.textColor = UIColorFromRGBValue(0xA3A3A3); |
| | | _labelZY.textAlignment = NSTextAlignmentLeft; |
| | | _labelZY.font = [UIFont systemFontOfSize:12]; |
| | | _labelZY.lineBreakMode = NSLineBreakByTruncatingTail; |
| | | _labelZY.numberOfLines = 2; |
| | | } |
| | | return _labelZY; |
| | | } |
| | | |
| | | - (UIButton *)buttonPlay { |
| | | if (!_buttonPlay) { |
| | | _buttonPlay = [UIButton buttonWithType:UIButtonTypeCustom]; |
| | | _buttonPlay.frame = CGRectMake(CGRectGetMaxX(self.imageViewLogo.frame) + 17, CGRectGetMaxY(self.labelZY.frame) + 15, 109, 24); |
| | | [_buttonPlay setTitle:@"立即播放" forState:UIControlStateNormal]; |
| | | [_buttonPlay setTitleColor:UIColorFromRGBValue(0xFFE84E) forState:UIControlStateNormal]; |
| | | _buttonPlay.titleLabel.font = [UIFont systemFontOfSize:12]; |
| | | _buttonPlay.backgroundColor = UIColorFromRGBValue(0x0051F5); |
| | | _buttonPlay.layer.masksToBounds = YES; |
| | | _buttonPlay.layer.cornerRadius = 12; |
| | | [_buttonPlay addTarget:self action:@selector(touchIndex:) forControlEvents:UIControlEventTouchUpInside]; |
| | | } |
| | | return _buttonPlay; |
| | | } |
| | | |
| | | - (UIView *)viewLevel { |
| | | if (!_viewLevel) { |
| | | _viewLevel = [[UIView alloc] initWithFrame:CGRectMake(0, CGRectGetMaxY(self.imageViewLogo.frame) + 8, KScreenW, 29)]; |
| | | } |
| | | return _viewLevel; |
| | | } |
| | | |
| | | - (CGSize)sizeWithText:(NSString *)text font:(UIFont *)font maxSize:(CGSize)maxSize { |
| | | NSDictionary *attrs = @{NSFontAttributeName:font}; |
| | | return [text boundingRectWithSize:maxSize options:NSStringDrawingUsesLineFragmentOrigin attributes:attrs context:nil].size; |
| | | } |
| | | |
| | | @end |
New file |
| | |
| | | // |
| | | // SearchTitleView.h |
| | | // BuWanVideo2.0 |
| | | // |
| | | // Created by Aeline on 2020/9/19. |
| | | // Copyright © 2020 com.yeshi.buwansheque.ios. All rights reserved. |
| | | // |
| | | |
| | | #import <UIKit/UIKit.h> |
| | | |
| | | NS_ASSUME_NONNULL_BEGIN |
| | | |
| | | @protocol SearchTitleViewDelegate <NSObject> |
| | | |
| | | - (void)selectType:(NSInteger)type; |
| | | |
| | | @end |
| | | |
| | | @interface SearchTitleView : UIView |
| | | |
| | | - (void)setTitleData:(NSArray *)typeList :(BOOL)isSearch; |
| | | |
| | | @property (nonatomic, nullable, strong) NSArray *typeList; |
| | | |
| | | @property (nonatomic, weak) id<SearchTitleViewDelegate>delegate; |
| | | |
| | | |
| | | |
| | | @end |
| | | |
| | | NS_ASSUME_NONNULL_END |
New file |
| | |
| | | // |
| | | // SearchTitleView.m |
| | | // BuWanVideo2.0 |
| | | // |
| | | // Created by Aeline on 2020/9/19. |
| | | // Copyright © 2020 com.yeshi.buwansheque.ios. All rights reserved. |
| | | // |
| | | |
| | | #import "SearchTitleView.h" |
| | | |
| | | @interface SearchTitleView () |
| | | |
| | | @property (nonatomic, strong) UIScrollView *scrollView; |
| | | |
| | | @property (nonatomic, strong) UIButton *buttonLast; |
| | | |
| | | @property (nonatomic, strong) UIView *line; |
| | | @end |
| | | |
| | | @implementation SearchTitleView |
| | | |
| | | - (instancetype)initWithFrame:(CGRect)frame { |
| | | self = [super initWithFrame:frame]; |
| | | if (self) { |
| | | self.backgroundColor = UIColorFromRGBValue(0x000000); |
| | | [self setupViewConifg]; |
| | | } |
| | | return self; |
| | | } |
| | | |
| | | - (void)setupViewConifg { |
| | | [self addSubview:self.scrollView]; |
| | | } |
| | | |
| | | - (void)setTitleData:(NSArray *)typeList :(BOOL)isSearch { |
| | | self.typeList = typeList; |
| | | if (typeList) { |
| | | //if ([[self.scrollView subviews] count] > 1) return; |
| | | if (!isSearch) return; |
| | | |
| | | for (UIView *view in [self.scrollView subviews]) { |
| | | [view removeFromSuperview]; |
| | | } |
| | | |
| | | CGFloat scrWidth = 0; |
| | | for (int i = 0; i < typeList.count; i++) { |
| | | UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom]; |
| | | [button setTitle:typeList[i][@"Name"] forState:UIControlStateNormal]; |
| | | [button setTitleColor:UIColorFromRGBValue(0x999999) forState:UIControlStateNormal]; |
| | | [button setTitleColor:UIColorFromRGBValue(0xFFFFFF) forState:UIControlStateSelected]; |
| | | button.titleLabel.font = [UIFont systemFontOfSize:12]; |
| | | button.tag = i; |
| | | [self.scrollView addSubview:button]; |
| | | |
| | | if (i == 0) { |
| | | button.selected = YES; |
| | | self.buttonLast = button; |
| | | } |
| | | CGFloat width = 0; |
| | | width = [self sizeWithText:typeList[i][@"Name"] font:[UIFont boldSystemFontOfSize:12] maxSize:CGSizeMake(MAXFLOAT, MAXFLOAT)].width; |
| | | |
| | | if (i == 0) { |
| | | scrWidth = 17; |
| | | } |
| | | |
| | | button.frame = CGRectMake(scrWidth, 5, width, 30); |
| | | |
| | | scrWidth += width + 25; |
| | | |
| | | [button addTarget:self action:@selector(touchIndex:) forControlEvents:UIControlEventTouchUpInside]; |
| | | |
| | | if (i == 0) { |
| | | button.transform = CGAffineTransformMakeScale(1.5, 1.5); |
| | | } |
| | | |
| | | } |
| | | [self.scrollView addSubview:self.line]; |
| | | UIButton *button = [self.scrollView subviews][1]; |
| | | self.line.frame = CGRectMake(11, 38, button.bounds.size.width, 2); |
| | | self.scrollView.contentSize = CGSizeMake(scrWidth, 40); |
| | | } |
| | | } |
| | | |
| | | - (void)touchIndex:(UIButton *)button { |
| | | |
| | | if (button.tag == self.buttonLast.tag) return; |
| | | self.buttonLast.transform = CGAffineTransformMakeScale(1.0, 1.0); |
| | | self.buttonLast.selected = NO; |
| | | //self.buttonLast.titleLabel.font = [UIFont systemFontOfSize:12]; |
| | | |
| | | button.transform = CGAffineTransformMakeScale(1.5, 1.5); |
| | | button.selected = YES; |
| | | // button.titleLabel.font = [UIFont boldSystemFontOfSize:17]; |
| | | |
| | | |
| | | // CGFloat width1 = [self sizeWithText:self.buttonLast.titleLabel.text font:[UIFont systemFontOfSize:12] maxSize:CGSizeMake(MAXFLOAT, MAXFLOAT)].width; |
| | | // |
| | | // |
| | | // CGFloat width2 = [self sizeWithText:button.titleLabel.text font:[UIFont boldSystemFontOfSize:17] maxSize:CGSizeMake(MAXFLOAT, MAXFLOAT)].width; |
| | | // |
| | | // |
| | | // self.buttonLast.frame = CGRectMake(self.buttonLast.frame.origin.x, 5, width1, 30); |
| | | // |
| | | // button.frame = CGRectMake(button.frame.origin.x, 5, width2, 30); |
| | | |
| | | self.buttonLast = button; |
| | | __weak typeof(self) weakSelf = self; |
| | | [UIView animateWithDuration:0.2 animations:^{ |
| | | if ([_typeList[button.tag][@"Name"] length] >= 3) { |
| | | weakSelf.line.frame = CGRectMake(button.frame.origin.x, 38, button.bounds.size.width + 20, 2); |
| | | |
| | | } else { |
| | | weakSelf.line.frame = CGRectMake(button.frame.origin.x, 38, button.bounds.size.width + 10, 2); |
| | | } |
| | | |
| | | }]; |
| | | |
| | | if (_delegate && [_delegate respondsToSelector:@selector(selectType:)]) { |
| | | [_delegate selectType:[_typeList[button.tag][@"Id"] integerValue]]; |
| | | } |
| | | } |
| | | |
| | | - (UIScrollView *)scrollView { |
| | | if (!_scrollView) { |
| | | _scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, KScreenW, 40)]; |
| | | _scrollView.showsHorizontalScrollIndicator = NO; |
| | | } |
| | | return _scrollView; |
| | | } |
| | | |
| | | - (UIView *)line { |
| | | if (!_line) { |
| | | _line = [[UIView alloc] init]; |
| | | _line.backgroundColor = UIColorFromRGBValue(0xFFE84E); |
| | | } |
| | | return _line; |
| | | } |
| | | |
| | | - (CGSize)sizeWithText:(NSString *)text font:(UIFont *)font maxSize:(CGSize)maxSize { |
| | | NSDictionary *attrs = @{NSFontAttributeName:font}; |
| | | return [text boundingRectWithSize:maxSize options:NSStringDrawingUsesLineFragmentOrigin attributes:attrs context:nil].size; |
| | | } |
| | | |
| | | @end |
| | |
| | | // |
| | | |
| | | #import "SettingWebView.h" |
| | | #import <WebKit/WebKit.h> |
| | | |
| | | @interface SettingWebView () |
| | | |
| | |
| | | if (KIsiPhoneX) { |
| | | height = 84; |
| | | } |
| | | UIWebView *webView = [[UIWebView alloc] initWithFrame:CGRectMake(0, height, KScreenW, KScreenH - height)]; |
| | | NSURLRequest *request =[NSURLRequest requestWithURL:[NSURL URLWithString:_requestURL]]; |
| | | |
| | | WKWebView *webView = [[WKWebView alloc] initWithFrame:CGRectMake(0, height, KScreenW, KScreenH - height)]; |
| | | [self.view addSubview: webView]; |
| | | NSURLRequest *request =[NSURLRequest requestWithURL:[NSURL URLWithString:_requestURL]]; |
| | | [webView loadRequest:request]; |
| | | |
| | | // Do any additional setup after loading the view from its nib. |
| | | } |
| | | -(void)presentBack{ |
| | |
| | | // |
| | | |
| | | #import <Foundation/Foundation.h> |
| | | #import <UShareUI/UShareUI.h> |
| | | #import <UMSocialCore/UMSocialCore.h> //友盟分享 |
| | | |
| | | #import <AVFoundation/AVFoundation.h> |
| | | |
| | | typedef void(^closure)(); |
| | |
| | | @property (nonatomic ,strong) NSString *shareTitle; |
| | | |
| | | @property (nonatomic ,strong) UIImage *shareImage; |
| | | |
| | | |
| | | /** |
| | | 分享 |
| | | |
| | | @param controller 当前视图控制器 |
| | | @param text 标题、内容、链接 |
| | | @param image 图片 |
| | | */ |
| | | +(void)shareAPP:(UIViewController*)controller;//分享内容和图片 |
| | | |
| | | /** |
| | | 判断是否是电子邮箱 |
| | |
| | | @implementation Share |
| | | |
| | | /** |
| | | 分享 |
| | | |
| | | @param controller 当前视图控制器 |
| | | @param text 标题、内容、链接 |
| | | @param image 图片 |
| | | */ |
| | | +(void)shareAPP:(UIViewController*)controller{//分享响应 标题 内容 分享链接 |
| | | NSMutableArray *shareAry=[NSMutableArray array]; |
| | | if ([[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:@"mqq://"]]) { |
| | | NSArray *QQArr=@[@{@"image":@"newqq",@"title":@"QQ"},@{@"image":@"newqq空间",@"title":@"QQ空间"}]; |
| | | [shareAry addObjectsFromArray:QQArr]; |
| | | } |
| | | |
| | | if ([[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:@"weixin://"]]){ |
| | | NSArray *WXArr=@[@{@"image":@"new微信",@"title":@"微信"},@{@"image":@"new朋友圈",@"title":@"朋友圈"}]; |
| | | [shareAry addObjectsFromArray:WXArr]; |
| | | } |
| | | if ([[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:@"sinaweibo://"]]){ |
| | | NSArray *XLArr=@[@{@"image":@"new微博",@"title":@"新浪微博"}]; |
| | | [shareAry addObjectsFromArray:XLArr]; |
| | | } |
| | | |
| | | UIView *headerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, KScreenW, 54)]; |
| | | headerView.backgroundColor = [UIColor clearColor]; |
| | | |
| | | UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 20, headerView.frame.size.width, 15)]; |
| | | label.textAlignment = NSTextAlignmentCenter; |
| | | label.textColor = [UIColor blackColor]; |
| | | label.backgroundColor = [UIColor clearColor]; |
| | | label.font = [UIFont systemFontOfSize:15]; |
| | | label.text = @"分享到"; |
| | | [headerView addSubview:label]; |
| | | |
| | | UILabel *lineLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, headerView.frame.size.height-0.5, headerView.frame.size.width, 0.5)]; |
| | | lineLabel.backgroundColor = [UIColor colorWithRed:208/255.0 green:208/255.0 blue:208/255.0 alpha:1.0]; |
| | | [headerView addSubview:lineLabel]; |
| | | |
| | | UILabel *lineLabel1 = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, headerView.frame.size.width, 0.5)]; |
| | | lineLabel1.backgroundColor = [UIColor colorWithRed:208/255.0 green:208/255.0 blue:208/255.0 alpha:1.0]; |
| | | |
| | | HXEasyCustomShareView *shareView = [[HXEasyCustomShareView alloc] initWithFrame:CGRectMake(0, 0, KScreenW, KScreenH)]; |
| | | shareView.backView.backgroundColor = [UIColor colorWithRed:255/255.0 green:255/255.0 blue:255/255.0 alpha:1.0]; |
| | | shareView.headerView = headerView; |
| | | float height = [shareView getBoderViewHeight:shareAry firstCount:0]; |
| | | shareView.boderView.frame = CGRectMake(0, 0, shareView.frame.size.width, height); |
| | | shareView.middleLineLabel.hidden = YES; |
| | | [shareView.cancleButton addSubview:lineLabel1]; |
| | | shareView.cancleButton.frame = CGRectMake(shareView.cancleButton.frame.origin.x, shareView.cancleButton.frame.origin.y, shareView.cancleButton.frame.size.width, 54); |
| | | shareView.cancleButton.titleLabel.font = [UIFont systemFontOfSize:16]; |
| | | [shareView.cancleButton setTitleColor:[UIColor colorWithRed:184/255.0 green:184/255.0 blue:184/255.0 alpha:1.0] forState:UIControlStateNormal]; |
| | | [shareView setShareAry:shareAry delegate:controller]; |
| | | [controller.view addSubview:shareView]; |
| | | } |
| | | |
| | | /** |
| | | 判断是否是电子邮箱 |
| | | |
| | | @param candidate 传入需要验证的邮箱地址 |
| | |
| | | |
| | | - (void)viewDidLoad { |
| | | [super viewDidLoad]; |
| | | [MobClick beginLogPageView:@"进入明星合集"]; |
| | | //[MobClick beginLogPageView:@"进入明星合集"]; |
| | | |
| | | [self initScene]; |
| | | } |
| | | |
| | | -(void)dealloc{ |
| | | [MobClick beginLogPageView:@"退出明星合集"]; |
| | | //[MobClick beginLogPageView:@"退出明星合集"]; |
| | | } |
| | | |
| | | -(void)initScene{ |
| | |
| | | #import "HeaderCollectionReusableView.h" |
| | | #import "GoogleAdTableViewCell.h" |
| | | |
| | | @import GoogleMobileAds;//谷歌广告 |
| | | |
| | | @interface SubregionDetailViewController ()<UIScrollViewDelegate,UITableViewDelegate,UITableViewDataSource,UICollectionViewDelegate,UICollectionViewDataSource,UICollectionViewDelegateFlowLayout,GADNativeAppInstallAdLoaderDelegate, GADNativeContentAdLoaderDelegate>{ |
| | | @interface SubregionDetailViewController ()<UIScrollViewDelegate,UITableViewDelegate,UITableViewDataSource,UICollectionViewDelegate,UICollectionViewDataSource,UICollectionViewDelegateFlowLayout>{ |
| | | NSInteger SpeciesNumber;//种类的位置 |
| | | NSInteger typeNumber;//细分类 |
| | | |
| | |
| | | @property (nonatomic , strong) NSMutableArray *addrssForshuffling;//装载推荐轮播图的地址 |
| | | @property (nonatomic , strong) NSMutableArray *TitleForshuffling;//装载轮播图的标题 |
| | | |
| | | @property(nonatomic, strong) GADAdLoader *adLoader;//谷歌广告 |
| | | @property(nonatomic, strong) UIView *nativeAdView;//装载谷歌广告的视图 |
| | | @property (weak, nonatomic) IBOutlet NSLayoutConstraint *toplayout; |
| | | @property (nonatomic,assign)NSInteger kNavHeight; |
| | |
| | | { |
| | | [super viewWillAppear:animated]; |
| | | NSString *str=[NSString stringWithFormat:@"分类的%@界面",self.titles]; |
| | | [MobClick beginLogPageView:str]; |
| | | //[MobClick beginLogPageView:str]; |
| | | } |
| | | |
| | | - (void)viewWillDisappear:(BOOL)animated |
| | | { |
| | | [super viewWillDisappear:animated]; |
| | | NSString *str=[NSString stringWithFormat:@"分类的%@界面",self.titles]; |
| | | [MobClick endLogPageView:str]; |
| | | //[MobClick endLogPageView:str]; |
| | | } |
| | | |
| | | /** |
| | |
| | | [self.navigationController popViewControllerAnimated:YES]; |
| | | } |
| | | |
| | | /** |
| | | * 加载谷歌广告 |
| | | */ |
| | | -(void)loadgoogleAd{ |
| | | NSMutableArray *adTypes = [[NSMutableArray alloc] init]; |
| | | [adTypes addObject:kGADAdLoaderAdTypeNativeAppInstall]; |
| | | |
| | | GADNativeAdImageAdLoaderOptions *adOptions=[[GADNativeAdImageAdLoaderOptions alloc] init]; |
| | | adOptions.disableImageLoading=YES; |
| | | |
| | | self.adLoader = [[GADAdLoader alloc] initWithAdUnitID:AdGoogleKey |
| | | rootViewController:self |
| | | adTypes:adTypes |
| | | options:nil]; |
| | | self.adLoader.delegate = self; |
| | | [self.adLoader loadRequest:[GADRequest request]]; |
| | | } |
| | | |
| | | /// Gets an image representing the number of stars. Returns nil if rating is less than 3.5 stars. |
| | | - (UIImage *)imageForStars:(NSDecimalNumber *)numberOfStars { |
| | | double starRating = [numberOfStars doubleValue]; |
| | |
| | | } |
| | | [_dataDic setObject:_dataAry forKey:str]; |
| | | [_dataDic setObject:pagenumber forKey:str2]; |
| | | //请求谷歌广告 |
| | | [self loadgoogleAd]; |
| | | |
| | | |
| | | //刷新视图 |
| | | UITableView *tableView=[self.view viewWithTag:800+SpeciesNumber]; |
| | | [tableView.mj_header endRefreshing]; |
| | |
| | | NSString *str=[NSString stringWithFormat:@"ValueX%@Y%ldZ%ld",_Species,(long)SpeciesNumber,(long)typeNumber]; |
| | | NSMutableArray *dataAry=[_dataDic objectForKey:str]; |
| | | XYRDetailViewController *detailVC=[[XYRDetailViewController alloc] init]; |
| | | detailVC.modalPresentationStyle = 0; |
| | | if(LoadGoogleAD){//加载广告 |
| | | detailVC.Model=[XYRVideoInfoModel yy_modelWithDictionary:dataAry[indexPath.row-indexPath.row/20]]; |
| | | }else{ |
| | |
| | | return; |
| | | } |
| | | XYRDetailViewController *play=[[XYRDetailViewController alloc]init]; |
| | | play.modalPresentationStyle = 0; |
| | | play.Model = [XYRVideoInfoModel yy_modelWithDictionary:_hotListData[indexPath.row]]; |
| | | [self presentViewController:play animated:YES completion:^{ |
| | | |
| | |
| | | return UIEdgeInsetsMake(0, 10, 10, 10); |
| | | } |
| | | |
| | | #pragma mark -GADNativeAppInstallAdLoaderDelegate |
| | | - (void)adLoader:(GADAdLoader *)adLoader |
| | | didReceiveNativeAppInstallAd:(GADNativeAppInstallAd *)nativeAppInstallAd{ |
| | | // Create a new AdView instance from the xib file. |
| | | GADNativeAppInstallAdView *appInstallAdView = |
| | | [[[NSBundle mainBundle] loadNibNamed:@"View" |
| | | owner:nil |
| | | options:nil] firstObject]; |
| | | appInstallAdView.frame=CGRectMake(0, 0, KScreenW, 50); |
| | | |
| | | // Associate the app install ad view with the app install ad object. |
| | | // This is required to make the ad clickable. |
| | | appInstallAdView.nativeAppInstallAd = nativeAppInstallAd; |
| | | |
| | | // Populate the app install ad view with the app install ad assets. |
| | | ((UILabel *)appInstallAdView.headlineView).text = nativeAppInstallAd.headline; |
| | | [((UIButton *)appInstallAdView.callToActionView) |
| | | setTitle:nativeAppInstallAd.callToAction |
| | | forState:UIControlStateNormal]; |
| | | ((UIImageView *)appInstallAdView.iconView).image = nativeAppInstallAd.icon.image; |
| | | ((UILabel *)appInstallAdView.bodyView).text = nativeAppInstallAd.body; |
| | | ((UILabel *)appInstallAdView.storeView).text = nativeAppInstallAd.store; |
| | | ((UILabel *)appInstallAdView.priceView).text = nativeAppInstallAd.price; |
| | | ((UIImageView *)appInstallAdView.imageView).image = |
| | | ((GADNativeAdImage *)[nativeAppInstallAd.images firstObject]).image; |
| | | ((UIImageView *)appInstallAdView.starRatingView).image = |
| | | [self imageForStars:nativeAppInstallAd.starRating]; |
| | | |
| | | // In order for the SDK to process touch events properly, user interaction |
| | | // should be disabled on UIButtons. |
| | | appInstallAdView.callToActionView.userInteractionEnabled = NO; |
| | | |
| | | // Add appInstallAdView to the view controller's view. |
| | | self.nativeAdView=appInstallAdView; |
| | | } |
| | | |
| | | - (void)scrollViewDidScroll:(UIScrollView *)scrollView { |
| | | |
| | | if (scrollView.contentOffset.y<KScreenH/2) { |
| | |
| | | [self.topButton setHidden:NO]; |
| | | } |
| | | } |
| | | #pragma mark -GADAdLoaderDelegate |
| | | /** |
| | | * 广告加载失败 |
| | | */ |
| | | - (void)adLoader:(GADAdLoader *)adLoader didFailToReceiveAdWithError:(GADRequestError *)error { |
| | | NSLog(@"%@ failed with error: %@", adLoader, [error localizedDescription]); |
| | | //谷歌广告获取失败 |
| | | //通知视图加载芒果广告 |
| | | googleNoAdToShow=YES; |
| | | //刷新视图 |
| | | UITableView *tableView=[self.view viewWithTag:800+SpeciesNumber]; |
| | | [tableView reloadData]; |
| | | } |
| | | |
| | | - (void)dealloc{ |
| | | |
| | | } |
| | |
| | | |
| | | - (void)viewDidLoad { |
| | | [super viewDidLoad]; |
| | | [MobClick beginLogPageView:@"进入图文社"]; |
| | | |
| | | |
| | | [self initS]; |
| | | [self initTypedata]; |
| | | } |
| | | |
| | | -(void)dealloc{ |
| | | [MobClick beginLogPageView:@"退出图文社"]; |
| | | |
| | | } |
| | | |
| | | -(void)initS{ |
| | |
| | | // |
| | | |
| | | #import "WebControllerView.h" |
| | | #import "NJKWebViewProgress.h" |
| | | #import "NJKWebViewProgressView.h" |
| | | #import <WebKit/WebKit.h> |
| | | |
| | | @interface WebControllerView ()<UIWebViewDelegate,NJKWebViewProgressDelegate>{ |
| | | UIWebView * webview; |
| | | NJKWebViewProgressView *_progressView; |
| | | NJKWebViewProgress *_progressProxy; |
| | | @interface WebControllerView () <WKUIDelegate, WKNavigationDelegate> { |
| | | WKWebView * webview; |
| | | UIButton *button2; |
| | | CABasicAnimation *animation; |
| | | } |
| | |
| | | [self initScene]; |
| | | } |
| | | |
| | | -(void)initScene{ |
| | | -(void)initScene { |
| | | |
| | | self.navigationItem.title = @"发现"; |
| | | self.view.backgroundColor=[UIColor whiteColor]; |
| | |
| | | UIBarButtonItem *bar3 = [[UIBarButtonItem alloc]initWithCustomView:button2]; |
| | | self.navigationItem.rightBarButtonItem = bar3; |
| | | |
| | | webview = [UIWebView new]; |
| | | webview.frame = CGRectMake(0,0, self.view.frame.size.width, self.view.frame.size.height); |
| | | [webview loadRequest:[NSURLRequest requestWithURL:url]]; |
| | | webview.delegate = self; |
| | | webview = [[WKWebView alloc] initWithFrame:CGRectMake(0,0, self.view.frame.size.width, self.view.frame.size.height)]; |
| | | webview.UIDelegate = self; |
| | | webview.navigationDelegate = self; |
| | | |
| | | [self.view addSubview:webview]; |
| | | |
| | | //进度条 |
| | | CGRect barFrame = CGRectMake(0, 64, self.view.frame.size.width, 2); |
| | | |
| | | _progressView = [[NJKWebViewProgressView alloc] initWithFrame:barFrame]; |
| | | _progressView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleTopMargin; |
| | | [self.view addSubview:_progressView]; |
| | | |
| | | _progressProxy = [[NJKWebViewProgress alloc] init]; |
| | | webview.delegate = _progressProxy; |
| | | _progressProxy.webViewProxyDelegate = self; |
| | | _progressProxy.progressDelegate = self; |
| | | NSURLRequest *request = [NSURLRequest requestWithURL:url]; |
| | | [webview loadRequest:request]; |
| | | |
| | | [self beginrotate]; |
| | | } |
| | |
| | | } |
| | | } |
| | | |
| | | -(void)refurbish{ |
| | | -(void)refurbish { |
| | | [webview reload]; |
| | | } |
| | | |
| | | #pragma mark UIWebViewDelegate |
| | | - (void)webViewDidStartLoad:(UIWebView *)webView{ |
| | | //9.0才能使用,web内容处理中断时会触发 |
| | | - (void)webViewWebContentProcessDidTerminate:(WKWebView *)webView { |
| | | [webView reload]; |
| | | } |
| | | |
| | | // 页面开始加载时调用 |
| | | - (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation { |
| | | if(!animation){ |
| | | [self beginrotate]; |
| | | } |
| | | } |
| | | |
| | | - (void)webViewDidFinishLoad:(UIWebView *)webView{ |
| | | [self stoprotate]; |
| | | // 页面加载失败时调用 |
| | | - (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(null_unspecified WKNavigation *)navigation withError:(NSError *)error { |
| | | } |
| | | |
| | | #pragma mark - NJKWebViewProgressDelegate |
| | | -(void)webViewProgress:(NJKWebViewProgress *)webViewProgress updateProgress:(float)progress{ |
| | | [_progressView setProgress:progress animated:YES]; |
| | | // 页面加载完成之后调用 |
| | | - (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation { |
| | | [self stoprotate]; |
| | | } |
| | | |
| | | -(void)beginrotate{ |
| | |
| | | [button2.layer addAnimation:animation forKey:@"rotationAnimation"]; |
| | | } |
| | | |
| | | -(void)stoprotate{ |
| | | - (void)stoprotate { |
| | | [button2.layer removeAllAnimations]; |
| | | animation = nil; |
| | | } |
| | |
| | | [dic setObject:key forKey:@"key"]; |
| | | [dic setObject:contentid forKey:@"contentid"]; |
| | | [dic setObject:type forKey:@"type"]; |
| | | [dic setObject:device forKey:@"device"]; |
| | | |
| | | if (device) { |
| | | [dic setObject:device forKey:@"device"]; |
| | | } |
| | | AFHTTPSessionManager *manager = [AFHTTPSessionManager manager]; |
| | | manager.responseSerializer = [AFHTTPResponseSerializer serializer]; |
| | | [manager GET:url parameters:dic progress:^(NSProgress * _Nonnull downloadProgress) { |
| | |
| | | //广点通原生广告 |
| | | //#import "GDTNativeAd.h" |
| | | //广点通banner广告 |
| | | #import "GDTMobBannerView.h" |
| | | //#import "GDTMobBannerView.h" |
| | | |
| | | //优酷播放器 |
| | | //#import "YTEngineOpenViewManager.h" |
| | |
| | | #import "GDTNativeExpressAd.h" |
| | | #import "GDTNativeExpressAdView.h" |
| | | |
| | | #import <BUAdSDK/BUAdSDK.h> |
| | | |
| | | #define MARGIN 5 |
| | | #define BACK_WIDTH (DEVICE_TYPE_IPAD ? 30 : 20) |
| | |
| | | #define BETWEEN_BOUND_FULL 100 |
| | | #define BETWEEN_BOUND_NORMAL 20 |
| | | |
| | | @interface XYRDetailViewController ()<CMuneBarDelegate,UIScrollViewDelegate,UICollectionViewDelegate,UICollectionViewDataSource,UICollectionViewDelegateFlowLayout,UITableViewDelegate,UITableViewDataSource,UITextFieldDelegate,YTHNetDelegateRecommend,UIGestureRecognizerDelegate,YTHBacktoApplicationsDelegate,GDTNativeExpressAdDelegete,GDTMobBannerViewDelegate,HXEasyCustomShareViewDelegate>{ |
| | | @interface XYRDetailViewController ()<CMuneBarDelegate,UIScrollViewDelegate,UICollectionViewDelegate,UICollectionViewDataSource,UICollectionViewDelegateFlowLayout,UITableViewDelegate,UITableViewDataSource,UITextFieldDelegate,YTHNetDelegateRecommend,UIGestureRecognizerDelegate,YTHBacktoApplicationsDelegate,GDTNativeExpressAdDelegete,HXEasyCustomShareViewDelegate,BUNativeExpressFullscreenVideoAdDelegate>{ |
| | | int _gather;//集数加载更多的控制变量,默认为1 |
| | | int isCollectNum;//当前选中的集 |
| | | |
| | |
| | | CGSize CELLSize;//选择集cell的大小 |
| | | |
| | | //广点通原生广告 |
| | | // GDTNativeAd *_nativeAd; //原生广告实例 |
| | | // NSMutableArray *nativeArray;//存储请求下来的原生广告信息 |
| | | // GDTNativeAd *_nativeAd; //原生广告实例 |
| | | // NSMutableArray *nativeArray;//存储请求下来的原生广告信息 |
| | | } |
| | | |
| | | @property (weak, nonatomic) IBOutlet NSLayoutConstraint *imageH;//顶部图片的高 |
| | |
| | | @property (nonatomic, strong) NSDate *startTime; |
| | | @property (nonatomic, strong) NSArray *expressAdViews; |
| | | @property (nonatomic, strong) GDTNativeExpressAd *nativeExpressAd; |
| | | |
| | | @property (nonatomic, strong) BUNativeExpressFullscreenVideoAd *fullscreenVideoAd; |
| | | |
| | | @end |
| | | |
| | | @implementation XYRDetailViewController |
| | |
| | | //实现出去应用或者回到应用的处理 |
| | | ApplicationDelegate.YBackAppDelegate = self; |
| | | if (KIsiPhoneX) { |
| | | // self.topLayout.constant = 20; |
| | | // self.topLayout.constant = 20; |
| | | self.backLayout.constant = 39; |
| | | }else{ |
| | | // self.topLayout.constant = 0; |
| | | // self.topLayout.constant = 0; |
| | | self.backLayout.constant = 19; |
| | | |
| | | |
| | | } |
| | | //加载基础数据 |
| | | [self loadData]; |
| | |
| | | [self addTitleBackView]; |
| | | //加载视频详情页面的数据 |
| | | [self getVideoDetailViewWithMovieId:self.Model.Id WithThirdType:self.Model.ThirdType WithResourceId:nil]; |
| | | |
| | | if ([YTHsharedManger startManger].ad[@"videoDetailFullVideo"] && [[YTHsharedManger startManger].ad[@"videoDetailFullVideo"] isEqualToString:@"csj"]) { |
| | | [self loadFullscreenVideoAd]; |
| | | } |
| | | } |
| | | |
| | | - (void)viewWillAppear:(BOOL)animated{ |
| | | - (void)loadFullscreenVideoAd { |
| | | self.fullscreenVideoAd = [[BUNativeExpressFullscreenVideoAd alloc] initWithSlotID:@"945472378"]; |
| | | self.fullscreenVideoAd.delegate = self; |
| | | [self.fullscreenVideoAd loadAdData]; |
| | | } |
| | | |
| | | //此方法在视频广告素材加载成功时调用。 |
| | | - (void)nativeExpressFullscreenVideoAdDidLoad:(BUNativeExpressFullscreenVideoAd *)fullscreenVideoAd { |
| | | |
| | | } |
| | | |
| | | //当视频广告素材加载失败时调用此方法。 |
| | | - (void)nativeExpressFullscreenVideoAd:(BUNativeExpressFullscreenVideoAd *)fullscreenVideoAd didFailWithError:(NSError *_Nullable)error { |
| | | |
| | | } |
| | | |
| | | //此方法在成功呈现nativeExpressAdView时调用。 |
| | | - (void)nativeExpressFullscreenVideoAdViewRenderSuccess:(BUNativeExpressFullscreenVideoAd *)rewardedVideoAd { |
| | | |
| | | } |
| | | |
| | | //当nativeExpressAdView无法呈现时,将调用此方法 |
| | | - (void)nativeExpressFullscreenVideoAdViewRenderFail:(BUNativeExpressFullscreenVideoAd *)rewardedVideoAd error:(NSError *_Nullable)error { |
| | | |
| | | } |
| | | //当视频缓存成功时调用此方法 |
| | | - (void)nativeExpressFullscreenVideoAdDidDownLoadVideo:(BUNativeExpressFullscreenVideoAd *)fullscreenVideoAd { |
| | | [fullscreenVideoAd showAdFromRootViewController:self]; |
| | | } |
| | | |
| | | //此方法在用户单击“跳过”按钮时调用 |
| | | - (void)nativeExpressFullscreenVideoAdDidClickSkip:(BUNativeExpressFullscreenVideoAd *)fullscreenVideoAd { |
| | | |
| | | } |
| | | |
| | | //此方法在视频广告即将关闭时调用。 |
| | | - (void)nativeExpressFullscreenVideoAdWillClose:(BUNativeExpressFullscreenVideoAd *)fullscreenVideoAd { |
| | | |
| | | } |
| | | |
| | | //关闭视频广告时调用此方法 |
| | | - (void)nativeExpressFullscreenVideoAdDidClose:(BUNativeExpressFullscreenVideoAd *)fullscreenVideoAd { |
| | | |
| | | } |
| | | |
| | | //此方法在视频广告播放完成或发生错误时调用。 |
| | | - (void)nativeExpressFullscreenVideoAdDidPlayFinish:(BUNativeExpressFullscreenVideoAd *)fullscreenVideoAd didFailWithError:(NSError *_Nullable)error { |
| | | |
| | | |
| | | } |
| | | |
| | | - (void)viewWillAppear:(BOOL)animated { |
| | | [super viewWillAppear:animated]; |
| | | //让页面保持常亮 |
| | | [[UIApplication sharedApplication] setIdleTimerDisabled:YES]; |
| | |
| | | //增加通知中心监听, |
| | | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(replyMessage:) name:@"reply" object:nil]; |
| | | //友盟页面统计 |
| | | [MobClick beginLogPageView:@"视频播放页面"]; |
| | | //[MobClick beginLogPageView:@"视频播放页面"]; |
| | | //显示状态栏 |
| | | [[UIApplication sharedApplication] setStatusBarHidden:NO]; |
| | | //网络状态 |
| | |
| | | //让页面关闭常亮 |
| | | [[UIApplication sharedApplication] setIdleTimerDisabled:NO]; |
| | | //友盟页面统计 |
| | | [MobClick endLogPageView:@"视频播放页面"]; |
| | | // [MobClick endLogPageView:@"视频播放页面"]; |
| | | |
| | | //强制竖屏 |
| | | NSNumber *orientationUnknown = [NSNumber numberWithInt:UIInterfaceOrientationUnknown]; |
| | |
| | | }else{ |
| | | //未登录,引导用户登录 |
| | | LoggingViewController *loginVC=[[LoggingViewController alloc] init]; |
| | | loginVC.modalPresentationStyle = 0; |
| | | loginVC.ispresent=YES; |
| | | [self presentViewController:loginVC animated:YES completion:^{ |
| | | |
| | |
| | | } |
| | | |
| | | //评论数 |
| | | // NSString *commentNub=[NSString stringWithFormat:@"评 论(%ld)",(long)_DetailModel.Data.CommentCount]; |
| | | // NSString *commentNub=[NSString stringWithFormat:@"评 论(%ld)",(long)_DetailModel.Data.CommentCount]; |
| | | self.segmentedControl.sectionTitles = @[@"详 情"]; |
| | | } |
| | | |
| | |
| | | _MuneBar.delegate = self; |
| | | _MuneBar.center = CGPointMake(((KScreenW/3)-80)/2, 22); |
| | | [self.collectionView bringSubviewToFront:_MuneBar]; |
| | | // [self.collectionView reloadSections:[NSIndexSet indexSetWithIndex:0]]; |
| | | // [self.collectionView reloadSections:[NSIndexSet indexSetWithIndex:0]]; |
| | | [self.collectionView reloadData]; |
| | | |
| | | |
| | | } |
| | | } |
| | | //默认网络情况 |
| | | - (void)NetWorkStuas{ |
| | | |
| | | |
| | | switch ([YTHsharedManger startManger].NetworkStatus) { |
| | | case 0:{//当前网络不可用 |
| | | UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"提示"message:@"当前网络不可用,是否使用连接网络?"preferredStyle:UIAlertControllerStyleAlert]; |
| | |
| | | }]]; |
| | | //去连接网络 |
| | | [alert addAction:[UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) { |
| | | |
| | | |
| | | }]]; |
| | | [self presentViewController:alert animated:YES completion:^{ |
| | | |
| | |
| | | - (UIInterfaceOrientationMask)supportedInterfaceOrientations |
| | | #endif |
| | | { |
| | | // if(_isPPTVSuccess){ //如果是PPTV 播放 返回可旋转 |
| | | // if(_pptvview.playoptions.isHalfScreen){ |
| | | // return UIInterfaceOrientationMaskLandscape; |
| | | // }else{ |
| | | // return UIInterfaceOrientationMaskPortrait; |
| | | // } |
| | | // } |
| | | // if(_isPPTVSuccess){ //如果是PPTV 播放 返回可旋转 |
| | | // if(_pptvview.playoptions.isHalfScreen){ |
| | | // return UIInterfaceOrientationMaskLandscape; |
| | | // }else{ |
| | | // return UIInterfaceOrientationMaskPortrait; |
| | | // } |
| | | // } |
| | | if (self.YKloadSuccess==YES) { //如果加载了优酷播放器 |
| | | return UIInterfaceOrientationMaskAllButUpsideDown; |
| | | } |
| | |
| | | /** |
| | | * 播放详情页面的分享按钮被触发 |
| | | */ |
| | | -(void)clickShareButton:(UIButton *)sender{ |
| | | [Share shareAPP:self]; |
| | | - (void)clickShareButton:(UIButton *)sender{ |
| | | // [Share shareAPP:self]; |
| | | } |
| | | |
| | | /** |
| | |
| | | }else{ |
| | | //未登录,引导用户登录 |
| | | LoggingViewController *loginVC=[[LoggingViewController alloc] init]; |
| | | loginVC.modalPresentationStyle = 0; |
| | | loginVC.ispresent=YES; |
| | | [self presentViewController:loginVC animated:YES completion:^{ |
| | | |
| | |
| | | NSLog(@"选集更多"); |
| | | _gather++; |
| | | //刷新视图 |
| | | // [self.collectionView reloadSections:[NSIndexSet indexSetWithIndex:1]]; |
| | | // [self.collectionView reloadSections:[NSIndexSet indexSetWithIndex:1]]; |
| | | [self.collectionView reloadData]; |
| | | |
| | | |
| | | }else {//广点通广告 |
| | | // GDTNativeAdData * info =nativeArray[sender.tag-523]; |
| | | // [_nativeAd clickAd:info]; |
| | | // GDTNativeAdData * info =nativeArray[sender.tag-523]; |
| | | // [_nativeAd clickAd:info]; |
| | | } |
| | | } |
| | | |
| | |
| | | targetIndex = temp; |
| | | } |
| | | } |
| | | // [_collectionView reloadItemsAtIndexPaths:@[targetIndex]]; |
| | | // [_collectionView reloadItemsAtIndexPaths:@[targetIndex]]; |
| | | [_collectionView reloadData]; |
| | | } |
| | | } |
| | |
| | | [self PPTVplay:[NSString stringWithFormat:@"%d",isCollectNum-1] WithBoolInit:_isPPTVSuccess]; |
| | | }else if([self.NewResource intValue]==18){ //乐视播放器 |
| | | [self YKPlay:[NSString stringWithFormat:@"%d",isCollectNum-1]]; |
| | | // [_collectionView reloadSections:[NSIndexSet indexSetWithIndex:1]]; |
| | | // [_collectionView reloadSections:[NSIndexSet indexSetWithIndex:1]]; |
| | | [self.collectionView reloadData]; |
| | | |
| | | |
| | | }else{ |
| | | [self startToPlay:[NSString stringWithFormat:@"%d",isCollectNum-1]]; |
| | | } |
| | |
| | | |
| | | //加载PPTV播放器 |
| | | if(!BL){ //没有被初始化过 |
| | | // [self playPPTV:urlstring]; |
| | | // [self playPPTV:urlstring]; |
| | | }else{ |
| | | // [self playPPTVSecend:urlstring]; |
| | | // [self playPPTVSecend:urlstring]; |
| | | } |
| | | }else{ |
| | | NSLog(@"获取视频播放链接失败%@",error); |
| | |
| | | [_backgroundButton setEnabled:YES]; |
| | | if([_NewResource intValue]==15){ |
| | | //加载优酷播放器 |
| | | // [self loadYKPlayer:urlstring]; |
| | | // [self loadYKPlayer:urlstring]; |
| | | } |
| | | }else{//站外播放 |
| | | NSString *urlstring=[[dictionaryDta objectForKey:@"Data"] objectForKey:@"Url"]; |
| | |
| | | CGFloat y = 0; |
| | | |
| | | if (!fullscreen) { |
| | | // _cloudPlayer.view.frame = _cloudPlayerFrame; |
| | | // _cloudPlayer.view.frame = _cloudPlayerFrame; |
| | | y = (44 - backHeight) / 2; |
| | | _backButton.frame = CGRectMake(MARGIN, y , BACK_WIDTH, backHeight); |
| | | } else { |
| | | // _cloudPlayer.view.frame = self.view.frame; |
| | | // _cloudPlayer.view.frame = self.view.frame; |
| | | y = (30 - backHeight) / 2 + 20; |
| | | _backButton.frame = CGRectMake(MARGIN, y, BACK_WIDTH, _backButton.bounds.size.height); |
| | | } |
| | | // _textView.frame = CGRectMake(_cloudPlayer.view.center.x - TEXTVIEW_WIDTH/2, _cloudPlayer.view.center.y - TEXTVIEW_HEIGHT/2, TEXTVIEW_WIDTH, TEXTVIEW_HEIGHT); |
| | | // _textView.frame = CGRectMake(_cloudPlayer.view.center.x - TEXTVIEW_WIDTH/2, _cloudPlayer.view.center.y - TEXTVIEW_HEIGHT/2, TEXTVIEW_WIDTH, TEXTVIEW_HEIGHT); |
| | | } |
| | | |
| | | - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)orien{ |
| | |
| | | _textView.font = [UIFont systemFontOfSize:TEXTVIEW_FONT]; |
| | | _textView.editable = NO; |
| | | _textView.userInteractionEnabled = NO; |
| | | // _textView.frame = CGRectMake(_cloudPlayer.view.center.x - TEXTVIEW_WIDTH/2,_cloudPlayer.view.center.y - TEXTVIEW_HEIGHT/2, TEXTVIEW_WIDTH, TEXTVIEW_HEIGHT); |
| | | // _textView.frame = CGRectMake(_cloudPlayer.view.center.x - TEXTVIEW_WIDTH/2,_cloudPlayer.view.center.y - TEXTVIEW_HEIGHT/2, TEXTVIEW_WIDTH, TEXTVIEW_HEIGHT); |
| | | [_textView setTextAlignment:NSTextAlignmentCenter]; |
| | | // [_cloudPlayer.view addSubview:_textView]; |
| | | // [_cloudPlayer.view addSubview:_textView]; |
| | | } |
| | | |
| | | /** |
| | |
| | | if (!DEVICE_TYPE_IPAD) { |
| | | if (orien == UIInterfaceOrientationPortrait && |
| | | self.interfaceOrientation != orien) { |
| | | // [_cloudPlayer setFullscreen:NO]; |
| | | // [_cloudPlayer setFullscreen:NO]; |
| | | } else if (UIInterfaceOrientationIsLandscape(orien)) { |
| | | UIInterfaceOrientation corien = self.interfaceOrientation; |
| | | if (!UIInterfaceOrientationIsLandscape(corien)) { |
| | | // [_cloudPlayer setFullscreen:YES]; |
| | | // [_cloudPlayer setFullscreen:YES]; |
| | | } |
| | | } |
| | | } |
| | |
| | | }else{ |
| | | webVC.orMake=UIInterfaceOrientationMaskPortrait; |
| | | } |
| | | |
| | | webVC.modalPresentationStyle = 0; |
| | | [self presentViewController:webVC animated:YES completion:^{ |
| | | [_playBtn setEnabled:YES]; |
| | | [_backgroundButton setEnabled:YES]; |
| | |
| | | * 退出详情页面的方法 |
| | | */ |
| | | -(void)backToRootView{ |
| | | // if(_isPPTVSuccess){ |
| | | // if(_pptvview.playoptions.isHalfScreen){ |
| | | // [_pptvview FullScreen]; |
| | | // return; |
| | | // } |
| | | // [self PPTVclear]; |
| | | // } |
| | | // |
| | | // if(_isPPTVSuccess){ |
| | | // if(_pptvview.playoptions.isHalfScreen){ |
| | | // [_pptvview FullScreen]; |
| | | // return; |
| | | // } |
| | | // [self PPTVclear]; |
| | | // } |
| | | // |
| | | [SVProgressHUD dismiss]; |
| | | self.collectionView.delegate = nil; |
| | | self.collectionView.dataSource = nil; |
| | | [self.collectionView removeFromSuperview]; |
| | | self.collectionView = nil; |
| | | // _nativeAd.controller = nil; |
| | | // _nativeAd.delegate = nil; |
| | | // [self.player removeEventsObserver:_viewManager]; |
| | | // _nativeAd.controller = nil; |
| | | // _nativeAd.delegate = nil; |
| | | // [self.player removeEventsObserver:_viewManager]; |
| | | [self dismissViewControllerAnimated:YES completion:nil]; |
| | | //显示状态栏 |
| | | [[UIApplication sharedApplication] setStatusBarHidden:NO]; |
| | |
| | | } |
| | | dispatch_async(dispatch_get_main_queue(), ^{ |
| | | [self.collectionView reloadData]; |
| | | |
| | | |
| | | }); |
| | | //判断Model是否已经加载了最上面图片 |
| | | if(self.Model.Hpicture==nil){ |
| | |
| | | _VideoDetailList=self.DetailModel.Data.VideoDetailList; |
| | | //计算cell的大小 |
| | | [self CalculateHeightWithArray:_VideoDetailList]; |
| | | |
| | | |
| | | //加载广告 |
| | | [self loadAd]; |
| | | //加载相关视频 |
| | |
| | | NSLog(@"%@",error); |
| | | //提示用户错误 |
| | | [SVProgressHUD dismiss]; |
| | | |
| | | // [SVProgressHUD showErrorWithStatus:@"加载失败!"]; |
| | | |
| | | // [SVProgressHUD showErrorWithStatus:@"加载失败!"]; |
| | | |
| | | } |
| | | }]; |
| | |
| | | -(void)SourcesSwitching:(NSInteger)index{ |
| | | [SVProgressHUD showWithStatus:@"视频源切换中"]; |
| | | if(_isPPTVSuccess){ |
| | | // [self PPTVclear]; |
| | | // [self PPTVclear]; |
| | | } |
| | | [[YTHNetInterface startInterface] getVoideoDetailWithUid:[YTHsharedManger startManger].Uid withLoginUid:[[NSUserDefaults standardUserDefaults] objectForKey:@"LoginUid"] withId:self.Model.Id withThirdType:self.Model.ThirdType withSystem:@"1" WithResourceId:_NewResource withBlock:^(BOOL isSuccessful, id result, NSString *error) { |
| | | if (isSuccessful) { |
| | |
| | | |
| | | //需要考虑到正在播放优酷视屏时,如果切换爱奇艺的情况 |
| | | if([_NewResource intValue]!=15){ |
| | | // [self.player.view removeFromSuperview]; |
| | | // [self.player removeEventsObserver:_viewManager]; |
| | | // [self.player stop]; |
| | | // [self.player deinit]; |
| | | // [self.player.view removeFromSuperview]; |
| | | // [self.player removeEventsObserver:_viewManager]; |
| | | // [self.player stop]; |
| | | // [self.player deinit]; |
| | | |
| | | //取消隐藏playBtn |
| | | [_playBtn setHidden:NO]; |
| | |
| | | } |
| | | dispatch_async(dispatch_get_main_queue(), ^{ |
| | | [_collectionView reloadData]; |
| | | |
| | | |
| | | }); |
| | | |
| | | |
| | | //提示视频源切换成功 |
| | | [SVProgressHUD dismiss]; |
| | | }else{ |
| | |
| | | * 联网检查是否收藏 |
| | | */ |
| | | -(void)checkWhetherCollection{ |
| | | // if([[NSUserDefaults standardUserDefaults] boolForKey:@"userOnLine"]){ |
| | | [[YTHNetInterface startInterface] getIsCollectedWithUid:[YTHsharedManger startManger].Uid withId:self.Model.Id withThirdType:self.Model.ThirdType withSystem:@"1" withBlock:^(BOOL isSuccessful, id result, NSString *error) { |
| | | UIButton *B1=[self.view viewWithTag:321]; |
| | | if (isSuccessful) { |
| | | [B1 setSelected:YES]; |
| | | }else{ |
| | | [B1 setSelected:NO]; |
| | | } |
| | | }]; |
| | | // } |
| | | // if([[NSUserDefaults standardUserDefaults] boolForKey:@"userOnLine"]){ |
| | | [[YTHNetInterface startInterface] getIsCollectedWithUid:[YTHsharedManger startManger].Uid withId:self.Model.Id withThirdType:self.Model.ThirdType withSystem:@"1" withBlock:^(BOOL isSuccessful, id result, NSString *error) { |
| | | UIButton *B1=[self.view viewWithTag:321]; |
| | | if (isSuccessful) { |
| | | [B1 setSelected:YES]; |
| | | }else{ |
| | | [B1 setSelected:NO]; |
| | | } |
| | | }]; |
| | | // } |
| | | } |
| | | |
| | | //用于计算选集cell的大小 |
| | | -(void)CalculateHeightWithArray:(NSArray *)arr{ |
| | | NSString *MAXStr=[_VideoDetailList[0] objectForKey:@"Tag"]; |
| | | -(void)CalculateHeightWithArray:(NSArray *)arr { |
| | | if (_VideoDetailList.count == 0) return; |
| | | |
| | | NSString *MAXStr=_VideoDetailList[0][@"Tag"]; |
| | | for (int i=1; i<arr.count; i++) { |
| | | NSString *tempStr=[_VideoDetailList[i] objectForKey:@"Tag"]; |
| | | NSString *tempStr = _VideoDetailList[i][@"Tag"]; |
| | | if (MAXStr.length<tempStr.length) { |
| | | MAXStr=tempStr; |
| | | } |
| | |
| | | * 加载广点通原生广告 |
| | | */ |
| | | -(void)loadAd{ |
| | | // _nativeAd = [[GDTNativeAd alloc] initWithAppkey:GDTADkey placementId:GDTYSADkey4]; |
| | | // _nativeAd.controller = self; |
| | | // _nativeAd.delegate = self; |
| | | // [_nativeAd loadAd:4]; |
| | | // _nativeAd = [[GDTNativeAd alloc] initWithAppkey:GDTADkey placementId:GDTYSADkey4]; |
| | | // _nativeAd.controller = self; |
| | | // _nativeAd.delegate = self; |
| | | // [_nativeAd loadAd:4]; |
| | | self.nativeExpressAd = [[GDTNativeExpressAd alloc] initWithAppId:GDTADkey placementId:GDTYSADkey4 adSize:CGSizeMake(KScreenW, (KScreenW-20)/16*9 + 10)]; |
| | | self.nativeExpressAd.delegate = self; |
| | | // 配置视频播放属性 |
| | |
| | | * 获取视频的相关视频信息 |
| | | * |
| | | * @param MovieId 视频的id |
| | | */ |
| | | */ |
| | | -(void)getRelativeVideosWithVideoId:(NSString *)MovieId{ |
| | | [[YTHNetInterface startInterface] getRelativeVideosWithUid:[YTHsharedManger startManger].Uid withVideoId:MovieId withSystem:@"1" withBlock:^(BOOL isSuccessful, id result, NSString *error) { |
| | | if (isSuccessful) { |
| | | _RelativeVideos=[[(NSDictionary*)result objectForKey:@"Data"] objectForKey:@"data"]; |
| | | //刷新瀑布流 |
| | | // dispatch_sync(dispatch_get_main_queue(), ^{ |
| | | // [self.collectionView reloadSections:[NSIndexSet indexSetWithIndex:3]]; |
| | | // dispatch_sync(dispatch_get_main_queue(), ^{ |
| | | // [self.collectionView reloadSections:[NSIndexSet indexSetWithIndex:3]]; |
| | | [self.collectionView reloadData]; |
| | | // }); |
| | | // }); |
| | | }else{ |
| | | |
| | | } |
| | |
| | | if (isSuccessful) { |
| | | _GuessYoulike=[[(NSDictionary*)result objectForKey:@"Data"] objectForKey:@"data"]; |
| | | //刷新瀑布流 |
| | | // dispatch_sync(dispatch_get_main_queue(), ^{ |
| | | // [self.collectionView reloadSections:[NSIndexSet indexSetWithIndex:4]]; |
| | | // dispatch_sync(dispatch_get_main_queue(), ^{ |
| | | // [self.collectionView reloadSections:[NSIndexSet indexSetWithIndex:4]]; |
| | | [self.collectionView reloadData]; |
| | | |
| | | // }); |
| | | |
| | | // }); |
| | | }else{ |
| | | |
| | | } |
| | |
| | | if (isSuccessful) { |
| | | _PeopleSeeVideo=[[(NSDictionary*)result objectForKey:@"Data"] objectForKey:@"data"]; |
| | | //刷新瀑布流 |
| | | // dispatch_sync(dispatch_get_main_queue(), ^{ |
| | | // [self.collectionView reloadSections:[NSIndexSet indexSetWithIndex:5]]; |
| | | // dispatch_sync(dispatch_get_main_queue(), ^{ |
| | | // [self.collectionView reloadSections:[NSIndexSet indexSetWithIndex:5]]; |
| | | [self.collectionView reloadData]; |
| | | |
| | | |
| | | // }); |
| | | |
| | | |
| | | // }); |
| | | }else{ |
| | | } |
| | | }]; |
| | |
| | | [_textField resignFirstResponder]; |
| | | [_commenttableview setContentOffset:CGPointMake(0, 0) animated:YES]; |
| | | [self reloadCommentView]; |
| | | |
| | | |
| | | [SVProgressHUD showSuccessWithStatus:@"评论成功"]; |
| | | |
| | | |
| | | }else{ |
| | | [SVProgressHUD showErrorWithStatus:@"发送失败!"]; |
| | | } |
| | |
| | | }else{ |
| | | //如果用户未登录 |
| | | LoggingViewController *loginVC=[[LoggingViewController alloc] init]; |
| | | loginVC.modalPresentationStyle = 0; |
| | | loginVC.ispresent=YES; |
| | | [self presentViewController:loginVC animated:YES completion:nil]; |
| | | } |
| | |
| | | [_commenttableview reloadData]; |
| | | }); |
| | | //刷新评论按钮上的评论数 |
| | | // NSString *commentNub=[NSString stringWithFormat:@"评 论(%ld)",(long)_DetailModel.Data.CommentCount]; |
| | | // NSString *commentNub=[NSString stringWithFormat:@"评 论(%ld)",(long)_DetailModel.Data.CommentCount]; |
| | | self.segmentedControl.sectionTitles = @[@"详 情"]; |
| | | [_commenttableview.mj_header endRefreshing]; |
| | | [_commenttableview.mj_footer endRefreshing]; |
| | |
| | | }else{ |
| | | //如果用户未登录 |
| | | LoggingViewController *loginVC=[[LoggingViewController alloc] init]; |
| | | loginVC.modalPresentationStyle = 0; |
| | | loginVC.ispresent=YES; |
| | | [self presentViewController:loginVC animated:YES completion:nil]; |
| | | } |
| | |
| | | - (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView { |
| | | NSLog(@"%f",scrollView.contentOffset.x); |
| | | if (scrollView==self.scrollView) { |
| | | // NSInteger page = scrollView.contentOffset.x / KScreenW; |
| | | // NSInteger page = scrollView.contentOffset.x / KScreenW; |
| | | |
| | | // [self.scrollView scrollRectToVisible:CGRectMake(KScreenW * page, KScreenW/48*27+35, KScreenW, KScreenH-(KScreenW/48*27)-35) animated:YES]; |
| | | // [self.segmentedControl setSelectedSegmentIndex:page animated:YES]; |
| | | // [self.scrollView scrollRectToVisible:CGRectMake(KScreenW * page, KScreenW/48*27+35, KScreenW, KScreenH-(KScreenW/48*27)-35) animated:YES]; |
| | | // [self.segmentedControl setSelectedSegmentIndex:page animated:YES]; |
| | | //考虑到用户在输入的时候突然切换到详情,这个时候就需要取消评论框的第一响应 |
| | | // if(page==0){ |
| | | // [_textField resignFirstResponder]; |
| | | // } |
| | | // if(page==0){ |
| | | // [_textField resignFirstResponder]; |
| | | // } |
| | | } |
| | | } |
| | | |
| | |
| | | |
| | | - (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath{ |
| | | if (indexPath.section==0) {//点击了广告 |
| | | // GDTNativeAdData * info=nativeArray[3]; |
| | | // [_nativeAd clickAd:info]; |
| | | // GDTNativeAdData * info=nativeArray[3]; |
| | | // [_nativeAd clickAd:info]; |
| | | }else if (indexPath.section==1) { |
| | | //查找刷新视图 |
| | | NSMutableArray * indexPatharr = [[NSMutableArray alloc]init]; |
| | |
| | | isCollectNum=(int)indexPath.row +1; |
| | | if(lastIndex.row == 0 || indexPath.row == 0 || !lastIndex){ //在iphone6以上刷新row==0时无效的特殊处理 |
| | | [_collectionView reloadSections:[NSIndexSet indexSetWithIndex:1]]; |
| | | // [self.collectionView reloadData]; |
| | | |
| | | // [self.collectionView reloadData]; |
| | | |
| | | }else{ |
| | | [_collectionView reloadItemsAtIndexPaths:indexPatharr]; |
| | | // [_collectionView reloadData]; |
| | | |
| | | // [_collectionView reloadData]; |
| | | |
| | | } |
| | | |
| | | //刷新播放器 |
| | |
| | | |
| | | }else{ |
| | | if(_isPPTVSuccess){ //清空pptv进行转换 |
| | | // [self PPTVclear]; |
| | | // [self PPTVclear]; |
| | | _isPPTVSuccess = NO; |
| | | } |
| | | |
| | | //考虑到正在播放优酷视频,切换到爱奇艺资源,所以要做一次移除优酷播放器的操作 |
| | | // [self.player.view removeFromSuperview]; |
| | | // [self.player removeEventsObserver:_viewManager]; |
| | | // [self.player stop]; |
| | | // [self.player deinit]; |
| | | // [self.player.view removeFromSuperview]; |
| | | // [self.player removeEventsObserver:_viewManager]; |
| | | // [self.player stop]; |
| | | // [self.player deinit]; |
| | | //取消隐藏playBtn |
| | | [_playBtn setHidden:NO]; |
| | | [_backgroundButton setEnabled:NO]; |
| | |
| | | GDTNativeExpressAdView *adView = (GDTNativeExpressAdView *)self.expressAdViews[3]; |
| | | [cell.contentView.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)]; |
| | | [cell.contentView addSubview:adView]; |
| | | // GDTNativeAdData *info=nativeArray[3]; |
| | | // cell.ADtitle.text=[info.properties objectForKey:GDTNativeAdDataKeyTitle]; |
| | | // cell.ADtitle.backgroundColor=[UIColor clearColor]; |
| | | // [cell.ADimage setYthImageWithURL:[info.properties objectForKey:GDTNativeAdDataKeyImgUrl] placeholderImage:nil]; |
| | | // [_nativeAd attachAd:info toView:cell]; |
| | | // GDTNativeAdData *info=nativeArray[3]; |
| | | // cell.ADtitle.text=[info.properties objectForKey:GDTNativeAdDataKeyTitle]; |
| | | // cell.ADtitle.backgroundColor=[UIColor clearColor]; |
| | | // [cell.ADimage setYthImageWithURL:[info.properties objectForKey:GDTNativeAdDataKeyImgUrl] placeholderImage:nil]; |
| | | // [_nativeAd attachAd:info toView:cell]; |
| | | return cell; |
| | | } |
| | | break; |
| | |
| | | - (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath{ |
| | | switch (indexPath.section) { |
| | | case 0:{ |
| | | if (kind == UICollectionElementKindSectionHeader){ |
| | | if (kind == UICollectionElementKindSectionHeader) { |
| | | |
| | | titleCollectionReusableView *titleCollectionReusableView = [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"titleCollectionReusableViewID" forIndexPath:indexPath]; |
| | | |
| | | |
| | | //添加收藏的点击事件 |
| | | [titleCollectionReusableView.collectionBtn addTarget:self action:@selector(ClickCollection:) forControlEvents:UIControlEventTouchUpInside]; |
| | | _collectionbt = titleCollectionReusableView.collectionBtn; |
| | | //添加分享的点击事件 |
| | | titleCollectionReusableView.shareBtn.hidden = YES; |
| | | [titleCollectionReusableView.shareBtn addTarget:self action:@selector(clickShareButton:) forControlEvents:UIControlEventTouchUpInside]; |
| | | //联网检查是否收藏 |
| | | [self checkWhetherCollection]; |
| | |
| | | |
| | | if(self.expressAdViews.count>0){ |
| | | ADCollectionReusableView *groupfootSection = [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionFooter withReuseIdentifier:@"ADCollectionReusableView" forIndexPath:indexPath]; |
| | | |
| | | |
| | | //把button设为透明 |
| | | groupfootSection.ADClickButton.backgroundColor=[UIColor clearColor]; |
| | | [groupfootSection.ADClickButton setTag:520+indexPath.section]; |
| | |
| | | //协议中的方法,用于返回单元格的大小 |
| | | - (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath{ |
| | | if (indexPath.section==0) { |
| | | // return CGSizeMake(KScreenW-20, (KScreenW-20)/16*9); |
| | | // return CGSizeMake(KScreenW-20, (KScreenW-20)/16*9); |
| | | GDTNativeExpressAdView *adView = (GDTNativeExpressAdView *)self.expressAdViews[indexPath.section]; |
| | | return CGSizeMake(KScreenW, adView.bounds.size.height); |
| | | }else if (indexPath.section==1) { |
| | |
| | | * 0 . 不可用 1. 移动网络 2.wifi 3.当前网络未知 |
| | | */ |
| | | - (void)updateNet:(NSInteger )status{ |
| | | |
| | | |
| | | switch (status) { |
| | | |
| | | case 0:{//当前网络不可用 |
| | |
| | | //去连接网络 |
| | | [alert addAction:[UIAlertAction actionWithTitle:@"连接网络" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) { |
| | | if (IOS_VERSION < 8.0) { |
| | | |
| | | |
| | | }else{ |
| | | [[UIApplication sharedApplication]openURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString]]; |
| | | } |
| | |
| | | }]]; |
| | | //去连接网络 |
| | | [alert addAction:[UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) { |
| | | |
| | | |
| | | }]]; |
| | | [self presentViewController:alert animated:YES completion:^{ |
| | | |
| | |
| | | } |
| | | |
| | | #pragma mark -HXEasyCustomShareViewDelegate |
| | | - (void)easyCustomShareViewButtonAction:(HXEasyCustomShareView *)shareView title:(NSString *)title { |
| | | if ([title isEqualToString:@"微信"]) { |
| | | [self shareWebPageToPlatformType:UMSocialPlatformType_WechatSession]; |
| | | }else if ([title isEqualToString:@"朋友圈"]) { |
| | | [self shareWebPageToPlatformType:UMSocialPlatformType_WechatTimeLine]; |
| | | }else if ([title isEqualToString:@"QQ"]) { |
| | | [self shareWebPageToPlatformType:UMSocialPlatformType_QQ]; |
| | | }else if ([title isEqualToString:@"新浪微博"]) { |
| | | [self shareWebPageToPlatformType:UMSocialPlatformType_Sina]; |
| | | }else if ([title isEqualToString:@"QQ空间"]) { |
| | | [self shareWebPageToPlatformType:UMSocialPlatformType_Qzone]; |
| | | }else{ |
| | | //到这里就错了 |
| | | } |
| | | [shareView tappedCancel]; |
| | | } |
| | | //- (void)easyCustomShareViewButtonAction:(HXEasyCustomShareView *)shareView title:(NSString *)title { |
| | | // if ([title isEqualToString:@"微信"]) { |
| | | // [self shareWebPageToPlatformType:UMSocialPlatformType_WechatSession]; |
| | | // }else if ([title isEqualToString:@"朋友圈"]) { |
| | | // [self shareWebPageToPlatformType:UMSocialPlatformType_WechatTimeLine]; |
| | | // }else if ([title isEqualToString:@"QQ"]) { |
| | | // [self shareWebPageToPlatformType:UMSocialPlatformType_QQ]; |
| | | // }else if ([title isEqualToString:@"新浪微博"]) { |
| | | // [self shareWebPageToPlatformType:UMSocialPlatformType_Sina]; |
| | | // }else if ([title isEqualToString:@"QQ空间"]) { |
| | | // [self shareWebPageToPlatformType:UMSocialPlatformType_Qzone]; |
| | | // }else{ |
| | | // //到这里就错了 |
| | | // } |
| | | // [shareView tappedCancel]; |
| | | //} |
| | | |
| | | /** |
| | | 分享 |
| | | */ |
| | | - (void)shareWebPageToPlatformType:(UMSocialPlatformType)platformType{ |
| | | NSURL *imageurl; |
| | | //判断分享的图片地址是否存在 |
| | | NSString *picUrl=_DetailModel.Data.Picture; |
| | | if (picUrl .length>4) { |
| | | //判断图片地址是否为http开头,是则为第三方图片 |
| | | if ([[picUrl substringWithRange:NSMakeRange(0, 4)] isEqualToString:@"http"]) { |
| | | imageurl = [NSURL URLWithString:picUrl]; |
| | | }else{ |
| | | //否者为公司的图片,需要添加地址 |
| | | imageurl =[NSURL URLWithString:[NSString stringWithFormat:@"%@%@",ImageUrl,picUrl]]; |
| | | } |
| | | } |
| | | |
| | | //创建分享消息对象 |
| | | UMSocialMessageObject *messageObject = [UMSocialMessageObject messageObject]; |
| | | |
| | | //创建网页内容对象 |
| | | UMShareWebpageObject *shareObject = [UMShareWebpageObject shareObjectWithTitle:@"布丸影视大全" descr:[NSString stringWithFormat:@"我在布丸影视大全看了《%@》影片,非常不错,大家一起看看吧!%@",_DetailModel.Data.Name,[[NSUserDefaults standardUserDefaults] objectForKey:@"ShareUrl"]] thumImage:[NSData dataWithContentsOfURL:imageurl]]; |
| | | |
| | | //设置网页地址 |
| | | shareObject.webpageUrl =[[NSUserDefaults standardUserDefaults] objectForKey:@"ShareUrl"]; |
| | | |
| | | //分享消息对象设置分享内容对象 |
| | | messageObject.shareObject = shareObject; |
| | | |
| | | //调用分享接口 |
| | | [[UMSocialManager defaultManager] shareToPlatform:platformType messageObject:messageObject currentViewController:self completion:^(id data, NSError *error) { |
| | | if (error) { |
| | | [SVProgressHUD showErrorWithStatus:@"分享失败!"]; |
| | | NSLog(@"************Share fail with error %@*********",error); |
| | | }else{ |
| | | NSLog(@"response data is %@",data); |
| | | } |
| | | }]; |
| | | } |
| | | //- (void)shareWebPageToPlatformType:(UMSocialPlatformType)platformType{ |
| | | // NSURL *imageurl; |
| | | // //判断分享的图片地址是否存在 |
| | | // NSString *picUrl=_DetailModel.Data.Picture; |
| | | // if (picUrl .length>4) { |
| | | // //判断图片地址是否为http开头,是则为第三方图片 |
| | | // if ([[picUrl substringWithRange:NSMakeRange(0, 4)] isEqualToString:@"http"]) { |
| | | // imageurl = [NSURL URLWithString:picUrl]; |
| | | // }else{ |
| | | // //否者为公司的图片,需要添加地址 |
| | | // imageurl =[NSURL URLWithString:[NSString stringWithFormat:@"%@%@",ImageUrl,picUrl]]; |
| | | // } |
| | | // } |
| | | // |
| | | // //创建分享消息对象 |
| | | // UMSocialMessageObject *messageObject = [UMSocialMessageObject messageObject]; |
| | | // |
| | | // //创建网页内容对象 |
| | | // UMShareWebpageObject *shareObject = [UMShareWebpageObject shareObjectWithTitle:@"布丸影视大全" descr:[NSString stringWithFormat:@"我在布丸影视大全看了《%@》影片,非常不错,大家一起看看吧!%@",_DetailModel.Data.Name,[[NSUserDefaults standardUserDefaults] objectForKey:@"ShareUrl"]] thumImage:[NSData dataWithContentsOfURL:imageurl]]; |
| | | // |
| | | // //设置网页地址 |
| | | // shareObject.webpageUrl =[[NSUserDefaults standardUserDefaults] objectForKey:@"ShareUrl"]; |
| | | // |
| | | // //分享消息对象设置分享内容对象 |
| | | // messageObject.shareObject = shareObject; |
| | | // |
| | | // //调用分享接口 |
| | | // [[UMSocialManager defaultManager] shareToPlatform:platformType messageObject:messageObject currentViewController:self completion:^(id data, NSError *error) { |
| | | // if (error) { |
| | | // [SVProgressHUD showErrorWithStatus:@"分享失败!"]; |
| | | // NSLog(@"************Share fail with error %@*********",error); |
| | | // }else{ |
| | | // NSLog(@"response data is %@",data); |
| | | // } |
| | | // }]; |
| | | //} |
| | | |
| | | - (void)dealloc { |
| | | |
| | |
| | | |
| | | @property (nonatomic, copy) NSString *DetailId;//播放志愿 |
| | | |
| | | @property (nonatomic, strong) NSArray *VideoDetailList; |
| | | |
| | | @end |
| | |
| | | |
| | | - (void)getFoundGuessLike:(NSMutableDictionary *)dic WithBlock:(YthNetWorkBlock)block; |
| | | |
| | | - (void)fetchCommenConfig:(NSMutableDictionary *)dic WithBlock:(YthNetWorkBlock)block; |
| | | |
| | | @end |
| | |
| | | |
| | | [self mangerPostWithURL:url WithMutableDictionary:dic withBlock:block]; |
| | | } |
| | | |
| | | - (void)postFetchCommonConfig:(NSMutableDictionary *)dic withBlock:(YthNetWorkBlock)block{ |
| | | NSString *url = [NSString stringWithFormat:@"%@/config",domainHTTP]; |
| | | |
| | | [self mangerPostWithURL:url WithMutableDictionary:dic withBlock:block]; |
| | | } |
| | | |
| | | #pragma mark 图文社 |
| | | - (void)postFoundGraphicSocietyRequestDataWith:(NSMutableDictionary *)dic withBlock:(YthNetWorkBlock)block{ |
| | | NSString *url = [NSString stringWithFormat:@"%@/news",domainHTTP]; |
| | |
| | | }]; |
| | | } |
| | | |
| | | - (void)fetchCommenConfig:(NSMutableDictionary *)dic WithBlock:(YthNetWorkBlock)block { |
| | | NSString *sign; |
| | | sign = [NSString stringWithFormat:@"%@%@%@",@"getConfig",[[UIDevice currentDevice].identifierForVendor UUIDString],@"1"]; |
| | | |
| | | [dic setObject:[NSString md5:sign] forKey:@"Sign"]; |
| | | [dic setObject:@"ios" forKey:@"Platform"]; |
| | | [dic setObject:Version forKey:@"Version"]; |
| | | [dic setObject:Package forKey:@"Package"]; |
| | | [dic setObject:@"1" forKey:@"System"]; |
| | | [dic setObject:[[UIDevice currentDevice].identifierForVendor UUIDString] forKey:@"Device"]; |
| | | [self postFetchCommonConfig:dic withBlock:^(BOOL isSuccessful, id result, NSString *error) { |
| | | if (isSuccessful) { |
| | | NSDictionary *data = (NSDictionary *)result; |
| | | block(TRUE , data , nil); |
| | | }else{ |
| | | block(FALSE , nil , error); |
| | | } |
| | | }]; |
| | | } |
| | | |
| | | #pragma mark 获得 发现 的应用汇 |
| | | -(void)getFoundHomeApp:(NSString *)uid WithSystem:(NSString *)system WithBlock:(YthNetWorkBlock)block{ |
| | | |
| | |
| | | |
| | | [dic setObject:GetNewVideoDetail forKey:@"Method"]; |
| | | NSString *sign; |
| | | if (uid!=nil) { |
| | | if (uid) { |
| | | [dic setObject:uid forKey:@"Uid"]; |
| | | sign = [NSString stringWithFormat:@"%@%@%@",GetNewVideoDetail,uid,system]; |
| | | }else{ |
| | | |
| | | } else { |
| | | sign = [NSString stringWithFormat:@"%@%@%@",GetNewVideoDetail,[[UIDevice currentDevice].identifierForVendor UUIDString],system]; |
| | | } |
| | | if (movieId.length != 0) { |
| | | [dic setObject:movieId forKey:@"VideoId"]; |
| | | } |
| | | [dic setObject:system forKey:@"System"]; |
| | | [dic setObject:[NSString md5:sign] forKey:@"Sign"]; |
| | | |
| | | if (system) { |
| | | [dic setObject:system forKey:@"System"]; |
| | | } |
| | | |
| | | if ([NSString md5:sign]) { |
| | | [dic setObject:[NSString md5:sign] forKey:@"Sign"]; |
| | | } |
| | | |
| | | [dic setObject:@"IOS" forKey:@"Platform"]; |
| | | [dic setObject:Package forKey:@"Package"]; |
| | | if (ThirdType!=nil) { |
| | | |
| | | if (Package) { |
| | | [dic setObject:Package forKey:@"Package"]; |
| | | } |
| | | |
| | | if (ThirdType) { |
| | | [dic setObject:ThirdType forKey:@"Type"]; |
| | | } |
| | | |
| | | [dic setObject:Version forKey:@"Version"]; |
| | | if (LoginUid!=nil) { |
| | | |
| | | if (LoginUid) { |
| | | [dic setObject:LoginUid forKey:@"LoginUid"]; |
| | | } |
| | | |
| | | if (ResourceId) { |
| | | [dic setObject:ResourceId forKey:@"ResourceId"]; |
| | | } |
| | | [dic setObject:[[UIDevice currentDevice].identifierForVendor UUIDString] forKey:@"Device"]; |
| | | NSLog(@"%@",dic); |
| | | return dic; |
| | | } |
| | | |
| | |
| | | */ |
| | | @property (nonatomic , assign) NSInteger NetworkStatus; |
| | | @property (nonatomic , strong) NSString *searchTitle; |
| | | /// 首页广告位配置 |
| | | @property (nonatomic , strong) NSDictionary *ad; |
| | | |
| | | + (YTHsharedManger *)startManger; |
| | | |
| | | |
| | |
| | | |
| | | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{ |
| | | XYRDetailViewController *play=[[XYRDetailViewController alloc]init]; |
| | | play.modalPresentationStyle = 0; |
| | | NSDictionary *dic = [information[indexPath.section]objectForKey:@"VideoInfo"]; |
| | | play.Model = [XYRVideoInfoModel yy_modelWithDictionary:dic]; |
| | | [temp presentViewController:play animated:YES completion:^{ }]; |
| | |
| | | #import "GDTNativeExpressAdView.h" |
| | | |
| | | #define collectTag 270 |
| | | @import GoogleMobileAds; |
| | | |
| | | @interface recommendView()<UICollectionViewDelegate,UICollectionViewDataSource,UICollectionViewDelegateFlowLayout,BSKImagesPageViewViewDelegate,GADNativeAppInstallAdLoaderDelegate, GADNativeContentAdLoaderDelegate,UIScrollViewDelegate,GDTNativeExpressAdDelegete>{ |
| | | @interface recommendView()<UICollectionViewDelegate,UICollectionViewDataSource,UICollectionViewDelegateFlowLayout,BSKImagesPageViewViewDelegate,UIScrollViewDelegate,GDTNativeExpressAdDelegete>{ |
| | | |
| | | // UICollectionView *_recommentCollectionView;//覆盖整个View的瀑布流 |
| | | BSKImagesPageView *_cycleScrollView;//头部的推荐轮播图 |
| | |
| | | BOOL googleNoAdToShow;//当这个变量为YES时,说明谷歌广告没有资源 |
| | | |
| | | //广点通原生广告 |
| | | // GDTNativeAd *_nativeAd; //原生广告实例 |
| | | // NSArray *nativeArray;//存储请求下来的原生广告信息 |
| | | // GDTNativeAd *_nativeAd; //原生广告实例 |
| | | // NSArray *nativeArray;//存储请求下来的原生广告信息 |
| | | NSString *_type_id; |
| | | NSString *_type_title; |
| | | NSInteger maintypeNumber;//种类的位置 |
| | | NSInteger typeNumber;//细分类 |
| | | BOOL _isrefresh; |
| | | |
| | | |
| | | } |
| | | |
| | | @property (nonatomic , strong) NSMutableArray *dataAdverti;//顶部广告数据 |
| | | |
| | | |
| | | @property (nonatomic , strong) NSMutableArray *addrssForshuffling;//装载轮播图的地址 |
| | | |
| | | @property (nonatomic , strong) NSMutableArray *TitleForshuffling;//装载轮播图的标题 |
| | | |
| | | @property(nonatomic, strong) GADAdLoader *adLoader;//谷歌广告 |
| | | |
| | | @property(nonatomic, strong) UIView *nativeAdView;//装载谷歌广告的视图 |
| | | |
| | |
| | | // maintypeNumber = 0; |
| | | self.allDataSourece = @[].mutableCopy; |
| | | self.dataDic = @{}.mutableCopy; |
| | | |
| | | |
| | | [self NetworkMonitoring]; |
| | | [self loadDataFromFile]; |
| | | UIViewController *controller = [self viewController]; |
| | |
| | | } |
| | | break; |
| | | case AFNetworkReachabilityStatusReachableViaWWAN:{//万维网 |
| | | // [self loadDataFromFile]; |
| | | // [self loadDataFromFile]; |
| | | _noNetworkView.hidden = YES; |
| | | |
| | | } |
| | | break; |
| | | case AFNetworkReachabilityStatusReachableViaWiFi:{// 使用WiFi网络 |
| | | // [self loadDataFromFile]; |
| | | // [self loadDataFromFile]; |
| | | _noNetworkView.hidden = YES; |
| | | |
| | | } |
| | |
| | | } |
| | | NSLog(@"%@",array); |
| | | self.vidioGmentControl = [[HMSegmentedControl alloc]initWithSectionTitles:array]; |
| | | [self.vidioGmentControl setFrame:CGRectMake(0, 64, KScreenW, 40)]; |
| | | |
| | | [self.vidioGmentControl setFrame:CGRectMake(0, 0, KScreenW, 40)]; |
| | | |
| | | if (KIsiPhoneX) { |
| | | [self.vidioGmentControl setFrame:CGRectMake(0, 84, KScreenW, 40)]; |
| | | [self.vidioGmentControl setFrame:CGRectMake(0, 0, KScreenW, 40)]; |
| | | } |
| | | self.vidioGmentControl.selectionIndicatorHeight = 2.0f; |
| | | self.vidioGmentControl.backgroundColor = kGlobalMainColor; |
| | |
| | | [weakSelf loadAd]; |
| | | // NSLog(@"<- %@ ->",_type_id); |
| | | maintypeNumber = index; |
| | | // NSArray * dataHomeType = weakSelf.allDataSourece[maintypeNumber][@"shopping"]; |
| | | // if (dataHomeType.count == 0) { |
| | | [weakSelf loadNewData]; |
| | | // } |
| | | // NSArray * dataHomeType = weakSelf.allDataSourece[maintypeNumber][@"shopping"]; |
| | | // if (dataHomeType.count == 0) { |
| | | [weakSelf loadNewData]; |
| | | // } |
| | | }]; |
| | | [self addSubview:self.vidioGmentControl]; |
| | | } |
| | | //加载数据 |
| | | -(void)loadDataFromFile{ |
| | | [[YTHNetInterface startInterface]cancelAll]; |
| | | |
| | | |
| | | [[YTHNetInterface startInterface] getVideoClassWithUid:[YTHsharedManger startManger].Uid WithSystem:@"1" withBlock:^(BOOL isSuccessful, id result, NSString *error) { |
| | | if (isSuccessful) { |
| | | NSDictionary *dic = (NSDictionary *)result; |
| | |
| | | //获取轮播图的数据 |
| | | [self getHomeAd]; |
| | | //小广告推广视图 |
| | | // [self SpreadRequest]; |
| | | |
| | | // [self SpreadRequest]; |
| | | |
| | | //获取推荐分类 |
| | | // [self getHomeType]; |
| | | // [self getHomeType]; |
| | | // UICollectionView *collectview = [self viewWithTag:900 + SpeciesNumber]; |
| | | // [collectview reloadData]; |
| | | } |
| | |
| | | */ |
| | | -(void)loadOldData{ |
| | | //获取旧的轮播图数据 |
| | | // NSFileManager *fileManager = [NSFileManager defaultManager]; |
| | | // if ([fileManager fileExistsAtPath:ADVERTISEFILE]){ |
| | | // _dataAdverti=[NSKeyedUnarchiver unarchiveObjectWithData:[NSData dataWithContentsOfFile:ADVERTISEFILE]]; |
| | | // [self addSliderView]; |
| | | // } |
| | | // //获取旧的推荐分类数据 |
| | | // if ([fileManager fileExistsAtPath:HOMETYPEFILE]){ |
| | | // _dataHomeType = [NSKeyedUnarchiver unarchiveObjectWithData:[NSData dataWithContentsOfFile:HOMETYPEFILE]]; |
| | | // } |
| | | // //判断本地是否有明星数据,如果有数据就进行预加载 |
| | | // if ([fileManager fileExistsAtPath:DISCOVERSTAR]){ |
| | | // _dataStar=[NSKeyedUnarchiver unarchiveObjectWithData:[NSData dataWithContentsOfFile:DISCOVERSTAR]]; |
| | | // } |
| | | // NSFileManager *fileManager = [NSFileManager defaultManager]; |
| | | // if ([fileManager fileExistsAtPath:ADVERTISEFILE]){ |
| | | // _dataAdverti=[NSKeyedUnarchiver unarchiveObjectWithData:[NSData dataWithContentsOfFile:ADVERTISEFILE]]; |
| | | // [self addSliderView]; |
| | | // } |
| | | // //获取旧的推荐分类数据 |
| | | // if ([fileManager fileExistsAtPath:HOMETYPEFILE]){ |
| | | // _dataHomeType = [NSKeyedUnarchiver unarchiveObjectWithData:[NSData dataWithContentsOfFile:HOMETYPEFILE]]; |
| | | // } |
| | | // //判断本地是否有明星数据,如果有数据就进行预加载 |
| | | // if ([fileManager fileExistsAtPath:DISCOVERSTAR]){ |
| | | // _dataStar=[NSKeyedUnarchiver unarchiveObjectWithData:[NSData dataWithContentsOfFile:DISCOVERSTAR]]; |
| | | // } |
| | | //加载新数据 |
| | | [self loadNewData]; |
| | | } |
| | |
| | | [[YTHNetInterface startInterface] getHomeAdWithUid:[YTHsharedManger startManger].Uid vtid:_type_id withSystem:@"1" withBlock:^(BOOL isSuccessful, id result, NSString *error) { |
| | | [self SpreadRequest]; |
| | | [self getHomeType]; |
| | | |
| | | |
| | | if (isSuccessful) { |
| | | NSDictionary *dic = (NSDictionary *)result; |
| | | if (!_dataAdverti) { |
| | |
| | | _dataAdverti = [[dic objectForKey:@"Data"] objectForKey:@"data"]; |
| | | |
| | | //存储获取到的数据 |
| | | // NSData *data = [NSKeyedArchiver archivedDataWithRootObject:_dataAdverti]; |
| | | // [data writeToFile:ADVERTISEFILE atomically:YES]; |
| | | // NSData *data = [NSKeyedArchiver archivedDataWithRootObject:_dataAdverti]; |
| | | // [data writeToFile:ADVERTISEFILE atomically:YES]; |
| | | // [_recommentCollectionView reloadData]; |
| | | NSLog(@"<------- %@ --------->",_dataAdverti); |
| | | //结束刷新 |
| | | // UICollectionView *collectview = [self viewWithTag:collectTag + maintypeNumber]; |
| | | |
| | | UICollectionView *collectview = self.collectArray[maintypeNumber]; |
| | | |
| | | |
| | | [collectview.mj_header endRefreshing]; |
| | | |
| | | // [self collectLoadNewData]; |
| | | // NSDictionary *datasourceDic = @{@"ad":_dataAdverti}; |
| | | |
| | | // [self collectLoadNewData]; |
| | | // NSDictionary *datasourceDic = @{@"ad":_dataAdverti}; |
| | | [self.dataDic setValue:_dataAdverti forKey:@"ad"]; |
| | | [self.allDataSourece removeObjectAtIndex:maintypeNumber]; |
| | | [self.allDataSourece insertObject:self.dataDic atIndex:maintypeNumber]; |
| | |
| | | //提示网络不稳定 |
| | | // UICollectionView *collectview = [self viewWithTag:collectTag + maintypeNumber]; |
| | | UICollectionView *collectview = self.collectArray[maintypeNumber]; |
| | | // [self addSliderView]; |
| | | |
| | | // [self addSliderView]; |
| | | |
| | | [collectview.mj_header endRefreshing]; |
| | | } |
| | | }]; |
| | |
| | | _dataAdverti = [[dic objectForKey:@"Data"] objectForKey:@"data"]; |
| | | |
| | | //存储获取到的数据 |
| | | // NSData *data = [NSKeyedArchiver archivedDataWithRootObject:_dataAdverti]; |
| | | // [data writeToFile:ADVERTISEFILE atomically:YES]; |
| | | // NSData *data = [NSKeyedArchiver archivedDataWithRootObject:_dataAdverti]; |
| | | // [data writeToFile:ADVERTISEFILE atomically:YES]; |
| | | // [_recommentCollectionView reloadData]; |
| | | NSLog(@"<------- %@ --------->",_dataAdverti); |
| | | //结束刷新 |
| | |
| | | //提示网络不稳定 |
| | | UICollectionView *collectview = self.collectArray[maintypeNumber]; |
| | | [collectview.mj_header endRefreshing]; |
| | | // [self addSliderView]; |
| | | |
| | | // [self addSliderView]; |
| | | |
| | | } |
| | | }]; |
| | | } |
| | |
| | | * 小广告推广视图 |
| | | */ |
| | | - (void)SpreadRequest{ |
| | | |
| | | |
| | | if (!_adView) { |
| | | _adView = [[WeiKouAdView alloc]initWithFrame:CGRectMake(0.0, 0.0, KScreenW, KScreenW/6) withBlock:^(NSString *text) { |
| | | // [_recommentCollectionView reloadData]; |
| | | // UICollectionView *collectView = [self viewWithTag:collectTag +maintypeNumber]; |
| | | UICollectionView *collectview = self.collectArray[maintypeNumber]; |
| | | // [collectview reloadData]; |
| | | // [self collectLoadNewData]; |
| | | // [self collectLoadNewData]; |
| | | |
| | | }]; |
| | | } |
| | |
| | | // [_recommentCollectionView reloadData]; |
| | | // UICollectionView *collectview = [self viewWithTag:collectTag + maintypeNumber]; |
| | | UICollectionView *collectview = self.collectArray[maintypeNumber]; |
| | | |
| | | |
| | | [collectview.mj_header endRefreshing]; |
| | | // [collectview reloadData]; |
| | | // [self collectLoadNewData]; |
| | | // [self collectLoadNewData]; |
| | | |
| | | [self loadStarsData]; |
| | | // NSData *data = [NSKeyedArchiver archivedDataWithRootObject:_dataHomeType]; |
| | | // [data writeToFile:HOMETYPEFILE atomically:YES]; |
| | | // NSData *data = [NSKeyedArchiver archivedDataWithRootObject:_dataHomeType]; |
| | | // [data writeToFile:HOMETYPEFILE atomically:YES]; |
| | | NSLog(@"<-。。。。%@、、、、、->",_dataHomeType); |
| | | NSLog(@"%ld",(unsigned long)_dataHomeType.count); |
| | | //请求明星分类,为什么要放在这里?因为明星分类是放在最后的,你必须知道推荐分类的个数,才好确定明星分类的个数 |
| | | //结束刷新 |
| | | collectview.mj_footer.hidden = NO; |
| | | |
| | | |
| | | |
| | | //获取广点通原生广告数据 |
| | | [self loadAd]; |
| | | //获取谷歌广告 |
| | | [self loadgoogleAd]; |
| | | |
| | | }else{ |
| | | //提示网络不稳定 |
| | | //UICollectionView *collectview = [self viewWithTag:collectTag + maintypeNumber]; |
| | | UICollectionView *collectview = self.collectArray[maintypeNumber]; |
| | | |
| | | |
| | | [collectview.mj_header endRefreshing]; |
| | | if ([error compare:@"似乎已断开与互联网的连接。"] == 0) { |
| | | collectview.mj_footer.hidden = YES; |
| | | [viewcontroller autoDisappearAlertTime:1 msg:@"网络不可用,请检查网络"]; |
| | | }else{ |
| | | collectview.mj_footer.hidden = NO; |
| | | |
| | | |
| | | } |
| | | } |
| | | }]; |
| | |
| | | [self.allDataSourece insertObject:self.dataDic atIndex:maintypeNumber]; |
| | | //跟新视图数据 |
| | | UICollectionView *collectview = self.collectArray[maintypeNumber]; |
| | | // [self collectLoadNewData]; |
| | | // [self collectLoadNewData]; |
| | | |
| | | // [collectview reloadData]; |
| | | |
| | | // NSData *data = [NSKeyedArchiver archivedDataWithRootObject:_dataHomeType]; |
| | | // [data writeToFile:HOMETYPEFILE atomically:YES]; |
| | | // NSData *data = [NSKeyedArchiver archivedDataWithRootObject:_dataHomeType]; |
| | | // [data writeToFile:HOMETYPEFILE atomically:YES]; |
| | | NSLog(@"<-。。。。%@、、、、、->",_dataHomeType); |
| | | //请求明星分类,为什么要放在这里?因为明星分类是放在最后的,你必须知道推荐分类的个数,才好确定明星分类的个数 |
| | | [self loadStarsData]; |
| | | //结束刷新 |
| | | collectview.mj_footer.hidden = NO; |
| | | |
| | | |
| | | [collectview.mj_header endRefreshing]; |
| | | //获取广点通原生广告数据 |
| | | [self loadAd]; |
| | | //获取谷歌广告 |
| | | [self loadgoogleAd]; |
| | | |
| | | }else{ |
| | | //提示网络不稳定 |
| | | // UICollectionView *collectview = [self viewWithTag:collectTag + maintypeNumber]; |
| | | UICollectionView *collectview = self.collectArray[maintypeNumber]; |
| | | // [collectview reloadData]; |
| | | // [collectview reloadData]; |
| | | [collectview.mj_header endRefreshing]; |
| | | if ([error compare:@"似乎已断开与互联网的连接。"] == 0) { |
| | | collectview.mj_footer.hidden = YES; |
| | |
| | | if ([_type_id integerValue] == 310) { |
| | | _cycleScrollView = [[BSKImagesPageView alloc]initWithFrame:CGRectMake(0, 0,KScreenW, KScreenH / 3.12) imageNames:_addrssForshuffling]; |
| | | }else{ |
| | | _cycleScrollView = [[BSKImagesPageView alloc]initWithFrame:CGRectMake(0, 0,KScreenW, KScreenW*7/16) imageNames:_addrssForshuffling]; |
| | | _cycleScrollView = [[BSKImagesPageView alloc]initWithFrame:CGRectMake(0, 0,KScreenW, KScreenW*7/16) imageNames:_addrssForshuffling]; |
| | | } |
| | | _cycleScrollView.timerTimeInterval = 2; |
| | | _cycleScrollView.delegate = self; |
| | |
| | | |
| | | // [collectview reloadData]; |
| | | //存储获取到的数据 |
| | | // NSData *data = [NSKeyedArchiver archivedDataWithRootObject:_dataStar]; |
| | | // [data writeToFile:DISCOVERSTAR atomically:YES]; |
| | | // NSData *data = [NSKeyedArchiver archivedDataWithRootObject:_dataStar]; |
| | | // [data writeToFile:DISCOVERSTAR atomically:YES]; |
| | | }else{ |
| | | NSLog(@"%@",error); |
| | | // UICollectionView *collectview = [self viewWithTag:collectTag + maintypeNumber]; |
| | | // UICollectionView *collectview = self.collectArray[maintypeNumber]; |
| | | // UICollectionView *collectview = self.collectArray[maintypeNumber]; |
| | | [self collectLoadNewData]; |
| | | |
| | | // [collectview reloadData]; |
| | | } |
| | | }]; |
| | | |
| | | |
| | | } |
| | | |
| | | /** |
| | |
| | | * 加载广点通原生广告 |
| | | */ |
| | | -(void)loadAd{ |
| | | |
| | | |
| | | self.nativeExpressAd = [self loadAdWithId:GDTYSADkey2 adSize:CGSizeMake((KScreenW-30)/2, (KScreenW-30)*10/32+55)]; |
| | | self.secNativeExpressAd = [self loadAdWithId:GDTYSADkey8 adSize:CGSizeMake(KScreenW, (KScreenW-20)/16*9 + 10)]; |
| | | self.thiNativeExpressAd = [self loadAdWithId:GDTYSADkey9 adSize:CGSizeMake(KScreenW, (KScreenW-20)/16*9 + 10)]; |
| | |
| | | return expressAd; |
| | | } |
| | | |
| | | /** |
| | | * 加载谷歌广告 |
| | | */ |
| | | -(void)loadgoogleAd{ |
| | | //请求谷歌广告的时候,就不忙加载芒果广告了 |
| | | googleNoAdToShow=NO; |
| | | |
| | | //谷歌广告请求时的配置 |
| | | NSMutableArray *adTypes = [[NSMutableArray alloc] init]; |
| | | [adTypes addObject:kGADAdLoaderAdTypeNativeAppInstall]; |
| | | |
| | | GADNativeAdImageAdLoaderOptions *adOptions=[[GADNativeAdImageAdLoaderOptions alloc] init]; |
| | | adOptions.disableImageLoading=YES; |
| | | |
| | | self.adLoader = [[GADAdLoader alloc] initWithAdUnitID:AdGoogleKey |
| | | rootViewController:[self viewController] |
| | | adTypes:adTypes |
| | | options:nil]; |
| | | self.adLoader.delegate = self; |
| | | [self.adLoader loadRequest:[GADRequest request]]; |
| | | } |
| | | |
| | | /** |
| | | * 点击芒果广告的方法 |
| | | */ |
| | | //-(void)getMoreInformation:(UIButton *)sender{ |
| | | // GDTNativeAdData * info; |
| | | // if (sender.tag-456==1) { |
| | | // info=nativeArray[0]; |
| | | // }else if(sender.tag-456==_dataHomeType.count){ |
| | | // info=nativeArray[1]; |
| | | // }else{ |
| | | // info=nativeArray[2]; |
| | | // } |
| | | // |
| | | // [_nativeAd clickAd:info]; |
| | | // |
| | | //} |
| | | //在主线程刷新collectview,非主线程不能刷新 |
| | | - (void)collectLoadNewData{ |
| | | dispatch_async(dispatch_get_main_queue(), ^{ |
| | |
| | | collectview.scrollEnabled = YES; |
| | | [CATransaction commit]; |
| | | [UIView setAnimationsEnabled:YES]; |
| | | |
| | | |
| | | }); |
| | | } |
| | | #pragma mark 把json格式的字符串转换为字典格式 |
| | |
| | | #pragma mark -UICollection----ViewDataSource |
| | | - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{ |
| | | NSArray * dataHomeType = self.allDataSourece[maintypeNumber][@"shopping"]; |
| | | |
| | | |
| | | if (section==0) { |
| | | return 0; |
| | | }else |
| | |
| | | return nil; |
| | | } |
| | | if (indexPath.row == 0 && indexPath.section == 1) { |
| | | |
| | | |
| | | AdCollectionViewCell *cell=[collectionView dequeueReusableCellWithReuseIdentifier:@"AdCollectionViewCell" forIndexPath:indexPath]; |
| | | GDTNativeExpressAdView *adView ; |
| | | if ([_type_id integerValue] == 309) { |
| | |
| | | adView.frame = cell.bounds; |
| | | [cell.contentView.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)]; |
| | | [cell.contentView addSubview: adView]; |
| | | |
| | | |
| | | //添加阴影 |
| | | cell.layer.masksToBounds = NO; |
| | | cell.layer.contentsScale = [UIScreen mainScreen].scale; |
| | |
| | | recommentCollectionViewCell *cell=[collectionView dequeueReusableCellWithReuseIdentifier:@"recommentCollectionViewCell" forIndexPath:indexPath]; |
| | | //设置cell的背景色(白色) |
| | | cell.backgroundColor=[UIColor whiteColor]; |
| | | |
| | | |
| | | |
| | | //在这里对cell进行设置 |
| | | if (_dataHomeType.count < indexPath.section) { |
| | | return cell; |
| | | } |
| | | |
| | | |
| | | NSArray *HomeVideoList=[_dataHomeType[indexPath.section-1] objectForKey:@"HomeVideoList"]; |
| | | if (indexPath.row >= HomeVideoList.count) { |
| | | return cell; |
| | |
| | | //设置图片 |
| | | cell.recommentImageView.contentMode=UIViewContentModeScaleAspectFill; |
| | | if (picStr.length>1) { |
| | | // NSString *path = [[NSBundle mainBundle] pathForResource:picStr ofType:@"gif"]; |
| | | // NSData *data = [NSData dataWithContentsOfFile:path]; |
| | | // UIImage *image = [UIImage sd_animatedGIFWithData:data]; |
| | | // cell.recommentImageView.image = image; |
| | | // [cell.recommentImageView sd_setImageWithURL:[NSURL URLWithString:picStr]]; |
| | | // NSString *path = [[NSBundle mainBundle] pathForResource:picStr ofType:@"gif"]; |
| | | // NSData *data = [NSData dataWithContentsOfFile:path]; |
| | | // UIImage *image = [UIImage sd_animatedGIFWithData:data]; |
| | | // cell.recommentImageView.image = image; |
| | | // [cell.recommentImageView sd_setImageWithURL:[NSURL URLWithString:picStr]]; |
| | | [cell.recommentImageView setYthImageWithURL:picStr placeholderImage:[UIImage imageNamed:@"默认加载图片"]]; |
| | | }else{ |
| | | picStr=[VideoDic objectForKey:@"Picture"]; |
| | |
| | | cell.recommentReplyLabel.text=TagStr2; |
| | | }else if([Score intValue]>0){ |
| | | cell.recommentReplyLabel.hidden = YES; |
| | | |
| | | |
| | | cell.recommentReplyLabel.text=[NSString stringWithFormat:@"评分:%@",Score]; |
| | | }else{ |
| | | cell.recommentReplyLabel.text=[NSString stringWithFormat:@"评分:无"]; |
| | | cell.recommentReplyLabel.hidden = YES; |
| | | |
| | | |
| | | } |
| | | cell.recommentReplyLabel.backgroundColor=[UIColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:0.7]; |
| | | //标题 |
| | |
| | | cell.layer.shouldRasterize = YES; |
| | | //设置抗锯齿边缘 |
| | | cell.layer.rasterizationScale = [UIScreen mainScreen].scale; |
| | | |
| | | |
| | | return cell; |
| | | } |
| | | else{ |
| | | StartCollectionViewCell *cell=[collectionView dequeueReusableCellWithReuseIdentifier:@"StartCollectionViewCell" forIndexPath:indexPath]; |
| | | // [cell.image setYthImageWithURL:[_dataStar[indexPath.row] objectForKey:@"Portrait"] placeholderImage:[UIImage imageNamed:@"关注默认头像"]]; |
| | | // [cell.name setText:[_dataStar[indexPath.row] objectForKey:@"Name"]]; |
| | | // [cell.image setYthImageWithURL:[_dataStar[indexPath.row] objectForKey:@"Portrait"] placeholderImage:[UIImage imageNamed:@"关注默认头像"]]; |
| | | // [cell.name setText:[_dataStar[indexPath.row] objectForKey:@"Name"]]; |
| | | return cell; |
| | | } |
| | | }else{ |
| | | if (indexPath.row < _dataHomeType.count) { |
| | | if (indexPath.row == 0 && indexPath.section == 1) { |
| | | AdCollectionViewCell *cell=[collectionView dequeueReusableCellWithReuseIdentifier:@"AdCollectionViewCell" forIndexPath:indexPath]; |
| | | |
| | | |
| | | GDTNativeExpressAdView *adView = (GDTNativeExpressAdView *)self.clSecExpressAdViews[0]; |
| | | adView.frame = cell.bounds; |
| | | [cell.contentView.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)]; |
| | |
| | | |
| | | //设置cell的背景色(白色) |
| | | cell.backgroundColor=[UIColor whiteColor]; |
| | | |
| | | |
| | | //在这里对cell进行设置 |
| | | // NSArray *HomeVideoList=_dataHomeType[indexPath.row]; |
| | | |
| | |
| | | |
| | | } |
| | | } |
| | | if(kind == UICollectionElementKindSectionFooter){ |
| | | if (indexPath.section==0) { |
| | | if (kind == UICollectionElementKindSectionFooter) { |
| | | if (indexPath.section == 0) { |
| | | //放置小广告 |
| | | FooterCollectionReusableView *footer=[collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionFooter withReuseIdentifier:@"FooterCollectionReusableView" forIndexPath:indexPath]; |
| | | //添加小广告视图 |
| | |
| | | return nil; |
| | | } |
| | | return footer; |
| | | }else |
| | | |
| | | } else { |
| | | if (indexPath.section==1) { |
| | | //返回广告视图 |
| | | ADCollectionReusableView *groupfootSection = [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionFooter withReuseIdentifier:@"ADCollectionReusableView" forIndexPath:indexPath]; |
| | | |
| | | |
| | | GDTNativeExpressAdView *adView; |
| | | if ([_type_id integerValue] == 309) { |
| | | adView = (GDTNativeExpressAdView *)self.secExpressAdViews[0]; |
| | |
| | | } |
| | | [groupfootSection addSubview:adView]; |
| | | return groupfootSection; |
| | | }else if (indexPath.section==_dataHomeType.count){ |
| | | if(googleNoAdToShow){//加载芒果广告 |
| | | ADCollectionReusableView *groupfootSection = [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionFooter withReuseIdentifier:@"ADCollectionReusableView" forIndexPath:indexPath]; |
| | | GDTNativeExpressAdView *adView = (GDTNativeExpressAdView *)self.thiExpressAdViews[0]; |
| | | [groupfootSection addSubview:adView]; |
| | | return groupfootSection; |
| | | }else{ |
| | | if (self.nativeAdView!=nil) { |
| | | ADCollectionReusableView *groupfootSection = [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionFooter withReuseIdentifier:@"GoogleAdCollectionReusableView" forIndexPath:indexPath]; |
| | | self.nativeAdView.frame=CGRectMake(0, 0, KScreenW, KScreenW/2); |
| | | [groupfootSection addSubview:self.nativeAdView]; |
| | | return groupfootSection; |
| | | } |
| | | } |
| | | } |
| | | // else if (indexPath.section==_dataHomeType.count){ |
| | | // |
| | | // |
| | | // UICollectionReusableView *reusableFootView = [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionFooter withReuseIdentifier:@"UICollectionReusableView" forIndexPath:indexPath]; |
| | | // |
| | | // if(googleNoAdToShow){//加载芒果广告 |
| | | // |
| | | // return reusableFootView; |
| | | // } else { |
| | | // if (self.nativeAdView!=nil) { |
| | | // |
| | | // return reusableFootView; |
| | | // } |
| | | // } |
| | | // } |
| | | } |
| | | } |
| | | return nil; |
| | | UICollectionReusableView *reusableFootView = [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionFooter withReuseIdentifier:@"UICollectionReusableView" forIndexPath:indexPath]; |
| | | return reusableFootView; |
| | | } |
| | | |
| | | - (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout referenceSizeForHeaderInSection:(NSInteger)section{ |
| | |
| | | } |
| | | } |
| | | - (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout referenceSizeForFooterInSection:(NSInteger)section{ |
| | | |
| | | if (section==0) { |
| | | // if(_adView!=nil){ |
| | | // if(_adView.dataArray.count>0){ |
| | |
| | | }else if(section==1){ |
| | | if (self.expressAdViews==nil) { |
| | | return CGSizeMake(0, 0); |
| | | }else{ |
| | | |
| | | } else { |
| | | GDTNativeExpressAdView *adView = (GDTNativeExpressAdView *)self.secExpressAdViews[0]; |
| | | |
| | | return CGSizeMake(0, adView.bounds.size.height); |
| | | } |
| | | }else if(section==_dataHomeType.count){ |
| | | |
| | | } else if (section == _dataHomeType.count) { |
| | | if(googleNoAdToShow){ |
| | | if (self.expressAdViews==nil) { |
| | | return CGSizeMake(0, 0); |
| | | }else{ |
| | | GDTNativeExpressAdView *adView = (GDTNativeExpressAdView *)self.thiExpressAdViews[0]; |
| | | return CGSizeMake(0, adView.bounds.size.height); |
| | | |
| | | } else { |
| | | return CGSizeMake(0, 0); |
| | | } |
| | | |
| | | }else{ |
| | | if (self.nativeAdView==nil) { |
| | | return CGSizeMake(0, 0); |
| | | }else{ |
| | | return CGSizeMake(0, KScreenW/2); |
| | | return CGSizeMake(0, 0); |
| | | } |
| | | } |
| | | }else{ |
| | |
| | | |
| | | NSString *s = [[_dataHomeType[indexPath.section-1] objectForKey:@"Params"] stringByReplacingOccurrencesOfString:[NSString stringWithFormat:@"%@\"",@"\\"] withString:@"\""]; |
| | | NSDictionary *Params = [self dictionaryWithJsonString:s]; |
| | | |
| | | |
| | | //因为福利社的样式是与其他分类的更多信息不一样,所以,必须要做一个判断 |
| | | NSLog( @"%@",Params); |
| | | NSLog(@"%@",[Params objectForKey:@"Name"]); |
| | |
| | | if ([_type_id integerValue] == 309 || [_type_id integerValue] == 310) { |
| | | NSArray *HomeVideoList=[self.dataHomeType[indexPath.section-1] objectForKey:@"HomeVideoList"]; |
| | | XYRDetailViewController *play=[[XYRDetailViewController alloc]init]; |
| | | play.modalPresentationStyle = 0; |
| | | play.Model = [XYRVideoInfoModel yy_modelWithDictionary:[HomeVideoList[indexPath.row] objectForKey:@"Video"]]; |
| | | [[self viewController] presentViewController:play animated:YES completion:^{ |
| | | |
| | | }]; |
| | | }else{ |
| | | |
| | | } else { |
| | | NSDictionary *HomeVideoList=self.dataHomeType[indexPath.row]; |
| | | XYRDetailViewController *play=[[XYRDetailViewController alloc]init]; |
| | | play.modalPresentationStyle = 0; |
| | | play.Model = [XYRVideoInfoModel yy_modelWithDictionary:HomeVideoList]; |
| | | [[self viewController] presentViewController:play animated:YES completion:^{ |
| | | |
| | | }]; |
| | | } |
| | | |
| | | } |
| | | } |
| | | }else{ |
| | | |
| | | } else { |
| | | if ([_type_id integerValue] == 309 || [_type_id integerValue] == 310) { |
| | | NSArray *HomeVideoList=[self.dataHomeType[indexPath.section-1] objectForKey:@"HomeVideoList"]; |
| | | XYRDetailViewController *play=[[XYRDetailViewController alloc]init]; |
| | | XYRDetailViewController *play = [[XYRDetailViewController alloc]init]; |
| | | play.modalPresentationStyle = 0; |
| | | play.Model = [XYRVideoInfoModel yy_modelWithDictionary:[HomeVideoList[indexPath.row] objectForKey:@"Video"]]; |
| | | [[self viewController] presentViewController:play animated:YES completion:^{ |
| | | }]; |
| | | }else{ |
| | | |
| | | } else { |
| | | NSDictionary *HomeVideoList=self.dataHomeType[indexPath.row] ; |
| | | XYRDetailViewController *play=[[XYRDetailViewController alloc]init]; |
| | | play.modalPresentationStyle = 0; |
| | | play.Model = [XYRVideoInfoModel yy_modelWithDictionary:HomeVideoList]; |
| | | [[self viewController] presentViewController:play animated:YES completion:^{ |
| | | }]; |
| | |
| | | video = @"VideoInfo"; |
| | | } |
| | | NSLog(@"%@",self.dataAdverti[index]); |
| | | play.modalPresentationStyle = 0; |
| | | play.Model = [XYRVideoInfoModel yy_modelWithDictionary:[self.dataAdverti[index] objectForKey:video]]; |
| | | [[self viewController] presentViewController:play animated:YES completion:^{ |
| | | |
| | | }]; |
| | | }else if (LinkType == 2){//网页(网页) |
| | | //url |
| | | // NSString *s = [[self.dataAdverti[index] objectForKey:@"Params"] stringByReplacingOccurrencesOfString:[NSString stringWithFormat:@"%@\"",@"\\"] withString:@"\""]; |
| | | // NSString *s = [[self.dataAdverti[index] objectForKey:@"Params"] stringByReplacingOccurrencesOfString:[NSString stringWithFormat:@"%@\"",@"\\"] withString:@"\""]; |
| | | NSString *s = [[self.dataAdverti[index] objectForKey:@"Params"] stringByReplacingOccurrencesOfString:@"\\"withString:@""]; |
| | | |
| | | |
| | | NSDictionary *Params = [self dictionaryWithJsonString:s]; |
| | | NSLog(@"%@",Params); |
| | | [[UIApplication sharedApplication] openURL:[NSURL URLWithString:[Params objectForKey:@"url"]]]; |
| | | }else if (LinkType == 3){//专辑 |
| | | |
| | | } else if (LinkType == 3){//专辑 |
| | | OnlySpecialController *OnlySpecial =[OnlySpecialController new]; |
| | | OnlySpecial.Id=[[self.dataAdverti[index] objectForKey:@"Id"] intValue]; |
| | | [[self viewController].navigationController pushViewController:OnlySpecial animated:YES]; |
| | | } |
| | | } |
| | | #pragma mark -GADAdLoaderDelegate |
| | | /** |
| | | * 广告加载失败 |
| | | */ |
| | | - (void)adLoader:(GADAdLoader *)adLoader didFailToReceiveAdWithError:(GADRequestError *)error { |
| | | NSLog(@"%@ failed with error: %@", adLoader, [error localizedDescription]); |
| | | //谷歌广告获取失败 |
| | | //通知视图加载芒果广告 |
| | | googleNoAdToShow=YES; |
| | | //刷新视图 |
| | | // UICollectionView *collectview = [self viewWithTag:collectTag +maintypeNumber]; |
| | | // UICollectionView *collectview = self.collectArray[maintypeNumber]; |
| | | [self collectLoadNewData]; |
| | | // [collectview reloadData]; |
| | | // [_recommentCollectionView reloadData]; |
| | | } |
| | | |
| | | #pragma mark -GADNativeAppInstallAdLoaderDelegate |
| | | - (void)adLoader:(GADAdLoader *)adLoader |
| | | didReceiveNativeAppInstallAd:(GADNativeAppInstallAd *)nativeAppInstallAd{ |
| | | // Create a new AdView instance from the xib file. |
| | | GADNativeAppInstallAdView *appInstallAdView = |
| | | [[[NSBundle mainBundle] loadNibNamed:@"googleADS" |
| | | owner:nil |
| | | options:nil] firstObject]; |
| | | |
| | | // Associate the app install ad view with the app install ad object. |
| | | // This is required to make the ad clickable. |
| | | appInstallAdView.nativeAppInstallAd = nativeAppInstallAd; |
| | | |
| | | // Populate the app install ad view with the app install ad assets. |
| | | ((UILabel *)appInstallAdView.headlineView).text = nativeAppInstallAd.headline; |
| | | [((UIButton *)appInstallAdView.callToActionView) |
| | | setTitle:nativeAppInstallAd.callToAction |
| | | forState:UIControlStateNormal]; |
| | | ((UIImageView *)appInstallAdView.iconView).image = nativeAppInstallAd.icon.image; |
| | | ((UILabel *)appInstallAdView.bodyView).text = nativeAppInstallAd.body; |
| | | ((UILabel *)appInstallAdView.storeView).text = nativeAppInstallAd.store; |
| | | ((UILabel *)appInstallAdView.priceView).text = nativeAppInstallAd.price; |
| | | ((UIImageView *)appInstallAdView.imageView).image = |
| | | ((GADNativeAdImage *)[nativeAppInstallAd.images firstObject]).image; |
| | | ((UIImageView *)appInstallAdView.starRatingView).image = |
| | | [self imageForStars:nativeAppInstallAd.starRating]; |
| | | |
| | | // In order for the SDK to process touch events properly, user interaction |
| | | // should be disabled on UIButtons. |
| | | appInstallAdView.callToActionView.userInteractionEnabled = NO; |
| | | |
| | | // Add appInstallAdView to the view controller's view. |
| | | self.nativeAdView=appInstallAdView; |
| | | // UICollectionView *collectview = [self viewWithTag:collectTag + maintypeNumber]; |
| | | [self collectLoadNewData]; |
| | | |
| | | // [collectview reloadData]; |
| | | // [_recommentCollectionView reloadData]; |
| | | } |
| | | |
| | | // Gets an image representing the number of stars. Returns nil if rating is less than 3.5 stars. |
| | |
| | | // nativeArray = nativeAdDataArray; |
| | | // [self collectLoadNewData]; |
| | | |
| | | // [collectview reloadData]; |
| | | // [_recommentCollectionView reloadData]; |
| | | // [collectview reloadData]; |
| | | // [_recommentCollectionView reloadData]; |
| | | //} |
| | | |
| | | /** |
| | |
| | | NSLog(@"%@",error); |
| | | } |
| | | |
| | | #pragma mark -GADNativeContentAdLoaderDelegate |
| | | - (void)adLoader:(GADAdLoader *)adLoader didReceiveNativeContentAd:(GADNativeContentAd *)nativeContentAd{ |
| | | |
| | | } |
| | | |
| | | #pragma mark - UIScrollViewDelegate |
| | | - (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView { |
| | | CGFloat pageWidth =KScreenW; |
| | |
| | | NSLog(@"%d",scrollView.mj_header.isRefreshing); |
| | | }else{ |
| | | [self loadAd]; |
| | | |
| | | |
| | | maintypeNumber = page; |
| | | _type_id = self.classArray[page][@"Id"]; |
| | | // UICollectionView *collectview = self.collectArray[maintypeNumber]; |
| | | // collectview.hidden = NO; |
| | | // [collectview scrollToItemAtIndexPath:[NSIndexPath indexPathForItem:0 inSection:0] atScrollPosition:UICollectionViewScrollPositionTop animated:NO]; |
| | | |
| | | // UICollectionView *collectview = self.collectArray[maintypeNumber]; |
| | | // collectview.hidden = NO; |
| | | // [collectview scrollToItemAtIndexPath:[NSIndexPath indexPathForItem:0 inSection:0] atScrollPosition:UICollectionViewScrollPositionTop animated:NO]; |
| | | |
| | | [self.vidioGmentControl setSelectedSegmentIndex:page animated:YES]; |
| | | // NSArray * dataHomeType = self.allDataSourece[maintypeNumber][@"shopping"]; |
| | | // |
| | | // if (dataHomeType.count == 0) { |
| | | // collectview.scrollEnabled = NO; |
| | | [self loadNewData]; |
| | | // } |
| | | // NSArray * dataHomeType = self.allDataSourece[maintypeNumber][@"shopping"]; |
| | | // |
| | | // if (dataHomeType.count == 0) { |
| | | // collectview.scrollEnabled = NO; |
| | | [self loadNewData]; |
| | | // } |
| | | |
| | | } |
| | | } |
| | |
| | | } |
| | | //添加主UIScrollView |
| | | -(void)addScrollView { |
| | | |
| | | |
| | | if (KIsiPhoneX) { |
| | | _scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 124, KScreenW, self.frame.size.height-104)]; |
| | | |
| | | _scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 40, KScreenW, self.frame.size.height-124)]; |
| | | |
| | | }else{ |
| | | _scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 104, KScreenW, self.frame.size.height-104)]; |
| | | |
| | | _scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 40, KScreenW, self.frame.size.height-104)]; |
| | | |
| | | } |
| | | _scrollView.pagingEnabled = YES; |
| | | _scrollView.showsHorizontalScrollIndicator = NO; |
| | | _scrollView.contentSize = CGSizeMake(KScreenW * self.classArray.count , self.frame.size.height-104); |
| | | _scrollView.delegate = self; |
| | | [_scrollView scrollRectToVisible:CGRectMake(0, 0, KScreenW, self.frame.size.height-104) animated:NO]; |
| | | // [_cycleScrollView adjustWhenControllerViewWillAppera]; |
| | | // [_cycleScrollView adjustWhenControllerViewWillAppera]; |
| | | [self addSubview:self.scrollView]; |
| | | // _scrollView .alwaysBounceVertical = YES; |
| | | // _scrollView .alwaysBounceHorizontal = YES; |
| | | [UIView setAnimationsEnabled:NO]; |
| | | |
| | | |
| | | |
| | | |
| | | for (NSInteger index = 0; index <self.classArray.count; index++) { |
| | | UICollectionViewFlowLayout *flow = [[UICollectionViewFlowLayout alloc]init]; |
| | | //指定布局方式为垂直 |
| | |
| | | collectview.delegate=self; |
| | | collectview.dataSource=self; |
| | | collectview.backgroundColor=kGlobalBackgroundColor; |
| | | // collectview.backgroundColor = [UIColor orangeColor]; |
| | | // collectview.backgroundColor = [UIColor orangeColor]; |
| | | collectview .mj_footer = [MJRefreshAutoNormalFooter footerWithRefreshingBlock:^{ |
| | | [collectview.mj_footer endRefreshingWithNoMoreData]; |
| | | }]; |
| | |
| | | [collectview registerNib:[UINib nibWithNibName:@"ADCollectionReusableView" bundle:nil] forSupplementaryViewOfKind:UICollectionElementKindSectionFooter withReuseIdentifier:@"ADCollectionReusableView"]; |
| | | //设置尾部谷歌广告的foot |
| | | [collectview registerNib:[UINib nibWithNibName:@"GoogleAdCollectionReusableView" bundle:nil] forSupplementaryViewOfKind:UICollectionElementKindSectionFooter withReuseIdentifier:@"GoogleAdCollectionReusableView"]; |
| | | |
| | | [collectview registerClass:[UICollectionReusableView class] forSupplementaryViewOfKind:UICollectionElementKindSectionFooter withReuseIdentifier:@"UICollectionReusableView"]; |
| | | |
| | | //推荐视图 |
| | | //先查收看是否有旧的数据,在网络差的时候优先加载旧的数据 |
| | | //给collectionView设置下拉刷新 |
| | |
| | | [_scrollView addSubview:collectview]; |
| | | } |
| | | [UIView setAnimationsEnabled:YES]; |
| | | |
| | | |
| | | maintypeNumber = 0; |
| | | UICollectionView *collectview = self.collectArray[0]; |
| | | collectview.hidden = NO; |
| | | |
| | | |
| | | _type_id = self.classArray[0][@"Id"]; |
| | | |
| | | |
| | | [self loadOldData]; |
| | | [self addSubview:self.noNetworkView]; |
| | | } |
| | |
| | | } |
| | | - (void)viewWillAppear:(BOOL)animated{ |
| | | [super viewWillAppear:animated]; |
| | | [self.navigationController.navigationBar setBackgroundColor:kGlobalMainColor]; |
| | | self.navigationController.navigationBar.barTintColor = kGlobalMainColor; |
| | | |
| | | // self.navigationController.navigationBar.translucent = NO; |
| | | |
| | | self.navigationController.navigationBar.translucent = NO; |
| | | } |
| | | |
| | | - (void)viewWillDisappear:(BOOL)animated { |
| | | //self.navigationController.navigationBar.translucent = YES; |
| | | } |
| | | |
| | | - (void)viewDidLoad { |
| | | [super viewDidLoad]; |
| | | self.automaticallyAdjustsScrollViewInsets = NO; |
| | |
| | | } |
| | | [self.view addSubview:self.recommendView]; |
| | | [self.view addSubview:self.primtView]; |
| | | |
| | | [self.navigationController.navigationBar setBackgroundColor:kGlobalMainColor]; |
| | | self.navigationController.navigationBar.barTintColor = [UIColor blackColor]; |
| | | } |
| | | - (void)refreshTaped:(UIButton *)sender{ |
| | | self.primtView.hidden = YES; |
| | |
| | | #import "searchDetailViewController.h" |
| | | #import "YTHSearchTextField.h" |
| | | #import "searchTableViewCell.h" |
| | | #import "SearchDetailListCell.h" |
| | | |
| | | #import "XYRDetailViewController.h" |
| | | #import "XYRVideoInfoModel.h" |
| | | //#import "GDTNativeAd.h" |
| | | #import "DisCoverADView.h" |
| | | #import "GDTNativeExpressAd.h" |
| | | #import "GDTNativeExpressAdView.h" |
| | | |
| | | #import "SearchTitleView.h" |
| | | |
| | | static NSString *indentfly = @"cell"; |
| | | static NSString *indentfly2=@"searchTableViewCellID"; |
| | | |
| | | @interface searchDetailViewController ()<YTHSearchTextFieldDelegate,UITableViewDataSource,UITableViewDelegate,GDTNativeExpressAdDelegete>{ |
| | | @interface searchDetailViewController ()<YTHSearchTextFieldDelegate,UITableViewDataSource,UITableViewDelegate,GDTNativeExpressAdDelegete,SearchDetailListCellDelegate,SearchTitleViewDelegate>{ |
| | | NSInteger pagenumber; |
| | | NSInteger typenumber; |
| | | //广点通原生广告 |
| | | // GDTNativeAd *_nativeAd; //原生广告实例 |
| | | // NSArray *nativeArray;//存储请求下来的原生广告信息 |
| | | // GDTNativeAd *_nativeAd; //原生广告实例 |
| | | // NSArray *nativeArray;//存储请求下来的原生广告信息 |
| | | } |
| | | @property (nonatomic , strong) YTHSearchTextField *searchField;//搜索框对象 |
| | | @property (nonatomic , strong) NSMutableArray *dataSearch;//搜索结果数据 |
| | | |
| | | @property (weak, nonatomic) UITableView *suggestTableview;//模糊搜索弹出的表格 |
| | | @property (nonatomic , strong) NSMutableArray *suggestSearch;//搜索建议 |
| | | @property (weak, nonatomic) IBOutlet UISegmentedControl *segment;//分段按钮 |
| | | @property (weak, nonatomic) IBOutlet NSLayoutConstraint *topConstraint; |
| | | |
| | | @property (nonatomic , strong) UITableView *DisplayTabelView;//用于显示搜索结果的列表 |
| | | @property (nonatomic, strong) NSArray *expressAdViews; |
| | | @property (nonatomic, strong) GDTNativeExpressAd *nativeExpressAd; |
| | | |
| | | @property (nonatomic, strong) SearchTitleView *viewSearchTitle; |
| | | |
| | | @property (nonatomic, strong) NSArray *typeList; |
| | | @end |
| | | |
| | | @implementation searchDetailViewController |
| | |
| | | [self setNavgtionView]; |
| | | //添加搜索建议的tableview |
| | | [self addsuggestTableview]; |
| | | //添加分段按钮的属性 |
| | | [self addSegment]; |
| | | //添加搜索结果的列表 |
| | | [self addTabelView]; |
| | | [self loadAd]; |
| | | |
| | | |
| | | } |
| | | |
| | | - (void)viewWillAppear:(BOOL)animated |
| | | { |
| | | [super viewWillAppear:animated]; |
| | | [MobClick beginLogPageView:@"搜索结果界面"]; |
| | | } |
| | | |
| | | - (void)viewWillDisappear:(BOOL)animated |
| | | { |
| | | [super viewWillDisappear:animated]; |
| | | [MobClick endLogPageView:@"搜索结果界面"]; |
| | | |
| | | } |
| | | |
| | | /** |
| | | * 设置导航栏 |
| | | */ |
| | | - (void)setNavgtionView{ |
| | | - (void)setNavgtionView { |
| | | UIView *titleView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, KScreenW-115, 30)]; |
| | | YTHSearchTextField *searchField = [[YTHSearchTextField alloc] initWithFrame:CGRectMake(0, 0, titleView.frame.size.width, titleView.frame.size.height)]; |
| | | |
| | |
| | | searchField.layer.cornerRadius =searchField.frame.size.height / 2; |
| | | searchField.layer.masksToBounds = YES; |
| | | searchField.backgroundColor = [UIColor colorWithWhite:0.7 alpha:0.2]; |
| | | |
| | | |
| | | [titleView addSubview:searchField]; |
| | | self.navigationItem.titleView = titleView; |
| | | //取消输入框的第一响应事件 |
| | |
| | | searchField.Field.text = self.searchString; |
| | | |
| | | //加载用户搜索的数据 |
| | | [self loadSearchData]; |
| | | //[self loadSearchData]; |
| | | |
| | | //定制返回按钮 |
| | | UIButton *backBtn=[[UIButton alloc] initWithFrame:CGRectMake(0, 0, 30, 50)]; |
| | |
| | | self.navigationItem.rightBarButtonItem=searchItem; |
| | | |
| | | self.view.backgroundColor = kGlobalBackgroundColor; |
| | | |
| | | [self.view addSubview:self.viewSearchTitle]; |
| | | } |
| | | /** |
| | | * 添加segment的属性 |
| | | */ |
| | | -(void)addSegment{ |
| | | self.segment.tintColor = kGlobalYellowColor; |
| | | if (KIsiPhoneX) { |
| | | self.topConstraint.constant = 94; |
| | | } |
| | | [self.segment setTitleTextAttributes:@{NSForegroundColorAttributeName:KGlobalLightGreyColor_153} forState:UIControlStateNormal]; |
| | | [self.segment setTitleTextAttributes:@{NSForegroundColorAttributeName:kGlobalMainColor} forState:UIControlStateSelected]; |
| | | [self.segment addTarget:self action:@selector(segmentClick:) forControlEvents:UIControlEventValueChanged]; |
| | | } |
| | | |
| | | /** |
| | | * 加载广点通原生广告 |
| | | */ |
| | | -(void)loadAd{ |
| | | // _nativeAd = [[GDTNativeAd alloc]initWithAppId: GDTADkey placementId:GDTYSADkey3]; |
| | | // _nativeAd.controller = self; |
| | | // _nativeAd.delegate = self; |
| | | // [_nativeAd loadAd:10]; |
| | | // _nativeAd = [[GDTNativeAd alloc]initWithAppId: GDTADkey placementId:GDTYSADkey3]; |
| | | // _nativeAd.controller = self; |
| | | // _nativeAd.delegate = self; |
| | | // [_nativeAd loadAd:10]; |
| | | self.nativeExpressAd = [[GDTNativeExpressAd alloc] initWithAppId:GDTADkey placementId:GDTYSADkey7 adSize:CGSizeMake(KScreenW, 95)]; |
| | | self.nativeExpressAd.delegate = self; |
| | | // 配置视频播放属性 |
| | |
| | | /** |
| | | * 添加用于显示的列表 |
| | | */ |
| | | -(void)addTabelView{ |
| | | if(self.DisplayTabelView==nil){ |
| | | -(void)addTabelView { |
| | | if(!self.DisplayTabelView) { |
| | | CGFloat height = 64; |
| | | if (KIsiPhoneX) { |
| | | height = 94; |
| | | height = 84; |
| | | } |
| | | |
| | | self.DisplayTabelView=[[UITableView alloc] initWithFrame:CGRectMake(0, height+40, KScreenW, KScreenH-height-40) style:UITableViewStyleGrouped]; |
| | | self.DisplayTabelView = [[UITableView alloc] initWithFrame:CGRectMake(0, 40, KScreenW, KScreenH - height - 40) style:UITableViewStyleGrouped]; |
| | | } |
| | | self.DisplayTabelView.delegate=self; |
| | | self.DisplayTabelView.dataSource=self; |
| | | NSLog(@"%f",KScreenH); |
| | | self.DisplayTabelView.rowHeight = 95.0; |
| | | |
| | | |
| | | //tableView背景色 |
| | | self.DisplayTabelView.backgroundColor=kGlobalBackgroundColor; |
| | | self.DisplayTabelView.backgroundColor = [UIColor whiteColor]; |
| | | self.DisplayTabelView.separatorStyle = UITableViewCellSeparatorStyleNone; |
| | | //注册Cell |
| | | [self.DisplayTabelView registerNib:[UINib nibWithNibName:@"searchTableViewCell" bundle:nil] forCellReuseIdentifier:indentfly2]; |
| | | [self.view addSubview:self.DisplayTabelView]; |
| | | //下拉刷新 |
| | | self.DisplayTabelView.mj_header = [MJRefreshNormalHeader headerWithRefreshingBlock:^{ |
| | | if (!self.searchField.Field.text || [self.searchField.Field.text isEqualToString:@""]) { |
| | | [self.DisplayTabelView.mj_header endRefreshing]; |
| | | return; |
| | | } |
| | | pagenumber = 1; |
| | | //请求数据 |
| | | [self loadSearchData]; |
| | | [self loadSearchData:NO]; |
| | | [self.DisplayTabelView.mj_footer resetNoMoreData]; |
| | | }]; |
| | | //上拉加载更多 |
| | | self.DisplayTabelView.mj_footer=[MJRefreshAutoNormalFooter footerWithRefreshingBlock:^{ |
| | | ++pagenumber; |
| | | //请求数据 |
| | | [self loadSearchData]; |
| | | [self loadSearchData:NO]; |
| | | }]; |
| | | [self.DisplayTabelView.mj_header beginRefreshing]; |
| | | //添加手势 |
| | | UISwipeGestureRecognizer *recognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(SwipeGesture:)]; |
| | | [recognizer setDirection:UISwipeGestureRecognizerDirectionLeft]; |
| | | [self.DisplayTabelView addGestureRecognizer:recognizer]; |
| | | |
| | | UISwipeGestureRecognizer *recognizer2 = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(SwipeGesture:)]; |
| | | [recognizer2 setDirection:UISwipeGestureRecognizerDirectionRight]; |
| | | [self.DisplayTabelView addGestureRecognizer:recognizer2]; |
| | | } |
| | | /** |
| | | * 手势的响应方法 |
| | | * |
| | | * @param gestureRecognizer 传入手势 |
| | | */ |
| | | -(void)SwipeGesture:(UISwipeGestureRecognizer *)gestureRecognizer{ |
| | | if (gestureRecognizer.direction==UISwipeGestureRecognizerDirectionRight) { |
| | | if (typenumber==0) { |
| | | typenumber=2; |
| | | }else{ |
| | | --typenumber; |
| | | } |
| | | }else if(gestureRecognizer.direction==UISwipeGestureRecognizerDirectionLeft){ |
| | | if (typenumber==2) { |
| | | typenumber=0; |
| | | }else{ |
| | | ++typenumber; |
| | | } |
| | | } |
| | | self.segment.selectedSegmentIndex=typenumber; |
| | | [self.DisplayTabelView.mj_header beginRefreshing]; |
| | | } |
| | | |
| | | /** |
| | | * 分段按钮的值变化事件 |
| | | * |
| | | * @param seg 传入分段按钮 |
| | | */ |
| | | - (void)segmentClick:(UISegmentedControl *)seg{ |
| | | switch (seg.selectedSegmentIndex) { |
| | | case 0:{//点击了全部 |
| | | typenumber = 0; |
| | | [self.DisplayTabelView.mj_header beginRefreshing]; |
| | | } |
| | | break; |
| | | case 1:{//点击了正片 |
| | | typenumber = 1; |
| | | [self.DisplayTabelView.mj_header beginRefreshing]; |
| | | } |
| | | break; |
| | | case 2:{//点击了专辑 |
| | | typenumber = 2; |
| | | [self.DisplayTabelView.mj_header beginRefreshing]; |
| | | } |
| | | break; |
| | | default: |
| | | break; |
| | | } |
| | | [self loadSearchData:YES]; |
| | | //[self.DisplayTabelView.mj_header beginRefreshing]; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * 请求搜索数据 |
| | | */ |
| | | -(void)loadSearchData{ |
| | | [self searchDataWithText:self.searchField.Field.text withType:typenumber withPage:pagenumber]; |
| | | /// 请求搜索数据 |
| | | /// @param isSearch 是不是搜索来的数据 |
| | | -(void)loadSearchData:(BOOL)isSearch { |
| | | [self searchDataWithText:self.searchField.Field.text withType:typenumber withPage:pagenumber :isSearch]; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * 添加搜索建议的tableView |
| | | */ |
| | | -(void)addsuggestTableview{ |
| | | UITableView *suggestTableview = [[UITableView alloc]initWithFrame:CGRectMake(0,kNavigationBarH , KScreenW, KScreenH-kNavigationBarH) style:UITableViewStyleGrouped]; |
| | | - (void)addsuggestTableview { |
| | | CGFloat spaceTop = 64; |
| | | if (KIsiPhoneX) { |
| | | spaceTop = 84; |
| | | } |
| | | UITableView *suggestTableview = [[UITableView alloc]initWithFrame:CGRectMake(0, 0, KScreenW, KScreenH - spaceTop) style:UITableViewStyleGrouped]; |
| | | [suggestTableview setBackgroundColor:[UIColor whiteColor]]; |
| | | suggestTableview.delegate = self; |
| | | suggestTableview.dataSource = self; |
| | | suggestTableview.hidden = YES; |
| | | suggestTableview.rowHeight = 44; |
| | | _suggestTableview = suggestTableview; |
| | | [self.view addSubview:suggestTableview]; |
| | | } |
| | |
| | | * |
| | | * @param sender 搜索按钮 |
| | | */ |
| | | -(void)search:(UIButton *)sender{ |
| | | -(void)search:(UIButton *)sender { |
| | | if ([_searchField.Field.text isEqualToString:@""] || !_searchField.Field.text) { |
| | | return; |
| | | } |
| | | pagenumber = 1; |
| | | [_searchField.Field resignFirstResponder]; |
| | | [_DisplayTabelView setHidden:NO]; |
| | | [_suggestTableview setHidden:YES]; |
| | | [self loadSearchData]; |
| | | [self loadSearchData:YES]; |
| | | } |
| | | |
| | | |
| | | - (void)selectType:(NSInteger)type { |
| | | typenumber = type; |
| | | [self.DisplayTabelView.mj_header beginRefreshing]; |
| | | } |
| | | |
| | | /** |
| | | * 请求搜索数据 |
| | |
| | | * @param type 搜索的类型 |
| | | * @param page 搜索的页数 |
| | | */ |
| | | - (void)searchDataWithText:(NSString *)searchText withType:(NSInteger)type withPage:(NSInteger )page{ |
| | | - (void)searchDataWithText:(NSString *)searchText withType:(NSInteger)type withPage:(NSInteger )page :(BOOL)isSearch { |
| | | [self loadAd]; |
| | | if (isSearch) { |
| | | [SVProgressHUD show]; |
| | | } |
| | | [[YTHNetInterface startInterface] getSerachWithUid:[YTHsharedManger startManger].Uid withKey:searchText withType:[NSString stringWithFormat:@"%ld",(long)type] withVideoType:[NSString stringWithFormat:@"%ld",(long)type] withSystem:@"1" withPage:[NSString stringWithFormat:@"%ld",(long)page] withblock:^(BOOL isSuccessful, id result, NSString *error) { |
| | | [SVProgressHUD dismiss]; |
| | | |
| | | if (isSuccessful) { |
| | | NSDictionary *dic = (NSDictionary *)result; |
| | | if (!_dataSearch) { |
| | | _dataSearch = [[NSMutableArray alloc] initWithCapacity:0]; |
| | | } |
| | | if (pagenumber ==1) { |
| | | if (pagenumber == 1) { |
| | | [_dataSearch removeAllObjects]; |
| | | if (isSearch) {// 如果是搜索 重新创建title |
| | | self.typeList = dic[@"Data"][@"typeList"]; |
| | | [self.viewSearchTitle setTitleData:self.typeList :isSearch]; |
| | | } |
| | | //self.viewSearchTitle.typeList = _typeList; |
| | | } |
| | | NSArray *ar = [[dic objectForKey:@"Data"] objectForKey:@"data"]; |
| | | for (int i =0; i<ar.count; i++) { |
| | |
| | | } |
| | | if (_dataSearch.count<1) { |
| | | //没有数据,需要告诉用户 |
| | | |
| | | } |
| | | ++pagenumber; |
| | | [self.DisplayTabelView.mj_header endRefreshing]; |
| | | [self.DisplayTabelView.mj_footer endRefreshing]; |
| | | [self.DisplayTabelView reloadData]; |
| | | |
| | | if ( [dic[@"Data"][@"count"] integerValue] == _dataSearch.count) { |
| | | [self.DisplayTabelView.mj_footer endRefreshingWithNoMoreData]; |
| | | } |
| | | |
| | | }else{ |
| | | [SVProgressHUD showWithStatus:error]; |
| | | //提示用户失败 |
| | |
| | | self.DisplayTabelView.hidden = NO; |
| | | } |
| | | |
| | | - (void)playVideo:(XYRVideoInfoModel *)model { |
| | | XYRDetailViewController *detailVC=[[XYRDetailViewController alloc] init]; |
| | | detailVC.modalPresentationStyle = 0; |
| | | detailVC.Model = model; |
| | | [self presentViewController:detailVC animated:YES completion:^{}]; |
| | | } |
| | | |
| | | #pragma mark -UITableViewDataSource |
| | | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ |
| | | return 1; |
| | | } |
| | | - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{ |
| | | if (tableView==self.suggestTableview) { |
| | | if (tableView == self.suggestTableview) { |
| | | return _suggestSearch.count; |
| | | |
| | | }else{ |
| | | return _dataSearch.count; |
| | | } |
| | |
| | | } |
| | | cell.textLabel.text = [_suggestSearch objectAtIndex:indexPath.section]; |
| | | return cell; |
| | | }else{ |
| | | searchTableViewCell *cell=[tableView dequeueReusableCellWithIdentifier:indentfly2]; |
| | | cell.clickBtn.hidden = YES; |
| | | cell.ADImage.hidden = YES; |
| | | //获取到该cell的数据 |
| | | XYRVideoInfoModel *model = [XYRVideoInfoModel yy_modelWithDictionary:[_dataSearch objectAtIndex:indexPath.section]]; |
| | | //加载图片 |
| | | [cell.searchTableViewCellImage setYthImageWithURL:model.Hpicture placeholderImage:[UIImage imageNamed:@"默认加载图片"]]; |
| | | NSLog(@"%@",cell.searchTableViewCellImage); |
| | | //加载名称 |
| | | cell.searchTableViewCellTitle.text=model.Name; |
| | | //显示Tag值 |
| | | cell.SearchTabelViewTag.text=model.Tag; |
| | | cell.SearchTabelViewTag.textColor=[UIColor grayColor]; |
| | | //观看数量 |
| | | cell.searchTableViewCellWatchNUB.textColor=kGlobalLightGreyColor_210; |
| | | |
| | | NSString *recommentStr; |
| | | if (model.WatchCount==nil){ |
| | | recommentStr=[NSString stringWithFormat:@"0"]; |
| | | }else if ([model.WatchCount intValue]<10000) { |
| | | recommentStr=model.WatchCount; |
| | | }else{ |
| | | recommentStr=[NSString stringWithFormat:@"%0.1f万",[model.WatchCount floatValue]/10000.0]; |
| | | } |
| | | cell.searchTableViewCellWatchNUB.text=recommentStr; |
| | | //评论数量CommentCount |
| | | cell.searchTableViewCellCommentNUB.textColor=kGlobalLightGreyColor_210; |
| | | NSString *commentCountStr; |
| | | commentCountStr=[NSString stringWithFormat:@"%ld",(long)model.CommentCount]; |
| | | if (model.CommentCount<10000) { |
| | | } else { |
| | | //获取到该cell的数据 |
| | | XYRVideoInfoModel *model = [XYRVideoInfoModel yy_modelWithDictionary:_dataSearch[indexPath.section]]; |
| | | |
| | | if (model.ShowType == 1) { |
| | | SearchDetailListCell *cell = [tableView dequeueReusableCellWithIdentifier:indentfly]; |
| | | if (!cell) { |
| | | cell = [[SearchDetailListCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:indentfly]; |
| | | cell.delegate = self; |
| | | } |
| | | cell.model = model; |
| | | return cell; |
| | | |
| | | }else{ |
| | | commentCountStr=[NSString stringWithFormat:@"%0.1f万",[commentCountStr floatValue]/10000.0]; |
| | | } else { |
| | | searchTableViewCell *cell=[tableView dequeueReusableCellWithIdentifier:indentfly2]; |
| | | cell.clickBtn.hidden = YES; |
| | | cell.ADImage.hidden = YES; |
| | | |
| | | //加载图片 |
| | | [cell.searchTableViewCellImage setYthImageWithURL:model.Hpicture placeholderImage:[UIImage imageNamed:@"默认加载图片"]]; |
| | | NSLog(@"%@",cell.searchTableViewCellImage); |
| | | //加载名称 |
| | | cell.searchTableViewCellTitle.text=model.Name; |
| | | //显示Tag值 |
| | | cell.SearchTabelViewTag.text=model.Tag; |
| | | cell.SearchTabelViewTag.textColor=[UIColor grayColor]; |
| | | //观看数量 |
| | | cell.searchTableViewCellWatchNUB.textColor=kGlobalLightGreyColor_210; |
| | | |
| | | NSString *recommentStr; |
| | | if (model.WatchCount==nil){ |
| | | recommentStr=[NSString stringWithFormat:@"0"]; |
| | | }else if ([model.WatchCount intValue]<10000) { |
| | | recommentStr=model.WatchCount; |
| | | }else{ |
| | | recommentStr=[NSString stringWithFormat:@"%0.1f万",[model.WatchCount floatValue]/10000.0]; |
| | | } |
| | | cell.searchTableViewCellWatchNUB.text=recommentStr; |
| | | //评论数量CommentCount |
| | | cell.searchTableViewCellCommentNUB.textColor=kGlobalLightGreyColor_210; |
| | | NSString *commentCountStr; |
| | | commentCountStr=[NSString stringWithFormat:@"%ld",(long)model.CommentCount]; |
| | | if (model.CommentCount<10000) { |
| | | |
| | | }else{ |
| | | commentCountStr=[NSString stringWithFormat:@"%0.1f万",[commentCountStr floatValue]/10000.0]; |
| | | } |
| | | cell.searchTableViewCellCommentNUB.text=[NSString stringWithFormat:@"%@",commentCountStr]; |
| | | cell.backgroundColor = [UIColor whiteColor]; |
| | | |
| | | return cell; |
| | | } |
| | | cell.searchTableViewCellCommentNUB.text=[NSString stringWithFormat:@"%@",commentCountStr]; |
| | | cell.backgroundColor = kGlobalBackgroundColor; |
| | | |
| | | return cell; |
| | | } |
| | | } |
| | | #pragma mark -UITableViewDelegate |
| | |
| | | infoIndex = section / 20; |
| | | } |
| | | GDTNativeExpressAdView *adView = (GDTNativeExpressAdView *)self.expressAdViews[infoIndex]; |
| | | return adView.bounds.size.height - 4; |
| | | }else{ |
| | | return adView.bounds.size.height; |
| | | |
| | | } else { |
| | | return CGFLOAT_MIN; |
| | | } |
| | | } |
| | |
| | | } |
| | | |
| | | |
| | | //- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{ |
| | | // if(tableView==self.suggestTableview){ |
| | | // return 44; |
| | | // }else{ |
| | | // return 95; |
| | | // } |
| | | //} |
| | | - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{ |
| | | if(tableView == self.suggestTableview) { |
| | | return 44; |
| | | |
| | | } else { |
| | | XYRVideoInfoModel *model = [XYRVideoInfoModel yy_modelWithDictionary:_dataSearch[indexPath.section]]; |
| | | if (model.ShowType == 1) { |
| | | if (model.VideoDetailList.count == 0) { |
| | | return 152; |
| | | |
| | | } else { |
| | | return 190; |
| | | } |
| | | } |
| | | return 95; |
| | | } |
| | | } |
| | | |
| | | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{ |
| | | [tableView deselectRowAtIndexPath:indexPath animated:YES]; |
| | | if(tableView==self.suggestTableview){ |
| | | _searchField.Field.text = [_suggestSearch objectAtIndex:indexPath.section]; |
| | | [self searchCotol:_searchField.Field.text]; |
| | | [self.DisplayTabelView.mj_header beginRefreshing]; |
| | | }else{ |
| | | XYRDetailViewController *detailVC=[[XYRDetailViewController alloc] init]; |
| | | detailVC.Model=[XYRVideoInfoModel yy_modelWithDictionary:_dataSearch[indexPath.section]]; |
| | | [self presentViewController:detailVC animated:YES completion:^{ |
| | | //[self.DisplayTabelView.mj_header beginRefreshing]; |
| | | [self searchDataWithText:self.searchField.Field.text withType:typenumber withPage:1 :YES]; |
| | | |
| | | } else { |
| | | XYRVideoInfoModel *model = [XYRVideoInfoModel yy_modelWithDictionary:_dataSearch[indexPath.section]]; |
| | | if (model.ShowType == 1) { |
| | | |
| | | }]; |
| | | return; |
| | | } |
| | | XYRDetailViewController *detailVC=[[XYRDetailViewController alloc] init]; |
| | | detailVC.modalPresentationStyle = 0; |
| | | detailVC.Model = model; |
| | | [self presentViewController:detailVC animated:YES completion:^{}]; |
| | | } |
| | | } |
| | | |
| | | - (SearchTitleView *)viewSearchTitle { |
| | | if (!_viewSearchTitle) { |
| | | _viewSearchTitle = [[SearchTitleView alloc] initWithFrame:CGRectMake(0, 0, KScreenW, 40)]; |
| | | _viewSearchTitle.delegate = self; |
| | | } |
| | | return _viewSearchTitle; |
| | | } |
| | | @end |
BuWanVideo2.0/searchDetailViewController.xib
BuWanVideo2.0/searchViewController.m
BuWanVideo2.0/subregionView.m
BuWanVideo2.0/猜你喜欢/GuessLikeViewController.m
Podfile
Podfile.lock
Pods/AFNetworking/UIKit+AFNetworking/UIKit+AFNetworking.h
Pods/AFNetworking/UIKit+AFNetworking/UIWebView+AFNetworking.h (deleted)
Pods/AFNetworking/UIKit+AFNetworking/UIWebView+AFNetworking.m (deleted)
Pods/Firebase/Core/Sources/Firebase.h (deleted)
Pods/Firebase/Core/Sources/module.modulemap (deleted)
Pods/Firebase/README.md (deleted)
Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.framework/FirebaseAnalytics (deleted)
Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.framework/Headers/FIRAnalytics+AppDelegate.h (deleted)
Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.framework/Headers/FIRAnalytics.h (deleted)
Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.framework/Headers/FIRAnalyticsConfiguration.h (deleted)
Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.framework/Headers/FIRAnalyticsSwiftNameSupport.h (deleted)
Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.framework/Headers/FIRApp.h (deleted)
Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.framework/Headers/FIRConfiguration.h (deleted)
Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.framework/Headers/FIREventNames.h (deleted)
Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.framework/Headers/FIROptions.h (deleted)
Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.framework/Headers/FIRParameterNames.h (deleted)
Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.framework/Headers/FIRUserPropertyNames.h (deleted)
Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.framework/Headers/FirebaseAnalytics.h (deleted)
Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.framework/Modules/module.modulemap (deleted)
Pods/FirebaseCore/Frameworks/FirebaseCore.framework/FirebaseCore (deleted)
Pods/FirebaseCore/Frameworks/FirebaseCore.framework/Headers/FIRAnalyticsConfiguration.h (deleted)
Pods/FirebaseCore/Frameworks/FirebaseCore.framework/Headers/FIRApp.h (deleted)
Pods/FirebaseCore/Frameworks/FirebaseCore.framework/Headers/FIRConfiguration.h (deleted)
Pods/FirebaseCore/Frameworks/FirebaseCore.framework/Headers/FIRCoreSwiftNameSupport.h (deleted)
Pods/FirebaseCore/Frameworks/FirebaseCore.framework/Headers/FIRLoggerLevel.h (deleted)
Pods/FirebaseCore/Frameworks/FirebaseCore.framework/Headers/FIROptions.h (deleted)
Pods/FirebaseCore/Frameworks/FirebaseCore.framework/Headers/FirebaseCore.h (deleted)
Pods/FirebaseCore/Frameworks/FirebaseCore.framework/Modules/module.modulemap (deleted)
Pods/FirebaseCore/Frameworks/FirebaseCoreDiagnostics.framework/FirebaseCoreDiagnostics (deleted)
Pods/FirebaseCore/Frameworks/FirebaseCoreDiagnostics.framework/Modules/module.modulemap (deleted)
Pods/FirebaseCore/Frameworks/FirebaseNanoPB.framework/FirebaseNanoPB (deleted)
Pods/FirebaseInstanceID/CHANGELOG.md (deleted)
Pods/FirebaseInstanceID/Frameworks/FirebaseInstanceID.framework/FirebaseInstanceID (deleted)
Pods/FirebaseInstanceID/Frameworks/FirebaseInstanceID.framework/Headers/FIRInstanceID.h (deleted)
Pods/FirebaseInstanceID/Frameworks/FirebaseInstanceID.framework/Headers/FirebaseInstanceID.h (deleted)
Pods/FirebaseInstanceID/Frameworks/FirebaseInstanceID.framework/Modules/module.modulemap (deleted)
Pods/FirebaseInstanceID/README.md (deleted)
Pods/Google-Mobile-Ads-SDK/Frameworks/frameworks/GoogleMobileAds.framework/GoogleMobileAds (deleted)
Pods/Google-Mobile-Ads-SDK/Frameworks/frameworks/GoogleMobileAds.framework/Headers (deleted)
Pods/Google-Mobile-Ads-SDK/Frameworks/frameworks/GoogleMobileAds.framework/Modules/module.modulemap (deleted)
Pods/Google-Mobile-Ads-SDK/Frameworks/frameworks/GoogleMobileAds.framework/Versions/A/GoogleMobileAds (deleted)
Pods/Google-Mobile-Ads-SDK/Frameworks/frameworks/GoogleMobileAds.framework/Versions/A/Headers/DFPBannerView.h (deleted)
Pods/Google-Mobile-Ads-SDK/Frameworks/frameworks/GoogleMobileAds.framework/Versions/A/Headers/DFPBannerViewOptions.h (deleted)
Pods/Google-Mobile-Ads-SDK/Frameworks/frameworks/GoogleMobileAds.framework/Versions/A/Headers/DFPCustomRenderedAd.h (deleted)
Pods/Google-Mobile-Ads-SDK/Frameworks/frameworks/GoogleMobileAds.framework/Versions/A/Headers/DFPCustomRenderedBannerViewDelegate.h (deleted)
Pods/Google-Mobile-Ads-SDK/Frameworks/frameworks/GoogleMobileAds.framework/Versions/A/Headers/DFPCustomRenderedInterstitialDelegate.h (deleted)
Pods/Google-Mobile-Ads-SDK/Frameworks/frameworks/GoogleMobileAds.framework/Versions/A/Headers/DFPInterstitial.h (deleted)
Pods/Google-Mobile-Ads-SDK/Frameworks/frameworks/GoogleMobileAds.framework/Versions/A/Headers/DFPRequest.h (deleted)
Pods/Google-Mobile-Ads-SDK/Frameworks/frameworks/GoogleMobileAds.framework/Versions/A/Headers/GADAdChoicesView.h (deleted)
Pods/Google-Mobile-Ads-SDK/Frameworks/frameworks/GoogleMobileAds.framework/Versions/A/Headers/GADAdLoader.h (deleted)
Pods/Google-Mobile-Ads-SDK/Frameworks/frameworks/GoogleMobileAds.framework/Versions/A/Headers/GADAdLoaderAdTypes.h (deleted)
Pods/Google-Mobile-Ads-SDK/Frameworks/frameworks/GoogleMobileAds.framework/Versions/A/Headers/GADAdLoaderDelegate.h (deleted)
Pods/Google-Mobile-Ads-SDK/Frameworks/frameworks/GoogleMobileAds.framework/Versions/A/Headers/GADAdNetworkExtras.h (deleted)
Pods/Google-Mobile-Ads-SDK/Frameworks/frameworks/GoogleMobileAds.framework/Versions/A/Headers/GADAdReward.h (deleted)
Pods/Google-Mobile-Ads-SDK/Frameworks/frameworks/GoogleMobileAds.framework/Versions/A/Headers/GADAdSize.h (deleted)
Pods/Google-Mobile-Ads-SDK/Frameworks/frameworks/GoogleMobileAds.framework/Versions/A/Headers/GADAdSizeDelegate.h (deleted)
Pods/Google-Mobile-Ads-SDK/Frameworks/frameworks/GoogleMobileAds.framework/Versions/A/Headers/GADAppEventDelegate.h (deleted)
Pods/Google-Mobile-Ads-SDK/Frameworks/frameworks/GoogleMobileAds.framework/Versions/A/Headers/GADAudioVideoManager.h (deleted)
Pods/Google-Mobile-Ads-SDK/Frameworks/frameworks/GoogleMobileAds.framework/Versions/A/Headers/GADAudioVideoManagerDelegate.h (deleted)
Pods/Google-Mobile-Ads-SDK/Frameworks/frameworks/GoogleMobileAds.framework/Versions/A/Headers/GADBannerView.h (deleted)
Pods/Google-Mobile-Ads-SDK/Frameworks/frameworks/GoogleMobileAds.framework/Versions/A/Headers/GADBannerViewDelegate.h (deleted)
Pods/Google-Mobile-Ads-SDK/Frameworks/frameworks/GoogleMobileAds.framework/Versions/A/Headers/GADCorrelator.h (deleted)
Pods/Google-Mobile-Ads-SDK/Frameworks/frameworks/GoogleMobileAds.framework/Versions/A/Headers/GADCorrelatorAdLoaderOptions.h (deleted)
Pods/Google-Mobile-Ads-SDK/Frameworks/frameworks/GoogleMobileAds.framework/Versions/A/Headers/GADCustomEventBanner.h (deleted)
Pods/Google-Mobile-Ads-SDK/Frameworks/frameworks/GoogleMobileAds.framework/Versions/A/Headers/GADCustomEventBannerDelegate.h (deleted)
Pods/Google-Mobile-Ads-SDK/Frameworks/frameworks/GoogleMobileAds.framework/Versions/A/Headers/GADCustomEventExtras.h (deleted)
Pods/Google-Mobile-Ads-SDK/Frameworks/frameworks/GoogleMobileAds.framework/Versions/A/Headers/GADCustomEventInterstitial.h (deleted)
Pods/Google-Mobile-Ads-SDK/Frameworks/frameworks/GoogleMobileAds.framework/Versions/A/Headers/GADCustomEventInterstitialDelegate.h (deleted)
Pods/Google-Mobile-Ads-SDK/Frameworks/frameworks/GoogleMobileAds.framework/Versions/A/Headers/GADCustomEventNativeAd.h (deleted)
Pods/Google-Mobile-Ads-SDK/Frameworks/frameworks/GoogleMobileAds.framework/Versions/A/Headers/GADCustomEventNativeAdDelegate.h (deleted)
Pods/Google-Mobile-Ads-SDK/Frameworks/frameworks/GoogleMobileAds.framework/Versions/A/Headers/GADCustomEventParameters.h (deleted)
Pods/Google-Mobile-Ads-SDK/Frameworks/frameworks/GoogleMobileAds.framework/Versions/A/Headers/GADCustomEventRequest.h (deleted)
Pods/Google-Mobile-Ads-SDK/Frameworks/frameworks/GoogleMobileAds.framework/Versions/A/Headers/GADDebugOptionsViewController.h (deleted)
Pods/Google-Mobile-Ads-SDK/Frameworks/frameworks/GoogleMobileAds.framework/Versions/A/Headers/GADDynamicHeightSearchRequest.h (deleted)
Pods/Google-Mobile-Ads-SDK/Frameworks/frameworks/GoogleMobileAds.framework/Versions/A/Headers/GADExtras.h (deleted)
Pods/Google-Mobile-Ads-SDK/Frameworks/frameworks/GoogleMobileAds.framework/Versions/A/Headers/GADInAppPurchase.h (deleted)
Pods/Google-Mobile-Ads-SDK/Frameworks/frameworks/GoogleMobileAds.framework/Versions/A/Headers/GADInAppPurchaseDelegate.h (deleted)
Pods/Google-Mobile-Ads-SDK/Frameworks/frameworks/GoogleMobileAds.framework/Versions/A/Headers/GADInterstitial.h (deleted)
Pods/Google-Mobile-Ads-SDK/Frameworks/frameworks/GoogleMobileAds.framework/Versions/A/Headers/GADInterstitialDelegate.h (deleted)
Pods/Google-Mobile-Ads-SDK/Frameworks/frameworks/GoogleMobileAds.framework/Versions/A/Headers/GADMediaView.h (deleted)
Pods/Google-Mobile-Ads-SDK/Frameworks/frameworks/GoogleMobileAds.framework/Versions/A/Headers/GADMediatedNativeAd.h (deleted)
Pods/Google-Mobile-Ads-SDK/Frameworks/frameworks/GoogleMobileAds.framework/Versions/A/Headers/GADMediatedNativeAdDelegate.h (deleted)
Pods/Google-Mobile-Ads-SDK/Frameworks/frameworks/GoogleMobileAds.framework/Versions/A/Headers/GADMediatedNativeAdNotificationSource.h (deleted)
Pods/Google-Mobile-Ads-SDK/Frameworks/frameworks/GoogleMobileAds.framework/Versions/A/Headers/GADMediatedNativeAppInstallAd.h (deleted)
Pods/Google-Mobile-Ads-SDK/Frameworks/frameworks/GoogleMobileAds.framework/Versions/A/Headers/GADMediatedNativeContentAd.h (deleted)
Pods/Google-Mobile-Ads-SDK/Frameworks/frameworks/GoogleMobileAds.framework/Versions/A/Headers/GADMobileAds.h (deleted)
Pods/Google-Mobile-Ads-SDK/Frameworks/frameworks/GoogleMobileAds.framework/Versions/A/Headers/GADMultipleAdsAdLoaderOptions.h (deleted)
Pods/Google-Mobile-Ads-SDK/Frameworks/frameworks/GoogleMobileAds.framework/Versions/A/Headers/GADNativeAd.h (deleted)
Pods/Google-Mobile-Ads-SDK/Frameworks/frameworks/GoogleMobileAds.framework/Versions/A/Headers/GADNativeAdDelegate.h (deleted)
Pods/Google-Mobile-Ads-SDK/Frameworks/frameworks/GoogleMobileAds.framework/Versions/A/Headers/GADNativeAdImage+Mediation.h (deleted)
Pods/Google-Mobile-Ads-SDK/Frameworks/frameworks/GoogleMobileAds.framework/Versions/A/Headers/GADNativeAdImage.h (deleted)
Pods/Google-Mobile-Ads-SDK/Frameworks/frameworks/GoogleMobileAds.framework/Versions/A/Headers/GADNativeAdImageAdLoaderOptions.h (deleted)
Pods/Google-Mobile-Ads-SDK/Frameworks/frameworks/GoogleMobileAds.framework/Versions/A/Headers/GADNativeAdViewAdOptions.h (deleted)
Pods/Google-Mobile-Ads-SDK/Frameworks/frameworks/GoogleMobileAds.framework/Versions/A/Headers/GADNativeAppInstallAd.h (deleted)
Pods/Google-Mobile-Ads-SDK/Frameworks/frameworks/GoogleMobileAds.framework/Versions/A/Headers/GADNativeAppInstallAdAssetIDs.h (deleted)
Pods/Google-Mobile-Ads-SDK/Frameworks/frameworks/GoogleMobileAds.framework/Versions/A/Headers/GADNativeContentAd.h (deleted)
Pods/Google-Mobile-Ads-SDK/Frameworks/frameworks/GoogleMobileAds.framework/Versions/A/Headers/GADNativeContentAdAssetIDs.h (deleted)
Pods/Google-Mobile-Ads-SDK/Frameworks/frameworks/GoogleMobileAds.framework/Versions/A/Headers/GADNativeCustomTemplateAd.h (deleted)
Pods/Google-Mobile-Ads-SDK/Frameworks/frameworks/GoogleMobileAds.framework/Versions/A/Headers/GADNativeExpressAdView.h (deleted)
Pods/Google-Mobile-Ads-SDK/Frameworks/frameworks/GoogleMobileAds.framework/Versions/A/Headers/GADNativeExpressAdViewDelegate.h (deleted)
Pods/Google-Mobile-Ads-SDK/Frameworks/frameworks/GoogleMobileAds.framework/Versions/A/Headers/GADRequest.h (deleted)
Pods/Google-Mobile-Ads-SDK/Frameworks/frameworks/GoogleMobileAds.framework/Versions/A/Headers/GADRequestError.h (deleted)
Pods/Google-Mobile-Ads-SDK/Frameworks/frameworks/GoogleMobileAds.framework/Versions/A/Headers/GADRewardBasedVideoAd.h (deleted)
Pods/Google-Mobile-Ads-SDK/Frameworks/frameworks/GoogleMobileAds.framework/Versions/A/Headers/GADRewardBasedVideoAdDelegate.h (deleted)
Pods/Google-Mobile-Ads-SDK/Frameworks/frameworks/GoogleMobileAds.framework/Versions/A/Headers/GADSearchBannerView.h (deleted)
Pods/Google-Mobile-Ads-SDK/Frameworks/frameworks/GoogleMobileAds.framework/Versions/A/Headers/GADSearchRequest.h (deleted)
Pods/Google-Mobile-Ads-SDK/Frameworks/frameworks/GoogleMobileAds.framework/Versions/A/Headers/GADVideoController.h (deleted)
Pods/Google-Mobile-Ads-SDK/Frameworks/frameworks/GoogleMobileAds.framework/Versions/A/Headers/GADVideoControllerDelegate.h (deleted)
Pods/Google-Mobile-Ads-SDK/Frameworks/frameworks/GoogleMobileAds.framework/Versions/A/Headers/GADVideoOptions.h (deleted)
Pods/Google-Mobile-Ads-SDK/Frameworks/frameworks/GoogleMobileAds.framework/Versions/A/Headers/GoogleMobileAds.h (deleted)
Pods/Google-Mobile-Ads-SDK/Frameworks/frameworks/GoogleMobileAds.framework/Versions/A/Headers/GoogleMobileAdsDefines.h (deleted)
Pods/Google-Mobile-Ads-SDK/Frameworks/frameworks/GoogleMobileAds.framework/Versions/A/Headers/Mediation/GADMAdNetworkAdapterProtocol.h (deleted)
Pods/Google-Mobile-Ads-SDK/Frameworks/frameworks/GoogleMobileAds.framework/Versions/A/Headers/Mediation/GADMAdNetworkConnectorProtocol.h (deleted)
Pods/Google-Mobile-Ads-SDK/Frameworks/frameworks/GoogleMobileAds.framework/Versions/A/Headers/Mediation/GADMEnums.h (deleted)
Pods/Google-Mobile-Ads-SDK/Frameworks/frameworks/GoogleMobileAds.framework/Versions/A/Headers/Mediation/GADMRewardBasedVideoAdNetworkAdapterProtocol.h (deleted)
Pods/Google-Mobile-Ads-SDK/Frameworks/frameworks/GoogleMobileAds.framework/Versions/A/Headers/Mediation/GADMRewardBasedVideoAdNetworkConnectorProtocol.h (deleted)
Pods/Google-Mobile-Ads-SDK/Frameworks/frameworks/GoogleMobileAds.framework/Versions/A/Headers/Mediation/GADMediationAdRequest.h (deleted)
Pods/Google-Mobile-Ads-SDK/Frameworks/frameworks/GoogleMobileAds.framework/Versions/Current (deleted)
Pods/Google-Mobile-Ads-SDK/README.txt (deleted)
Pods/GoogleToolboxForMac/Foundation/GTMNSData+zlib.h (deleted)
Pods/GoogleToolboxForMac/Foundation/GTMNSData+zlib.m (deleted)
Pods/GoogleToolboxForMac/GTMDefines.h (deleted)
Pods/GoogleToolboxForMac/LICENSE (deleted)
Pods/GoogleToolboxForMac/README.md (deleted)
Pods/Headers/Private/Firebase/Firebase.h (deleted)
Pods/Headers/Private/UMengUShare/UMSocialQQHandler.h (deleted)
Pods/Headers/Private/UMengUShare/UMSocialSinaHandler.h (deleted)
Pods/Headers/Private/UMengUShare/UMSocialWechatHandler.h (deleted)
Pods/Headers/Public/Firebase/Firebase.h (deleted)
Pods/Headers/Public/UMengUShare/UMSocialQQHandler.h (deleted)
Pods/Headers/Public/UMengUShare/UMSocialSinaHandler.h (deleted)
Pods/Headers/Public/UMengUShare/UMSocialWechatHandler.h (deleted)
Pods/MJRefresh/LICENSE (deleted)
Pods/MJRefresh/MJRefresh/Base/MJRefreshAutoFooter.h (deleted)
Pods/MJRefresh/MJRefresh/Base/MJRefreshAutoFooter.m (deleted)
Pods/MJRefresh/MJRefresh/Base/MJRefreshBackFooter.h (deleted)
Pods/MJRefresh/MJRefresh/Base/MJRefreshBackFooter.m (deleted)
Pods/MJRefresh/MJRefresh/Base/MJRefreshComponent.h (deleted)
Pods/MJRefresh/MJRefresh/Base/MJRefreshComponent.m (deleted)
Pods/MJRefresh/MJRefresh/Base/MJRefreshFooter.h (deleted)
Pods/MJRefresh/MJRefresh/Base/MJRefreshFooter.m (deleted)
Pods/MJRefresh/MJRefresh/Base/MJRefreshHeader.h (deleted)
Pods/MJRefresh/MJRefresh/Base/MJRefreshHeader.m (deleted)
Pods/MJRefresh/MJRefresh/Custom/Footer/Auto/MJRefreshAutoGifFooter.h (deleted)
Pods/MJRefresh/MJRefresh/Custom/Footer/Auto/MJRefreshAutoGifFooter.m (deleted)
Pods/MJRefresh/MJRefresh/Custom/Footer/Auto/MJRefreshAutoNormalFooter.h (deleted)
Pods/MJRefresh/MJRefresh/Custom/Footer/Auto/MJRefreshAutoNormalFooter.m (deleted)
Pods/MJRefresh/MJRefresh/Custom/Footer/Auto/MJRefreshAutoStateFooter.h (deleted)
Pods/MJRefresh/MJRefresh/Custom/Footer/Auto/MJRefreshAutoStateFooter.m (deleted)
Pods/MJRefresh/MJRefresh/Custom/Footer/Back/MJRefreshBackGifFooter.h (deleted)
Pods/MJRefresh/MJRefresh/Custom/Footer/Back/MJRefreshBackGifFooter.m (deleted)
Pods/MJRefresh/MJRefresh/Custom/Footer/Back/MJRefreshBackNormalFooter.h (deleted)
Pods/MJRefresh/MJRefresh/Custom/Footer/Back/MJRefreshBackNormalFooter.m (deleted)
Pods/MJRefresh/MJRefresh/Custom/Footer/Back/MJRefreshBackStateFooter.h (deleted)
Pods/MJRefresh/MJRefresh/Custom/Header/MJRefreshGifHeader.h (deleted)
Pods/MJRefresh/MJRefresh/Custom/Header/MJRefreshGifHeader.m (deleted)
Pods/MJRefresh/MJRefresh/Custom/Header/MJRefreshNormalHeader.h (deleted)
Pods/MJRefresh/MJRefresh/Custom/Header/MJRefreshNormalHeader.m (deleted)
Pods/MJRefresh/MJRefresh/Custom/Header/MJRefreshStateHeader.h (deleted)
Pods/MJRefresh/MJRefresh/Custom/Header/MJRefreshStateHeader.m (deleted)
Pods/MJRefresh/MJRefresh/MJRefresh.bundle/en.lproj/Localizable.strings (deleted)
Pods/MJRefresh/MJRefresh/MJRefresh.bundle/zh-Hans.lproj/Localizable.strings (deleted)
Pods/MJRefresh/MJRefresh/MJRefresh.bundle/zh-Hant.lproj/Localizable.strings (deleted)
Pods/MJRefresh/MJRefresh/MJRefresh.h (deleted)
Pods/MJRefresh/MJRefresh/MJRefreshConst.h (deleted)
Pods/MJRefresh/MJRefresh/MJRefreshConst.m (deleted)
Pods/MJRefresh/MJRefresh/NSBundle+MJRefresh.h (deleted)
Pods/MJRefresh/MJRefresh/NSBundle+MJRefresh.m (deleted)
Pods/MJRefresh/MJRefresh/UIScrollView+MJExtension.h (deleted)
Pods/MJRefresh/MJRefresh/UIScrollView+MJExtension.m (deleted)
Pods/MJRefresh/MJRefresh/UIScrollView+MJRefresh.h (deleted)
Pods/MJRefresh/MJRefresh/UIScrollView+MJRefresh.m (deleted)
Pods/MJRefresh/MJRefresh/UIView+MJExtension.h (deleted)
Pods/MJRefresh/README.md (deleted)
Pods/Manifest.lock
Pods/Pods.xcodeproj/project.pbxproj
Pods/Pods.xcodeproj/xcuserdata/aeline.xcuserdatad/xcschemes/AFNetworking.xcscheme
Pods/Pods.xcodeproj/xcuserdata/aeline.xcuserdatad/xcschemes/Pods-BuWanVideo2.0.xcscheme
Pods/Pods.xcodeproj/xcuserdata/aeline.xcuserdatad/xcschemes/SDWebImage.xcscheme
Pods/Pods.xcodeproj/xcuserdata/aeline.xcuserdatad/xcschemes/SVProgressHUD.xcscheme
Pods/Pods.xcodeproj/xcuserdata/aeline.xcuserdatad/xcschemes/UMCCommon.xcscheme
Pods/Pods.xcodeproj/xcuserdata/aeline.xcuserdatad/xcschemes/YYCache.xcscheme
Pods/Pods.xcodeproj/xcuserdata/aeline.xcuserdatad/xcschemes/YYImage.xcscheme
Pods/Pods.xcodeproj/xcuserdata/aeline.xcuserdatad/xcschemes/YYModel.xcscheme
Pods/Pods.xcodeproj/xcuserdata/aeline.xcuserdatad/xcschemes/YYWebImage.xcscheme
Pods/Pods.xcodeproj/xcuserdata/aeline.xcuserdatad/xcschemes/xcschememanagement.plist
Pods/Target Support Files/AFNetworking/AFNetworking-Info.plist
Pods/Target Support Files/AFNetworking/AFNetworking-umbrella.h
Pods/Target Support Files/AFNetworking/AFNetworking.debug.xcconfig
Pods/Target Support Files/AFNetworking/AFNetworking.release.xcconfig
Pods/Target Support Files/GoogleToolboxForMac/GoogleToolboxForMac-dummy.m (deleted)
Pods/Target Support Files/GoogleToolboxForMac/GoogleToolboxForMac-prefix.pch (deleted)
Pods/Target Support Files/GoogleToolboxForMac/GoogleToolboxForMac-umbrella.h (deleted)
Pods/Target Support Files/GoogleToolboxForMac/GoogleToolboxForMac.modulemap (deleted)
Pods/Target Support Files/GoogleToolboxForMac/GoogleToolboxForMac.xcconfig (deleted)
Pods/Target Support Files/GoogleToolboxForMac/Info.plist (deleted)
Pods/Target Support Files/MJRefresh/Info.plist (deleted)
Pods/Target Support Files/MJRefresh/MJRefresh-dummy.m (deleted)
Pods/Target Support Files/MJRefresh/MJRefresh-prefix.pch (deleted)
Pods/Target Support Files/MJRefresh/MJRefresh-umbrella.h (deleted)
Pods/Target Support Files/MJRefresh/MJRefresh.modulemap (deleted)
Pods/Target Support Files/MJRefresh/MJRefresh.xcconfig (deleted)
Pods/Target Support Files/Pods-BuWanVideo2.0/Pods-BuWanVideo2.0-Info.plist
Pods/Target Support Files/Pods-BuWanVideo2.0/Pods-BuWanVideo2.0-acknowledgements.markdown
Pods/Target Support Files/Pods-BuWanVideo2.0/Pods-BuWanVideo2.0-acknowledgements.plist
Pods/Target Support Files/Pods-BuWanVideo2.0/Pods-BuWanVideo2.0-frameworks.sh
Pods/Target Support Files/Pods-BuWanVideo2.0/Pods-BuWanVideo2.0-resources.sh
Pods/Target Support Files/Pods-BuWanVideo2.0/Pods-BuWanVideo2.0.debug.xcconfig
Pods/Target Support Files/Pods-BuWanVideo2.0/Pods-BuWanVideo2.0.release.xcconfig
Pods/Target Support Files/SDWebImage/SDWebImage-Info.plist
Pods/Target Support Files/SDWebImage/SDWebImage.debug.xcconfig
Pods/Target Support Files/SDWebImage/SDWebImage.release.xcconfig
Pods/Target Support Files/SVProgressHUD/SVProgressHUD-Info.plist
Pods/Target Support Files/SVProgressHUD/SVProgressHUD.debug.xcconfig
Pods/Target Support Files/SVProgressHUD/SVProgressHUD.release.xcconfig
Pods/Target Support Files/UMCCommon/UMCCommon.debug.xcconfig
Pods/Target Support Files/UMCCommon/UMCCommon.release.xcconfig
Pods/Target Support Files/YYCache/YYCache-Info.plist
Pods/Target Support Files/YYCache/YYCache.debug.xcconfig
Pods/Target Support Files/YYCache/YYCache.release.xcconfig
Pods/Target Support Files/YYImage/YYImage-Info.plist
Pods/Target Support Files/YYImage/YYImage.debug.xcconfig
Pods/Target Support Files/YYImage/YYImage.release.xcconfig
Pods/Target Support Files/YYModel/YYModel-Info.plist
Pods/Target Support Files/YYModel/YYModel.debug.xcconfig
Pods/Target Support Files/YYModel/YYModel.release.xcconfig
Pods/Target Support Files/YYWebImage/YYWebImage-Info.plist
Pods/Target Support Files/YYWebImage/YYWebImage.debug.xcconfig
Pods/Target Support Files/YYWebImage/YYWebImage.release.xcconfig
Pods/Target Support Files/nanopb/Info.plist (deleted)
Pods/Target Support Files/nanopb/nanopb-dummy.m (deleted)
Pods/Target Support Files/nanopb/nanopb-prefix.pch (deleted)
Pods/Target Support Files/nanopb/nanopb-umbrella.h (deleted)
Pods/Target Support Files/nanopb/nanopb.modulemap (deleted)
Pods/Target Support Files/nanopb/nanopb.xcconfig (deleted)
Pods/UMCCommon/UMCommon.framework/7.1.3_3de3f40d44_20200917132918
Pods/UMCCommon/UMCommon.framework/Headers
Pods/UMCCommon/UMCommon.framework/UMCommon
Pods/UMCCommon/UMCommon.framework/Versions/A/Headers/MobClick.h
Pods/UMCCommon/UMCommon.framework/Versions/A/Headers/UMCommon.h
Pods/UMCCommon/UMCommon.framework/Versions/A/Headers/UMConfigure.h
Pods/UMCCommon/UMCommon.framework/Versions/A/Headers/UMRemoteConfig.h
Pods/UMCCommon/UMCommon.framework/Versions/A/Headers/UMRemoteConfigEnum.h
Pods/UMCCommon/UMCommon.framework/Versions/A/Headers/UMRemoteConfigSettings.h
Pods/UMCCommon/UMCommon.framework/Versions/A/UMCommon
Pods/UMCCommon/UMCommon.framework/Versions/Current
Pods/UMengAnalytics/umsdk_IOS_analyics_idfa_v4.2.4/UMMobClick.framework/UMMobClick (deleted)
Pods/UMengAnalytics/umsdk_IOS_analyics_idfa_v4.2.4/UMMobClick.framework/Versions/A/Headers/MobClick.h (deleted)
Pods/UMengAnalytics/umsdk_IOS_analyics_idfa_v4.2.4/UMMobClick.framework/Versions/A/Headers/MobClickGameAnalytics.h (deleted)
Pods/UMengAnalytics/umsdk_IOS_analyics_idfa_v4.2.4/UMMobClick.framework/Versions/A/Headers/MobClickSocialAnalytics.h (deleted)
Pods/UMengAnalytics/umsdk_IOS_analyics_idfa_v4.2.4/UMMobClick.framework/Versions/A/UMMobClick (deleted)
Pods/UMengUShare/UShareSDK/SocialLibraries/QQ/QQSDK/TencentOpenAPI.framework/Headers/QQApiInterface.h (deleted)
Pods/UMengUShare/UShareSDK/SocialLibraries/QQ/QQSDK/TencentOpenAPI.framework/Headers/QQApiInterfaceObject.h (deleted)
Pods/UMengUShare/UShareSDK/SocialLibraries/QQ/QQSDK/TencentOpenAPI.framework/Headers/TencentApiInterface.h (deleted)
Pods/UMengUShare/UShareSDK/SocialLibraries/QQ/QQSDK/TencentOpenAPI.framework/Headers/TencentMessageObject.h (deleted)
Pods/UMengUShare/UShareSDK/SocialLibraries/QQ/QQSDK/TencentOpenAPI.framework/Headers/TencentOAuth.h (deleted)
Pods/UMengUShare/UShareSDK/SocialLibraries/QQ/QQSDK/TencentOpenAPI.framework/Headers/TencentOAuthObject.h (deleted)
Pods/UMengUShare/UShareSDK/SocialLibraries/QQ/QQSDK/TencentOpenAPI.framework/Headers/sdkdef.h (deleted)
Pods/UMengUShare/UShareSDK/SocialLibraries/QQ/QQSDK/TencentOpenAPI.framework/TencentOpenAPI (deleted)
Pods/UMengUShare/UShareSDK/SocialLibraries/QQ/QQSDK/TencentOpenApi_IOS_Bundle.bundle/Info.plist (deleted)
Pods/UMengUShare/UShareSDK/SocialLibraries/QQ/QQSDK/TencentOpenApi_IOS_Bundle.bundle/error.png (deleted)
Pods/UMengUShare/UShareSDK/SocialLibraries/QQ/QQSDK/TencentOpenApi_IOS_Bundle.bundle/local.html (deleted)
Pods/UMengUShare/UShareSDK/SocialLibraries/QQ/QQSDK/TencentOpenApi_IOS_Bundle.bundle/qqicon.png (deleted)
Pods/UMengUShare/UShareSDK/SocialLibraries/QQ/QQSDK/TencentOpenApi_IOS_Bundle.bundle/success.png (deleted)
Pods/UMengUShare/UShareSDK/SocialLibraries/QQ/UMSocialQQHandler.h (deleted)
Pods/UMengUShare/UShareSDK/SocialLibraries/QQ/libSocialQQ.a (deleted)
Pods/UMengUShare/UShareSDK/SocialLibraries/Sina/UMSocialSinaHandler.h (deleted)
Pods/UMengUShare/UShareSDK/SocialLibraries/Sina/libSocialSina.a (deleted)
Pods/UMengUShare/UShareSDK/SocialLibraries/WeChat/UMSocialWechatHandler.h (deleted)
Pods/UMengUShare/UShareSDK/SocialLibraries/WeChat/libSocialWeChat.a (deleted)
Pods/UMengUShare/UShareSDK/UMSocialSDK/UMSocialCore.framework/Headers/UMSocialCore.h (deleted)
Pods/UMengUShare/UShareSDK/UMSocialSDK/UMSocialCore.framework/Headers/UMSocialCoreImageUtils.h (deleted)
Pods/UMengUShare/UShareSDK/UMSocialSDK/UMSocialCore.framework/Headers/UMSocialDataManager.h (deleted)
Pods/UMengUShare/UShareSDK/UMSocialSDK/UMSocialCore.framework/Headers/UMSocialGlobal.h (deleted)
Pods/UMengUShare/UShareSDK/UMSocialSDK/UMSocialCore.framework/Headers/UMSocialHandler.h (deleted)
Pods/UMengUShare/UShareSDK/UMSocialSDK/UMSocialCore.framework/Headers/UMSocialImageUtil.h (deleted)
Pods/UMengUShare/UShareSDK/UMSocialSDK/UMSocialCore.framework/Headers/UMSocialManager.h (deleted)
Pods/UMengUShare/UShareSDK/UMSocialSDK/UMSocialCore.framework/Headers/UMSocialMessageObject.h (deleted)
Pods/UMengUShare/UShareSDK/UMSocialSDK/UMSocialCore.framework/Headers/UMSocialPlatformConfig.h (deleted)
Pods/UMengUShare/UShareSDK/UMSocialSDK/UMSocialCore.framework/Headers/UMSocialPlatformProvider.h (deleted)
Pods/UMengUShare/UShareSDK/UMSocialSDK/UMSocialCore.framework/Headers/UMSocialResponse.h (deleted)
Pods/UMengUShare/UShareSDK/UMSocialSDK/UMSocialCore.framework/Headers/UMSocialWarterMarkConfig.h (deleted)
Pods/UMengUShare/UShareSDK/UMSocialSDK/UMSocialCore.framework/Headers/UMSociallogMacros.h (deleted)
Pods/UMengUShare/UShareSDK/UMSocialSDK/UMSocialCore.framework/Info.plist (deleted)
Pods/UMengUShare/UShareSDK/UMSocialSDK/UMSocialCore.framework/UMSocialCore (deleted)
Pods/UMengUShare/UShareSDK/UMSocialSDK/UMSocialNetwork.framework/Headers/UMSocialHttpFactory.h (deleted)
Pods/UMengUShare/UShareSDK/UMSocialSDK/UMSocialNetwork.framework/Headers/UMSocialNetwork.h (deleted)
Pods/UMengUShare/UShareSDK/UMSocialSDK/UMSocialNetwork.framework/Headers/UMSocialTask.h (deleted)
Pods/UMengUShare/UShareSDK/UMSocialSDK/UMSocialNetwork.framework/Headers/UMSocialTaskConfig.h (deleted)
Pods/UMengUShare/UShareSDK/UMSocialSDK/UMSocialNetwork.framework/Headers/UMSocialTaskManager.h (deleted)
Pods/UMengUShare/UShareSDK/UMSocialSDK/UMSocialNetwork.framework/Info.plist (deleted)
Pods/UMengUShare/UShareSDK/UMSocialSDK/UMSocialNetwork.framework/UMSocialNetwork (deleted)
Pods/UMengUShare/UShareSDK/UMSocialSDK/UMSocialSDKPromptResources.bundle/en.lproj/UMSocialPromptLocalizable.strings (deleted)
Pods/UMengUShare/UShareSDK/UMSocialSDK/UMSocialSDKPromptResources.bundle/zh-Hans.lproj/UMSocialPromptLocalizable.strings (deleted)
Pods/UMengUShare/UShareSDK/UMSocialSDKPlugin/libUMSocialLog.a (deleted)
Pods/UMengUShare/UShareSDK/UMSocialUI/UMSocialSDKResources.bundle/Buttons/UMS_add_friend_off@2x.png (deleted)
Pods/UMengUShare/UShareSDK/UMSocialUI/UMSocialSDKResources.bundle/Buttons/UMS_delete_image_button_normal@2x.png (deleted)
Pods/UMengUShare/UShareSDK/UMSocialUI/UMSocialSDKResources.bundle/Buttons/UMS_nav_button_close@2x.png (deleted)
Pods/UMengUShare/UShareSDK/UMSocialUI/UMSocialSDKResources.bundle/Buttons/UMS_nav_button_send@2x.png (deleted)
Pods/UMengUShare/UShareSDK/UMSocialUI/UMSocialSDKResources.bundle/Buttons/UMS_url_image@2x.png (deleted)
Pods/UMengUShare/UShareSDK/UMSocialUI/UMSocialSDKResources.bundle/Buttons/UMS_url_music@2x.png (deleted)
Pods/UMengUShare/UShareSDK/UMSocialUI/UMSocialSDKResources.bundle/Buttons/UMS_url_video@2x.png (deleted)
Pods/UMengUShare/UShareSDK/UMSocialUI/UMSocialSDKResources.bundle/UMSocialPlatformTheme/default/umsocial_alipay.png (deleted)
Pods/UMengUShare/UShareSDK/UMSocialUI/UMSocialSDKResources.bundle/UMSocialPlatformTheme/default/umsocial_default.png (deleted)
Pods/UMengUShare/UShareSDK/UMSocialUI/UMSocialSDKResources.bundle/UMSocialPlatformTheme/default/umsocial_dingding.png (deleted)
Pods/UMengUShare/UShareSDK/UMSocialUI/UMSocialSDKResources.bundle/UMSocialPlatformTheme/default/umsocial_douban.png (deleted)
Pods/UMengUShare/UShareSDK/UMSocialUI/UMSocialSDKResources.bundle/UMSocialPlatformTheme/default/umsocial_dropbox.png (deleted)
Pods/UMengUShare/UShareSDK/UMSocialUI/UMSocialSDKResources.bundle/UMSocialPlatformTheme/default/umsocial_email.png (deleted)
Pods/UMengUShare/UShareSDK/UMSocialUI/UMSocialSDKResources.bundle/UMSocialPlatformTheme/default/umsocial_evernote.png (deleted)
Pods/UMengUShare/UShareSDK/UMSocialUI/UMSocialSDKResources.bundle/UMSocialPlatformTheme/default/umsocial_facebook.png (deleted)
Pods/UMengUShare/UShareSDK/UMSocialUI/UMSocialSDKResources.bundle/UMSocialPlatformTheme/default/umsocial_facebookmessenger.png (deleted)
Pods/UMengUShare/UShareSDK/UMSocialUI/UMSocialSDKResources.bundle/UMSocialPlatformTheme/default/umsocial_flickr.png (deleted)
Pods/UMengUShare/UShareSDK/UMSocialUI/UMSocialSDKResources.bundle/UMSocialPlatformTheme/default/umsocial_googleplus.png (deleted)
Pods/UMengUShare/UShareSDK/UMSocialUI/UMSocialSDKResources.bundle/UMSocialPlatformTheme/default/umsocial_instagram.png (deleted)
Pods/UMengUShare/UShareSDK/UMSocialUI/UMSocialSDKResources.bundle/UMSocialPlatformTheme/default/umsocial_kakaoTalk.png (deleted)
Pods/UMengUShare/UShareSDK/UMSocialUI/UMSocialSDKResources.bundle/UMSocialPlatformTheme/default/umsocial_line.png (deleted)
Pods/UMengUShare/UShareSDK/UMSocialUI/UMSocialSDKResources.bundle/UMSocialPlatformTheme/default/umsocial_linkedin.png (deleted)
Pods/UMengUShare/UShareSDK/UMSocialUI/UMSocialSDKResources.bundle/UMSocialPlatformTheme/default/umsocial_lw_session.png (deleted)
Pods/UMengUShare/UShareSDK/UMSocialUI/UMSocialSDKResources.bundle/UMSocialPlatformTheme/default/umsocial_lw_timeline.png (deleted)
Pods/UMengUShare/UShareSDK/UMSocialUI/UMSocialSDKResources.bundle/UMSocialPlatformTheme/default/umsocial_pinterest.png (deleted)
Pods/UMengUShare/UShareSDK/UMSocialUI/UMSocialSDKResources.bundle/UMSocialPlatformTheme/default/umsocial_pocket.png (deleted)
Pods/UMengUShare/UShareSDK/UMSocialUI/UMSocialSDKResources.bundle/UMSocialPlatformTheme/default/umsocial_qq.png (deleted)
Pods/UMengUShare/UShareSDK/UMSocialUI/UMSocialSDKResources.bundle/UMSocialPlatformTheme/default/umsocial_qzone.png (deleted)
Pods/UMengUShare/UShareSDK/UMSocialUI/UMSocialSDKResources.bundle/UMSocialPlatformTheme/default/umsocial_renren.png (deleted)
Pods/UMengUShare/UShareSDK/UMSocialUI/UMSocialSDKResources.bundle/UMSocialPlatformTheme/default/umsocial_sina.png (deleted)
Pods/UMengUShare/UShareSDK/UMSocialUI/UMSocialSDKResources.bundle/UMSocialPlatformTheme/default/umsocial_sms.png (deleted)
Pods/UMengUShare/UShareSDK/UMSocialUI/UMSocialSDKResources.bundle/UMSocialPlatformTheme/default/umsocial_tencentWB.png (deleted)
Pods/UMengUShare/UShareSDK/UMSocialUI/UMSocialSDKResources.bundle/UMSocialPlatformTheme/default/umsocial_tim.png (deleted)
Pods/UMengUShare/UShareSDK/UMSocialUI/UMSocialSDKResources.bundle/UMSocialPlatformTheme/default/umsocial_tumblr.png (deleted)
Pods/UMengUShare/UShareSDK/UMSocialUI/UMSocialSDKResources.bundle/UMSocialPlatformTheme/default/umsocial_twitter.png (deleted)
Pods/UMengUShare/UShareSDK/UMSocialUI/UMSocialSDKResources.bundle/UMSocialPlatformTheme/default/umsocial_vkontakte.png (deleted)
Pods/UMengUShare/UShareSDK/UMSocialUI/UMSocialSDKResources.bundle/UMSocialPlatformTheme/default/umsocial_wechat.png (deleted)
Pods/UMengUShare/UShareSDK/UMSocialUI/UMSocialSDKResources.bundle/UMSocialPlatformTheme/default/umsocial_wechat_favorite.png (deleted)
Pods/UMengUShare/UShareSDK/UMSocialUI/UMSocialSDKResources.bundle/UMSocialPlatformTheme/default/umsocial_wechat_timeline.png (deleted)
Pods/UMengUShare/UShareSDK/UMSocialUI/UMSocialSDKResources.bundle/UMSocialPlatformTheme/default/umsocial_whatsapp.png (deleted)
Pods/UMengUShare/UShareSDK/UMSocialUI/UMSocialSDKResources.bundle/UMSocialPlatformTheme/default/umsocial_yixin_favorite.png (deleted)
Pods/UMengUShare/UShareSDK/UMSocialUI/UMSocialSDKResources.bundle/UMSocialPlatformTheme/default/umsocial_yixin_session.png (deleted)
Pods/UMengUShare/UShareSDK/UMSocialUI/UMSocialSDKResources.bundle/UMSocialPlatformTheme/default/umsocial_yixin_timeline.png (deleted)
Pods/UMengUShare/UShareSDK/UMSocialUI/UMSocialSDKResources.bundle/UMSocialPlatformTheme/default/umsocial_youdaonote.png (deleted)
Pods/UMengUShare/UShareSDK/UMSocialUI/UMSocialSDKResources.bundle/UMSocialWaterMark/umsocial_defaultwatermark.png (deleted)
Pods/UMengUShare/UShareSDK/UMSocialUI/UMSocialSDKResources.bundle/en.lproj/UMSocialLocalizable.strings (deleted)
Pods/UMengUShare/UShareSDK/UMSocialUI/UMSocialSDKResources.bundle/zh-Hans.lproj/UMSocialLocalizable.strings (deleted)
Pods/UMengUShare/UShareSDK/UMSocialUI/UShareUI.framework/Headers/UMSocialShareUIConfig.h (deleted)
Pods/UMengUShare/UShareSDK/UMSocialUI/UShareUI.framework/Headers/UMSocialUIManager.h (deleted)
Pods/UMengUShare/UShareSDK/UMSocialUI/UShareUI.framework/Headers/UMSocialUIUtility.h (deleted)
Pods/UMengUShare/UShareSDK/UMSocialUI/UShareUI.framework/Headers/UShareUI.h (deleted)
Pods/UMengUShare/UShareSDK/UMSocialUI/UShareUI.framework/Info.plist (deleted)
Pods/UMengUShare/UShareSDK/UMSocialUI/UShareUI.framework/UShareUI (deleted)
Pods/nanopb/LICENSE.txt (deleted)
Pods/nanopb/README.md (deleted)
Pods/nanopb/pb.h (deleted)
Pods/nanopb/pb_common.c (deleted)
Pods/nanopb/pb_common.h (deleted)
Pods/nanopb/pb_decode.c (deleted)
Pods/nanopb/pb_decode.h (deleted)
Pods/nanopb/pb_encode.c (deleted)
Pods/nanopb/pb_encode.h (deleted)
Pofile |