diff --git a/Ifish.xcodeproj/project.pbxproj b/Ifish.xcodeproj/project.pbxproj index 530bb67..5f2243a 100644 --- a/Ifish.xcodeproj/project.pbxproj +++ b/Ifish.xcodeproj/project.pbxproj @@ -24,7 +24,6 @@ 18C54F282350541500DF4E7D /* UTMini.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 18C54F142350541400DF4E7D /* UTMini.framework */; }; 18C54F292350541500DF4E7D /* OpenMtopSDK.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 18C54F152350541400DF4E7D /* OpenMtopSDK.framework */; }; 18C54F2A2350541500DF4E7D /* SGNoCaptcha.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 18C54F162350541400DF4E7D /* SGNoCaptcha.framework */; }; - 18C54F2B2350541500DF4E7D /* AlipaySDK.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 18C54F172350541400DF4E7D /* AlipaySDK.framework */; }; 18C54F2C2350541500DF4E7D /* SGSecurityBody.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 18C54F182350541400DF4E7D /* SGSecurityBody.framework */; }; 18C54F2D2350541500DF4E7D /* OpenMtopExt.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 18C54F192350541400DF4E7D /* OpenMtopExt.framework */; }; 3D13F835212FE2C200D725F7 /* IFishWaterChangeView.m in Sources */ = {isa = PBXBuildFile; fileRef = 3D13F834212FE2C200D725F7 /* IFishWaterChangeView.m */; }; @@ -1552,22 +1551,6 @@ 885FBE341E4DC2F600E0D7D1 /* merchant_iocn_a_left.png in Resources */ = {isa = PBXBuildFile; fileRef = 885FBE311E4DC2F600E0D7D1 /* merchant_iocn_a_left.png */; }; 885FBE351E4DC2F600E0D7D1 /* merchant_iocn_a_left@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 885FBE321E4DC2F600E0D7D1 /* merchant_iocn_a_left@2x.png */; }; 885FBE361E4DC2F600E0D7D1 /* merchant_iocn_a_left@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 885FBE331E4DC2F600E0D7D1 /* merchant_iocn_a_left@3x.png */; }; - 88602DB01E10D97E00F3DB5D /* MKAnnotationView+WebCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 88602D901E10D97E00F3DB5D /* MKAnnotationView+WebCache.m */; }; - 88602DB11E10D97E00F3DB5D /* NSData+ImageContentType.m in Sources */ = {isa = PBXBuildFile; fileRef = 88602D921E10D97E00F3DB5D /* NSData+ImageContentType.m */; }; - 88602DB21E10D97E00F3DB5D /* SDImageCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 88602D941E10D97E00F3DB5D /* SDImageCache.m */; }; - 88602DB31E10D97E00F3DB5D /* SDWebImageCompat.m in Sources */ = {isa = PBXBuildFile; fileRef = 88602D961E10D97E00F3DB5D /* SDWebImageCompat.m */; }; - 88602DB41E10D97E00F3DB5D /* SDWebImageDecoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 88602D981E10D97E00F3DB5D /* SDWebImageDecoder.m */; }; - 88602DB51E10D97E00F3DB5D /* SDWebImageDownloader.m in Sources */ = {isa = PBXBuildFile; fileRef = 88602D9A1E10D97E00F3DB5D /* SDWebImageDownloader.m */; }; - 88602DB61E10D97E00F3DB5D /* SDWebImageDownloaderOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = 88602D9C1E10D97E00F3DB5D /* SDWebImageDownloaderOperation.m */; }; - 88602DB71E10D97E00F3DB5D /* SDWebImageManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 88602D9E1E10D97E00F3DB5D /* SDWebImageManager.m */; }; - 88602DB81E10D97E00F3DB5D /* SDWebImagePrefetcher.m in Sources */ = {isa = PBXBuildFile; fileRef = 88602DA11E10D97E00F3DB5D /* SDWebImagePrefetcher.m */; }; - 88602DB91E10D97E00F3DB5D /* UIButton+WebCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 88602DA31E10D97E00F3DB5D /* UIButton+WebCache.m */; }; - 88602DBA1E10D97E00F3DB5D /* UIImage+GIF.m in Sources */ = {isa = PBXBuildFile; fileRef = 88602DA51E10D97E00F3DB5D /* UIImage+GIF.m */; }; - 88602DBB1E10D97E00F3DB5D /* UIImage+MultiFormat.m in Sources */ = {isa = PBXBuildFile; fileRef = 88602DA71E10D97E00F3DB5D /* UIImage+MultiFormat.m */; }; - 88602DBC1E10D97E00F3DB5D /* UIImage+WebP.m in Sources */ = {isa = PBXBuildFile; fileRef = 88602DA91E10D97E00F3DB5D /* UIImage+WebP.m */; }; - 88602DBD1E10D97E00F3DB5D /* UIImageView+HighlightedWebCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 88602DAB1E10D97E00F3DB5D /* UIImageView+HighlightedWebCache.m */; }; - 88602DBE1E10D97E00F3DB5D /* UIImageView+WebCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 88602DAD1E10D97E00F3DB5D /* UIImageView+WebCache.m */; }; - 88602DBF1E10D97E00F3DB5D /* UIView+WebCacheOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = 88602DAF1E10D97E00F3DB5D /* UIView+WebCacheOperation.m */; }; 88605F1C1D8256600037F1AA /* ShareReportCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 88605F1B1D8256600037F1AA /* ShareReportCell.m */; }; 8860D78F1D6D7BE8001E544C /* KanHuWorkViewFirstCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 8860D78D1D6D7BE8001E544C /* KanHuWorkViewFirstCell.m */; }; 8860D7901D6D7BE8001E544C /* KanHuWorkViewFirstCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 8860D78E1D6D7BE8001E544C /* KanHuWorkViewFirstCell.xib */; }; @@ -2271,6 +2254,56 @@ C024B7AF2379668B00509424 /* NSMutableString+AvoidCrash.h in Headers */ = {isa = PBXBuildFile; fileRef = C024B79B2379668B00509424 /* NSMutableString+AvoidCrash.h */; }; C024B7B02379668B00509424 /* NSMutableAttributedString+AvoidCrash.h in Headers */ = {isa = PBXBuildFile; fileRef = C024B79C2379668B00509424 /* NSMutableAttributedString+AvoidCrash.h */; }; C024B7B12379668B00509424 /* NSMutableArray+AvoidCrash.h in Headers */ = {isa = PBXBuildFile; fileRef = C024B79D2379668B00509424 /* NSMutableArray+AvoidCrash.h */; }; + C0E746D5239E4A7D001BCD6D /* wechatlogin.png in Resources */ = {isa = PBXBuildFile; fileRef = C0E746D4239E4A7C001BCD6D /* wechatlogin.png */; }; + C0E7D6C023A1D11500256A10 /* WXApiRequestHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = C0E7D6BC23A1D11200256A10 /* WXApiRequestHandler.h */; }; + C0E7D6C123A1D11500256A10 /* WXApiManager.h in Headers */ = {isa = PBXBuildFile; fileRef = C0E7D6BD23A1D11200256A10 /* WXApiManager.h */; }; + C0E7D6C223A1D11500256A10 /* WXApiManager.mm in Sources */ = {isa = PBXBuildFile; fileRef = C0E7D6BE23A1D11300256A10 /* WXApiManager.mm */; }; + C0E7D6C323A1D11500256A10 /* WXApiRequestHandler.mm in Sources */ = {isa = PBXBuildFile; fileRef = C0E7D6BF23A1D11400256A10 /* WXApiRequestHandler.mm */; }; + C0E7D6CE23A1D16D00256A10 /* WXMediaMessage+messageConstruct.h in Headers */ = {isa = PBXBuildFile; fileRef = C0E7D6C523A1D16C00256A10 /* WXMediaMessage+messageConstruct.h */; }; + C0E7D6CF23A1D16D00256A10 /* GetMessageFromWXResp+responseWithTextOrMediaMessage.mm in Sources */ = {isa = PBXBuildFile; fileRef = C0E7D6C623A1D16C00256A10 /* GetMessageFromWXResp+responseWithTextOrMediaMessage.mm */; }; + C0E7D6D023A1D16D00256A10 /* Constant.h in Headers */ = {isa = PBXBuildFile; fileRef = C0E7D6C723A1D16C00256A10 /* Constant.h */; }; + C0E7D6D123A1D16D00256A10 /* SendMessageToWXReq+requestWithTextOrMediaMessage.mm in Sources */ = {isa = PBXBuildFile; fileRef = C0E7D6C823A1D16C00256A10 /* SendMessageToWXReq+requestWithTextOrMediaMessage.mm */; }; + C0E7D6D223A1D16D00256A10 /* GetMessageFromWXResp+responseWithTextOrMediaMessage.h in Headers */ = {isa = PBXBuildFile; fileRef = C0E7D6C923A1D16C00256A10 /* GetMessageFromWXResp+responseWithTextOrMediaMessage.h */; }; + C0E7D6D323A1D16D00256A10 /* UIAlertView+WX.h in Headers */ = {isa = PBXBuildFile; fileRef = C0E7D6CA23A1D16C00256A10 /* UIAlertView+WX.h */; }; + C0E7D6D423A1D16D00256A10 /* SendMessageToWXReq+requestWithTextOrMediaMessage.h in Headers */ = {isa = PBXBuildFile; fileRef = C0E7D6CB23A1D16C00256A10 /* SendMessageToWXReq+requestWithTextOrMediaMessage.h */; }; + C0E7D6D523A1D16D00256A10 /* WXMediaMessage+messageConstruct.mm in Sources */ = {isa = PBXBuildFile; fileRef = C0E7D6CC23A1D16C00256A10 /* WXMediaMessage+messageConstruct.mm */; }; + C0E7D6D623A1D16D00256A10 /* UIAlertView+WX.mm in Sources */ = {isa = PBXBuildFile; fileRef = C0E7D6CD23A1D16C00256A10 /* UIAlertView+WX.mm */; }; + C0E7D6DB23A3D4C200256A10 /* renyuan.png in Resources */ = {isa = PBXBuildFile; fileRef = C0E7D6DA23A3D4C200256A10 /* renyuan.png */; }; + C0EA89EC23AF73EE003DC53B /* UIColor+HexString.h in Headers */ = {isa = PBXBuildFile; fileRef = C0EA89EA23AF73EE003DC53B /* UIColor+HexString.h */; }; + C0EA89ED23AF73EE003DC53B /* UIColor+HexString.m in Sources */ = {isa = PBXBuildFile; fileRef = C0EA89EB23AF73EE003DC53B /* UIColor+HexString.m */; }; + C0EA8A1123AF74F4003DC53B /* UIImage+WebP.m in Sources */ = {isa = PBXBuildFile; fileRef = C0EA89F023AF74F3003DC53B /* UIImage+WebP.m */; }; + C0EA8A1223AF74F4003DC53B /* MKAnnotationView+WebCache.m in Sources */ = {isa = PBXBuildFile; fileRef = C0EA89F123AF74F3003DC53B /* MKAnnotationView+WebCache.m */; }; + C0EA8A1323AF74F4003DC53B /* UIImageView+WebCache.h in Headers */ = {isa = PBXBuildFile; fileRef = C0EA89F223AF74F3003DC53B /* UIImageView+WebCache.h */; }; + C0EA8A1423AF74F4003DC53B /* NSData+ImageContentType.h in Headers */ = {isa = PBXBuildFile; fileRef = C0EA89F323AF74F3003DC53B /* NSData+ImageContentType.h */; }; + C0EA8A1523AF74F4003DC53B /* SDWebImageManager.m in Sources */ = {isa = PBXBuildFile; fileRef = C0EA89F423AF74F3003DC53B /* SDWebImageManager.m */; }; + C0EA8A1623AF74F4003DC53B /* SDWebImageDecoder.m in Sources */ = {isa = PBXBuildFile; fileRef = C0EA89F523AF74F3003DC53B /* SDWebImageDecoder.m */; }; + C0EA8A1723AF74F4003DC53B /* SDWebImageDownloaderOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = C0EA89F623AF74F3003DC53B /* SDWebImageDownloaderOperation.h */; }; + C0EA8A1823AF74F4003DC53B /* UIImageView+HighlightedWebCache.m in Sources */ = {isa = PBXBuildFile; fileRef = C0EA89F723AF74F3003DC53B /* UIImageView+HighlightedWebCache.m */; }; + C0EA8A1923AF74F4003DC53B /* SDImageCache.h in Headers */ = {isa = PBXBuildFile; fileRef = C0EA89F823AF74F3003DC53B /* SDImageCache.h */; }; + C0EA8A1A23AF74F4003DC53B /* SDWebImageDownloader.m in Sources */ = {isa = PBXBuildFile; fileRef = C0EA89F923AF74F3003DC53B /* SDWebImageDownloader.m */; }; + C0EA8A1B23AF74F4003DC53B /* UIImage+GIF.m in Sources */ = {isa = PBXBuildFile; fileRef = C0EA89FA23AF74F3003DC53B /* UIImage+GIF.m */; }; + C0EA8A1C23AF74F4003DC53B /* UIButton+WebCache.h in Headers */ = {isa = PBXBuildFile; fileRef = C0EA89FB23AF74F3003DC53B /* UIButton+WebCache.h */; }; + C0EA8A1D23AF74F4003DC53B /* UIImage+MultiFormat.m in Sources */ = {isa = PBXBuildFile; fileRef = C0EA89FC23AF74F3003DC53B /* UIImage+MultiFormat.m */; }; + C0EA8A1E23AF74F4003DC53B /* SDWebImageCompat.m in Sources */ = {isa = PBXBuildFile; fileRef = C0EA89FD23AF74F3003DC53B /* SDWebImageCompat.m */; }; + C0EA8A1F23AF74F4003DC53B /* SDWebImagePrefetcher.m in Sources */ = {isa = PBXBuildFile; fileRef = C0EA89FE23AF74F3003DC53B /* SDWebImagePrefetcher.m */; }; + C0EA8A2023AF74F4003DC53B /* UIView+WebCacheOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = C0EA89FF23AF74F3003DC53B /* UIView+WebCacheOperation.h */; }; + C0EA8A2123AF74F4003DC53B /* MKAnnotationView+WebCache.h in Headers */ = {isa = PBXBuildFile; fileRef = C0EA8A0023AF74F3003DC53B /* MKAnnotationView+WebCache.h */; }; + C0EA8A2223AF74F4003DC53B /* UIImage+WebP.h in Headers */ = {isa = PBXBuildFile; fileRef = C0EA8A0123AF74F3003DC53B /* UIImage+WebP.h */; }; + C0EA8A2323AF74F4003DC53B /* SDImageCache.m in Sources */ = {isa = PBXBuildFile; fileRef = C0EA8A0223AF74F3003DC53B /* SDImageCache.m */; }; + C0EA8A2423AF74F4003DC53B /* UIImageView+HighlightedWebCache.h in Headers */ = {isa = PBXBuildFile; fileRef = C0EA8A0323AF74F3003DC53B /* UIImageView+HighlightedWebCache.h */; }; + C0EA8A2523AF74F4003DC53B /* SDWebImageDownloaderOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = C0EA8A0423AF74F3003DC53B /* SDWebImageDownloaderOperation.m */; }; + C0EA8A2623AF74F4003DC53B /* SDWebImageDecoder.h in Headers */ = {isa = PBXBuildFile; fileRef = C0EA8A0523AF74F3003DC53B /* SDWebImageDecoder.h */; }; + C0EA8A2723AF74F4003DC53B /* SDWebImageManager.h in Headers */ = {isa = PBXBuildFile; fileRef = C0EA8A0623AF74F3003DC53B /* SDWebImageManager.h */; }; + C0EA8A2823AF74F4003DC53B /* NSData+ImageContentType.m in Sources */ = {isa = PBXBuildFile; fileRef = C0EA8A0723AF74F3003DC53B /* NSData+ImageContentType.m */; }; + C0EA8A2923AF74F4003DC53B /* UIImageView+WebCache.m in Sources */ = {isa = PBXBuildFile; fileRef = C0EA8A0823AF74F3003DC53B /* UIImageView+WebCache.m */; }; + C0EA8A2A23AF74F4003DC53B /* SDWebImageOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = C0EA8A0923AF74F3003DC53B /* SDWebImageOperation.h */; }; + C0EA8A2B23AF74F4003DC53B /* SDWebImageDownloader.h in Headers */ = {isa = PBXBuildFile; fileRef = C0EA8A0A23AF74F3003DC53B /* SDWebImageDownloader.h */; }; + C0EA8A2C23AF74F4003DC53B /* UIView+WebCacheOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = C0EA8A0B23AF74F3003DC53B /* UIView+WebCacheOperation.m */; }; + C0EA8A2D23AF74F4003DC53B /* SDWebImagePrefetcher.h in Headers */ = {isa = PBXBuildFile; fileRef = C0EA8A0C23AF74F3003DC53B /* SDWebImagePrefetcher.h */; }; + C0EA8A2E23AF74F4003DC53B /* SDWebImageCompat.h in Headers */ = {isa = PBXBuildFile; fileRef = C0EA8A0D23AF74F3003DC53B /* SDWebImageCompat.h */; }; + C0EA8A2F23AF74F4003DC53B /* UIImage+MultiFormat.h in Headers */ = {isa = PBXBuildFile; fileRef = C0EA8A0E23AF74F3003DC53B /* UIImage+MultiFormat.h */; }; + C0EA8A3023AF74F4003DC53B /* UIButton+WebCache.m in Sources */ = {isa = PBXBuildFile; fileRef = C0EA8A0F23AF74F3003DC53B /* UIButton+WebCache.m */; }; + C0EA8A3123AF74F4003DC53B /* UIImage+GIF.h in Headers */ = {isa = PBXBuildFile; fileRef = C0EA8A1023AF74F3003DC53B /* UIImage+GIF.h */; }; C0F0400C23756F3C00B61D3B /* ExternalAccessory.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C0F0400B23756F3C00B61D3B /* ExternalAccessory.framework */; }; CB0F4E8622951A130091C76D /* SVRadialGradientLayer.m in Sources */ = {isa = PBXBuildFile; fileRef = CB0F4E7B22951A130091C76D /* SVRadialGradientLayer.m */; }; CB0F4E8722951A130091C76D /* SVIndefiniteAnimatedView.h in Headers */ = {isa = PBXBuildFile; fileRef = CB0F4E7C22951A130091C76D /* SVIndefiniteAnimatedView.h */; }; @@ -2414,8 +2447,6 @@ CB7D6AA722953BEB0014E5C7 /* YYMemoryCache.m in Sources */ = {isa = PBXBuildFile; fileRef = CB7D6A9F22953BEB0014E5C7 /* YYMemoryCache.m */; }; CB7D6AB022954DE20014E5C7 /* CommonUtils.h in Headers */ = {isa = PBXBuildFile; fileRef = CB7D6AAE22954DBC0014E5C7 /* CommonUtils.h */; }; CB7D6AB122954DE20014E5C7 /* CommonUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = CB7D6AAF22954DE10014E5C7 /* CommonUtils.m */; }; - CB7D6AB422954E090014E5C7 /* UIColor+HexString.m in Sources */ = {isa = PBXBuildFile; fileRef = CB7D6AB222954E060014E5C7 /* UIColor+HexString.m */; }; - CB7D6AB522954E090014E5C7 /* UIColor+HexString.h in Headers */ = {isa = PBXBuildFile; fileRef = CB7D6AB322954E090014E5C7 /* UIColor+HexString.h */; }; CB7D6AB822954FB90014E5C7 /* FuncUserDefault.m in Sources */ = {isa = PBXBuildFile; fileRef = CB7D6AB622954FB80014E5C7 /* FuncUserDefault.m */; }; CB7D6AB922954FB90014E5C7 /* FuncUserDefault.h in Headers */ = {isa = PBXBuildFile; fileRef = CB7D6AB722954FB80014E5C7 /* FuncUserDefault.h */; }; CB7D6ABC229660370014E5C7 /* IfishConnectUsViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = CB7D6ABA229660370014E5C7 /* IfishConnectUsViewController.h */; }; @@ -2615,7 +2646,6 @@ 18C54F142350541400DF4E7D /* UTMini.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = UTMini.framework; sourceTree = ""; }; 18C54F152350541400DF4E7D /* OpenMtopSDK.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = OpenMtopSDK.framework; sourceTree = ""; }; 18C54F162350541400DF4E7D /* SGNoCaptcha.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = SGNoCaptcha.framework; sourceTree = ""; }; - 18C54F172350541400DF4E7D /* AlipaySDK.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = AlipaySDK.framework; sourceTree = ""; }; 18C54F182350541400DF4E7D /* SGSecurityBody.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = SGSecurityBody.framework; sourceTree = ""; }; 18C54F192350541400DF4E7D /* OpenMtopExt.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = OpenMtopExt.framework; sourceTree = ""; }; 3D13F833212FE2C200D725F7 /* IFishWaterChangeView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = IFishWaterChangeView.h; sourceTree = ""; }; @@ -4665,39 +4695,6 @@ 885FBE311E4DC2F600E0D7D1 /* merchant_iocn_a_left.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = merchant_iocn_a_left.png; sourceTree = ""; }; 885FBE321E4DC2F600E0D7D1 /* merchant_iocn_a_left@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "merchant_iocn_a_left@2x.png"; sourceTree = ""; }; 885FBE331E4DC2F600E0D7D1 /* merchant_iocn_a_left@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "merchant_iocn_a_left@3x.png"; sourceTree = ""; }; - 88602D8F1E10D97E00F3DB5D /* MKAnnotationView+WebCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "MKAnnotationView+WebCache.h"; sourceTree = ""; }; - 88602D901E10D97E00F3DB5D /* MKAnnotationView+WebCache.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "MKAnnotationView+WebCache.m"; sourceTree = ""; }; - 88602D911E10D97E00F3DB5D /* NSData+ImageContentType.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSData+ImageContentType.h"; sourceTree = ""; }; - 88602D921E10D97E00F3DB5D /* NSData+ImageContentType.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSData+ImageContentType.m"; sourceTree = ""; }; - 88602D931E10D97E00F3DB5D /* SDImageCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDImageCache.h; sourceTree = ""; }; - 88602D941E10D97E00F3DB5D /* SDImageCache.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDImageCache.m; sourceTree = ""; }; - 88602D951E10D97E00F3DB5D /* SDWebImageCompat.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDWebImageCompat.h; sourceTree = ""; }; - 88602D961E10D97E00F3DB5D /* SDWebImageCompat.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDWebImageCompat.m; sourceTree = ""; }; - 88602D971E10D97E00F3DB5D /* SDWebImageDecoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDWebImageDecoder.h; sourceTree = ""; }; - 88602D981E10D97E00F3DB5D /* SDWebImageDecoder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDWebImageDecoder.m; sourceTree = ""; }; - 88602D991E10D97E00F3DB5D /* SDWebImageDownloader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDWebImageDownloader.h; sourceTree = ""; }; - 88602D9A1E10D97E00F3DB5D /* SDWebImageDownloader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDWebImageDownloader.m; sourceTree = ""; }; - 88602D9B1E10D97E00F3DB5D /* SDWebImageDownloaderOperation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDWebImageDownloaderOperation.h; sourceTree = ""; }; - 88602D9C1E10D97E00F3DB5D /* SDWebImageDownloaderOperation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDWebImageDownloaderOperation.m; sourceTree = ""; }; - 88602D9D1E10D97E00F3DB5D /* SDWebImageManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDWebImageManager.h; sourceTree = ""; }; - 88602D9E1E10D97E00F3DB5D /* SDWebImageManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDWebImageManager.m; sourceTree = ""; }; - 88602D9F1E10D97E00F3DB5D /* SDWebImageOperation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDWebImageOperation.h; sourceTree = ""; }; - 88602DA01E10D97E00F3DB5D /* SDWebImagePrefetcher.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDWebImagePrefetcher.h; sourceTree = ""; }; - 88602DA11E10D97E00F3DB5D /* SDWebImagePrefetcher.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDWebImagePrefetcher.m; sourceTree = ""; }; - 88602DA21E10D97E00F3DB5D /* UIButton+WebCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIButton+WebCache.h"; sourceTree = ""; }; - 88602DA31E10D97E00F3DB5D /* UIButton+WebCache.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIButton+WebCache.m"; sourceTree = ""; }; - 88602DA41E10D97E00F3DB5D /* UIImage+GIF.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIImage+GIF.h"; sourceTree = ""; }; - 88602DA51E10D97E00F3DB5D /* UIImage+GIF.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIImage+GIF.m"; sourceTree = ""; }; - 88602DA61E10D97E00F3DB5D /* UIImage+MultiFormat.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIImage+MultiFormat.h"; sourceTree = ""; }; - 88602DA71E10D97E00F3DB5D /* UIImage+MultiFormat.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIImage+MultiFormat.m"; sourceTree = ""; }; - 88602DA81E10D97E00F3DB5D /* UIImage+WebP.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIImage+WebP.h"; sourceTree = ""; }; - 88602DA91E10D97E00F3DB5D /* UIImage+WebP.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIImage+WebP.m"; sourceTree = ""; }; - 88602DAA1E10D97E00F3DB5D /* UIImageView+HighlightedWebCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIImageView+HighlightedWebCache.h"; sourceTree = ""; }; - 88602DAB1E10D97E00F3DB5D /* UIImageView+HighlightedWebCache.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIImageView+HighlightedWebCache.m"; sourceTree = ""; }; - 88602DAC1E10D97E00F3DB5D /* UIImageView+WebCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIImageView+WebCache.h"; sourceTree = ""; }; - 88602DAD1E10D97E00F3DB5D /* UIImageView+WebCache.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIImageView+WebCache.m"; sourceTree = ""; }; - 88602DAE1E10D97E00F3DB5D /* UIView+WebCacheOperation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIView+WebCacheOperation.h"; sourceTree = ""; }; - 88602DAF1E10D97E00F3DB5D /* UIView+WebCacheOperation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIView+WebCacheOperation.m"; sourceTree = ""; }; 88605F1A1D8256600037F1AA /* ShareReportCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ShareReportCell.h; sourceTree = ""; }; 88605F1B1D8256600037F1AA /* ShareReportCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ShareReportCell.m; sourceTree = ""; }; 8860D78C1D6D7BE8001E544C /* KanHuWorkViewFirstCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KanHuWorkViewFirstCell.h; sourceTree = ""; }; @@ -5697,6 +5694,56 @@ C024B79B2379668B00509424 /* NSMutableString+AvoidCrash.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSMutableString+AvoidCrash.h"; sourceTree = ""; }; C024B79C2379668B00509424 /* NSMutableAttributedString+AvoidCrash.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSMutableAttributedString+AvoidCrash.h"; sourceTree = ""; }; C024B79D2379668B00509424 /* NSMutableArray+AvoidCrash.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSMutableArray+AvoidCrash.h"; sourceTree = ""; }; + C0E746D4239E4A7C001BCD6D /* wechatlogin.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = wechatlogin.png; sourceTree = ""; }; + C0E7D6BC23A1D11200256A10 /* WXApiRequestHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WXApiRequestHandler.h; sourceTree = ""; }; + C0E7D6BD23A1D11200256A10 /* WXApiManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WXApiManager.h; sourceTree = ""; }; + C0E7D6BE23A1D11300256A10 /* WXApiManager.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WXApiManager.mm; sourceTree = ""; }; + C0E7D6BF23A1D11400256A10 /* WXApiRequestHandler.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WXApiRequestHandler.mm; sourceTree = ""; }; + C0E7D6C523A1D16C00256A10 /* WXMediaMessage+messageConstruct.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "WXMediaMessage+messageConstruct.h"; sourceTree = ""; }; + C0E7D6C623A1D16C00256A10 /* GetMessageFromWXResp+responseWithTextOrMediaMessage.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = "GetMessageFromWXResp+responseWithTextOrMediaMessage.mm"; sourceTree = ""; }; + C0E7D6C723A1D16C00256A10 /* Constant.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Constant.h; sourceTree = ""; }; + C0E7D6C823A1D16C00256A10 /* SendMessageToWXReq+requestWithTextOrMediaMessage.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = "SendMessageToWXReq+requestWithTextOrMediaMessage.mm"; sourceTree = ""; }; + C0E7D6C923A1D16C00256A10 /* GetMessageFromWXResp+responseWithTextOrMediaMessage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "GetMessageFromWXResp+responseWithTextOrMediaMessage.h"; sourceTree = ""; }; + C0E7D6CA23A1D16C00256A10 /* UIAlertView+WX.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIAlertView+WX.h"; sourceTree = ""; }; + C0E7D6CB23A1D16C00256A10 /* SendMessageToWXReq+requestWithTextOrMediaMessage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "SendMessageToWXReq+requestWithTextOrMediaMessage.h"; sourceTree = ""; }; + C0E7D6CC23A1D16C00256A10 /* WXMediaMessage+messageConstruct.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = "WXMediaMessage+messageConstruct.mm"; sourceTree = ""; }; + C0E7D6CD23A1D16C00256A10 /* UIAlertView+WX.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = "UIAlertView+WX.mm"; sourceTree = ""; }; + C0E7D6DA23A3D4C200256A10 /* renyuan.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = renyuan.png; sourceTree = ""; }; + C0EA89EA23AF73EE003DC53B /* UIColor+HexString.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIColor+HexString.h"; sourceTree = ""; }; + C0EA89EB23AF73EE003DC53B /* UIColor+HexString.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIColor+HexString.m"; sourceTree = ""; }; + C0EA89F023AF74F3003DC53B /* UIImage+WebP.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIImage+WebP.m"; sourceTree = ""; }; + C0EA89F123AF74F3003DC53B /* MKAnnotationView+WebCache.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "MKAnnotationView+WebCache.m"; sourceTree = ""; }; + C0EA89F223AF74F3003DC53B /* UIImageView+WebCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIImageView+WebCache.h"; sourceTree = ""; }; + C0EA89F323AF74F3003DC53B /* NSData+ImageContentType.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSData+ImageContentType.h"; sourceTree = ""; }; + C0EA89F423AF74F3003DC53B /* SDWebImageManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDWebImageManager.m; sourceTree = ""; }; + C0EA89F523AF74F3003DC53B /* SDWebImageDecoder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDWebImageDecoder.m; sourceTree = ""; }; + C0EA89F623AF74F3003DC53B /* SDWebImageDownloaderOperation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDWebImageDownloaderOperation.h; sourceTree = ""; }; + C0EA89F723AF74F3003DC53B /* UIImageView+HighlightedWebCache.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIImageView+HighlightedWebCache.m"; sourceTree = ""; }; + C0EA89F823AF74F3003DC53B /* SDImageCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDImageCache.h; sourceTree = ""; }; + C0EA89F923AF74F3003DC53B /* SDWebImageDownloader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDWebImageDownloader.m; sourceTree = ""; }; + C0EA89FA23AF74F3003DC53B /* UIImage+GIF.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIImage+GIF.m"; sourceTree = ""; }; + C0EA89FB23AF74F3003DC53B /* UIButton+WebCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIButton+WebCache.h"; sourceTree = ""; }; + C0EA89FC23AF74F3003DC53B /* UIImage+MultiFormat.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIImage+MultiFormat.m"; sourceTree = ""; }; + C0EA89FD23AF74F3003DC53B /* SDWebImageCompat.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDWebImageCompat.m; sourceTree = ""; }; + C0EA89FE23AF74F3003DC53B /* SDWebImagePrefetcher.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDWebImagePrefetcher.m; sourceTree = ""; }; + C0EA89FF23AF74F3003DC53B /* UIView+WebCacheOperation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIView+WebCacheOperation.h"; sourceTree = ""; }; + C0EA8A0023AF74F3003DC53B /* MKAnnotationView+WebCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "MKAnnotationView+WebCache.h"; sourceTree = ""; }; + C0EA8A0123AF74F3003DC53B /* UIImage+WebP.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIImage+WebP.h"; sourceTree = ""; }; + C0EA8A0223AF74F3003DC53B /* SDImageCache.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDImageCache.m; sourceTree = ""; }; + C0EA8A0323AF74F3003DC53B /* UIImageView+HighlightedWebCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIImageView+HighlightedWebCache.h"; sourceTree = ""; }; + C0EA8A0423AF74F3003DC53B /* SDWebImageDownloaderOperation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDWebImageDownloaderOperation.m; sourceTree = ""; }; + C0EA8A0523AF74F3003DC53B /* SDWebImageDecoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDWebImageDecoder.h; sourceTree = ""; }; + C0EA8A0623AF74F3003DC53B /* SDWebImageManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDWebImageManager.h; sourceTree = ""; }; + C0EA8A0723AF74F3003DC53B /* NSData+ImageContentType.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSData+ImageContentType.m"; sourceTree = ""; }; + C0EA8A0823AF74F3003DC53B /* UIImageView+WebCache.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIImageView+WebCache.m"; sourceTree = ""; }; + C0EA8A0923AF74F3003DC53B /* SDWebImageOperation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDWebImageOperation.h; sourceTree = ""; }; + C0EA8A0A23AF74F3003DC53B /* SDWebImageDownloader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDWebImageDownloader.h; sourceTree = ""; }; + C0EA8A0B23AF74F3003DC53B /* UIView+WebCacheOperation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIView+WebCacheOperation.m"; sourceTree = ""; }; + C0EA8A0C23AF74F3003DC53B /* SDWebImagePrefetcher.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDWebImagePrefetcher.h; sourceTree = ""; }; + C0EA8A0D23AF74F3003DC53B /* SDWebImageCompat.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDWebImageCompat.h; sourceTree = ""; }; + C0EA8A0E23AF74F3003DC53B /* UIImage+MultiFormat.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIImage+MultiFormat.h"; sourceTree = ""; }; + C0EA8A0F23AF74F3003DC53B /* UIButton+WebCache.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIButton+WebCache.m"; sourceTree = ""; }; + C0EA8A1023AF74F3003DC53B /* UIImage+GIF.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIImage+GIF.h"; sourceTree = ""; }; C0F0400B23756F3C00B61D3B /* ExternalAccessory.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ExternalAccessory.framework; path = System/Library/Frameworks/ExternalAccessory.framework; sourceTree = SDKROOT; }; CB0F4E7B22951A130091C76D /* SVRadialGradientLayer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SVRadialGradientLayer.m; sourceTree = ""; }; CB0F4E7C22951A130091C76D /* SVIndefiniteAnimatedView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVIndefiniteAnimatedView.h; sourceTree = ""; }; @@ -5839,8 +5886,6 @@ CB7D6A9F22953BEB0014E5C7 /* YYMemoryCache.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = YYMemoryCache.m; sourceTree = ""; }; CB7D6AAE22954DBC0014E5C7 /* CommonUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CommonUtils.h; sourceTree = ""; }; CB7D6AAF22954DE10014E5C7 /* CommonUtils.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CommonUtils.m; sourceTree = ""; }; - CB7D6AB222954E060014E5C7 /* UIColor+HexString.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIColor+HexString.m"; sourceTree = ""; }; - CB7D6AB322954E090014E5C7 /* UIColor+HexString.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIColor+HexString.h"; sourceTree = ""; }; CB7D6AB622954FB80014E5C7 /* FuncUserDefault.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FuncUserDefault.m; sourceTree = ""; }; CB7D6AB722954FB80014E5C7 /* FuncUserDefault.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FuncUserDefault.h; sourceTree = ""; }; CB7D6ABA229660370014E5C7 /* IfishConnectUsViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = IfishConnectUsViewController.h; sourceTree = ""; }; @@ -6031,7 +6076,6 @@ 18C54F2C2350541500DF4E7D /* SGSecurityBody.framework in Frameworks */, 88C6865A1EA612A6004CDFD9 /* AssetsLibrary.framework in Frameworks */, 88C686601EA612DE004CDFD9 /* Accelerate.framework in Frameworks */, - 18C54F2B2350541500DF4E7D /* AlipaySDK.framework in Frameworks */, 88C686561EA61285004CDFD9 /* AVFoundation.framework in Frameworks */, 88C686541EA61275004CDFD9 /* CFNetwork.framework in Frameworks */, 88C686521EA61267004CDFD9 /* CoreAudio.framework in Frameworks */, @@ -6161,7 +6205,6 @@ 18C54F142350541400DF4E7D /* UTMini.framework */, 18C54F152350541400DF4E7D /* OpenMtopSDK.framework */, 18C54F162350541400DF4E7D /* SGNoCaptcha.framework */, - 18C54F172350541400DF4E7D /* AlipaySDK.framework */, 18C54F182350541400DF4E7D /* SGSecurityBody.framework */, 18C54F192350541400DF4E7D /* OpenMtopExt.framework */, ); @@ -7859,6 +7902,7 @@ 8849EFAC1EB883840096CAD7 /* enter_background@3x.png */, 8849EFAD1EB883840096CAD7 /* enter_logo.png */, 8849EFAE1EB883840096CAD7 /* enter_logo@2x.png */, + C0E746D4239E4A7C001BCD6D /* wechatlogin.png */, 8849EFAF1EB883840096CAD7 /* enter_logo@3x.png */, 8849EFB01EB883840096CAD7 /* enter_padlock.png */, 8849EFB11EB883840096CAD7 /* enter_padlock@2x.png */, @@ -8346,6 +8390,7 @@ children = ( E5F1B03821183E9600A879A1 /* setting-restart.png */, E5F1B03921183E9700A879A1 /* setting-restart@2x.png */, + C0E7D6DA23A3D4C200256A10 /* renyuan.png */, E5F1B03721183E9600A879A1 /* setting-restart@3x.png */, E5F1B03321183DCD00A879A1 /* setting-reset.png */, E5F1B03121183DCC00A879A1 /* setting-reset@2x.png */, @@ -10403,54 +10448,6 @@ path = ViewController; sourceTree = ""; }; - 88602D8D1E10D97E00F3DB5D /* SDWebImage3.8.2 */ = { - isa = PBXGroup; - children = ( - 88602D8E1E10D97E00F3DB5D /* SDWebImage */, - ); - path = SDWebImage3.8.2; - sourceTree = ""; - }; - 88602D8E1E10D97E00F3DB5D /* SDWebImage */ = { - isa = PBXGroup; - children = ( - 88602D8F1E10D97E00F3DB5D /* MKAnnotationView+WebCache.h */, - 88602D901E10D97E00F3DB5D /* MKAnnotationView+WebCache.m */, - 88602D911E10D97E00F3DB5D /* NSData+ImageContentType.h */, - 88602D921E10D97E00F3DB5D /* NSData+ImageContentType.m */, - 88602D931E10D97E00F3DB5D /* SDImageCache.h */, - 88602D941E10D97E00F3DB5D /* SDImageCache.m */, - 88602D951E10D97E00F3DB5D /* SDWebImageCompat.h */, - 88602D961E10D97E00F3DB5D /* SDWebImageCompat.m */, - 88602D971E10D97E00F3DB5D /* SDWebImageDecoder.h */, - 88602D981E10D97E00F3DB5D /* SDWebImageDecoder.m */, - 88602D991E10D97E00F3DB5D /* SDWebImageDownloader.h */, - 88602D9A1E10D97E00F3DB5D /* SDWebImageDownloader.m */, - 88602D9B1E10D97E00F3DB5D /* SDWebImageDownloaderOperation.h */, - 88602D9C1E10D97E00F3DB5D /* SDWebImageDownloaderOperation.m */, - 88602D9D1E10D97E00F3DB5D /* SDWebImageManager.h */, - 88602D9E1E10D97E00F3DB5D /* SDWebImageManager.m */, - 88602D9F1E10D97E00F3DB5D /* SDWebImageOperation.h */, - 88602DA01E10D97E00F3DB5D /* SDWebImagePrefetcher.h */, - 88602DA11E10D97E00F3DB5D /* SDWebImagePrefetcher.m */, - 88602DA21E10D97E00F3DB5D /* UIButton+WebCache.h */, - 88602DA31E10D97E00F3DB5D /* UIButton+WebCache.m */, - 88602DA41E10D97E00F3DB5D /* UIImage+GIF.h */, - 88602DA51E10D97E00F3DB5D /* UIImage+GIF.m */, - 88602DA61E10D97E00F3DB5D /* UIImage+MultiFormat.h */, - 88602DA71E10D97E00F3DB5D /* UIImage+MultiFormat.m */, - 88602DA81E10D97E00F3DB5D /* UIImage+WebP.h */, - 88602DA91E10D97E00F3DB5D /* UIImage+WebP.m */, - 88602DAA1E10D97E00F3DB5D /* UIImageView+HighlightedWebCache.h */, - 88602DAB1E10D97E00F3DB5D /* UIImageView+HighlightedWebCache.m */, - 88602DAC1E10D97E00F3DB5D /* UIImageView+WebCache.h */, - 88602DAD1E10D97E00F3DB5D /* UIImageView+WebCache.m */, - 88602DAE1E10D97E00F3DB5D /* UIView+WebCacheOperation.h */, - 88602DAF1E10D97E00F3DB5D /* UIView+WebCacheOperation.m */, - ); - path = SDWebImage; - sourceTree = ""; - }; 88613F601E5C1E86008D2C69 /* FishP2PshareFeed */ = { isa = PBXGroup; children = ( @@ -11779,6 +11776,7 @@ 88C685E71EA603A8004CDFD9 /* WechatAuthSDK.h */, 88C685E81EA603A8004CDFD9 /* WXApi.h */, 88C685E91EA603A8004CDFD9 /* WXApiObject.h */, + C0E7D6C423A1D16C00256A10 /* Helper */, ); path = WechatSDK; sourceTree = ""; @@ -11963,6 +11961,7 @@ 88F5EEE81D48D04100CC7CAF /* libs */ = { isa = PBXGroup; children = ( + C0EA883E23AF61D6003DC53B /* SDWebImage3.8.2 */, C024B7892379668B00509424 /* AvoidCrash */, CB484CE822B76DEC0075F050 /* GWP2PSDK */, CB7D6AEA2296A1870014E5C7 /* AliPush */, @@ -11972,7 +11971,6 @@ CBA6164E228F9A6C00ED380D /* YYModel */, 3DD7AB8E21E474930064856A /* AsyncSocket */, 3DD7AB2021E2F2FB0064856A /* ZbarSDK */, - 88602D8D1E10D97E00F3DB5D /* SDWebImage3.8.2 */, 88F5EEE91D48D08000CC7CAF /* AFNet */, 88F5EF1B1D48D08000CC7CAF /* fmdb */, 88F5EF271D48D08000CC7CAF /* JHRefresh */, @@ -12182,6 +12180,82 @@ path = AvoidCrash; sourceTree = ""; }; + C0E7D6C423A1D16C00256A10 /* Helper */ = { + isa = PBXGroup; + children = ( + C0E7D6BD23A1D11200256A10 /* WXApiManager.h */, + C0E7D6BE23A1D11300256A10 /* WXApiManager.mm */, + C0E7D6BC23A1D11200256A10 /* WXApiRequestHandler.h */, + C0E7D6BF23A1D11400256A10 /* WXApiRequestHandler.mm */, + C0E7D6C523A1D16C00256A10 /* WXMediaMessage+messageConstruct.h */, + C0E7D6C623A1D16C00256A10 /* GetMessageFromWXResp+responseWithTextOrMediaMessage.mm */, + C0E7D6C723A1D16C00256A10 /* Constant.h */, + C0E7D6C823A1D16C00256A10 /* SendMessageToWXReq+requestWithTextOrMediaMessage.mm */, + C0E7D6C923A1D16C00256A10 /* GetMessageFromWXResp+responseWithTextOrMediaMessage.h */, + C0E7D6CA23A1D16C00256A10 /* UIAlertView+WX.h */, + C0E7D6CB23A1D16C00256A10 /* SendMessageToWXReq+requestWithTextOrMediaMessage.h */, + C0E7D6CC23A1D16C00256A10 /* WXMediaMessage+messageConstruct.mm */, + C0E7D6CD23A1D16C00256A10 /* UIAlertView+WX.mm */, + ); + path = Helper; + sourceTree = ""; + }; + C0EA883E23AF61D6003DC53B /* SDWebImage3.8.2 */ = { + isa = PBXGroup; + children = ( + C0EA89EE23AF74F3003DC53B /* SDWebImage3.8.2 */, + ); + path = SDWebImage3.8.2; + sourceTree = ""; + }; + C0EA89EE23AF74F3003DC53B /* SDWebImage3.8.2 */ = { + isa = PBXGroup; + children = ( + C0EA89EF23AF74F3003DC53B /* SDWebImage */, + ); + name = SDWebImage3.8.2; + sourceTree = ""; + }; + C0EA89EF23AF74F3003DC53B /* SDWebImage */ = { + isa = PBXGroup; + children = ( + C0EA89F023AF74F3003DC53B /* UIImage+WebP.m */, + C0EA89F123AF74F3003DC53B /* MKAnnotationView+WebCache.m */, + C0EA89F223AF74F3003DC53B /* UIImageView+WebCache.h */, + C0EA89F323AF74F3003DC53B /* NSData+ImageContentType.h */, + C0EA89F423AF74F3003DC53B /* SDWebImageManager.m */, + C0EA89F523AF74F3003DC53B /* SDWebImageDecoder.m */, + C0EA89F623AF74F3003DC53B /* SDWebImageDownloaderOperation.h */, + C0EA89F723AF74F3003DC53B /* UIImageView+HighlightedWebCache.m */, + C0EA89F823AF74F3003DC53B /* SDImageCache.h */, + C0EA89F923AF74F3003DC53B /* SDWebImageDownloader.m */, + C0EA89FA23AF74F3003DC53B /* UIImage+GIF.m */, + C0EA89FB23AF74F3003DC53B /* UIButton+WebCache.h */, + C0EA89FC23AF74F3003DC53B /* UIImage+MultiFormat.m */, + C0EA89FD23AF74F3003DC53B /* SDWebImageCompat.m */, + C0EA89FE23AF74F3003DC53B /* SDWebImagePrefetcher.m */, + C0EA89FF23AF74F3003DC53B /* UIView+WebCacheOperation.h */, + C0EA8A0023AF74F3003DC53B /* MKAnnotationView+WebCache.h */, + C0EA8A0123AF74F3003DC53B /* UIImage+WebP.h */, + C0EA8A0223AF74F3003DC53B /* SDImageCache.m */, + C0EA8A0323AF74F3003DC53B /* UIImageView+HighlightedWebCache.h */, + C0EA8A0423AF74F3003DC53B /* SDWebImageDownloaderOperation.m */, + C0EA8A0523AF74F3003DC53B /* SDWebImageDecoder.h */, + C0EA8A0623AF74F3003DC53B /* SDWebImageManager.h */, + C0EA8A0723AF74F3003DC53B /* NSData+ImageContentType.m */, + C0EA8A0823AF74F3003DC53B /* UIImageView+WebCache.m */, + C0EA8A0923AF74F3003DC53B /* SDWebImageOperation.h */, + C0EA8A0A23AF74F3003DC53B /* SDWebImageDownloader.h */, + C0EA8A0B23AF74F3003DC53B /* UIView+WebCacheOperation.m */, + C0EA8A0C23AF74F3003DC53B /* SDWebImagePrefetcher.h */, + C0EA8A0D23AF74F3003DC53B /* SDWebImageCompat.h */, + C0EA8A0E23AF74F3003DC53B /* UIImage+MultiFormat.h */, + C0EA8A0F23AF74F3003DC53B /* UIButton+WebCache.m */, + C0EA8A1023AF74F3003DC53B /* UIImage+GIF.h */, + ); + path = SDWebImage; + sourceTree = ""; + }; CB0F4E622294F2B00091C76D /* Networking */ = { isa = PBXGroup; children = ( @@ -12618,8 +12692,8 @@ CBA6169C22928A1800ED380D /* Categorys */ = { isa = PBXGroup; children = ( - CB7D6AB322954E090014E5C7 /* UIColor+HexString.h */, - CB7D6AB222954E060014E5C7 /* UIColor+HexString.m */, + C0EA89EA23AF73EE003DC53B /* UIColor+HexString.h */, + C0EA89EB23AF73EE003DC53B /* UIColor+HexString.m */, CBA616AA22928BCE00ED380D /* UIButton+button.h */, CBA616A722928B1700ED380D /* UIButton+button.m */, ); @@ -12703,6 +12777,7 @@ CBA6167F228F9AB100ED380D /* MASViewConstraint.h in Headers */, C024B7A22379668B00509424 /* NSAttributedString+AvoidCrash.h in Headers */, CB8B6468230F7F980032EB24 /* IfishMainInfoCell.h in Headers */, + C0EA8A2A23AF74F4003DC53B /* SDWebImageOperation.h in Headers */, CB484E1122B8C8C90075F050 /* version.h in Headers */, 3D1C5122221A9EE00096AE43 /* IfishRecVideoViewCell.h in Headers */, CB48207C2334E99700A50C92 /* IQTextView.h in Headers */, @@ -12710,8 +12785,10 @@ CB484DE822B8C8C80075F050 /* lfg.h in Headers */, CB4820512334DFCF00A50C92 /* ConnectingAquarVC.h in Headers */, 3D1C5137221A9EE10096AE43 /* ifishdeviceListCell.h in Headers */, + C0E7D6CE23A1D16D00256A10 /* WXMediaMessage+messageConstruct.h in Headers */, 3D1C5085221A9EDF0096AE43 /* KTPhotoBrowserGlobal.h in Headers */, 3D1C50B6221A9EDF0096AE43 /* YSlider.h in Headers */, + C0EA89EC23AF73EE003DC53B /* UIColor+HexString.h in Headers */, CB484DDC22B8C8C80075F050 /* Rtsp_instance.h in Headers */, CB484DF722B8C8C80075F050 /* dict.h in Headers */, CBA6167A228F9AB100ED380D /* View+MASAdditions.h in Headers */, @@ -12721,6 +12798,7 @@ 3D1C50FF221A9EE00096AE43 /* YooseeCenterViewCell.h in Headers */, CBB0243323517947002900D5 /* NSObject+MJKeyValue.h in Headers */, CB484CFF22B8B0D30075F050 /* Reachability.h in Headers */, + C0E7D6D423A1D16D00256A10 /* SendMessageToWXReq+requestWithTextOrMediaMessage.h in Headers */, CB484E0B22B8C8C80075F050 /* version.h in Headers */, CB484E1722B8C8C90075F050 /* dxva2.h in Headers */, CB484DE622B8C8C80075F050 /* sha.h in Headers */, @@ -12735,6 +12813,7 @@ CB484DED22B8C8C80075F050 /* file.h in Headers */, CBA61654228F9A6C00ED380D /* YYClassInfo.h in Headers */, 3D1C50BA221A9EE00096AE43 /* NetManager.h in Headers */, + C0E7D6D023A1D16D00256A10 /* Constant.h in Headers */, CB484DF622B8C8C80075F050 /* eval.h in Headers */, 3D1C513A221A9EE10096AE43 /* FishControlFirstCell.h in Headers */, 3D1C50EC221A9EE00096AE43 /* MessageDAO.h in Headers */, @@ -12742,6 +12821,7 @@ 3D1C50E2221A9EE00096AE43 /* UDPManager.h in Headers */, 3D1C509A221A9EDF0096AE43 /* ConnectFailurePromptView.h in Headers */, CBA6168A228F9AB100ED380D /* ViewController+MASAdditions.h in Headers */, + C0EA8A2723AF74F4003DC53B /* SDWebImageManager.h in Headers */, CBB0244023517947002900D5 /* NSObject+MJCoding.h in Headers */, FA0892ED226C15000084A609 /* Xuanduo2DataUtility.h in Headers */, 3D1C50B7221A9EDF0096AE43 /* YTargetAndAction.h in Headers */, @@ -12777,6 +12857,7 @@ CB484DF922B8C8C80075F050 /* opt.h in Headers */, FA0892F1226CA3920084A609 /* NSString+Add.h in Headers */, CB4820852334E99700A50C92 /* IQBarButtonItem.h in Headers */, + C0EA8A2B23AF74F4003DC53B /* SDWebImageDownloader.h in Headers */, CB484E0722B8C8C80075F050 /* avassert.h in Headers */, CB484DDE22B8C8C80075F050 /* error.h in Headers */, 3D1C5100221A9EE00096AE43 /* IfishCameraModel.h in Headers */, @@ -12785,6 +12866,7 @@ 3D1C50B4221A9EDF0096AE43 /* YTheNaviBar.h in Headers */, 3D1C5121221A9EE00096AE43 /* CameraBottomCollectionViewCell.h in Headers */, CB484E1222B8C8C90075F050 /* vdpau.h in Headers */, + C0EA8A1323AF74F4003DC53B /* UIImageView+WebCache.h in Headers */, CB4820962334E99700A50C92 /* IQUIView+Hierarchy.h in Headers */, FA0892E9226B22C90084A609 /* Xuanduo2Model.h in Headers */, 3D1C5115221A9EE00096AE43 /* ShotScreenImgViewController.h in Headers */, @@ -12794,6 +12876,7 @@ CB484E0222B8C8C80075F050 /* mem.h in Headers */, CB484DD922B8C8C80075F050 /* elian.h in Headers */, CB4820562334E30300A50C92 /* HKPieChartView.h in Headers */, + C0E7D6C023A1D11500256A10 /* WXApiRequestHandler.h in Headers */, CBA615FC228E8E5A00ED380D /* MyMessageViewController.h in Headers */, CB484E1522B8C8C90075F050 /* avfft.h in Headers */, CB484E0022B8C8C80075F050 /* channel_layout.h in Headers */, @@ -12821,28 +12904,36 @@ 3D1C50F2221A9EE00096AE43 /* mesg.h in Headers */, CBA6169922924F1E00ED380D /* MessageAlertView.h in Headers */, CB484E0C22B8C8C80075F050 /* avio.h in Headers */, + C0E7D6C123A1D11500256A10 /* WXApiManager.h in Headers */, 3D1C507F221A9EDF0096AE43 /* KTPhotoBrowserDataSource.h in Headers */, 3D1C50E9221A9EE00096AE43 /* AlarmDAO.h in Headers */, + C0EA8A2123AF74F4003DC53B /* MKAnnotationView+WebCache.h in Headers */, CBA61658228F9A6C00ED380D /* NSObject+YYModel.h in Headers */, 3D1C50C4221A9EE00096AE43 /* OBGradientView.h in Headers */, + C0E7D6D223A1D16D00256A10 /* GetMessageFromWXResp+responseWithTextOrMediaMessage.h in Headers */, 3D1C509D221A9EDF0096AE43 /* GetContactMessageResult.h in Headers */, CBB0243923517947002900D5 /* MJPropertyKey.h in Headers */, CBA61681228F9AB100ED380D /* NSLayoutConstraint+MASDebugAdditions.h in Headers */, 3D1C5109221A9EE00096AE43 /* P2PPlaybackController.h in Headers */, C024B7B02379668B00509424 /* NSMutableAttributedString+AvoidCrash.h in Headers */, + C0E7D6D323A1D16D00256A10 /* UIAlertView+WX.h in Headers */, CB484DE422B8C8C80075F050 /* base64.h in Headers */, + C0EA8A1423AF74F4003DC53B /* NSData+ImageContentType.h in Headers */, CB484E1922B8C8C90075F050 /* FfmpegInterface.h in Headers */, CB4820842334E99700A50C92 /* IQToolbar.h in Headers */, 3D1C50B9221A9EDF0096AE43 /* CheckNewMessageResult.h in Headers */, CB4820932334E99700A50C92 /* IQUIScrollView+Additions.h in Headers */, CB48208E2334E99700A50C92 /* IQUIViewController+Additions.h in Headers */, + C0EA8A1C23AF74F4003DC53B /* UIButton+WebCache.h in Headers */, C024B7AC2379668B00509424 /* NSArray+AvoidCrash.h in Headers */, CB48207D2334E99700A50C92 /* IQUIView+IQKeyboardToolbar.h in Headers */, C024B7AF2379668B00509424 /* NSMutableString+AvoidCrash.h in Headers */, + C0EA8A2023AF74F4003DC53B /* UIView+WebCacheOperation.h in Headers */, CB48208A2334E99700A50C92 /* IQKeyboardReturnKeyHandler.h in Headers */, CBA61678228F9AB100ED380D /* NSArray+MASShorthandAdditions.h in Headers */, 3D1C5095221A9EDF0096AE43 /* Alarm.h in Headers */, CB4820872334E99700A50C92 /* IQKeyboardManagerConstantsInternal.h in Headers */, + C0EA8A2D23AF74F4003DC53B /* SDWebImagePrefetcher.h in Headers */, 3D1C5145221A9EE10096AE43 /* BootomViewSoketBackMasgConreol.h in Headers */, 3D1C5146221A9EE10096AE43 /* FishTankBootmDataHelper.h in Headers */, CB484DF522B8C8C80075F050 /* hmac.h in Headers */, @@ -12854,11 +12945,11 @@ 3D1C50E8221A9EE00096AE43 /* Message.h in Headers */, 3D1C5101221A9EE00096AE43 /* IfishP2PMonitorController.h in Headers */, 3D1C50F5221A9EE00096AE43 /* CameraManager.h in Headers */, + C0EA8A2423AF74F4003DC53B /* UIImageView+HighlightedWebCache.h in Headers */, CB484DF422B8C8C80075F050 /* common.h in Headers */, 3D1C50A3221A9EDF0096AE43 /* WaitingPageView.h in Headers */, CB484DEB22B8C8C80075F050 /* xtea.h in Headers */, CB484DE022B8C8C80075F050 /* blowfish.h in Headers */, - CB7D6AB522954E090014E5C7 /* UIColor+HexString.h in Headers */, CB484DE122B8C8C80075F050 /* version.h in Headers */, CB484DDD22B8C8C80075F050 /* intfloat.h in Headers */, CB5B9B1A22EEC4BC00F0DFB1 /* UIView+Toast.h in Headers */, @@ -12869,9 +12960,11 @@ 3D1C50A7221A9EDF0096AE43 /* MXSCycleScrollView3.h in Headers */, 3D1C50F0221A9EE00096AE43 /* RecommendInfo.h in Headers */, 3D1C509C221A9EDF0096AE43 /* ModifyLoginPasswordResult.h in Headers */, + C0EA8A2E23AF74F4003DC53B /* SDWebImageCompat.h in Headers */, CBA61680228F9AB100ED380D /* MASConstraint.h in Headers */, CB484E0622B8C8C80075F050 /* timestamp.h in Headers */, 3D1C512E221A9EE10096AE43 /* CameraBottomHView.h in Headers */, + C0EA8A2223AF74F4003DC53B /* UIImage+WebP.h in Headers */, CB484E0E22B8C8C80075F050 /* version.h in Headers */, 3D1C50E4221A9EE00096AE43 /* config.h in Headers */, CBB0243223517947002900D5 /* NSObject+MJProperty.h in Headers */, @@ -12886,6 +12979,7 @@ CB4820922334E99700A50C92 /* IQNSArray+Sort.h in Headers */, CB4820942334E99700A50C92 /* IQUITextFieldView+Additions.h in Headers */, 3D1C5139221A9EE10096AE43 /* FishControlSecondCell.h in Headers */, + C0EA8A1723AF74F4003DC53B /* SDWebImageDownloaderOperation.h in Headers */, 3D1C50B2221A9EDF0096AE43 /* FounderButton.h in Headers */, CBB0244323517947002900D5 /* MJPropertyType.h in Headers */, 3D1C509F221A9EDF0096AE43 /* YProgressView.h in Headers */, @@ -12899,6 +12993,7 @@ 3D1C50D3221A9EE00096AE43 /* UIScrollView+SVInfiniteScrolling.h in Headers */, CBA61655228F9A6C00ED380D /* YYModel.h in Headers */, CB484DFE22B8C8C80075F050 /* cpu.h in Headers */, + C0EA8A2F23AF74F4003DC53B /* UIImage+MultiFormat.h in Headers */, CB4820882334E99700A50C92 /* IQKeyboardManagerConstants.h in Headers */, 3D1C5089221A9EDF0096AE43 /* KTPhotoView.h in Headers */, CB484DFB22B8C8C80075F050 /* aes.h in Headers */, @@ -12918,6 +13013,7 @@ CB484E1B22B8C8C90075F050 /* RtspInterface.h in Headers */, CB484DEE22B8C8C80075F050 /* md5.h in Headers */, FAA732D4227BE2B80062C252 /* ReadTimerModel.h in Headers */, + C0EA8A1923AF74F4003DC53B /* SDImageCache.h in Headers */, CBA61676228F9AB100ED380D /* MASConstraint+Private.h in Headers */, CB484DF022B8C8C80075F050 /* attributes.h in Headers */, 3D1C508B221A9EDF0096AE43 /* KTPhotoScrollViewController.h in Headers */, @@ -12925,6 +13021,8 @@ 3D1C50E3221A9EE00096AE43 /* OpenGLView.h in Headers */, CBA61679228F9AB100ED380D /* MASConstraintMaker.h in Headers */, 3D1C5105221A9EE00096AE43 /* YooseeCenterViewController.h in Headers */, + C0EA8A3123AF74F4003DC53B /* UIImage+GIF.h in Headers */, + C0EA8A2623AF74F4003DC53B /* SDWebImageDecoder.h in Headers */, 3D1C5108221A9EE00096AE43 /* P2PPlayingbackVC.h in Headers */, 3D1C50AD221A9EDF0096AE43 /* FXBlurView.h in Headers */, CB0F4E8A22951A130091C76D /* SVRadialGradientLayer.h in Headers */, @@ -13006,7 +13104,7 @@ 8876A5821BB83447007A4B54 = { CreatedOnToolsVersion = 7.0; DevelopmentTeam = WFX8GD5HFX; - ProvisioningStyle = Manual; + ProvisioningStyle = Automatic; SystemCapabilities = { com.apple.AccessWiFi = { enabled = 1; @@ -13195,6 +13293,7 @@ 883E79CB1D48B0280030E075 /* TemperatureSetCell.xib in Resources */, 889133211ECE99B900F52EBC /* record_iocn_start@3x.png in Resources */, 88C1B2201DCC5A1400C2C99A /* personal_iocn_switch.png in Resources */, + C0E7D6DB23A3D4C200256A10 /* renyuan.png in Resources */, 882956691DBDA3A200E9DDD7 /* minelook_buy.png in Resources */, E5212236210760A700BA24C5 /* SettingResetViewController.xib in Resources */, 18C54F1C2350541500DF4E7D /* ALPLinkPartnerSDK.bundle in Resources */, @@ -13573,6 +13672,7 @@ 8832834B1EAEE60500A47157 /* ifish_me_off.png in Resources */, 885FBDD51E4C0CB400E0D7D1 /* explore_iocn_merchants@3x.png in Resources */, 8871FB221EBC822B0038E99A /* select_waiting@2x.png in Resources */, + C0E746D5239E4A7D001BCD6D /* wechatlogin.png in Resources */, 881477C41E6F968D00BFB79C /* signin_popup_egg.png in Resources */, 8829562E1DBDA3A200E9DDD7 /* neves0049.png in Resources */, 8829561E1DBDA3A100E9DDD7 /* neves0033.png in Resources */, @@ -14404,7 +14504,6 @@ 3D1C5084221A9EDF0096AE43 /* KTPhotoView.m in Sources */, 886FB1801E5A89A800256332 /* CusomeCameraViewController.m in Sources */, 886F4DEB1D751B22001EDA34 /* LookReportViewCell.m in Sources */, - 88602DBF1E10D97E00F3DB5D /* UIView+WebCacheOperation.m in Sources */, 881671B61EA5DE2B00BEBF23 /* UMComLoginUser.m in Sources */, 883E78621D48A5E50030E075 /* RightViewController.m in Sources */, CBA61675228F9AB100ED380D /* NSLayoutConstraint+MASDebugAdditions.m in Sources */, @@ -14425,8 +14524,8 @@ 886F4E011D76BFF8001EDA34 /* KanHuBaoGaoModel.m in Sources */, 883E79C21D48B0280030E075 /* InfoCell.m in Sources */, CBA6169A22924F1E00ED380D /* MessageAlertView.m in Sources */, + C0EA8A1F23AF74F4003DC53B /* SDWebImagePrefetcher.m in Sources */, 88F5EE531D48CA2800CC7CAF /* ESPUDPSocketClient.m in Sources */, - 88602DBE1E10D97E00F3DB5D /* UIImageView+WebCache.m in Sources */, 883E78561D48A5E50030E075 /* IfishBlackListCenterViewController.m in Sources */, CB484E1A22B8C8C90075F050 /* RtspInterface.mm in Sources */, 883A3D181EC44EF300DA84FF /* IfishUsersActivityListController.m in Sources */, @@ -14497,6 +14596,7 @@ 3D8F64CA2157842200F04BD3 /* IfishPackageHeaderVo.m in Sources */, 88591EE71D655B9E00A1316E /* CityModel.m in Sources */, 881477CD1E6FAAEB00BFB79C /* RenQuYinDaoVIew.m in Sources */, + C0EA8A1D23AF74F4003DC53B /* UIImage+MultiFormat.m in Sources */, 8871C4791E6D4F50000AA49F /* QianDaoTimeLineView.m in Sources */, 8839BAEE1EC581BE00CA62CF /* FishActivityData.m in Sources */, 3D1C17522171BB0700A159A8 /* PNScatterChartData.m in Sources */, @@ -14591,6 +14691,7 @@ 881672071EA5DE2B00BEBF23 /* UMComGridTableViewCell.m in Sources */, 885353081D66A2CB009B828B /* ShopCertifyCheckViewController.m in Sources */, 881671BF1EA5DE2B00BEBF23 /* UMComPhotoAlbumViewController.m in Sources */, + C0EA8A2323AF74F4003DC53B /* SDImageCache.m in Sources */, 883E79BA1D48B0280030E075 /* LYPhoto.m in Sources */, 88C598A41EA0A2C200BDC812 /* IfishDocAliGoodsListTitleViewCell.m in Sources */, 881672021EA5DE2B00BEBF23 /* UMImagePickerThumbnailView.m in Sources */, @@ -14608,6 +14709,7 @@ 3D1C5141221A9EE10096AE43 /* MonitorBootmView.m in Sources */, 3D1C17492171BB0700A159A8 /* PNGenericChart.m in Sources */, CBA61656228F9A6C00ED380D /* NSObject+YYModel.m in Sources */, + C0E7D6D123A1D16D00256A10 /* SendMessageToWXReq+requestWithTextOrMediaMessage.mm in Sources */, 3D1C50FD221A9EE00096AE43 /* YProgressView.m in Sources */, 8871C4331E6CFE98000AA49F /* QianDaoTimeViewCell.m in Sources */, 88742C4A1D645D390074F1F8 /* ShopCertificationHtmlController.m in Sources */, @@ -14636,11 +14738,13 @@ 8869B3761E6939FE0010F099 /* NJKWebViewProgressView.m in Sources */, 883E79CA1D48B0280030E075 /* TemperatureSetCell.m in Sources */, 3DD7AB5321E2F2FB0064856A /* rscode.c in Sources */, + C0EA8A1623AF74F4003DC53B /* SDWebImageDecoder.m in Sources */, 885A376E1E6EBB67007AD930 /* QianDaoGiftView.m in Sources */, CBA61657228F9A6C00ED380D /* YYClassInfo.m in Sources */, 88F5EE4E1D48CA2800CC7CAF /* ESP_NetUtil.m in Sources */, FA0892F2226CA3920084A609 /* NSString+Add.m in Sources */, 883E763E1D4897570030E075 /* ServerBackDeviceLogInModel.m in Sources */, + C0EA8A1223AF74F4003DC53B /* MKAnnotationView+WebCache.m in Sources */, 88F5EE511D48CA2800CC7CAF /* ESPTouchTask.m in Sources */, CBA616A822928B1700ED380D /* UIButton+button.m in Sources */, 3D1C5098221A9EDF0096AE43 /* UDManager.m in Sources */, @@ -14655,6 +14759,7 @@ 886D94D21D6BFFFD00CF0B63 /* LookafterPhoneNumberCell.m in Sources */, 3D1C5080221A9EDF0096AE43 /* KTThumbsView.m in Sources */, 883E76381D4897570030E075 /* DeviceOnlineModel.m in Sources */, + C0E7D6CF23A1D16D00256A10 /* GetMessageFromWXResp+responseWithTextOrMediaMessage.mm in Sources */, 882C85B61EB08295001CC414 /* DiscountCoupon.m in Sources */, 881477D61E6FE9D300BFB79C /* IfishGoldAndExpTostView.m in Sources */, 883E784C1D48A5E50030E075 /* songNuoLightModel.m in Sources */, @@ -14724,7 +14829,6 @@ 887DA78C1D547A49001DB880 /* IfishTanSuoViewCell.m in Sources */, 8816720D1EA5DE2B00BEBF23 /* UMComEmojiPageView.m in Sources */, 881672441EA5DE2B00BEBF23 /* UMCommunityUI.m in Sources */, - 88602DB51E10D97E00F3DB5D /* SDWebImageDownloader.m in Sources */, 883E787F1D48A5E50030E075 /* AboutUsViewController.m in Sources */, 8816720F1EA5DE2B00BEBF23 /* UMComWebView.m in Sources */, 88597ABB1E56BAF1003D0E5C /* DrawView.m in Sources */, @@ -14773,7 +14877,6 @@ 8871C44B1E6D2A93000AA49F /* QianDaoGongLueViewCell.m in Sources */, CBB0244223517947002900D5 /* MJPropertyType.m in Sources */, 8871FAA41EBC0CE30038E99A /* ShopCerProgressHeaderView.m in Sources */, - 88602DBC1E10D97E00F3DB5D /* UIImage+WebP.m in Sources */, 88F5EFD81D48D08100CC7CAF /* MMVectorImage.m in Sources */, CBB0243623517947002900D5 /* NSObject+MJProperty.m in Sources */, 883E79B81D48B0280030E075 /* remindCyclePic.m in Sources */, @@ -14786,7 +14889,6 @@ 88597AC21E56BAF1003D0E5C /* WFTailoringViewController.m in Sources */, 882957FD1DC0443600E9DDD7 /* IfishCardScrollView.m in Sources */, E51D7D4E208CD5C8001FF053 /* RuiMeiCHControl.m in Sources */, - 88602DB81E10D97E00F3DB5D /* SDWebImagePrefetcher.m in Sources */, 885979EF1E541C28003D0E5C /* IfishShopEditeNewViewController.m in Sources */, 883E784F1D48A5E50030E075 /* SetTimeController.m in Sources */, 881671A01EA5DE2B00BEBF23 /* UMComFeedListDataController.m in Sources */, @@ -14798,6 +14900,7 @@ 88696FD41E9C8B4A005D4AFB /* MemberEditeViewLocationCell.m in Sources */, 886F4DF61D753877001EDA34 /* Report3ViewCell.m in Sources */, 885353131D66D22C009B828B /* LookafterPicCell.m in Sources */, + C0EA8A3023AF74F4003DC53B /* UIButton+WebCache.m in Sources */, 885979D31E529F64003D0E5C /* GoNetShopViewCell.m in Sources */, 881671A81EA5DE2B00BEBF23 /* UMComTopicGroupDataController.m in Sources */, 883E762C1D4897570030E075 /* setRemindWaterModel.m in Sources */, @@ -14805,6 +14908,7 @@ 88742C3D1D63FA270074F1F8 /* CertifyListFourthCell.m in Sources */, 8871FAAF1EBC2CE60038E99A /* ShopCerPatr1DetailLocationCell.m in Sources */, 88597A2B1E5597C8003D0E5C /* KanHuGuanLi1ViewCell.m in Sources */, + C0EA89ED23AF73EE003DC53B /* UIColor+HexString.m in Sources */, 88883B1F1EF0FF6000CAC0AE /* SonNuo128NameViewController.m in Sources */, 8867F5B01E65421900AF021C /* IifshMineDJViewController.m in Sources */, 881671D81EA5DE2B00BEBF23 /* UMComSysLikeTableViewCell.m in Sources */, @@ -14845,7 +14949,6 @@ 886B80641D62F57000E1B9B3 /* SOngNuoGuiDeng.m in Sources */, 881F0F591D73DFFF0091507E /* BaoGaoViewThirdCell.m in Sources */, 88653C9B1E76691E00FF973E /* IfishInformationViewController.m in Sources */, - 88602DB61E10D97E00F3DB5D /* SDWebImageDownloaderOperation.m in Sources */, 88F5EFB81D48D08100CC7CAF /* UIRefreshControl+AFNetworking.m in Sources */, 88D3373C1DC7440C006C0ADB /* IfishConnectingView.m in Sources */, 8856B0EC1DED4AE0009D384A /* IfishUserDefaultHelper.m in Sources */, @@ -14853,12 +14956,12 @@ C024B7AB2379668B00509424 /* AvoidCrash.m in Sources */, 3D1C50DA221A9EE00096AE43 /* RecommendInfo.m in Sources */, 883E79B21D48B0280030E075 /* MerchantCell.m in Sources */, + C0E7D6D623A1D16D00256A10 /* UIAlertView+WX.mm in Sources */, 883E76421D4897570030E075 /* TimerSateModel.m in Sources */, CB484CF922B8B0AC0075F050 /* GCDAsyncUdpSocket.m in Sources */, 881869341D6FDD3B00CE9DFF /* ShopKanHuP2PViewController.m in Sources */, C024B79E2379668B00509424 /* NSArray+AvoidCrash.m in Sources */, CBA6168C228F9AB100ED380D /* MASViewAttribute.m in Sources */, - 88602DB91E10D97E00F3DB5D /* UIButton+WebCache.m in Sources */, 883E762F1D4897570030E075 /* TemperatureSetModel.m in Sources */, 886B806A1D630BCE00E1B9B3 /* ShopCertificationIntroduceController.m in Sources */, CB484D8422B8BE830075F050 /* P2PClient.m in Sources */, @@ -14870,6 +14973,7 @@ 88605F1C1D8256600037F1AA /* ShareReportCell.m in Sources */, 881672051EA5DE2B00BEBF23 /* UMComSegmentedControl.m in Sources */, CBB0243B23517947002900D5 /* MJPropertyKey.m in Sources */, + C0EA8A1B23AF74F4003DC53B /* UIImage+GIF.m in Sources */, 88F5EFC91D48D08100CC7CAF /* JHRefreshFooterView.m in Sources */, 88645B161E83B7EC00234DB4 /* IfishInfoDetailContentViewCell.m in Sources */, 404D7CEA2238CF77005655F5 /* UIViewController+Swizzling.m in Sources */, @@ -14882,6 +14986,7 @@ 3D1C5136221A9EE10096AE43 /* YooseeCenterViewController.m in Sources */, 8869B3751E6939FE0010F099 /* NJKWebViewProgress.m in Sources */, 881B123A1E1CCA65004C074B /* RuSunHaveHeateViewController.m in Sources */, + C0EA8A1A23AF74F4003DC53B /* SDWebImageDownloader.m in Sources */, CB4820822334E99700A50C92 /* IQUIView+IQKeyboardToolbar.m in Sources */, 886EAC621E2DE91300A4DF27 /* KanHuFirstSectionViewCell.m in Sources */, CBA61686228F9AB100ED380D /* View+MASAdditions.m in Sources */, @@ -14935,7 +15040,6 @@ 883E790F1D48A74F0030E075 /* CreatErWeiMaController.m in Sources */, 881A1D6D1DD571C100BA1AF4 /* IfishP2PLivePlayViewController.m in Sources */, 8871C42F1E6CF9E0000AA49F /* QianDaoViewController.m in Sources */, - 88602DB11E10D97E00F3DB5D /* NSData+ImageContentType.m in Sources */, 8871FABE1EBC544A0038E99A /* ShopCerPart3DoneViewCell.m in Sources */, 88591EE81D655B9E00A1316E /* ProvinceModel.m in Sources */, FA0893022275D9AC0084A609 /* XuanduoSectionHeaderView.m in Sources */, @@ -14943,6 +15047,7 @@ 88883B1C1EF0DAA500CAC0AE /* SongNuo86Name.m in Sources */, 88696FC51E9C81F2005D4AFB /* ShopMemberDetailViewInfoCell.m in Sources */, 3D1C50D8221A9EE00096AE43 /* FXBlurView.m in Sources */, + C0EA8A1823AF74F4003DC53B /* UIImageView+HighlightedWebCache.m in Sources */, 883E76211D4897570030E075 /* BrandModel.m in Sources */, 881671C11EA5DE2B00BEBF23 /* UMComNavigationController.m in Sources */, 88380DB61EB1DA7B00FC7C0D /* ShopGoodsManageViewController.m in Sources */, @@ -14954,7 +15059,6 @@ 883E76401D4897570030E075 /* setWaringTpModel.m in Sources */, 8816720C1EA5DE2B00BEBF23 /* UMComEmojiKeyBoardView.m in Sources */, 881A1D5E1DD41C2200BA1AF4 /* MineKanEditSec2ThredCell.m in Sources */, - CB7D6AB422954E090014E5C7 /* UIColor+HexString.m in Sources */, 88768EAE1ED6C6D800545E23 /* ShopGoodsCollectionCell.m in Sources */, 3D1C50D4221A9EE00096AE43 /* SVPullToRefresh.m in Sources */, 881671CC1EA5DE2B00BEBF23 /* UMComLocationListController.m in Sources */, @@ -14980,7 +15084,6 @@ 8867C8761D49B6BC0029F1FA /* TabBarDeviceShouYeCell.m in Sources */, 885979E21E52E38E003D0E5C /* MinekanHuNotSelectShopController.m in Sources */, E58C998A2081A6930004C42B /* RuiMeiBackMsgUtils.m in Sources */, - 88602DB41E10D97E00F3DB5D /* SDWebImageDecoder.m in Sources */, 889133391ECEB97D00F52EBC /* VideoEditeNameViewCell.m in Sources */, 883E76351D4897570030E075 /* BackmassegeModel.m in Sources */, 881A1D541DD41BEE00BA1AF4 /* MineKanEditSec2FirstCell.m in Sources */, @@ -15007,6 +15110,7 @@ 883E78941D48A5E50030E075 /* IfishMassageModel.m in Sources */, 883E788D1D48A5E50030E075 /* InfoViewNiChengCell.m in Sources */, 885993CF1E307FC80037C540 /* ShopDetailCodeFirstCell.m in Sources */, + C0EA8A2923AF74F4003DC53B /* UIImageView+WebCache.m in Sources */, 8816720A1EA5DE2B00BEBF23 /* UMComShowToast.m in Sources */, 881672201EA5DE2B00BEBF23 /* UINavigationBar+ChangeBackgroundColor.m in Sources */, 881672171EA5DE2B00BEBF23 /* UMComSimpleGridView.m in Sources */, @@ -15043,7 +15147,6 @@ 88F5EFC81D48D08100CC7CAF /* JHRefreshConfig.m in Sources */, 880707F61DE302630076F65A /* LXColorTools.m in Sources */, 3D1C50EE221A9EE00096AE43 /* PAIOUnit.m in Sources */, - 88602DBD1E10D97E00F3DB5D /* UIImageView+HighlightedWebCache.m in Sources */, 883E78411D48A5E50030E075 /* FourControlNormalCenterController.m in Sources */, 88678C6B1E8BBA7C0043DA55 /* LoveFishLiveListBaseViewController.m in Sources */, 88597A0B1E542A0D003D0E5C /* IfishSHopEdite5VCell.m in Sources */, @@ -15051,6 +15154,7 @@ 88C1B2C11DD19B1F00C2C99A /* ZWCollectionViewFlowLayout.m in Sources */, 881671F01EA5DE2B00BEBF23 /* UMComProgressView.m in Sources */, 3D13F835212FE2C200D725F7 /* IFishWaterChangeView.m in Sources */, + C0EA8A1E23AF74F4003DC53B /* SDWebImageCompat.m in Sources */, 88F5EFAB1D48D08100CC7CAF /* AFHTTPSessionManager.m in Sources */, 886EAC581E2DC5BE00A4DF27 /* IFishShopsViewCell.m in Sources */, 88F5EFD21D48D08100CC7CAF /* MMProgressHUD+Class.m in Sources */, @@ -15062,7 +15166,6 @@ 883E76411D4897570030E075 /* ThreeControlBackbackmsgModel.m in Sources */, CBB0243D23517947002900D5 /* MJExtensionConst.m in Sources */, 886484161EE165ED0046C3BD /* RunSunChangeNameViewController.m in Sources */, - 88602DB01E10D97E00F3DB5D /* MKAnnotationView+WebCache.m in Sources */, 8871C4461E6D2819000AA49F /* QianDaoWayTitleViewCell.m in Sources */, 883E78401D48A5E50030E075 /* FourControlDataUnity.m in Sources */, 3D5C436E21339E9D00E15B66 /* IfishHistoryView.m in Sources */, @@ -15086,7 +15189,6 @@ 885979F81E542371003D0E5C /* IfishShopEdite2ViewCell.m in Sources */, 886185C41EF222AC00459AD1 /* ThreeControlName.m in Sources */, 3D8F64FE2158874000F04BD3 /* IfishConfigVo.m in Sources */, - 88602DBA1E10D97E00F3DB5D /* UIImage+GIF.m in Sources */, 883E784A1D48A5E50030E075 /* SongNuoBackMassage.m in Sources */, CB7D6AB122954DE20014E5C7 /* CommonUtils.m in Sources */, 883E78EA1D48A5E50030E075 /* BookViewController.m in Sources */, @@ -15117,6 +15219,7 @@ 883E78541D48A5E50030E075 /* TwoControlnoneTimerViewController.m in Sources */, 3D1C50C3221A9EE00096AE43 /* OBGradientView.m in Sources */, 3D1C50F6221A9EE00096AE43 /* ParamDao.m in Sources */, + C0E7D6C323A1D11500256A10 /* WXApiRequestHandler.mm in Sources */, 8876A58B1BB83447007A4B54 /* AppDelegate.m in Sources */, 3DD7AB4E21E2F2FB0064856A /* split.c in Sources */, 883E79431D48ACFF0030E075 /* Socketsingleton.m in Sources */, @@ -15137,6 +15240,7 @@ 881671C31EA5DE2B00BEBF23 /* UMComViewController.m in Sources */, E567026D21187E7C00E61993 /* ConnectHotspotModel.m in Sources */, 883E785D1D48A5E50030E075 /* XuToWenDuPicview.m in Sources */, + C0E7D6D523A1D16D00256A10 /* WXMediaMessage+messageConstruct.mm in Sources */, CBA61682228F9AB100ED380D /* MASCompositeConstraint.m in Sources */, 880707F51DE302630076F65A /* LXActionView.m in Sources */, 88696FB91E9C69E0005D4AFB /* MemberManageListViewCell.m in Sources */, @@ -15171,6 +15275,7 @@ FAA732D5227BE2B80062C252 /* ReadTimerModel.m in Sources */, 8843E2161EEFEC3D00176C65 /* RunSunControlName.m in Sources */, 881671F11EA5DE2B00BEBF23 /* UMImageProgressView.m in Sources */, + C0EA8A1523AF74F4003DC53B /* SDWebImageManager.m in Sources */, 8860D7991D6D89F2001E544C /* KanHuWorkHeaderViewCell.m in Sources */, 88742C451D6451ED0074F1F8 /* IfishCertifyImgFile.m in Sources */, 3D1C5093221A9EDF0096AE43 /* NetManager.m in Sources */, @@ -15232,17 +15337,18 @@ 88597A271E55901B003D0E5C /* IfishKanHuGuanLiViewController.m in Sources */, 883E787D1D48A5E50030E075 /* InfoViewController.m in Sources */, 883E78301D48A5E50030E075 /* BaseViewController.m in Sources */, + C0EA8A2823AF74F4003DC53B /* NSData+ImageContentType.m in Sources */, 881671A71EA5DE2B00BEBF23 /* UMComTopicDataController.m in Sources */, 881671F81EA5DE2B00BEBF23 /* UMComMutiText.m in Sources */, 3D1C50A5221A9EDF0096AE43 /* CyclePickerView.m in Sources */, CBB0243423517947002900D5 /* NSObject+MJKeyValue.m in Sources */, 883E762B1D4897570030E075 /* setModel.m in Sources */, CB48207B2334E99700A50C92 /* IQTextView.m in Sources */, + C0EA8A2523AF74F4003DC53B /* SDWebImageDownloaderOperation.m in Sources */, 881672151EA5DE2B00BEBF23 /* UMComSimpleCommentEditView.m in Sources */, 8868FE561E66C8BC002F7F33 /* DengJiShuoMingViewTopCell.m in Sources */, 88F5EFB91D48D08100CC7CAF /* UIWebView+AFNetworking.m in Sources */, 8867F5B41E654DFD00AF021C /* DengJiView0Cell.m in Sources */, - 88602DB71E10D97E00F3DB5D /* SDWebImageManager.m in Sources */, 883E785A1D48A5E50030E075 /* XuToLightModel.m in Sources */, 883E785E1D48A5E50030E075 /* CenterViewController.m in Sources */, 883283641EAF224700A47157 /* IfishGoldCoastDetailViewController.m in Sources */, @@ -15253,6 +15359,7 @@ 886FB1B01E5AA02400256332 /* FIshDocsection1TableView2Cell.m in Sources */, 3D1C5103221A9EE00096AE43 /* YooseeNextConnectViewController.mm in Sources */, 402591962238D91400CE4900 /* UINavigationController+Config.m in Sources */, + C0EA8A1123AF74F4003DC53B /* UIImage+WebP.m in Sources */, 882C85A61EB03759001CC414 /* GoldConvertDetailViewCell.m in Sources */, 881477EA1E711B4D00BFB79C /* IfishTaskViewCell.m in Sources */, E5317A1621188F8A0014AFDD /* RestartDeviceModel.m in Sources */, @@ -15272,7 +15379,6 @@ 3D1C17542171BB0700A159A8 /* UICountingLabel.m in Sources */, 88742C2A1D63F4EA0074F1F8 /* ShopCertificationViewController.m in Sources */, E5F1B03F21184F9400A879A1 /* IFishHotpotUDPHelper.m in Sources */, - 88602DBB1E10D97E00F3DB5D /* UIImage+MultiFormat.m in Sources */, 3D1C5143221A9EE10096AE43 /* ifishdeviceListCell.m in Sources */, 881671DF1EA5DE2B00BEBF23 /* UMComUserTableViewCell.m in Sources */, 881671EE1EA5DE2B00BEBF23 /* UMComGridView.m in Sources */, @@ -15280,6 +15386,7 @@ 88742C381D63FA060074F1F8 /* CertifyListThridCell.m in Sources */, 889C25E91E1C83F6004F745D /* RuSunBackMessageUtils.m in Sources */, 8843E2131EEFEBDA00176C65 /* RuSunTempNameViewController.m in Sources */, + C0EA8A2C23AF74F4003DC53B /* UIView+WebCacheOperation.m in Sources */, 883E763C1D4897570030E075 /* manulswitchMSModel.m in Sources */, 883E762E1D4897570030E075 /* ShopNameCellModel.m in Sources */, FA08930F2275F03F0084A609 /* PlusTableViewCell.m in Sources */, @@ -15290,7 +15397,6 @@ 881671F61EA5DE2B00BEBF23 /* UMComMenuControlView.m in Sources */, 883E78F61D48A5E50030E075 /* SetViewController.m in Sources */, 8876A5881BB83447007A4B54 /* main.m in Sources */, - 88602DB21E10D97E00F3DB5D /* SDImageCache.m in Sources */, 889133071ECE999A00F52EBC /* LXCompressionVideo.m in Sources */, 886E3A0B1EEA44B5007C0B04 /* UserExtendataArchaver.m in Sources */, 881F0F4F1D73DF4E0091507E /* BaoGaoViewFirstCell.m in Sources */, @@ -15309,8 +15415,8 @@ 3D1C5099221A9EDF0096AE43 /* GetAlarmRecordResult.m in Sources */, 881671F71EA5DE2B00BEBF23 /* UMComMutiStyleTextView.m in Sources */, FA0892FE2275A1B30084A609 /* Xuanduo2SettingController.m in Sources */, - 88602DB31E10D97E00F3DB5D /* SDWebImageCompat.m in Sources */, 88C1B2C51DD19CE000C2C99A /* KankanListCollectionViewCell.m in Sources */, + C0E7D6C223A1D11500256A10 /* WXApiManager.mm in Sources */, 881A1D701DD5C46A00BA1AF4 /* KanKanListTableCell.m in Sources */, 881671D91EA5DE2B00BEBF23 /* UMComSysPrivateLetterCell.m in Sources */, 883283611EAF21B500A47157 /* IfishGoldCoastViewController.m in Sources */, @@ -15516,11 +15622,11 @@ CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "compiler-default"; CODE_SIGN_ENTITLEMENTS = Ifish/Ifish.entitlements; - CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_IDENTITY = "Apple Development"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - CODE_SIGN_STYLE = Manual; + CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 3; - DEVELOPMENT_TEAM = WFX8GD5HFX; + DEVELOPMENT_TEAM = ""; ENABLE_BITCODE = NO; ENABLE_TESTABILITY = YES; FRAMEWORK_SEARCH_PATHS = ( @@ -15549,6 +15655,7 @@ "$(PROJECT_DIR)/Ifish/AlibcTradeSDK-3.1.1.96/Frameworks", "$(PROJECT_DIR)/Ifish/Bugly", "$(PROJECT_DIR)/Ifish/ALiBCTrade/Frameworks", + "$(PROJECT_DIR)/Ifish/SDWebImage3.8.2", ); GCC_PREFIX_HEADER = "Ifish/Ifish-Prefix.pch"; HEADER_SEARCH_PATHS = ""; @@ -15604,7 +15711,7 @@ PRODUCT_BUNDLE_IDENTIFIER = com.shyuying.Ifish8; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE = ""; - PROVISIONING_PROFILE_SPECIFIER = isfishAppstoreDevelopment; + PROVISIONING_PROFILE_SPECIFIER = ""; TARGETED_DEVICE_FAMILY = 1; USER_HEADER_SEARCH_PATHS = ""; VERSIONING_SYSTEM = "apple-generic"; @@ -15666,6 +15773,7 @@ "$(PROJECT_DIR)/Ifish/AlibcTradeSDK-3.1.1.96/Frameworks", "$(PROJECT_DIR)/Ifish/Bugly", "$(PROJECT_DIR)/Ifish/ALiBCTrade/Frameworks", + "$(PROJECT_DIR)/Ifish/SDWebImage3.8.2", ); GCC_PREFIX_HEADER = "Ifish/Ifish-Prefix.pch"; HEADER_SEARCH_PATHS = ""; diff --git a/Ifish.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/Ifish.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings index 0c67376..949b678 100644 --- a/Ifish.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings +++ b/Ifish.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -1,5 +1,8 @@ - + + BuildSystemType + Original + diff --git a/Ifish/.DS_Store b/Ifish/.DS_Store index 4739c77..94c50d3 100644 Binary files a/Ifish/.DS_Store and b/Ifish/.DS_Store differ diff --git a/Ifish/AlibcTradeSDK-3.1.1.96/Resources/NBResource.bundle/localConfig.json b/Ifish/AlibcTradeSDK-3.1.1.96/Resources/NBResource.bundle/localConfig.json index ef7f433..9e677a4 100644 --- a/Ifish/AlibcTradeSDK-3.1.1.96/Resources/NBResource.bundle/localConfig.json +++ b/Ifish/AlibcTradeSDK-3.1.1.96/Resources/NBResource.bundle/localConfig.json @@ -8,7 +8,7 @@ "albbTradeConfig": { "isSyncForTaoke": "YES", "isForceH5": "NO", - "isNeedAlipay": "YES", + "isNeedAlipay": "NO", "loginDegarade": "NO", "double11OpenType":"0", "sampling":"10000" diff --git a/Ifish/AppDelegate.h b/Ifish/AppDelegate.h index 8142d25..8fbb1ee 100644 --- a/Ifish/AppDelegate.h +++ b/Ifish/AppDelegate.h @@ -55,6 +55,7 @@ @property(nonatomic) BOOL canFullScreen; +@property(nonatomic,assign) BOOL isWechatLogin; @end diff --git a/Ifish/AppDelegate.m b/Ifish/AppDelegate.m index 3f2cc2a..98cc7af 100644 --- a/Ifish/AppDelegate.m +++ b/Ifish/AppDelegate.m @@ -22,6 +22,8 @@ #import "DisconnectNetController.h" //#import "JPUSHService.h" #import "DownLoadViewController.h" +#import "WXApi.h" +#import "WXApiManager.h" //#define RONYUN_APPKEY @"pgyu6atqyxxlu"// 融云appkey #import "ChatroomModel.h" #import "SVProgressHUD.h" @@ -75,7 +77,7 @@ #import "AccountResult.h" #import "ContactDAO.h" #import "IfishMianTabViewController.h" - +#import "SDWebImageDownloader.h" #import "IfishUncaughtExceptionHandler.h" //阿里百川 #import @@ -261,6 +263,7 @@ [[UMSocialManager defaultManager] setPlaform:UMSocialPlatformType_Sina appKey:@"1240247140" appSecret:@"d5825aae9f4c8552b60e112b42c345f3" redirectURL:@"https://sns.whalecloud.com/sina2/callback"]; //http://sns.whalecloud.com/sina2/callback + [WXApi registerApp:@"wxb3b27d653ec3e3cb"]; // 4s 宽高比 0.66 5 6 6p 宽高比 0.56 // 如果是5,autoSizeScaleX=1,autoSizeScaleY=1; @@ -281,8 +284,10 @@ if (kScreenSize.height>480) { NSString *password = [userDefsult objectForKey:@"password"]; NSString *isExit = [userDefsult objectForKey:@"isExit"]; + NSString *unionId=[userDefsult stringForKey:@"unionId"]; + self.isWechatLogin=NO; - if (password) { + if ((password||unionId.length)&&![isExit isEqualToString:@"1"]) { firstLogIn=NO; [self loginAnimated:application]; @@ -366,6 +371,8 @@ if (kScreenSize.height>480) { config.reportLogLevel = BuglyLogLevelWarn; [Bugly startWithAppId:BUGLY_APPID config:config]; + + return YES; } @@ -600,12 +607,26 @@ if (kScreenSize.height>480) { openURL:url options:options]) { //处理其他app跳转到自己的app,如果百川处理过会返回YES - BOOL result = [[UMSocialManager defaultManager] handleOpenURL:url]; - return result; + //友盟会消费掉code所以登录时,不给友盟处理 + if (self.isWechatLogin) + { + return [WXApi handleOpenURL:url delegate:[WXApiManager sharedManager]]; + } + + return [[UMSocialManager defaultManager] handleOpenURL:url]; } - return YES; + return [WXApi handleOpenURL:url delegate:[WXApiManager sharedManager]]; +} +- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url { + return [WXApi handleOpenURL:url delegate:[WXApiManager sharedManager]]; +} + +- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation { + return [WXApi handleOpenURL:url delegate:[WXApiManager sharedManager]]; } + + @end diff --git a/Ifish/Common/CommonUtils.h b/Ifish/Common/CommonUtils.h index dc40a86..37d9ead 100644 --- a/Ifish/Common/CommonUtils.h +++ b/Ifish/Common/CommonUtils.h @@ -60,6 +60,8 @@ typedef enum{ + (int)convertToInt:(NSString*)strtemp; //校验字符串是否含空格 + (BOOL)checkEmptyString:(NSString *)string ; ++(NSString*)getNotNilStr:(NSString*)str; ++ (BOOL)isIphoneX; //校验是否是数字 +(BOOL)isNumber:(NSString *)str; //******************************输入内容正确性校验*****************************************// diff --git a/Ifish/Common/CommonUtils.m b/Ifish/Common/CommonUtils.m index 8118565..ed4686d 100644 --- a/Ifish/Common/CommonUtils.m +++ b/Ifish/Common/CommonUtils.m @@ -508,7 +508,22 @@ CGAffineTransform GetCGAffineTransformRotateAroundPoint(float centerX, float ce } return NO; } - ++(NSString*)getNotNilStr:(NSString*)str{ + if ([str isKindOfClass:[NSString class]] && str.length>0) { + return str; + }else if([str isKindOfClass:[NSNumber class]] && str){ + return ((NSNumber*)str).stringValue; + }else{ + return @""; + } +} ++ (BOOL)isIphoneX { +if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone) { + return [[UIScreen mainScreen] bounds].size.height >= 812.0f; +}else{ + return NO; + } +} //判断是否为空或全为空格 + (BOOL)isEmptyWithString:(NSString *)str { if (str == nil) { diff --git a/Ifish/Ifish-Prefix.pch b/Ifish/Ifish-Prefix.pch index a86cb96..ac843c7 100644 --- a/Ifish/Ifish-Prefix.pch +++ b/Ifish/Ifish-Prefix.pch @@ -28,6 +28,7 @@ #import "CommonMacros.h" #import "FuncUserDefault.h" #import "CommonUtils.h" + #define NTES_USE_CLEAR_BAR - (BOOL)useClearBar{return YES;} #define NTES_FORBID_INTERACTIVE_POP - (BOOL)forbidInteractivePop{return YES;} diff --git a/Ifish/Info.plist b/Ifish/Info.plist index b8adc97..f9fa328 100644 --- a/Ifish/Info.plist +++ b/Ifish/Info.plist @@ -17,7 +17,7 @@ CFBundlePackageType APPL CFBundleShortVersionString - 5.1.3 + 5.1.4 CFBundleSignature ???? CFBundleURLTypes @@ -70,7 +70,7 @@ CFBundleVersion - 9 + 19 ITSAppUsesNonExemptEncryption LSApplicationCategoryType @@ -369,8 +369,6 @@ NSAllowsArbitraryLoads - NSAllowsArbitraryLoadsInWebContent - NSCameraUsageDescription 爱鱼奇需要您的同意,才能使用相机,以使用图片上传或扫一扫等功能 diff --git a/Ifish/UMSocial/SocialLibraries/WeChat/WechatSDK/Helper/Constant.h b/Ifish/UMSocial/SocialLibraries/WeChat/WechatSDK/Helper/Constant.h new file mode 100644 index 0000000..9915101 --- /dev/null +++ b/Ifish/UMSocial/SocialLibraries/WeChat/WechatSDK/Helper/Constant.h @@ -0,0 +1,64 @@ +// +// Constant.h +// SDKSample +// +// Created by Jeason on 15/7/14. +// +// + +#ifndef SDKSample_Constant_h +#define SDKSample_Constant_h + +#define RGBCOLOR(r,g,b) [UIColor colorWithRed:(r)/255.0f green:(g)/255.0f blue:(b)/255.0f alpha:1] + +#define TIPSLABEL_TAG 10086 +#define SCREEN_WIDTH [[UIScreen mainScreen] bounds].size.width +#define SCREEN_HEIGHT [[UIScreen mainScreen] bounds].size.height +#define BUFFER_SIZE 1024 * 100 + +static const int kHeadViewHeight = 135; +static const int kSceneViewHeight = 100; + +static NSString *kTextMessage = @"人文的东西并不是体现在你看得到的方面,它更多的体现在你看不到的那些方面,它会影响每一个功能,这才是最本质的。但是,对这点可能很多人没有思考过,以为人文的东西就是我们搞一个很小清新的图片什么的。”综合来看,人文的东西其实是贯穿整个产品的脉络,或者说是它的灵魂所在。"; + +static NSString *kImageTagName = @"WECHAT_TAG_JUMP_APP"; +static NSString *kMessageExt = @"这是第三方带的测试字段"; +static NSString *kMessageAction = @"dotalist"; + +static NSString *kLinkURL = @"http://tech.qq.com/zt2012/tmtdecode/252.htm"; +static NSString *kLinkTagName = @"WECHAT_TAG_JUMP_SHOWRANK"; +static NSString *kLinkTitle = @"专访张小龙:产品之上的世界观"; +static NSString *kLinkDescription = @"微信的平台化发展方向是否真的会让这个原本简洁的产品变得臃肿?在国际化发展方向上,微信面临的问题真的是文化差异壁垒吗?腾讯高级副总裁、微信产品负责人张小龙给出了自己的回复。"; + +static NSString *kMusicURL = @"http://y.qq.com/i/song.html#p=7B22736F6E675F4E616D65223A22E4B880E697A0E68980E69C89222C22736F6E675F5761704C69766555524C223A22687474703A2F2F74736D7573696334382E74632E71712E636F6D2F586B30305156342F4141414130414141414E5430577532394D7A59344D7A63774D4C6735586A4C517747335A50676F47443864704151526643473444442F4E653765776B617A733D2F31303130333334372E6D34613F7569643D3233343734363930373526616D703B63743D3026616D703B636869643D30222C22736F6E675F5769666955524C223A22687474703A2F2F73747265616D31342E71716D757369632E71712E636F6D2F33303130333334372E6D7033222C226E657454797065223A2277696669222C22736F6E675F416C62756D223A22E4B880E697A0E68980E69C89222C22736F6E675F4944223A3130333334372C22736F6E675F54797065223A312C22736F6E675F53696E676572223A22E5B494E581A5222C22736F6E675F576170446F776E4C6F616455524C223A22687474703A2F2F74736D757369633132382E74632E71712E636F6D2F586C464E4D313574414141416A41414141477A4C36445039536A457A525467304E7A38774E446E752B6473483833344843756B5041576B6D48316C4A434E626F4D34394E4E7A754450444A647A7A45304F513D3D2F33303130333334372E6D70333F7569643D3233343734363930373526616D703B63743D3026616D703B636869643D3026616D703B73747265616D5F706F733D35227D"; +static NSString *kMusicDataURL = @"http://stream20.qqmusic.qq.com/32464723.mp3"; +static NSString *kMusicTitle = @"一无所有"; +static NSString *kMusicDescription = @"崔健"; + +static NSString *kVideoURL = @"http://v.youku.com/v_show/id_XNTUxNDY1NDY4.html"; +static NSString *kVideoTitle = @"乔布斯访谈"; +static NSString *kVideoDescription = @"饿着肚皮,傻逼着。"; + +static NSString *kAPPContentTitle = @"App消息"; +static NSString *kAPPContentDescription = @"这种消息只有App自己才能理解,由App指定打开方式"; +static NSString *kAppContentExInfo = @"extend info"; +static NSString *kAppContnetExURL = @"http://weixin.qq.com"; +static NSString *kAppMessageExt = @"这是第三方带的测试字段"; +static NSString *kAppMessageAction = @"dotaliTest"; + +static NSString *kAuthScope = @"snsapi_message,snsapi_userinfo,snsapi_friend,snsapi_contact"; +static NSString *kAuthOpenID = @"0c806938e2413ce73eef92cc3"; +static NSString *kAuthState = @"xxx"; + +static NSString *kFileTitle = @"iphone4.pdf"; +static NSString *kFileDescription = @"Pro CoreData"; +static NSString *kFileExtension = @"pdf"; +static NSString *kFileName = @"iphone4"; + + +static NSString *kProfileExtMsg = @"http://we.qq.com/d/AQCIc9a3EqRfb19z8WnLB6iFNCxX5bO2S3lHwMQL"; +static NSString *kBizWebviewExtMsg = @"KOoCKdavezBjdj2wJZsq67N2j_g3XEQ5JP_pkLhBYS4"; + +static NSString *kMiniProgramTitle = @"小程序title"; +static NSString *kMiniProgramDesc = @"小程序Desc"; +#endif diff --git a/Ifish/UMSocial/SocialLibraries/WeChat/WechatSDK/Helper/GetMessageFromWXResp+responseWithTextOrMediaMessage.h b/Ifish/UMSocial/SocialLibraries/WeChat/WechatSDK/Helper/GetMessageFromWXResp+responseWithTextOrMediaMessage.h new file mode 100644 index 0000000..3d483a4 --- /dev/null +++ b/Ifish/UMSocial/SocialLibraries/WeChat/WechatSDK/Helper/GetMessageFromWXResp+responseWithTextOrMediaMessage.h @@ -0,0 +1,16 @@ +// +// GetMessageFromWXResp+responseWithTextOrMediaMessage.h +// SDKSample +// +// Created by Jeason on 15/7/14. +// +// + +#import "WXApiObject.h" + +@interface GetMessageFromWXResp (responseWithTextOrMediaMessage) + ++ (GetMessageFromWXResp *)responseWithText:(NSString *)text + OrMediaMessage:(WXMediaMessage *)message + bText:(BOOL)bText; +@end diff --git a/Ifish/UMSocial/SocialLibraries/WeChat/WechatSDK/Helper/GetMessageFromWXResp+responseWithTextOrMediaMessage.mm b/Ifish/UMSocial/SocialLibraries/WeChat/WechatSDK/Helper/GetMessageFromWXResp+responseWithTextOrMediaMessage.mm new file mode 100644 index 0000000..e943017 --- /dev/null +++ b/Ifish/UMSocial/SocialLibraries/WeChat/WechatSDK/Helper/GetMessageFromWXResp+responseWithTextOrMediaMessage.mm @@ -0,0 +1,25 @@ +// +// GetMessageFromWXResp+responseWithTextOrMediaMessage.m +// SDKSample +// +// Created by Jeason on 15/7/14. +// +// + +#import "GetMessageFromWXResp+responseWithTextOrMediaMessage.h" + +@implementation GetMessageFromWXResp (responseWithTextOrMediaMessage) + ++ (GetMessageFromWXResp *)responseWithText:(NSString *)text + OrMediaMessage:(WXMediaMessage *)message + bText:(BOOL)bText { + GetMessageFromWXResp *resp = [[GetMessageFromWXResp alloc] init]; + resp.bText = bText; + if (bText) + resp.text = text; + else + resp.message = message; + return resp; +} + +@end diff --git a/Ifish/UMSocial/SocialLibraries/WeChat/WechatSDK/Helper/SendMessageToWXReq+requestWithTextOrMediaMessage.h b/Ifish/UMSocial/SocialLibraries/WeChat/WechatSDK/Helper/SendMessageToWXReq+requestWithTextOrMediaMessage.h new file mode 100644 index 0000000..10f064b --- /dev/null +++ b/Ifish/UMSocial/SocialLibraries/WeChat/WechatSDK/Helper/SendMessageToWXReq+requestWithTextOrMediaMessage.h @@ -0,0 +1,17 @@ +// +// SendMessageToWXReq+requestWithTextOrMediaMessage.h +// SDKSample +// +// Created by Jeason on 15/7/14. +// +// + +#import "WXApiObject.h" + +@interface SendMessageToWXReq (requestWithTextOrMediaMessage) + ++ (SendMessageToWXReq *)requestWithText:(NSString *)text + OrMediaMessage:(WXMediaMessage *)message + bText:(BOOL)bText + InScene:(enum WXScene)scene; +@end diff --git a/Ifish/UMSocial/SocialLibraries/WeChat/WechatSDK/Helper/SendMessageToWXReq+requestWithTextOrMediaMessage.mm b/Ifish/UMSocial/SocialLibraries/WeChat/WechatSDK/Helper/SendMessageToWXReq+requestWithTextOrMediaMessage.mm new file mode 100644 index 0000000..446f718 --- /dev/null +++ b/Ifish/UMSocial/SocialLibraries/WeChat/WechatSDK/Helper/SendMessageToWXReq+requestWithTextOrMediaMessage.mm @@ -0,0 +1,27 @@ +// +// SendMessageToWXReq+requestWithTextOrMediaMessage.m +// SDKSample +// +// Created by Jeason on 15/7/14. +// +// + +#import "SendMessageToWXReq+requestWithTextOrMediaMessage.h" + +@implementation SendMessageToWXReq (requestWithTextOrMediaMessage) + ++ (SendMessageToWXReq *)requestWithText:(NSString *)text + OrMediaMessage:(WXMediaMessage *)message + bText:(BOOL)bText + InScene:(enum WXScene)scene { + SendMessageToWXReq *req = [[SendMessageToWXReq alloc] init]; + req.bText = bText; + req.scene = scene; + if (bText) + req.text = text; + else + req.message = message; + return req; +} + +@end diff --git a/Ifish/UMSocial/SocialLibraries/WeChat/WechatSDK/Helper/UIAlertView+WX.h b/Ifish/UMSocial/SocialLibraries/WeChat/WechatSDK/Helper/UIAlertView+WX.h new file mode 100644 index 0000000..e65172a --- /dev/null +++ b/Ifish/UMSocial/SocialLibraries/WeChat/WechatSDK/Helper/UIAlertView+WX.h @@ -0,0 +1,25 @@ +// +// UIAlertView+WX.h +// SDKSample +// +// Created by liuyunxuan on 2017/2/10. +// +// + +#import + +typedef void(^WXAlertSureBlock)(UIAlertView *alertView,NSString *text); + +@interface UIAlertView (WX) + +///请求输入内容的alert ++ (void)requestWithTitle:(NSString *)title + message:(NSString *)message + defaultText:(NSString *)defaultText + sure:(WXAlertSureBlock)sure; + +// 只返回确定的结果 ++ (void)showWithTitle:(NSString *)title + message:(NSString *)message + sure:(WXAlertSureBlock)sure; +@end diff --git a/Ifish/UMSocial/SocialLibraries/WeChat/WechatSDK/Helper/UIAlertView+WX.mm b/Ifish/UMSocial/SocialLibraries/WeChat/WechatSDK/Helper/UIAlertView+WX.mm new file mode 100644 index 0000000..be5bf77 --- /dev/null +++ b/Ifish/UMSocial/SocialLibraries/WeChat/WechatSDK/Helper/UIAlertView+WX.mm @@ -0,0 +1,87 @@ +// +// UIAlertView+WX.m +// SDKSample +// +// Created by liuyunxuan on 2017/2/10. +// +// + +#import "UIAlertView+WX.h" +#import + + +static const void *WXAlertSureKey = &WXAlertSureKey; +static const NSInteger kSureTag = 1010; +static const NSInteger kRequestTag = 1020; + +@implementation UIAlertView (WX) + +/// withOut delegate ++ (void)requestWithTitle:(NSString *)title + message:(NSString *)message + defaultText:(NSString *)defaultText + sure:(WXAlertSureBlock)sure; +{ + UIAlertView *view = [[UIAlertView alloc] initWithTitle:title + message:message + delegate:nil + cancelButtonTitle:@"取消" + otherButtonTitles:@"确认", nil]; + view.delegate = view; + view.alertViewStyle = UIAlertViewStylePlainTextInput; + [view setSureBlock:sure]; + [view textFieldAtIndex:0].text = defaultText; + view.tag = kRequestTag; + [view show]; +} + ++ (void)showWithTitle:(NSString *)title + message:(NSString *)message + sure:(WXAlertSureBlock)sure +{ + UIAlertView *view = [[UIAlertView alloc] initWithTitle:title + message:message + delegate:nil + cancelButtonTitle:@"取消" + otherButtonTitles:@"确认", nil]; + view.delegate = view; + view.tag = kSureTag; + [view setSureBlock:sure]; + [view show]; +} + +#pragma mark - delegate +- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex +{ + if (buttonIndex == alertView.cancelButtonIndex) + { + return; + } + WXAlertSureBlock sureBlock = [self sureBlock]; + if (alertView.tag == kRequestTag) + { + if (sureBlock) + { + sureBlock(alertView,[alertView textFieldAtIndex:0].text); + } + } + else if (alertView.tag == kSureTag) + { + if (sureBlock) + { + sureBlock(alertView,nil); + } + } +} + +#pragma mark - private method +-(void)setSureBlock:(WXAlertSureBlock)block +{ + objc_setAssociatedObject(self, WXAlertSureKey, block, OBJC_ASSOCIATION_RETAIN_NONATOMIC); +} + +-(WXAlertSureBlock)sureBlock +{ + return objc_getAssociatedObject(self, WXAlertSureKey); +} +@end diff --git a/Ifish/UMSocial/SocialLibraries/WeChat/WechatSDK/Helper/WXApiManager.h b/Ifish/UMSocial/SocialLibraries/WeChat/WechatSDK/Helper/WXApiManager.h new file mode 100644 index 0000000..a34aa32 --- /dev/null +++ b/Ifish/UMSocial/SocialLibraries/WeChat/WechatSDK/Helper/WXApiManager.h @@ -0,0 +1,39 @@ +// +// WXApiManager.h +// SDKSample +// +// Created by Jeason on 16/07/2015. +// +// + +#import +#import "WXApi.h" + +@protocol WXApiManagerDelegate + +@optional + +- (void)managerDidRecvShowMessageReq:(ShowMessageFromWXReq *)request; + +- (void)managerDidRecvLaunchFromWXReq:(LaunchFromWXReq *)request; + +- (void)managerDidRecvMessageResponse:(SendMessageToWXResp *)response; + +- (void)managerDidRecvAuthResponse:(SendAuthResp *)response; + +- (void)managerDidRecvAddCardResponse:(AddCardToWXCardPackageResp *)response; + +- (void)managerDidRecvChooseCardResponse:(WXChooseCardResp *)response; + +- (void)managerDidRecvChooseInvoiceResponse:(WXChooseInvoiceResp *)response; + + +@end + +@interface WXApiManager : NSObject + +@property (nonatomic, assign) id delegate; + ++ (instancetype)sharedManager; + +@end diff --git a/Ifish/UMSocial/SocialLibraries/WeChat/WechatSDK/Helper/WXApiManager.mm b/Ifish/UMSocial/SocialLibraries/WeChat/WechatSDK/Helper/WXApiManager.mm new file mode 100644 index 0000000..89717ed --- /dev/null +++ b/Ifish/UMSocial/SocialLibraries/WeChat/WechatSDK/Helper/WXApiManager.mm @@ -0,0 +1,74 @@ +// +// WXApiManager.m +// SDKSample +// +// Created by Jeason on 16/07/2015. +// +// + +#import "WXApiManager.h" + +@implementation WXApiManager + +#pragma mark - LifeCycle ++(instancetype)sharedManager { + static dispatch_once_t onceToken; + static WXApiManager *instance; + dispatch_once(&onceToken, ^{ + instance = [[WXApiManager alloc] init]; + }); + return instance; +} + +#pragma mark - WXApiDelegate +- (void)onResp:(BaseResp *)resp { + if ([resp isKindOfClass:[SendMessageToWXResp class]]) { + if (_delegate + && [_delegate respondsToSelector:@selector(managerDidRecvMessageResponse:)]) { + SendMessageToWXResp *messageResp = (SendMessageToWXResp *)resp; + [_delegate managerDidRecvMessageResponse:messageResp]; + } + } else if ([resp isKindOfClass:[SendAuthResp class]]) { + if (_delegate + && [_delegate respondsToSelector:@selector(managerDidRecvAuthResponse:)]) { + SendAuthResp *authResp = (SendAuthResp *)resp; + [_delegate managerDidRecvAuthResponse:authResp]; + } + } else if ([resp isKindOfClass:[AddCardToWXCardPackageResp class]]) { + if (_delegate + && [_delegate respondsToSelector:@selector(managerDidRecvAddCardResponse:)]) { + AddCardToWXCardPackageResp *addCardResp = (AddCardToWXCardPackageResp *)resp; + [_delegate managerDidRecvAddCardResponse:addCardResp]; + } + } else if ([resp isKindOfClass:[WXChooseCardResp class]]) { + if (_delegate + && [_delegate respondsToSelector:@selector(managerDidRecvChooseCardResponse:)]) { + WXChooseCardResp *chooseCardResp = (WXChooseCardResp *)resp; + [_delegate managerDidRecvChooseCardResponse:chooseCardResp]; + } + }else if ([resp isKindOfClass:[WXChooseInvoiceResp class]]){ + if (_delegate + && [_delegate respondsToSelector:@selector(managerDidRecvChooseInvoiceResponse:)]) { + WXChooseInvoiceResp *chooseInvoiceResp = (WXChooseInvoiceResp *)resp; + [_delegate managerDidRecvChooseInvoiceResponse:chooseInvoiceResp]; + } + } +} + +- (void)onReq:(BaseReq *)req { + if ([req isKindOfClass:[ShowMessageFromWXReq class]]) { + if (_delegate + && [_delegate respondsToSelector:@selector(managerDidRecvShowMessageReq:)]) { + ShowMessageFromWXReq *showMessageReq = (ShowMessageFromWXReq *)req; + [_delegate managerDidRecvShowMessageReq:showMessageReq]; + } + } else if ([req isKindOfClass:[LaunchFromWXReq class]]) { + if (_delegate + && [_delegate respondsToSelector:@selector(managerDidRecvLaunchFromWXReq:)]) { + LaunchFromWXReq *launchReq = (LaunchFromWXReq *)req; + [_delegate managerDidRecvLaunchFromWXReq:launchReq]; + } + } +} + +@end diff --git a/Ifish/UMSocial/SocialLibraries/WeChat/WechatSDK/Helper/WXApiRequestHandler.h b/Ifish/UMSocial/SocialLibraries/WeChat/WechatSDK/Helper/WXApiRequestHandler.h new file mode 100644 index 0000000..2adf575 --- /dev/null +++ b/Ifish/UMSocial/SocialLibraries/WeChat/WechatSDK/Helper/WXApiRequestHandler.h @@ -0,0 +1,87 @@ +// +// WXApiManager.h +// SDKSample +// +// Created by Jeason on 15/7/14. +// +// + +#import +#import "WXApiObject.h" + +@interface WXApiRequestHandler : NSObject + ++ (void)sendText:(NSString *)text + InScene:(enum WXScene)scene; + ++ (void)sendImageData:(NSData *)imageData + TagName:(NSString *)tagName + MessageExt:(NSString *)messageExt + Action:(NSString *)action + ThumbImage:(UIImage *)thumbImage + InScene:(enum WXScene)scene; + ++ (void)sendLinkURL:(NSString *)urlString + TagName:(NSString *)tagName + Title:(NSString *)title + Description:(NSString *)description + ThumbImage:(UIImage *)thumbImage + InScene:(enum WXScene)scene; + ++ (void)sendMusicURL:(NSString *)musicURL + dataURL:(NSString *)dataURL + Title:(NSString *)title + Description:(NSString *)description + ThumbImage:(UIImage *)thumbImage + InScene:(enum WXScene)scene; + ++ (void)sendVideoURL:(NSString *)videoURL + Title:(NSString *)title + Description:(NSString *)description + ThumbImage:(UIImage *)thumbImage + InScene:(enum WXScene)scene; + ++ (void)sendEmotionData:(NSData *)emotionData + ThumbImage:(UIImage *)thumbImage + InScene:(enum WXScene)scene; + ++ (void)sendFileData:(NSData *)fileData + fileExtension:(NSString *)extension + Title:(NSString *)title + Description:(NSString *)description + ThumbImage:(UIImage *)thumbImage + InScene:(enum WXScene)scene; + + + ++ (void)sendAppContentData:(NSData *)data + ExtInfo:(NSString *)info + ExtURL:(NSString *)url + Title:(NSString *)title + Description:(NSString *)description + MessageExt:(NSString *)messageExt + MessageAction:(NSString *)action + ThumbImage:(UIImage *)thumbImage + InScene:(enum WXScene)scene; + ++ (void)addCardsToCardPackage:(NSArray *)cardIds cardExts:(NSArray *)cardExts; + ++ (void)sendAuthRequestScope:(NSString *)scope + State:(NSString *)state + OpenID:(NSString *)openID + InViewController:(UIViewController *)viewController; + ++ (void)chooseCard:(NSString *)appid + cardSign:(NSString *)cardSign + nonceStr:(NSString *)nonceStr + signType:(NSString *)signType + timestamp:(UInt32)timestamp; + ++ (void)openUrl:(NSString *)url; + ++ (void)chooseInvoice:(NSString *)appid + cardSign:(NSString *)cardSign + nonceStr:(NSString *)nonceStr + signType:(NSString *)signType + timestamp:(UInt32)timestamp; +@end diff --git a/Ifish/UMSocial/SocialLibraries/WeChat/WechatSDK/Helper/WXApiRequestHandler.mm b/Ifish/UMSocial/SocialLibraries/WeChat/WechatSDK/Helper/WXApiRequestHandler.mm new file mode 100644 index 0000000..2a94650 --- /dev/null +++ b/Ifish/UMSocial/SocialLibraries/WeChat/WechatSDK/Helper/WXApiRequestHandler.mm @@ -0,0 +1,280 @@ +// +// WXApiManager.m +// SDKSample +// +// Created by Jeason on 15/7/14. +// +// + +#import "WXApi.h" +#import "WXApiRequestHandler.h" +#import "WXApiManager.h" +#import "SendMessageToWXReq+requestWithTextOrMediaMessage.h" +#import "WXMediaMessage+messageConstruct.h" + +@implementation WXApiRequestHandler + +#pragma mark - Public Methods ++ (void)sendText:(NSString *)text + InScene:(enum WXScene)scene { + SendMessageToWXReq *req = [SendMessageToWXReq requestWithText:text + OrMediaMessage:nil + bText:YES + InScene:scene]; + [WXApi sendReq:req]; +} + ++ (void)sendImageData:(NSData *)imageData + TagName:(NSString *)tagName + MessageExt:(NSString *)messageExt + Action:(NSString *)action + ThumbImage:(UIImage *)thumbImage + InScene:(enum WXScene)scene { + WXImageObject *ext = [WXImageObject object]; + ext.imageData = imageData; + + WXMediaMessage *message = [WXMediaMessage messageWithTitle:nil + Description:nil + Object:ext + MessageExt:messageExt + MessageAction:action + ThumbImage:thumbImage + MediaTag:tagName]; + + SendMessageToWXReq* req = [SendMessageToWXReq requestWithText:nil + OrMediaMessage:message + bText:NO + InScene:scene]; + + [WXApi sendReq:req ]; +} + ++ (void)sendLinkURL:(NSString *)urlString + TagName:(NSString *)tagName + Title:(NSString *)title + Description:(NSString *)description + ThumbImage:(UIImage *)thumbImage + InScene:(enum WXScene)scene { + WXWebpageObject *ext = [WXWebpageObject object]; + ext.webpageUrl = urlString; + + WXMediaMessage *message = [WXMediaMessage messageWithTitle:title + Description:description + Object:ext + MessageExt:nil + MessageAction:nil + ThumbImage:thumbImage + MediaTag:tagName]; + + SendMessageToWXReq* req = [SendMessageToWXReq requestWithText:nil + OrMediaMessage:message + bText:NO + InScene:scene]; + [WXApi sendReq:req ]; +} + ++ (void)sendMusicURL:(NSString *)musicURL + dataURL:(NSString *)dataURL + Title:(NSString *)title + Description:(NSString *)description + ThumbImage:(UIImage *)thumbImage + InScene:(enum WXScene)scene { + WXMusicObject *ext = [WXMusicObject object]; + ext.musicUrl = musicURL; + ext.musicDataUrl = dataURL; + + WXMediaMessage *message = [WXMediaMessage messageWithTitle:title + Description:description + Object:ext + MessageExt:nil + MessageAction:nil + ThumbImage:thumbImage + MediaTag:nil]; + + SendMessageToWXReq* req = [SendMessageToWXReq requestWithText:nil + OrMediaMessage:message + bText:NO + InScene:scene]; + + [WXApi sendReq:req ]; +} + ++ (void)sendVideoURL:(NSString *)videoURL + Title:(NSString *)title + Description:(NSString *)description + ThumbImage:(UIImage *)thumbImage + InScene:(enum WXScene)scene { + WXMediaMessage *message = [WXMediaMessage message]; + message.title = title; + message.description = description; + [message setThumbImage:thumbImage]; + + WXVideoObject *ext = [WXVideoObject object]; + ext.videoUrl = videoURL; + + message.mediaObject = ext; + + SendMessageToWXReq* req = [SendMessageToWXReq requestWithText:nil + OrMediaMessage:message + bText:NO + InScene:scene]; + [WXApi sendReq:req ]; +} + ++ (void)sendEmotionData:(NSData *)emotionData + ThumbImage:(UIImage *)thumbImage + InScene:(enum WXScene)scene { + WXMediaMessage *message = [WXMediaMessage message]; + [message setThumbImage:thumbImage]; + + WXEmoticonObject *ext = [WXEmoticonObject object]; + ext.emoticonData = emotionData; + + message.mediaObject = ext; + + SendMessageToWXReq* req = [SendMessageToWXReq requestWithText:nil + OrMediaMessage:message + bText:NO + InScene:scene]; + [WXApi sendReq:req ]; +} + ++ (void)sendFileData:(NSData *)fileData + fileExtension:(NSString *)extension + Title:(NSString *)title + Description:(NSString *)description + ThumbImage:(UIImage *)thumbImage + InScene:(enum WXScene)scene { + WXMediaMessage *message = [WXMediaMessage message]; + message.title = title; + message.description = description; + [message setThumbImage:thumbImage]; + + WXFileObject *ext = [WXFileObject object]; + ext.fileExtension = @"pdf"; + ext.fileData = fileData; + + message.mediaObject = ext; + + SendMessageToWXReq* req = [SendMessageToWXReq requestWithText:nil + OrMediaMessage:message + bText:NO + InScene:scene]; + [WXApi sendReq:req ]; +} + + + + + + + + ++ (void)sendAppContentData:(NSData *)data + ExtInfo:(NSString *)info + ExtURL:(NSString *)url + Title:(NSString *)title + Description:(NSString *)description + MessageExt:(NSString *)messageExt + MessageAction:(NSString *)action + ThumbImage:(UIImage *)thumbImage + InScene:(enum WXScene)scene { + WXAppExtendObject *ext = [WXAppExtendObject object]; + ext.extInfo = info; + ext.url = url; + ext.fileData = data; + + WXMediaMessage *message = [WXMediaMessage messageWithTitle:title + Description:description + Object:ext + MessageExt:messageExt + MessageAction:action + ThumbImage:thumbImage + MediaTag:nil]; + + SendMessageToWXReq* req = [SendMessageToWXReq requestWithText:nil + OrMediaMessage:message + bText:NO + InScene:scene]; + [WXApi sendReq:req ]; + +} + ++ (void)addCardsToCardPackage:(NSArray *)cardIds cardExts:(NSArray *)cardExts +{ + NSMutableArray *cardItems = [NSMutableArray array]; + for (NSString *cardId in cardIds) { + WXCardItem *item = [[WXCardItem alloc] init]; + item.cardId = cardId; + item.appID = @"wxf8b4f85f3a794e77"; + [cardItems addObject:item]; + } + + for (NSInteger index = 0; index < cardItems.count; index++) { + WXCardItem *item = cardItems[index]; + NSString *ext = cardExts[index]; + item.extMsg = ext; + } + + AddCardToWXCardPackageReq *req = [[AddCardToWXCardPackageReq alloc] init]; + req.cardAry = cardItems; + [WXApi sendReq:req ]; +} + ++ (void)chooseCard:(NSString *)appid + cardSign:(NSString *)cardSign + nonceStr:(NSString *)nonceStr + signType:(NSString *)signType + timestamp:(UInt32)timestamp +{ + WXChooseCardReq *chooseCardReq = [[WXChooseCardReq alloc] init]; + chooseCardReq.appID = appid; + chooseCardReq.cardSign = cardSign; + chooseCardReq.nonceStr = nonceStr; + chooseCardReq.signType = signType; + chooseCardReq.timeStamp = timestamp; + [WXApi sendReq:chooseCardReq ]; + +} + ++ (void)sendAuthRequestScope:(NSString *)scope + State:(NSString *)state + OpenID:(NSString *)openID + InViewController:(UIViewController *)viewController +{ + SendAuthReq* req = [[SendAuthReq alloc] init]; + req.scope = scope; // @"post_timeline,sns" + req.state = state; + req.openID = openID; + + [WXApi sendAuthReq:req + viewController:viewController + delegate:[WXApiManager sharedManager] + ]; +} + ++ (void)openUrl:(NSString *)url +{ + OpenWebviewReq *req = [[OpenWebviewReq alloc] init]; + req.url = url; + [WXApi sendReq:req ]; +} + ++ (void)chooseInvoice:(NSString *)appid + cardSign:(NSString *)cardSign + nonceStr:(NSString *)nonceStr + signType:(NSString *)signType + timestamp:(UInt32)timestamp +{ + WXChooseInvoiceReq *chooseInvoiceReq = [[WXChooseInvoiceReq alloc] init]; + chooseInvoiceReq.appID = appid; + chooseInvoiceReq.cardSign = cardSign; + chooseInvoiceReq.nonceStr = nonceStr; + chooseInvoiceReq.signType = signType; +// chooseCardReq.cardType = @"INVOICE"; + chooseInvoiceReq.timeStamp = timestamp; +// chooseCardReq.canMultiSelect = 1; + [WXApi sendReq:chooseInvoiceReq ]; +} + +@end diff --git a/Ifish/UMSocial/SocialLibraries/WeChat/WechatSDK/Helper/WXMediaMessage+messageConstruct.h b/Ifish/UMSocial/SocialLibraries/WeChat/WechatSDK/Helper/WXMediaMessage+messageConstruct.h new file mode 100644 index 0000000..683ab0d --- /dev/null +++ b/Ifish/UMSocial/SocialLibraries/WeChat/WechatSDK/Helper/WXMediaMessage+messageConstruct.h @@ -0,0 +1,20 @@ +// +// WXMediaMessage+messageConstruct.h +// SDKSample +// +// Created by Jeason on 15/7/14. +// +// + +#import "WXApiObject.h" + +@interface WXMediaMessage (messageConstruct) + ++ (WXMediaMessage *)messageWithTitle:(NSString *)title + Description:(NSString *)description + Object:(id)mediaObject + MessageExt:(NSString *)messageExt + MessageAction:(NSString *)action + ThumbImage:(UIImage *)thumbImage + MediaTag:(NSString *)tagName; +@end diff --git a/Ifish/UMSocial/SocialLibraries/WeChat/WechatSDK/Helper/WXMediaMessage+messageConstruct.mm b/Ifish/UMSocial/SocialLibraries/WeChat/WechatSDK/Helper/WXMediaMessage+messageConstruct.mm new file mode 100644 index 0000000..9fa4150 --- /dev/null +++ b/Ifish/UMSocial/SocialLibraries/WeChat/WechatSDK/Helper/WXMediaMessage+messageConstruct.mm @@ -0,0 +1,31 @@ +// +// WXMediaMessage+messageConstruct.m +// SDKSample +// +// Created by Jeason on 15/7/14. +// +// + +#import "WXMediaMessage+messageConstruct.h" + +@implementation WXMediaMessage (messageConstruct) + ++ (WXMediaMessage *)messageWithTitle:(NSString *)title + Description:(NSString *)description + Object:(id)mediaObject + MessageExt:(NSString *)messageExt + MessageAction:(NSString *)action + ThumbImage:(UIImage *)thumbImage + MediaTag:(NSString *)tagName { + WXMediaMessage *message = [WXMediaMessage message]; + message.title = title; + message.description = description; + message.mediaObject = mediaObject; + message.messageExt = messageExt; + message.messageAction = action; + message.mediaTagName = tagName; + [message setThumbImage:thumbImage]; + return message; +} + +@end diff --git a/Ifish/Utinitys/Define.h b/Ifish/Utinitys/Define.h index 7dd02b9..479295b 100644 --- a/Ifish/Utinitys/Define.h +++ b/Ifish/Utinitys/Define.h @@ -174,6 +174,7 @@ alpha:1.0] // 用户注册接口 最新有请求头验证参数 #define kAddSafeUser [NSString stringWithFormat:@"%@/api/users/v3/register.do",JIEKOUPORT] + // 用户登录接口 无请求头验证参数 //#define kUserLogin [NSString stringWithFormat:@"%@/api/user/userLogin.do",JIEKOUPORT] // 用户登录接口 最新有请求头验证参数 @@ -182,6 +183,12 @@ alpha:1.0] // 用户登录接口 v4.2 重写登录接口 设备数据与用户信息分不同接口获取 //登录验证接口 #define kUserLoginValidation [NSString stringWithFormat:@"%@/api/users/loginValidation",JIEKOUPORT] +//微信登陆 +#define kUserWechatLoginValidation [NSString stringWithFormat:@"%@/api/users/wechatLogin.do",JIEKOUPORT] +//绑定手机 +#define kUserBindPhone [NSString stringWithFormat:@"%@/api/users/bindPhone.do",JIEKOUPORT] + +#define kUserWechatValidation [NSString stringWithFormat:@"%@/api/users/wechatValidate.do",JIEKOUPORT] //更多用户数据如设备信息 #define kUserMoreUserData [NSString stringWithFormat:@"%@/api/users/moreUserData/",JIEKOUPORT] // 用户信息修改接口 diff --git a/Ifish/Utinitys/IfishHttpRequest/AFHttpTool.h b/Ifish/Utinitys/IfishHttpRequest/AFHttpTool.h index 1f7e6fb..b08139d 100644 --- a/Ifish/Utinitys/IfishHttpRequest/AFHttpTool.h +++ b/Ifish/Utinitys/IfishHttpRequest/AFHttpTool.h @@ -117,7 +117,7 @@ typedef NS_ENUM(NSInteger, IfishGoodsListType){ longitude:(double)longitude latitude:(double)latitude success:(void (^)(id response))success - failure:(void (^)(NSError* err))failure; + failure:(void (^)(NSError* err))failure expara:(NSDictionary*)dic; /* *获取更多用户数据 get 请求 */ diff --git a/Ifish/Utinitys/IfishHttpRequest/AFHttpTool.m b/Ifish/Utinitys/IfishHttpRequest/AFHttpTool.m index ba54f1b..85a2ebf 100644 --- a/Ifish/Utinitys/IfishHttpRequest/AFHttpTool.m +++ b/Ifish/Utinitys/IfishHttpRequest/AFHttpTool.m @@ -378,20 +378,42 @@ methodType url : (NSString *)url longitude:(double)longitude latitude:(double)latitude success:(void (^)(id))success - failure:(void (^)(NSError *))failure + failure:(void (^)(NSError *))failure expara:(NSDictionary *)dic { - NSDictionary*para=@{@"version":@"1.0", - @"phoneNumber":phoneNumber, - @"userPassword":userPassword, - @"loginType":phoneType, - @"address":address, - @"longitude":[NSString stringWithFormat:@"%f",longitude], - @"latitude":[NSString stringWithFormat:@"%f",latitude] - }; + NSDictionary*para=@{}; + NSString*url; + RequestMethodType type=RequestMethodTypePost; + if (dic[@"code"])//微信登登陆授权 + { + para=@{@"code":dic[@"code"] + }; + url=kUserWechatLoginValidation; + //type=RequestMethodTypeGet; + } + else if (dic[@"unionId"])//微信unionId登陆 + { + para=@{@"unionId":dic[@"unionId"] + }; + url=kUserWechatValidation; + } + else + { + para=@{@"version":@"1.0", + @"phoneNumber":phoneNumber, + @"userPassword":userPassword, + @"loginType":phoneType, + @"address":address, + @"longitude":[NSString stringWithFormat:@"%f",longitude], + @"latitude":[NSString stringWithFormat:@"%f",latitude] + }; + url=kUserLoginValidation; + } + + //kUserSafeLogin - [AFHttpTool requestWihtMethod:RequestMethodTypePost - url:kUserLoginValidation + [AFHttpTool requestWihtMethod:type + url:url params:para success:success failure:failure]; diff --git a/Ifish/Utinitys/IfishHttpRequest/IFISHHttpTool.m b/Ifish/Utinitys/IfishHttpRequest/IFISHHttpTool.m index 0e6f869..9e6312f 100644 --- a/Ifish/Utinitys/IfishHttpRequest/IFISHHttpTool.m +++ b/Ifish/Utinitys/IfishHttpRequest/IFISHHttpTool.m @@ -48,7 +48,12 @@ NSString*pasword=[userDefsult objectForKey:@"password"]; NSString*address=[userDefsult objectForKey:@"address"]; - + NSString*unionId=[userDefsult objectForKey:@"unionId"]; + NSDictionary*para=nil; + if (!pasword.length&&unionId.length) + { + para=@{@"unionId":unionId}; + } double userlongitude=[userDefsult doubleForKey:@"userlongitude"]; double userlatitude=[userDefsult doubleForKey:@"userlatitude"]; @@ -67,7 +72,12 @@ [userDefsult setObject:@"0" forKey:@"isExit"]; - NSString*passWordStr=[MyMD5 md5:pasword]; + NSString*passWordStr; + if (pasword.length) + { + passWordStr=[MyMD5 md5:pasword]; + } + //__weak typeof (self) weakSelf=self; [AFHttpTool userLogInWithPhoneNumber:name password:passWordStr phoneType:@"ios" address:address longitude:userlongitude @@ -123,7 +133,7 @@ NSString *errstr = [NSString stringWithFormat:@"%@",err]; BLYLog(BuglyLogLevelWarn, errstr); - }]; + } expara:para]; } diff --git a/Ifish/Utinitys/IfishHttpRequest/IfishUserDataUnity.h b/Ifish/Utinitys/IfishHttpRequest/IfishUserDataUnity.h index 14c94cb..49d45bc 100644 --- a/Ifish/Utinitys/IfishHttpRequest/IfishUserDataUnity.h +++ b/Ifish/Utinitys/IfishHttpRequest/IfishUserDataUnity.h @@ -20,6 +20,7 @@ * 登陆验证成功 返回 自动登录 */ -(void)userAutologinSuccsess:(NSDictionary *)dataDic; +-(void)setAppTabRoot; @end diff --git a/Ifish/Utinitys/IfishHttpRequest/IfishUserDataUnity.m b/Ifish/Utinitys/IfishHttpRequest/IfishUserDataUnity.m index 97c637a..0df87d6 100644 --- a/Ifish/Utinitys/IfishHttpRequest/IfishUserDataUnity.m +++ b/Ifish/Utinitys/IfishHttpRequest/IfishUserDataUnity.m @@ -13,6 +13,7 @@ #import "NSObject+LBLaunchImage.h" #import "IfishLoadingWebViewController.h" #import "IfishADTimerViewController.h" +#import "RegistViewController.h" @implementation IfishUserDataUnity +(IfishUserDataUnity*)shareDataInstance @@ -39,9 +40,21 @@ [[DataCenter defaultDtacenter]setValue:userAsset forKey:@"IfishUserAsset"]; NSUserDefaults*userdefult=[NSUserDefaults standardUserDefaults]; + if (password.length) + { + [userdefult setObject:password forKey:@"password"]; + } + if (phoneNumber.length) { + [userdefult setObject:phoneNumber forKey:@"name"]; + } + if (model.unionId.length) { + [userdefult setObject:model.unionId forKey:@"unionId"]; + } + if (model.wechatImgUrl.length) { + [userdefult setObject:model.wechatImgUrl forKey:@"wechatImgUrl"]; + } + - [userdefult setObject:password forKey:@"password"]; - [userdefult setObject:phoneNumber forKey:@"name"]; [userdefult setObject:@"0" forKey:@"isExit"]; [userdefult setObject:model.userId forKey:@"userId"]; @@ -55,7 +68,16 @@ NSLog(@"userDic:%@",userDic); NSLog(@"登录成功"); - [self setAppTabRoot]; + BOOL skiped =[userdefult boolForKey:[CommonUtils getNotNilStr:model.unionId]]; + if (!skiped&&[CommonUtils getNotNilStr:model.phoneNumber].length==0&&[CommonUtils getNotNilStr:model.unionId].length) + { + [self bindPhone]; + } + else + { + [self setAppTabRoot]; + } + } @@ -66,7 +88,14 @@ NSDictionary *userDic=dataDic[@"userInfo"]; UserModel *model=[[UserModel alloc] initWithDict:userDic]; [[DataCenter defaultDtacenter]setValue:model forKey:@"UserLogIn"]; - + NSUserDefaults*userdefult=[NSUserDefaults standardUserDefaults]; + if (model.unionId.length) { + [userdefult setObject:model.unionId forKey:@"unionId"]; + } + if (model.wechatImgUrl.length) { + [userdefult setObject:model.wechatImgUrl forKey:@"wechatImgUrl"]; + } + [userdefult synchronize]; //金币任务等级 NSDictionary *userAssetDic=dataDic[@"userAsset"]; IfishUserAsset *userAsset =[[IfishUserAsset alloc] initWithDict:userAssetDic]; @@ -153,5 +182,13 @@ [UIApplication sharedApplication].delegate.window.rootViewController=mianVC; } +-(void)bindPhone +{ + RegistViewController*revv=[[RegistViewController alloc]init]; + revv.isBind=YES; + revv.isFromLogin=YES; + UINavigationController*nav=[[UINavigationController alloc]initWithRootViewController:revv]; + [UIApplication sharedApplication].delegate.window.rootViewController=nav; +} @end diff --git a/Ifish/Utinitys/SocketSingleton/Socketsingleton.m b/Ifish/Utinitys/SocketSingleton/Socketsingleton.m index 1eb327d..8164107 100644 --- a/Ifish/Utinitys/SocketSingleton/Socketsingleton.m +++ b/Ifish/Utinitys/SocketSingleton/Socketsingleton.m @@ -105,7 +105,7 @@ -(void)onSocket:(AsyncSocket *)sock willDisconnectWithError:(NSError *)err{ NSLog(@"soket错误断开"); NSLog(@"存留数据%@",[sock unreadData]); - if (self.communiteDelegate) { + if (self.communiteDelegate&&[self.communiteDelegate respondsToSelector:@selector(ifishSocket:willDisconnectWithError:)]) { [self.communiteDelegate ifishSocket:sock willDisconnectWithError:err]; } @@ -116,7 +116,7 @@ - (BOOL)onSocketWillConnect:(AsyncSocket *)sock{ - if (self.communiteDelegate) { + if (self.communiteDelegate&&[self.communiteDelegate respondsToSelector:@selector(ifishSocketWillConnect:)]) { [self.communiteDelegate ifishSocketWillConnect:sock]; }; return YES; diff --git a/Ifish/YYWebImage/Cache/YYCache.h b/Ifish/YYWebImage/Cache/YYCache.h new file mode 100644 index 0000000..f042ed7 --- /dev/null +++ b/Ifish/YYWebImage/Cache/YYCache.h @@ -0,0 +1,206 @@ +// +// YYCache.h +// YYCache +// +// Created by ibireme on 15/2/13. +// Copyright (c) 2015 ibireme. +// +// This source code is licensed under the MIT-style license found in the +// LICENSE file in the root directory of this source tree. +// + +#import + +#if __has_include() +FOUNDATION_EXPORT double YYCacheVersionNumber; +FOUNDATION_EXPORT const unsigned char YYCacheVersionString[]; +#import +#import +#import +#elif __has_include() +#import +#import +#import +#else +#import "YYMemoryCache.h" +#import "YYDiskCache.h" +#import "YYKVStorage.h" +#endif + +NS_ASSUME_NONNULL_BEGIN + + +/** + `YYCache` is a thread safe key-value cache. + + It use `YYMemoryCache` to store objects in a small and fast memory cache, + and use `YYDiskCache` to persisting objects to a large and slow disk cache. + See `YYMemoryCache` and `YYDiskCache` for more information. + */ +@interface YYCache : NSObject + +/** The name of the cache, readonly. */ +@property (copy, readonly) NSString *name; + +/** The underlying memory cache. see `YYMemoryCache` for more information.*/ +@property (strong, readonly) YYMemoryCache *memoryCache; + +/** The underlying disk cache. see `YYDiskCache` for more information.*/ +@property (strong, readonly) YYDiskCache *diskCache; + +/** + Create a new instance with the specified name. + Multiple instances with the same name will make the cache unstable. + + @param name The name of the cache. It will create a dictionary with the name in + the app's caches dictionary for disk cache. Once initialized you should not + read and write to this directory. + @result A new cache object, or nil if an error occurs. + */ +- (nullable instancetype)initWithName:(NSString *)name; + +/** + Create a new instance with the specified path. + Multiple instances with the same name will make the cache unstable. + + @param path Full path of a directory in which the cache will write data. + Once initialized you should not read and write to this directory. + @result A new cache object, or nil if an error occurs. + */ +- (nullable instancetype)initWithPath:(NSString *)path NS_DESIGNATED_INITIALIZER; + +/** + Convenience Initializers + Create a new instance with the specified name. + Multiple instances with the same name will make the cache unstable. + + @param name The name of the cache. It will create a dictionary with the name in + the app's caches dictionary for disk cache. Once initialized you should not + read and write to this directory. + @result A new cache object, or nil if an error occurs. + */ ++ (nullable instancetype)cacheWithName:(NSString *)name; + +/** + Convenience Initializers + Create a new instance with the specified path. + Multiple instances with the same name will make the cache unstable. + + @param path Full path of a directory in which the cache will write data. + Once initialized you should not read and write to this directory. + @result A new cache object, or nil if an error occurs. + */ ++ (nullable instancetype)cacheWithPath:(NSString *)path; + +- (instancetype)init UNAVAILABLE_ATTRIBUTE; ++ (instancetype)new UNAVAILABLE_ATTRIBUTE; + +#pragma mark - Access Methods +///============================================================================= +/// @name Access Methods +///============================================================================= + +/** + 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 value. If nil, just return NO. + @return Whether the key is in cache. + */ +- (BOOL)containsObjectForKey:(NSString *)key; + +/** + Returns a boolean value with the block that indicates whether a given key is in cache. + This method returns immediately and invoke the passed block in background queue + when the operation finished. + + @param key A string identifying the value. If nil, just return NO. + @param block A block which will be invoked in background queue when finished. + */ +- (void)containsObjectForKey:(NSString *)key withBlock:(nullable void(^)(NSString *key, BOOL contains))block; + +/** + Returns the value associated with a given key. + This method may blocks the calling thread until file read finished. + + @param key A string 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:(NSString *)key; + +/** + Returns the value associated with a given key. + This method returns immediately and invoke the passed block in background queue + when the operation finished. + + @param key A string identifying the value. If nil, just return nil. + @param block A block which will be invoked in background queue when finished. + */ +- (void)objectForKey:(NSString *)key withBlock:(nullable void(^)(NSString *key, id object))block; + +/** + Sets the value of the specified key in the cache. + This method may blocks the calling thread until file write finished. + + @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. + */ +- (void)setObject:(nullable id)object forKey:(NSString *)key; + +/** + Sets the value of the specified key in the cache. + This method returns immediately and invoke the passed block in background queue + when the operation finished. + + @param object The object to be stored in the cache. If nil, it calls `removeObjectForKey:`. + @param block A block which will be invoked in background queue when finished. + */ +- (void)setObject:(nullable id)object forKey:(NSString *)key withBlock:(nullable void(^)(void))block; + +/** + 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)removeObjectForKey:(NSString *)key; + +/** + Removes the value of the specified key in the cache. + This method returns immediately and invoke the passed block in background queue + when the operation finished. + + @param key The key identifying the value to be removed. If nil, this method has no effect. + @param block A block which will be invoked in background queue when finished. + */ +- (void)removeObjectForKey:(NSString *)key withBlock:(nullable void(^)(NSString *key))block; + +/** + Empties the cache. + This method may blocks the calling thread until file delete finished. + */ +- (void)removeAllObjects; + +/** + Empties the cache. + This method returns immediately and invoke the passed block in background queue + when the operation finished. + + @param block A block which will be invoked in background queue when finished. + */ +- (void)removeAllObjectsWithBlock:(void(^)(void))block; + +/** + Empties the cache with block. + This method returns immediately and executes the clear operation with block in background. + + @warning You should not send message to this instance in these blocks. + @param progress This block will be invoked during removing, pass nil to ignore. + @param end This block will be invoked at the end, pass nil to ignore. + */ +- (void)removeAllObjectsWithProgressBlock:(nullable void(^)(int removedCount, int totalCount))progress + endBlock:(nullable void(^)(BOOL error))end; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Ifish/YYWebImage/Cache/YYCache.m b/Ifish/YYWebImage/Cache/YYCache.m new file mode 100644 index 0000000..e6cdcba --- /dev/null +++ b/Ifish/YYWebImage/Cache/YYCache.m @@ -0,0 +1,139 @@ +// +// YYCache.m +// YYCache +// +// Created by ibireme on 15/2/13. +// Copyright (c) 2015 ibireme. +// +// This source code is licensed under the MIT-style license found in the +// LICENSE file in the root directory of this source tree. +// + +#import "YYCache.h" +#import "YYMemoryCache.h" +#import "YYDiskCache.h" + +@implementation YYCache + +- (instancetype) init { + NSLog(@"Use \"initWithName\" or \"initWithPath\" to create YYCache instance."); + return [self initWithPath:@""]; +} + +- (instancetype)initWithName:(NSString *)name { + if (name.length == 0) return nil; + NSString *cacheFolder = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) firstObject]; + NSString *path = [cacheFolder stringByAppendingPathComponent:name]; + return [self initWithPath:path]; +} + +- (instancetype)initWithPath:(NSString *)path { + if (path.length == 0) return nil; + YYDiskCache *diskCache = [[YYDiskCache alloc] initWithPath:path]; + if (!diskCache) return nil; + NSString *name = [path lastPathComponent]; + YYMemoryCache *memoryCache = [YYMemoryCache new]; + memoryCache.name = name; + + self = [super init]; + _name = name; + _diskCache = diskCache; + _memoryCache = memoryCache; + return self; +} + ++ (instancetype)cacheWithName:(NSString *)name { + return [[self alloc] initWithName:name]; +} + ++ (instancetype)cacheWithPath:(NSString *)path { + return [[self alloc] initWithPath:path]; +} + +- (BOOL)containsObjectForKey:(NSString *)key { + return [_memoryCache containsObjectForKey:key] || [_diskCache containsObjectForKey:key]; +} + +- (void)containsObjectForKey:(NSString *)key withBlock:(void (^)(NSString *key, BOOL contains))block { + if (!block) return; + + if ([_memoryCache containsObjectForKey:key]) { + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + block(key, YES); + }); + } else { + [_diskCache containsObjectForKey:key withBlock:block]; + } +} + +- (id)objectForKey:(NSString *)key { + id object = [_memoryCache objectForKey:key]; + if (!object) { + object = [_diskCache objectForKey:key]; + if (object) { + [_memoryCache setObject:object forKey:key]; + } + } + return object; +} + +- (void)objectForKey:(NSString *)key withBlock:(void (^)(NSString *key, id object))block { + if (!block) return; + id object = [_memoryCache objectForKey:key]; + if (object) { + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + block(key, object); + }); + } else { + [_diskCache objectForKey:key withBlock:^(NSString *key, id object) { + if (object && ![_memoryCache objectForKey:key]) { + [_memoryCache setObject:object forKey:key]; + } + block(key, object); + }]; + } +} + +- (void)setObject:(id)object forKey:(NSString *)key { + [_memoryCache setObject:object forKey:key]; + [_diskCache setObject:object forKey:key]; +} + +- (void)setObject:(id)object forKey:(NSString *)key withBlock:(void (^)(void))block { + [_memoryCache setObject:object forKey:key]; + [_diskCache setObject:object forKey:key withBlock:block]; +} + +- (void)removeObjectForKey:(NSString *)key { + [_memoryCache removeObjectForKey:key]; + [_diskCache removeObjectForKey:key]; +} + +- (void)removeObjectForKey:(NSString *)key withBlock:(void (^)(NSString *key))block { + [_memoryCache removeObjectForKey:key]; + [_diskCache removeObjectForKey:key withBlock:block]; +} + +- (void)removeAllObjects { + [_memoryCache removeAllObjects]; + [_diskCache removeAllObjects]; +} + +- (void)removeAllObjectsWithBlock:(void(^)(void))block { + [_memoryCache removeAllObjects]; + [_diskCache removeAllObjectsWithBlock:block]; +} + +- (void)removeAllObjectsWithProgressBlock:(void(^)(int removedCount, int totalCount))progress + endBlock:(void(^)(BOOL error))end { + [_memoryCache removeAllObjects]; + [_diskCache removeAllObjectsWithProgressBlock:progress endBlock:end]; + +} + +- (NSString *)description { + if (_name) return [NSString stringWithFormat:@"<%@: %p> (%@)", self.class, self, _name]; + else return [NSString stringWithFormat:@"<%@: %p>", self.class, self]; +} + +@end diff --git a/Ifish/YYWebImage/Cache/YYDiskCache.h b/Ifish/YYWebImage/Cache/YYDiskCache.h new file mode 100644 index 0000000..dd193e4 --- /dev/null +++ b/Ifish/YYWebImage/Cache/YYDiskCache.h @@ -0,0 +1,412 @@ +// +// YYDiskCache.h +// YYCache +// +// Created by ibireme on 15/2/11. +// Copyright (c) 2015 ibireme. +// +// This source code is licensed under the MIT-style license found in the +// LICENSE file in the root directory of this source tree. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +/** + YYDiskCache is a thread-safe cache that stores key-value pairs backed by SQLite + and file system (similar to NSURLCache's disk cache). + + YYDiskCache has these features: + + * It use LRU (least-recently-used) to remove objects. + * It can be controlled by cost, count, and age. + * It can be configured to automatically evict objects when there's no free disk space. + * It can automatically decide the storage type (sqlite/file) for each object to get + better performance. + + You may compile the latest version of sqlite and ignore the libsqlite3.dylib in + iOS system to get 2x~4x speed up. + */ +@interface YYDiskCache : NSObject + +#pragma mark - Attribute +///============================================================================= +/// @name Attribute +///============================================================================= + +/** The name of the cache. Default is nil. */ +@property (nullable, copy) NSString *name; + +/** The path of the cache (read-only). */ +@property (readonly) NSString *path; + +/** + If the object's data size (in bytes) is larger than this value, then object will + be stored as a file, otherwise the object will be stored in sqlite. + + 0 means all objects will be stored as separated files, NSUIntegerMax means all + objects will be stored in sqlite. + + The default value is 20480 (20KB). + */ +@property (readonly) NSUInteger inlineThreshold; + +/** + If this block is not nil, then the block will be used to archive object instead + of NSKeyedArchiver. You can use this block to support the objects which do not + conform to the `NSCoding` protocol. + + The default value is nil. + */ +@property (nullable, copy) NSData *(^customArchiveBlock)(id object); + +/** + If this block is not nil, then the block will be used to unarchive object instead + of NSKeyedUnarchiver. You can use this block to support the objects which do not + conform to the `NSCoding` protocol. + + The default value is nil. + */ +@property (nullable, copy) id (^customUnarchiveBlock)(NSData *data); + +/** + When an object needs to be saved as a file, this block will be invoked to generate + a file name for a specified key. If the block is nil, the cache use md5(key) as + default file name. + + The default value is nil. + */ +@property (nullable, copy) NSString *(^customFileNameBlock)(NSString *key); + + + +#pragma mark - Limit +///============================================================================= +/// @name Limit +///============================================================================= + +/** + The maximum number of objects the cache should hold. + + @discussion The default value is NSUIntegerMax, which means no limit. + This is not a strict limit — if the cache goes over the limit, some objects in the + cache could be evicted later in background queue. + */ +@property NSUInteger countLimit; + +/** + The maximum total cost that the cache can hold before it starts evicting objects. + + @discussion The default value is NSUIntegerMax, which means no limit. + This is not a strict limit — if the cache goes over the limit, some objects in the + cache could be evicted later in background queue. + */ +@property NSUInteger costLimit; + +/** + The maximum expiry time of objects in cache. + + @discussion The default value is DBL_MAX, which means no limit. + This is not a strict limit — if an object goes over the limit, the objects could + be evicted later in background queue. + */ +@property NSTimeInterval ageLimit; + +/** + The minimum free disk space (in bytes) which the cache should kept. + + @discussion The default value is 0, which means no limit. + If the free disk space is lower than this value, the cache will remove objects + to free some disk space. This is not a strict limit—if the free disk space goes + over the limit, the objects could be evicted later in background queue. + */ +@property NSUInteger freeDiskSpaceLimit; + +/** + The auto trim check time interval in seconds. Default is 60 (1 minute). + + @discussion The cache holds an internal timer to check whether the cache reaches + its limits, and if the limit is reached, it begins to evict objects. + */ +@property NSTimeInterval autoTrimInterval; + +/** + Set `YES` to enable error logs for debug. + */ +@property BOOL errorLogsEnabled; + +#pragma mark - Initializer +///============================================================================= +/// @name Initializer +///============================================================================= +- (instancetype)init UNAVAILABLE_ATTRIBUTE; ++ (instancetype)new UNAVAILABLE_ATTRIBUTE; + +/** + Create a new cache based on the specified path. + + @param path Full path of a directory in which the cache will write data. + Once initialized you should not read and write to this directory. + + @return A new cache object, or nil if an error occurs. + + @warning If the cache instance for the specified path already exists in memory, + this method will return it directly, instead of creating a new instance. + */ +- (nullable instancetype)initWithPath:(NSString *)path; + +/** + The designated initializer. + + @param path Full path of a directory in which the cache will write data. + Once initialized you should not read and write to this directory. + + @param threshold The data store inline threshold in bytes. If the object's data + size (in bytes) is larger than this value, then object will be stored as a + file, otherwise the object will be stored in sqlite. 0 means all objects will + be stored as separated files, NSUIntegerMax means all objects will be stored + in sqlite. If you don't know your object's size, 20480 is a good choice. + After first initialized you should not change this value of the specified path. + + @return A new cache object, or nil if an error occurs. + + @warning If the cache instance for the specified path already exists in memory, + this method will return it directly, instead of creating a new instance. + */ +- (nullable instancetype)initWithPath:(NSString *)path + inlineThreshold:(NSUInteger)threshold NS_DESIGNATED_INITIALIZER; + + +#pragma mark - Access Methods +///============================================================================= +/// @name Access Methods +///============================================================================= + +/** + 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 value. If nil, just return NO. + @return Whether the key is in cache. + */ +- (BOOL)containsObjectForKey:(NSString *)key; + +/** + Returns a boolean value with the block that indicates whether a given key is in cache. + This method returns immediately and invoke the passed block in background queue + when the operation finished. + + @param key A string identifying the value. If nil, just return NO. + @param block A block which will be invoked in background queue when finished. + */ +- (void)containsObjectForKey:(NSString *)key withBlock:(void(^)(NSString *key, BOOL contains))block; + +/** + Returns the value associated with a given key. + This method may blocks the calling thread until file read finished. + + @param key A string 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:(NSString *)key; + +/** + Returns the value associated with a given key. + This method returns immediately and invoke the passed block in background queue + when the operation finished. + + @param key A string identifying the value. If nil, just return nil. + @param block A block which will be invoked in background queue when finished. + */ +- (void)objectForKey:(NSString *)key withBlock:(void(^)(NSString *key, id _Nullable object))block; + +/** + Sets the value of the specified key in the cache. + This method may blocks the calling thread until file write finished. + + @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. + */ +- (void)setObject:(nullable id)object forKey:(NSString *)key; + +/** + Sets the value of the specified key in the cache. + This method returns immediately and invoke the passed block in background queue + when the operation finished. + + @param object The object to be stored in the cache. If nil, it calls `removeObjectForKey:`. + @param block A block which will be invoked in background queue when finished. + */ +- (void)setObject:(nullable id)object forKey:(NSString *)key withBlock:(void(^)(void))block; + +/** + 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)removeObjectForKey:(NSString *)key; + +/** + Removes the value of the specified key in the cache. + This method returns immediately and invoke the passed block in background queue + when the operation finished. + + @param key The key identifying the value to be removed. If nil, this method has no effect. + @param block A block which will be invoked in background queue when finished. + */ +- (void)removeObjectForKey:(NSString *)key withBlock:(void(^)(NSString *key))block; + +/** + Empties the cache. + This method may blocks the calling thread until file delete finished. + */ +- (void)removeAllObjects; + +/** + Empties the cache. + This method returns immediately and invoke the passed block in background queue + when the operation finished. + + @param block A block which will be invoked in background queue when finished. + */ +- (void)removeAllObjectsWithBlock:(void(^)(void))block; + +/** + Empties the cache with block. + This method returns immediately and executes the clear operation with block in background. + + @warning You should not send message to this instance in these blocks. + @param progress This block will be invoked during removing, pass nil to ignore. + @param end This block will be invoked at the end, pass nil to ignore. + */ +- (void)removeAllObjectsWithProgressBlock:(nullable void(^)(int removedCount, int totalCount))progress + endBlock:(nullable void(^)(BOOL error))end; + + +/** + Returns the number of objects in this cache. + This method may blocks the calling thread until file read finished. + + @return The total objects count. + */ +- (NSInteger)totalCount; + +/** + Get the number of objects in this cache. + This method returns immediately and invoke the passed block in background queue + when the operation finished. + + @param block A block which will be invoked in background queue when finished. + */ +- (void)totalCountWithBlock:(void(^)(NSInteger totalCount))block; + +/** + Returns the total cost (in bytes) of objects in this cache. + This method may blocks the calling thread until file read finished. + + @return The total objects cost in bytes. + */ +- (NSInteger)totalCost; + +/** + Get the total cost (in bytes) of objects in this cache. + This method returns immediately and invoke the passed block in background queue + when the operation finished. + + @param block A block which will be invoked in background queue when finished. + */ +- (void)totalCostWithBlock:(void(^)(NSInteger totalCost))block; + + +#pragma mark - Trim +///============================================================================= +/// @name Trim +///============================================================================= + +/** + Removes objects from the cache use LRU, until the `totalCount` is below the specified value. + This method may blocks the calling thread until operation finished. + + @param count The total count allowed to remain after the cache has been trimmed. + */ +- (void)trimToCount:(NSUInteger)count; + +/** + Removes objects from the cache use LRU, until the `totalCount` is below the specified value. + This method returns immediately and invoke the passed block in background queue + when the operation finished. + + @param count The total count allowed to remain after the cache has been trimmed. + @param block A block which will be invoked in background queue when finished. + */ +- (void)trimToCount:(NSUInteger)count withBlock:(void(^)(void))block; + +/** + Removes objects from the cache use LRU, until the `totalCost` is below the specified value. + This method may blocks the calling thread until operation finished. + + @param cost The total cost allowed to remain after the cache has been trimmed. + */ +- (void)trimToCost:(NSUInteger)cost; + +/** + Removes objects from the cache use LRU, until the `totalCost` is below the specified value. + This method returns immediately and invoke the passed block in background queue + when the operation finished. + + @param cost The total cost allowed to remain after the cache has been trimmed. + @param block A block which will be invoked in background queue when finished. + */ +- (void)trimToCost:(NSUInteger)cost withBlock:(void(^)(void))block; + +/** + Removes objects from the cache use LRU, until all expiry objects removed by the specified value. + This method may blocks the calling thread until operation finished. + + @param age The maximum age of the object. + */ +- (void)trimToAge:(NSTimeInterval)age; + +/** + Removes objects from the cache use LRU, until all expiry objects removed by the specified value. + This method returns immediately and invoke the passed block in background queue + when the operation finished. + + @param age The maximum age of the object. + @param block A block which will be invoked in background queue when finished. + */ +- (void)trimToAge:(NSTimeInterval)age withBlock:(void(^)(void))block; + + +#pragma mark - Extended Data +///============================================================================= +/// @name Extended Data +///============================================================================= + +/** + Get extended data from an object. + + @discussion See 'setExtendedData:toObject:' for more information. + + @param object An object. + @return The extended data. + */ ++ (nullable NSData *)getExtendedDataFromObject:(id)object; + +/** + Set extended data to an object. + + @discussion You can set any extended data to an object before you save the object + to disk cache. The extended data will also be saved with this object. You can get + the extended data later with "getExtendedDataFromObject:". + + @param extendedData The extended data (pass nil to remove). + @param object The object. + */ ++ (void)setExtendedData:(nullable NSData *)extendedData toObject:(id)object; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Ifish/YYWebImage/Cache/YYDiskCache.m b/Ifish/YYWebImage/Cache/YYDiskCache.m new file mode 100644 index 0000000..735cc5d --- /dev/null +++ b/Ifish/YYWebImage/Cache/YYDiskCache.m @@ -0,0 +1,458 @@ +// +// YYDiskCache.m +// YYCache +// +// Created by ibireme on 15/2/11. +// Copyright (c) 2015 ibireme. +// +// This source code is licensed under the MIT-style license found in the +// LICENSE file in the root directory of this source tree. +// + +#import "YYDiskCache.h" +#import "YYKVStorage.h" +#import +#import +#import +#import + +#define Lock() dispatch_semaphore_wait(self->_lock, DISPATCH_TIME_FOREVER) +#define Unlock() dispatch_semaphore_signal(self->_lock) + +static const int extended_data_key; + +/// Free disk space in bytes. +static int64_t _YYDiskSpaceFree() { + NSError *error = nil; + NSDictionary *attrs = [[NSFileManager defaultManager] attributesOfFileSystemForPath:NSHomeDirectory() error:&error]; + if (error) return -1; + int64_t space = [[attrs objectForKey:NSFileSystemFreeSize] longLongValue]; + if (space < 0) space = -1; + return space; +} + +/// String's md5 hash. +static NSString *_YYNSStringMD5(NSString *string) { + if (!string) return nil; + NSData *data = [string dataUsingEncoding:NSUTF8StringEncoding]; + unsigned char result[CC_MD5_DIGEST_LENGTH]; + CC_MD5(data.bytes, (CC_LONG)data.length, result); + return [NSString stringWithFormat: + @"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", + result[0], result[1], result[2], result[3], + result[4], result[5], result[6], result[7], + result[8], result[9], result[10], result[11], + result[12], result[13], result[14], result[15] + ]; +} + +/// weak reference for all instances +static NSMapTable *_globalInstances; +static dispatch_semaphore_t _globalInstancesLock; + +static void _YYDiskCacheInitGlobal() { + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + _globalInstancesLock = dispatch_semaphore_create(1); + _globalInstances = [[NSMapTable alloc] initWithKeyOptions:NSPointerFunctionsStrongMemory valueOptions:NSPointerFunctionsWeakMemory capacity:0]; + }); +} + +static YYDiskCache *_YYDiskCacheGetGlobal(NSString *path) { + if (path.length == 0) return nil; + _YYDiskCacheInitGlobal(); + dispatch_semaphore_wait(_globalInstancesLock, DISPATCH_TIME_FOREVER); + id cache = [_globalInstances objectForKey:path]; + dispatch_semaphore_signal(_globalInstancesLock); + return cache; +} + +static void _YYDiskCacheSetGlobal(YYDiskCache *cache) { + if (cache.path.length == 0) return; + _YYDiskCacheInitGlobal(); + dispatch_semaphore_wait(_globalInstancesLock, DISPATCH_TIME_FOREVER); + [_globalInstances setObject:cache forKey:cache.path]; + dispatch_semaphore_signal(_globalInstancesLock); +} + + + +@implementation YYDiskCache { + YYKVStorage *_kv; + dispatch_semaphore_t _lock; + dispatch_queue_t _queue; +} + +- (void)_trimRecursively { + __weak typeof(self) _self = self; + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(_autoTrimInterval * NSEC_PER_SEC)), dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{ + __strong typeof(_self) self = _self; + if (!self) return; + [self _trimInBackground]; + [self _trimRecursively]; + }); +} + +- (void)_trimInBackground { + __weak typeof(self) _self = self; + dispatch_async(_queue, ^{ + __strong typeof(_self) self = _self; + if (!self) return; + Lock(); + [self _trimToCost:self.costLimit]; + [self _trimToCount:self.countLimit]; + [self _trimToAge:self.ageLimit]; + [self _trimToFreeDiskSpace:self.freeDiskSpaceLimit]; + Unlock(); + }); +} + +- (void)_trimToCost:(NSUInteger)costLimit { + if (costLimit >= INT_MAX) return; + [_kv removeItemsToFitSize:(int)costLimit]; + +} + +- (void)_trimToCount:(NSUInteger)countLimit { + if (countLimit >= INT_MAX) return; + [_kv removeItemsToFitCount:(int)countLimit]; +} + +- (void)_trimToAge:(NSTimeInterval)ageLimit { + if (ageLimit <= 0) { + [_kv removeAllItems]; + return; + } + long timestamp = time(NULL); + if (timestamp <= ageLimit) return; + long age = timestamp - ageLimit; + if (age >= INT_MAX) return; + [_kv removeItemsEarlierThanTime:(int)age]; +} + +- (void)_trimToFreeDiskSpace:(NSUInteger)targetFreeDiskSpace { + if (targetFreeDiskSpace == 0) return; + int64_t totalBytes = [_kv getItemsSize]; + if (totalBytes <= 0) return; + int64_t diskFreeBytes = _YYDiskSpaceFree(); + if (diskFreeBytes < 0) return; + int64_t needTrimBytes = targetFreeDiskSpace - diskFreeBytes; + if (needTrimBytes <= 0) return; + int64_t costLimit = totalBytes - needTrimBytes; + if (costLimit < 0) costLimit = 0; + [self _trimToCost:(int)costLimit]; +} + +- (NSString *)_filenameForKey:(NSString *)key { + NSString *filename = nil; + if (_customFileNameBlock) filename = _customFileNameBlock(key); + if (!filename) filename = _YYNSStringMD5(key); + return filename; +} + +- (void)_appWillBeTerminated { + Lock(); + _kv = nil; + Unlock(); +} + +#pragma mark - public + +- (void)dealloc { + [[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationWillTerminateNotification object:nil]; +} + +- (instancetype)init { + @throw [NSException exceptionWithName:@"YYDiskCache init error" reason:@"YYDiskCache must be initialized with a path. Use 'initWithPath:' or 'initWithPath:inlineThreshold:' instead." userInfo:nil]; + return [self initWithPath:@"" inlineThreshold:0]; +} + +- (instancetype)initWithPath:(NSString *)path { + return [self initWithPath:path inlineThreshold:1024 * 20]; // 20KB +} + +- (instancetype)initWithPath:(NSString *)path + inlineThreshold:(NSUInteger)threshold { + self = [super init]; + if (!self) return nil; + + YYDiskCache *globalCache = _YYDiskCacheGetGlobal(path); + if (globalCache) return globalCache; + + YYKVStorageType type; + if (threshold == 0) { + type = YYKVStorageTypeFile; + } else if (threshold == NSUIntegerMax) { + type = YYKVStorageTypeSQLite; + } else { + type = YYKVStorageTypeMixed; + } + + YYKVStorage *kv = [[YYKVStorage alloc] initWithPath:path type:type]; + if (!kv) return nil; + + _kv = kv; + _path = path; + _lock = dispatch_semaphore_create(1); + _queue = dispatch_queue_create("com.ibireme.cache.disk", DISPATCH_QUEUE_CONCURRENT); + _inlineThreshold = threshold; + _countLimit = NSUIntegerMax; + _costLimit = NSUIntegerMax; + _ageLimit = DBL_MAX; + _freeDiskSpaceLimit = 0; + _autoTrimInterval = 60; + + [self _trimRecursively]; + _YYDiskCacheSetGlobal(self); + + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_appWillBeTerminated) name:UIApplicationWillTerminateNotification object:nil]; + return self; +} + +- (BOOL)containsObjectForKey:(NSString *)key { + if (!key) return NO; + Lock(); + BOOL contains = [_kv itemExistsForKey:key]; + Unlock(); + return contains; +} + +- (void)containsObjectForKey:(NSString *)key withBlock:(void(^)(NSString *key, BOOL contains))block { + if (!block) return; + __weak typeof(self) _self = self; + dispatch_async(_queue, ^{ + __strong typeof(_self) self = _self; + BOOL contains = [self containsObjectForKey:key]; + block(key, contains); + }); +} + +- (id)objectForKey:(NSString *)key { + if (!key) return nil; + Lock(); + YYKVStorageItem *item = [_kv getItemForKey:key]; + Unlock(); + if (!item.value) return nil; + + id object = nil; + if (_customUnarchiveBlock) { + object = _customUnarchiveBlock(item.value); + } else { + @try { + object = [NSKeyedUnarchiver unarchiveObjectWithData:item.value]; + } + @catch (NSException *exception) { + // nothing to do... + } + } + if (object && item.extendedData) { + [YYDiskCache setExtendedData:item.extendedData toObject:object]; + } + return object; +} + +- (void)objectForKey:(NSString *)key withBlock:(void(^)(NSString *key, id object))block { + if (!block) return; + __weak typeof(self) _self = self; + dispatch_async(_queue, ^{ + __strong typeof(_self) self = _self; + id object = [self objectForKey:key]; + block(key, object); + }); +} + +- (void)setObject:(id)object forKey:(NSString *)key { + if (!key) return; + if (!object) { + [self removeObjectForKey:key]; + return; + } + + NSData *extendedData = [YYDiskCache getExtendedDataFromObject:object]; + NSData *value = nil; + if (_customArchiveBlock) { + value = _customArchiveBlock(object); + } else { + @try { + value = [NSKeyedArchiver archivedDataWithRootObject:object]; + } + @catch (NSException *exception) { + // nothing to do... + } + } + if (!value) return; + NSString *filename = nil; + if (_kv.type != YYKVStorageTypeSQLite) { + if (value.length > _inlineThreshold) { + filename = [self _filenameForKey:key]; + } + } + + Lock(); + [_kv saveItemWithKey:key value:value filename:filename extendedData:extendedData]; + Unlock(); +} + +- (void)setObject:(id)object forKey:(NSString *)key withBlock:(void(^)(void))block { + __weak typeof(self) _self = self; + dispatch_async(_queue, ^{ + __strong typeof(_self) self = _self; + [self setObject:object forKey:key]; + if (block) block(); + }); +} + +- (void)removeObjectForKey:(NSString *)key { + if (!key) return; + Lock(); + [_kv removeItemForKey:key]; + Unlock(); +} + +- (void)removeObjectForKey:(NSString *)key withBlock:(void(^)(NSString *key))block { + __weak typeof(self) _self = self; + dispatch_async(_queue, ^{ + __strong typeof(_self) self = _self; + [self removeObjectForKey:key]; + if (block) block(key); + }); +} + +- (void)removeAllObjects { + Lock(); + [_kv removeAllItems]; + Unlock(); +} + +- (void)removeAllObjectsWithBlock:(void(^)(void))block { + __weak typeof(self) _self = self; + dispatch_async(_queue, ^{ + __strong typeof(_self) self = _self; + [self removeAllObjects]; + if (block) block(); + }); +} + +- (void)removeAllObjectsWithProgressBlock:(void(^)(int removedCount, int totalCount))progress + endBlock:(void(^)(BOOL error))end { + __weak typeof(self) _self = self; + dispatch_async(_queue, ^{ + __strong typeof(_self) self = _self; + if (!self) { + if (end) end(YES); + return; + } + Lock(); + [_kv removeAllItemsWithProgressBlock:progress endBlock:end]; + Unlock(); + }); +} + +- (NSInteger)totalCount { + Lock(); + int count = [_kv getItemsCount]; + Unlock(); + return count; +} + +- (void)totalCountWithBlock:(void(^)(NSInteger totalCount))block { + if (!block) return; + __weak typeof(self) _self = self; + dispatch_async(_queue, ^{ + __strong typeof(_self) self = _self; + NSInteger totalCount = [self totalCount]; + block(totalCount); + }); +} + +- (NSInteger)totalCost { + Lock(); + int count = [_kv getItemsSize]; + Unlock(); + return count; +} + +- (void)totalCostWithBlock:(void(^)(NSInteger totalCost))block { + if (!block) return; + __weak typeof(self) _self = self; + dispatch_async(_queue, ^{ + __strong typeof(_self) self = _self; + NSInteger totalCost = [self totalCost]; + block(totalCost); + }); +} + +- (void)trimToCount:(NSUInteger)count { + Lock(); + [self _trimToCount:count]; + Unlock(); +} + +- (void)trimToCount:(NSUInteger)count withBlock:(void(^)(void))block { + __weak typeof(self) _self = self; + dispatch_async(_queue, ^{ + __strong typeof(_self) self = _self; + [self trimToCount:count]; + if (block) block(); + }); +} + +- (void)trimToCost:(NSUInteger)cost { + Lock(); + [self _trimToCost:cost]; + Unlock(); +} + +- (void)trimToCost:(NSUInteger)cost withBlock:(void(^)(void))block { + __weak typeof(self) _self = self; + dispatch_async(_queue, ^{ + __strong typeof(_self) self = _self; + [self trimToCost:cost]; + if (block) block(); + }); +} + +- (void)trimToAge:(NSTimeInterval)age { + Lock(); + [self _trimToAge:age]; + Unlock(); +} + +- (void)trimToAge:(NSTimeInterval)age withBlock:(void(^)(void))block { + __weak typeof(self) _self = self; + dispatch_async(_queue, ^{ + __strong typeof(_self) self = _self; + [self trimToAge:age]; + if (block) block(); + }); +} + ++ (NSData *)getExtendedDataFromObject:(id)object { + if (!object) return nil; + return (NSData *)objc_getAssociatedObject(object, &extended_data_key); +} + ++ (void)setExtendedData:(NSData *)extendedData toObject:(id)object { + if (!object) return; + objc_setAssociatedObject(object, &extended_data_key, extendedData, OBJC_ASSOCIATION_RETAIN_NONATOMIC); +} + +- (NSString *)description { + if (_name) return [NSString stringWithFormat:@"<%@: %p> (%@:%@)", self.class, self, _name, _path]; + else return [NSString stringWithFormat:@"<%@: %p> (%@)", self.class, self, _path]; +} + +- (BOOL)errorLogsEnabled { + Lock(); + BOOL enabled = _kv.errorLogsEnabled; + Unlock(); + return enabled; +} + +- (void)setErrorLogsEnabled:(BOOL)errorLogsEnabled { + Lock(); + _kv.errorLogsEnabled = errorLogsEnabled; + Unlock(); +} + +@end diff --git a/Ifish/YYWebImage/Cache/YYKVStorage.h b/Ifish/YYWebImage/Cache/YYKVStorage.h new file mode 100644 index 0000000..939a6e4 --- /dev/null +++ b/Ifish/YYWebImage/Cache/YYKVStorage.h @@ -0,0 +1,325 @@ +// +// YYKVStorage.h +// YYCache +// +// Created by ibireme on 15/4/22. +// Copyright (c) 2015 ibireme. +// +// This source code is licensed under the MIT-style license found in the +// LICENSE file in the root directory of this source tree. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +/** + YYKVStorageItem is used by `YYKVStorage` to store key-value pair and meta data. + Typically, you should not use this class directly. + */ +@interface YYKVStorageItem : NSObject +@property (nonatomic, strong) NSString *key; ///< key +@property (nonatomic, strong) NSData *value; ///< value +@property (nullable, nonatomic, strong) NSString *filename; ///< filename (nil if inline) +@property (nonatomic) int size; ///< value's size in bytes +@property (nonatomic) int modTime; ///< modification unix timestamp +@property (nonatomic) int accessTime; ///< last access unix timestamp +@property (nullable, nonatomic, strong) NSData *extendedData; ///< extended data (nil if no extended data) +@end + +/** + Storage type, indicated where the `YYKVStorageItem.value` stored. + + @discussion Typically, write data to sqlite is faster than extern file, but + reading performance is dependent on data size. In my test (on iPhone 6 64G), + read data from extern file is faster than from sqlite when the data is larger + than 20KB. + + * If you want to store large number of small datas (such as contacts cache), + use YYKVStorageTypeSQLite to get better performance. + * If you want to store large files (such as image cache), + use YYKVStorageTypeFile to get better performance. + * You can use YYKVStorageTypeMixed and choice your storage type for each item. + + See for more information. + */ +typedef NS_ENUM(NSUInteger, YYKVStorageType) { + + /// The `value` is stored as a file in file system. + YYKVStorageTypeFile = 0, + + /// The `value` is stored in sqlite with blob type. + YYKVStorageTypeSQLite = 1, + + /// The `value` is stored in file system or sqlite based on your choice. + YYKVStorageTypeMixed = 2, +}; + + + +/** + YYKVStorage is a key-value storage based on sqlite and file system. + Typically, you should not use this class directly. + + @discussion The designated initializer for YYKVStorage is `initWithPath:type:`. + After initialized, a directory is created based on the `path` to hold key-value data. + Once initialized you should not read or write this directory without the instance. + + You may compile the latest version of sqlite and ignore the libsqlite3.dylib in + iOS system to get 2x~4x speed up. + + @warning The instance of this class is *NOT* thread safe, you need to make sure + that there's only one thread to access the instance at the same time. If you really + need to process large amounts of data in multi-thread, you should split the data + to multiple KVStorage instance (sharding). + */ +@interface YYKVStorage : NSObject + +#pragma mark - Attribute +///============================================================================= +/// @name Attribute +///============================================================================= + +@property (nonatomic, readonly) NSString *path; ///< The path of this storage. +@property (nonatomic, readonly) YYKVStorageType type; ///< The type of this storage. +@property (nonatomic) BOOL errorLogsEnabled; ///< Set `YES` to enable error logs for debug. + +#pragma mark - Initializer +///============================================================================= +/// @name Initializer +///============================================================================= +- (instancetype)init UNAVAILABLE_ATTRIBUTE; ++ (instancetype)new UNAVAILABLE_ATTRIBUTE; + +/** + The designated initializer. + + @param path Full path of a directory in which the storage will write data. If + the directory is not exists, it will try to create one, otherwise it will + read the data in this directory. + @param type The storage type. After first initialized you should not change the + type of the specified path. + @return A new storage object, or nil if an error occurs. + @warning Multiple instances with the same path will make the storage unstable. + */ +- (nullable instancetype)initWithPath:(NSString *)path type:(YYKVStorageType)type NS_DESIGNATED_INITIALIZER; + + +#pragma mark - Save Items +///============================================================================= +/// @name Save Items +///============================================================================= + +/** + Save an item or update the item with 'key' if it already exists. + + @discussion This method will save the item.key, item.value, item.filename and + item.extendedData to disk or sqlite, other properties will be ignored. item.key + and item.value should not be empty (nil or zero length). + + If the `type` is YYKVStorageTypeFile, then the item.filename should not be empty. + If the `type` is YYKVStorageTypeSQLite, then the item.filename will be ignored. + It the `type` is YYKVStorageTypeMixed, then the item.value will be saved to file + system if the item.filename is not empty, otherwise it will be saved to sqlite. + + @param item An item. + @return Whether succeed. + */ +- (BOOL)saveItem:(YYKVStorageItem *)item; + +/** + Save an item or update the item with 'key' if it already exists. + + @discussion This method will save the key-value pair to sqlite. If the `type` is + YYKVStorageTypeFile, then this method will failed. + + @param key The key, should not be empty (nil or zero length). + @param value The key, should not be empty (nil or zero length). + @return Whether succeed. + */ +- (BOOL)saveItemWithKey:(NSString *)key value:(NSData *)value; + +/** + Save an item or update the item with 'key' if it already exists. + + @discussion + If the `type` is YYKVStorageTypeFile, then the `filename` should not be empty. + If the `type` is YYKVStorageTypeSQLite, then the `filename` will be ignored. + It the `type` is YYKVStorageTypeMixed, then the `value` will be saved to file + system if the `filename` is not empty, otherwise it will be saved to sqlite. + + @param key The key, should not be empty (nil or zero length). + @param value The key, should not be empty (nil or zero length). + @param filename The filename. + @param extendedData The extended data for this item (pass nil to ignore it). + + @return Whether succeed. + */ +- (BOOL)saveItemWithKey:(NSString *)key + value:(NSData *)value + filename:(nullable NSString *)filename + extendedData:(nullable NSData *)extendedData; + +#pragma mark - Remove Items +///============================================================================= +/// @name Remove Items +///============================================================================= + +/** + Remove an item with 'key'. + + @param key The item's key. + @return Whether succeed. + */ +- (BOOL)removeItemForKey:(NSString *)key; + +/** + Remove items with an array of keys. + + @param keys An array of specified keys. + + @return Whether succeed. + */ +- (BOOL)removeItemForKeys:(NSArray *)keys; + +/** + Remove all items which `value` is larger than a specified size. + + @param size The maximum size in bytes. + @return Whether succeed. + */ +- (BOOL)removeItemsLargerThanSize:(int)size; + +/** + Remove all items which last access time is earlier than a specified timestamp. + + @param time The specified unix timestamp. + @return Whether succeed. + */ +- (BOOL)removeItemsEarlierThanTime:(int)time; + +/** + Remove items to make the total size not larger than a specified size. + The least recently used (LRU) items will be removed first. + + @param maxSize The specified size in bytes. + @return Whether succeed. + */ +- (BOOL)removeItemsToFitSize:(int)maxSize; + +/** + Remove items to make the total count not larger than a specified count. + The least recently used (LRU) items will be removed first. + + @param maxCount The specified item count. + @return Whether succeed. + */ +- (BOOL)removeItemsToFitCount:(int)maxCount; + +/** + Remove all items in background queue. + + @discussion This method will remove the files and sqlite database to a trash + folder, and then clear the folder in background queue. So this method is much + faster than `removeAllItemsWithProgressBlock:endBlock:`. + + @return Whether succeed. + */ +- (BOOL)removeAllItems; + +/** + Remove all items. + + @warning You should not send message to this instance in these blocks. + @param progress This block will be invoked during removing, pass nil to ignore. + @param end This block will be invoked at the end, pass nil to ignore. + */ +- (void)removeAllItemsWithProgressBlock:(nullable void(^)(int removedCount, int totalCount))progress + endBlock:(nullable void(^)(BOOL error))end; + + +#pragma mark - Get Items +///============================================================================= +/// @name Get Items +///============================================================================= + +/** + Get item with a specified key. + + @param key A specified key. + @return Item for the key, or nil if not exists / error occurs. + */ +- (nullable YYKVStorageItem *)getItemForKey:(NSString *)key; + +/** + Get item information with a specified key. + The `value` in this item will be ignored. + + @param key A specified key. + @return Item information for the key, or nil if not exists / error occurs. + */ +- (nullable YYKVStorageItem *)getItemInfoForKey:(NSString *)key; + +/** + Get item value with a specified key. + + @param key A specified key. + @return Item's value, or nil if not exists / error occurs. + */ +- (nullable NSData *)getItemValueForKey:(NSString *)key; + +/** + Get items with an array of keys. + + @param keys An array of specified keys. + @return An array of `YYKVStorageItem`, or nil if not exists / error occurs. + */ +- (nullable NSArray *)getItemForKeys:(NSArray *)keys; + +/** + Get item infomartions with an array of keys. + The `value` in items will be ignored. + + @param keys An array of specified keys. + @return An array of `YYKVStorageItem`, or nil if not exists / error occurs. + */ +- (nullable NSArray *)getItemInfoForKeys:(NSArray *)keys; + +/** + Get items value with an array of keys. + + @param keys An array of specified keys. + @return A dictionary which key is 'key' and value is 'value', or nil if not + exists / error occurs. + */ +- (nullable NSDictionary *)getItemValueForKeys:(NSArray *)keys; + +#pragma mark - Get Storage Status +///============================================================================= +/// @name Get Storage Status +///============================================================================= + +/** + Whether an item exists for a specified key. + + @param key A specified key. + + @return `YES` if there's an item exists for the key, `NO` if not exists or an error occurs. + */ +- (BOOL)itemExistsForKey:(NSString *)key; + +/** + Get total item count. + @return Total item count, -1 when an error occurs. + */ +- (int)getItemsCount; + +/** + Get item value's total size in bytes. + @return Total size in bytes, -1 when an error occurs. + */ +- (int)getItemsSize; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Ifish/YYWebImage/Cache/YYKVStorage.m b/Ifish/YYWebImage/Cache/YYKVStorage.m new file mode 100644 index 0000000..501dfdd --- /dev/null +++ b/Ifish/YYWebImage/Cache/YYKVStorage.m @@ -0,0 +1,1069 @@ +// +// YYKVStorage.m +// YYCache +// +// Created by ibireme on 15/4/22. +// Copyright (c) 2015 ibireme. +// +// This source code is licensed under the MIT-style license found in the +// LICENSE file in the root directory of this source tree. +// + +#import "YYKVStorage.h" +#import +#import + +#if __has_include() +#import +#else +#import "sqlite3.h" +#endif + + +static const NSUInteger kMaxErrorRetryCount = 8; +static const NSTimeInterval kMinRetryTimeInterval = 2.0; +static const int kPathLengthMax = PATH_MAX - 64; +static NSString *const kDBFileName = @"manifest.sqlite"; +static NSString *const kDBShmFileName = @"manifest.sqlite-shm"; +static NSString *const kDBWalFileName = @"manifest.sqlite-wal"; +static NSString *const kDataDirectoryName = @"data"; +static NSString *const kTrashDirectoryName = @"trash"; + + +/* + File: + /path/ + /manifest.sqlite + /manifest.sqlite-shm + /manifest.sqlite-wal + /data/ + /e10adc3949ba59abbe56e057f20f883e + /e10adc3949ba59abbe56e057f20f883e + /trash/ + /unused_file_or_folder + + SQL: + create table if not exists manifest ( + key text, + filename text, + size integer, + inline_data blob, + modification_time integer, + last_access_time integer, + extended_data blob, + primary key(key) + ); + create index if not exists last_access_time_idx on manifest(last_access_time); + */ + +/// Returns nil in App Extension. +static UIApplication *_YYSharedApplication() { + static BOOL isAppExtension = NO; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + Class cls = NSClassFromString(@"UIApplication"); + if(!cls || ![cls respondsToSelector:@selector(sharedApplication)]) isAppExtension = YES; + if ([[[NSBundle mainBundle] bundlePath] hasSuffix:@".appex"]) isAppExtension = YES; + }); +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wundeclared-selector" + return isAppExtension ? nil : [UIApplication performSelector:@selector(sharedApplication)]; +#pragma clang diagnostic pop +} + + +@implementation YYKVStorageItem +@end + +@implementation YYKVStorage { + dispatch_queue_t _trashQueue; + + NSString *_path; + NSString *_dbPath; + NSString *_dataPath; + NSString *_trashPath; + + sqlite3 *_db; + CFMutableDictionaryRef _dbStmtCache; + NSTimeInterval _dbLastOpenErrorTime; + NSUInteger _dbOpenErrorCount; +} + + +#pragma mark - db + +- (BOOL)_dbOpen { + if (_db) return YES; + + int result = sqlite3_open(_dbPath.UTF8String, &_db); + if (result == SQLITE_OK) { + CFDictionaryKeyCallBacks keyCallbacks = kCFCopyStringDictionaryKeyCallBacks; + CFDictionaryValueCallBacks valueCallbacks = {0}; + _dbStmtCache = CFDictionaryCreateMutable(CFAllocatorGetDefault(), 0, &keyCallbacks, &valueCallbacks); + _dbLastOpenErrorTime = 0; + _dbOpenErrorCount = 0; + return YES; + } else { + _db = NULL; + if (_dbStmtCache) CFRelease(_dbStmtCache); + _dbStmtCache = NULL; + _dbLastOpenErrorTime = CACurrentMediaTime(); + _dbOpenErrorCount++; + + if (_errorLogsEnabled) { + NSLog(@"%s line:%d sqlite open failed (%d).", __FUNCTION__, __LINE__, result); + } + return NO; + } +} + +- (BOOL)_dbClose { + if (!_db) return YES; + + int result = 0; + BOOL retry = NO; + BOOL stmtFinalized = NO; + + if (_dbStmtCache) CFRelease(_dbStmtCache); + _dbStmtCache = NULL; + + do { + retry = NO; + result = sqlite3_close(_db); + if (result == SQLITE_BUSY || result == SQLITE_LOCKED) { + if (!stmtFinalized) { + stmtFinalized = YES; + sqlite3_stmt *stmt; + while ((stmt = sqlite3_next_stmt(_db, nil)) != 0) { + sqlite3_finalize(stmt); + retry = YES; + } + } + } else if (result != SQLITE_OK) { + if (_errorLogsEnabled) { + NSLog(@"%s line:%d sqlite close failed (%d).", __FUNCTION__, __LINE__, result); + } + } + } while (retry); + _db = NULL; + return YES; +} + +- (BOOL)_dbCheck { + if (!_db) { + if (_dbOpenErrorCount < kMaxErrorRetryCount && + CACurrentMediaTime() - _dbLastOpenErrorTime > kMinRetryTimeInterval) { + return [self _dbOpen] && [self _dbInitialize]; + } else { + return NO; + } + } + return YES; +} + +- (BOOL)_dbInitialize { + NSString *sql = @"pragma journal_mode = wal; pragma synchronous = normal; create table if not exists manifest (key text, filename text, size integer, inline_data blob, modification_time integer, last_access_time integer, extended_data blob, primary key(key)); create index if not exists last_access_time_idx on manifest(last_access_time);"; + return [self _dbExecute:sql]; +} + +- (void)_dbCheckpoint { + if (![self _dbCheck]) return; + // Cause a checkpoint to occur, merge `sqlite-wal` file to `sqlite` file. + sqlite3_wal_checkpoint(_db, NULL); +} + +- (BOOL)_dbExecute:(NSString *)sql { + if (sql.length == 0) return NO; + if (![self _dbCheck]) return NO; + + char *error = NULL; + int result = sqlite3_exec(_db, sql.UTF8String, NULL, NULL, &error); + if (error) { + if (_errorLogsEnabled) NSLog(@"%s line:%d sqlite exec error (%d): %s", __FUNCTION__, __LINE__, result, error); + sqlite3_free(error); + } + + return result == SQLITE_OK; +} + +- (sqlite3_stmt *)_dbPrepareStmt:(NSString *)sql { + if (![self _dbCheck] || sql.length == 0 || !_dbStmtCache) return NULL; + sqlite3_stmt *stmt = (sqlite3_stmt *)CFDictionaryGetValue(_dbStmtCache, (__bridge const void *)(sql)); + if (!stmt) { + int result = sqlite3_prepare_v2(_db, sql.UTF8String, -1, &stmt, NULL); + if (result != SQLITE_OK) { + if (_errorLogsEnabled) NSLog(@"%s line:%d sqlite stmt prepare error (%d): %s", __FUNCTION__, __LINE__, result, sqlite3_errmsg(_db)); + return NULL; + } + CFDictionarySetValue(_dbStmtCache, (__bridge const void *)(sql), stmt); + } else { + sqlite3_reset(stmt); + } + return stmt; +} + +- (NSString *)_dbJoinedKeys:(NSArray *)keys { + NSMutableString *string = [NSMutableString new]; + for (NSUInteger i = 0,max = keys.count; i < max; i++) { + [string appendString:@"?"]; + if (i + 1 != max) { + [string appendString:@","]; + } + } + return string; +} + +- (void)_dbBindJoinedKeys:(NSArray *)keys stmt:(sqlite3_stmt *)stmt fromIndex:(int)index{ + for (int i = 0, max = (int)keys.count; i < max; i++) { + NSString *key = keys[i]; + sqlite3_bind_text(stmt, index + i, key.UTF8String, -1, NULL); + } +} + +- (BOOL)_dbSaveWithKey:(NSString *)key value:(NSData *)value fileName:(NSString *)fileName extendedData:(NSData *)extendedData { + NSString *sql = @"insert or replace into manifest (key, filename, size, inline_data, modification_time, last_access_time, extended_data) values (?1, ?2, ?3, ?4, ?5, ?6, ?7);"; + sqlite3_stmt *stmt = [self _dbPrepareStmt:sql]; + if (!stmt) return NO; + + int timestamp = (int)time(NULL); + sqlite3_bind_text(stmt, 1, key.UTF8String, -1, NULL); + sqlite3_bind_text(stmt, 2, fileName.UTF8String, -1, NULL); + sqlite3_bind_int(stmt, 3, (int)value.length); + if (fileName.length == 0) { + sqlite3_bind_blob(stmt, 4, value.bytes, (int)value.length, 0); + } else { + sqlite3_bind_blob(stmt, 4, NULL, 0, 0); + } + sqlite3_bind_int(stmt, 5, timestamp); + sqlite3_bind_int(stmt, 6, timestamp); + sqlite3_bind_blob(stmt, 7, extendedData.bytes, (int)extendedData.length, 0); + + int result = sqlite3_step(stmt); + if (result != SQLITE_DONE) { + if (_errorLogsEnabled) NSLog(@"%s line:%d sqlite insert error (%d): %s", __FUNCTION__, __LINE__, result, sqlite3_errmsg(_db)); + return NO; + } + return YES; +} + +- (BOOL)_dbUpdateAccessTimeWithKey:(NSString *)key { + NSString *sql = @"update manifest set last_access_time = ?1 where key = ?2;"; + sqlite3_stmt *stmt = [self _dbPrepareStmt:sql]; + if (!stmt) return NO; + sqlite3_bind_int(stmt, 1, (int)time(NULL)); + sqlite3_bind_text(stmt, 2, key.UTF8String, -1, NULL); + int result = sqlite3_step(stmt); + if (result != SQLITE_DONE) { + if (_errorLogsEnabled) NSLog(@"%s line:%d sqlite update error (%d): %s", __FUNCTION__, __LINE__, result, sqlite3_errmsg(_db)); + return NO; + } + return YES; +} + +- (BOOL)_dbUpdateAccessTimeWithKeys:(NSArray *)keys { + if (![self _dbCheck]) return NO; + int t = (int)time(NULL); + NSString *sql = [NSString stringWithFormat:@"update manifest set last_access_time = %d where key in (%@);", t, [self _dbJoinedKeys:keys]]; + + sqlite3_stmt *stmt = NULL; + int result = sqlite3_prepare_v2(_db, sql.UTF8String, -1, &stmt, NULL); + if (result != SQLITE_OK) { + if (_errorLogsEnabled) NSLog(@"%s line:%d sqlite stmt prepare error (%d): %s", __FUNCTION__, __LINE__, result, sqlite3_errmsg(_db)); + return NO; + } + + [self _dbBindJoinedKeys:keys stmt:stmt fromIndex:1]; + result = sqlite3_step(stmt); + sqlite3_finalize(stmt); + if (result != SQLITE_DONE) { + if (_errorLogsEnabled) NSLog(@"%s line:%d sqlite update error (%d): %s", __FUNCTION__, __LINE__, result, sqlite3_errmsg(_db)); + return NO; + } + return YES; +} + +- (BOOL)_dbDeleteItemWithKey:(NSString *)key { + NSString *sql = @"delete from manifest where key = ?1;"; + sqlite3_stmt *stmt = [self _dbPrepareStmt:sql]; + if (!stmt) return NO; + sqlite3_bind_text(stmt, 1, key.UTF8String, -1, NULL); + + int result = sqlite3_step(stmt); + if (result != SQLITE_DONE) { + if (_errorLogsEnabled) NSLog(@"%s line:%d db delete error (%d): %s", __FUNCTION__, __LINE__, result, sqlite3_errmsg(_db)); + return NO; + } + return YES; +} + +- (BOOL)_dbDeleteItemWithKeys:(NSArray *)keys { + if (![self _dbCheck]) return NO; + NSString *sql = [NSString stringWithFormat:@"delete from manifest where key in (%@);", [self _dbJoinedKeys:keys]]; + sqlite3_stmt *stmt = NULL; + int result = sqlite3_prepare_v2(_db, sql.UTF8String, -1, &stmt, NULL); + if (result != SQLITE_OK) { + if (_errorLogsEnabled) NSLog(@"%s line:%d sqlite stmt prepare error (%d): %s", __FUNCTION__, __LINE__, result, sqlite3_errmsg(_db)); + return NO; + } + + [self _dbBindJoinedKeys:keys stmt:stmt fromIndex:1]; + result = sqlite3_step(stmt); + sqlite3_finalize(stmt); + if (result == SQLITE_ERROR) { + if (_errorLogsEnabled) NSLog(@"%s line:%d sqlite delete error (%d): %s", __FUNCTION__, __LINE__, result, sqlite3_errmsg(_db)); + return NO; + } + return YES; +} + +- (BOOL)_dbDeleteItemsWithSizeLargerThan:(int)size { + NSString *sql = @"delete from manifest where size > ?1;"; + sqlite3_stmt *stmt = [self _dbPrepareStmt:sql]; + if (!stmt) return NO; + sqlite3_bind_int(stmt, 1, size); + int result = sqlite3_step(stmt); + if (result != SQLITE_DONE) { + if (_errorLogsEnabled) NSLog(@"%s line:%d sqlite delete error (%d): %s", __FUNCTION__, __LINE__, result, sqlite3_errmsg(_db)); + return NO; + } + return YES; +} + +- (BOOL)_dbDeleteItemsWithTimeEarlierThan:(int)time { + NSString *sql = @"delete from manifest where last_access_time < ?1;"; + sqlite3_stmt *stmt = [self _dbPrepareStmt:sql]; + if (!stmt) return NO; + sqlite3_bind_int(stmt, 1, time); + int result = sqlite3_step(stmt); + if (result != SQLITE_DONE) { + if (_errorLogsEnabled) NSLog(@"%s line:%d sqlite delete error (%d): %s", __FUNCTION__, __LINE__, result, sqlite3_errmsg(_db)); + return NO; + } + return YES; +} + +- (YYKVStorageItem *)_dbGetItemFromStmt:(sqlite3_stmt *)stmt excludeInlineData:(BOOL)excludeInlineData { + int i = 0; + char *key = (char *)sqlite3_column_text(stmt, i++); + char *filename = (char *)sqlite3_column_text(stmt, i++); + int size = sqlite3_column_int(stmt, i++); + const void *inline_data = excludeInlineData ? NULL : sqlite3_column_blob(stmt, i); + int inline_data_bytes = excludeInlineData ? 0 : sqlite3_column_bytes(stmt, i++); + int modification_time = sqlite3_column_int(stmt, i++); + int last_access_time = sqlite3_column_int(stmt, i++); + const void *extended_data = sqlite3_column_blob(stmt, i); + int extended_data_bytes = sqlite3_column_bytes(stmt, i++); + + YYKVStorageItem *item = [YYKVStorageItem new]; + if (key) item.key = [NSString stringWithUTF8String:key]; + if (filename && *filename != 0) item.filename = [NSString stringWithUTF8String:filename]; + item.size = size; + if (inline_data_bytes > 0 && inline_data) item.value = [NSData dataWithBytes:inline_data length:inline_data_bytes]; + item.modTime = modification_time; + item.accessTime = last_access_time; + if (extended_data_bytes > 0 && extended_data) item.extendedData = [NSData dataWithBytes:extended_data length:extended_data_bytes]; + return item; +} + +- (YYKVStorageItem *)_dbGetItemWithKey:(NSString *)key excludeInlineData:(BOOL)excludeInlineData { + NSString *sql = excludeInlineData ? @"select key, filename, size, modification_time, last_access_time, extended_data from manifest where key = ?1;" : @"select key, filename, size, inline_data, modification_time, last_access_time, extended_data from manifest where key = ?1;"; + sqlite3_stmt *stmt = [self _dbPrepareStmt:sql]; + if (!stmt) return nil; + sqlite3_bind_text(stmt, 1, key.UTF8String, -1, NULL); + + YYKVStorageItem *item = nil; + int result = sqlite3_step(stmt); + if (result == SQLITE_ROW) { + item = [self _dbGetItemFromStmt:stmt excludeInlineData:excludeInlineData]; + } else { + if (result != SQLITE_DONE) { + if (_errorLogsEnabled) NSLog(@"%s line:%d sqlite query error (%d): %s", __FUNCTION__, __LINE__, result, sqlite3_errmsg(_db)); + } + } + return item; +} + +- (NSMutableArray *)_dbGetItemWithKeys:(NSArray *)keys excludeInlineData:(BOOL)excludeInlineData { + if (![self _dbCheck]) return nil; + NSString *sql; + if (excludeInlineData) { + sql = [NSString stringWithFormat:@"select key, filename, size, modification_time, last_access_time, extended_data from manifest where key in (%@);", [self _dbJoinedKeys:keys]]; + } else { + sql = [NSString stringWithFormat:@"select key, filename, size, inline_data, modification_time, last_access_time, extended_data from manifest where key in (%@)", [self _dbJoinedKeys:keys]]; + } + + sqlite3_stmt *stmt = NULL; + int result = sqlite3_prepare_v2(_db, sql.UTF8String, -1, &stmt, NULL); + if (result != SQLITE_OK) { + if (_errorLogsEnabled) NSLog(@"%s line:%d sqlite stmt prepare error (%d): %s", __FUNCTION__, __LINE__, result, sqlite3_errmsg(_db)); + return nil; + } + + [self _dbBindJoinedKeys:keys stmt:stmt fromIndex:1]; + NSMutableArray *items = [NSMutableArray new]; + do { + result = sqlite3_step(stmt); + if (result == SQLITE_ROW) { + YYKVStorageItem *item = [self _dbGetItemFromStmt:stmt excludeInlineData:excludeInlineData]; + if (item) [items addObject:item]; + } else if (result == SQLITE_DONE) { + break; + } else { + if (_errorLogsEnabled) NSLog(@"%s line:%d sqlite query error (%d): %s", __FUNCTION__, __LINE__, result, sqlite3_errmsg(_db)); + items = nil; + break; + } + } while (1); + sqlite3_finalize(stmt); + return items; +} + +- (NSData *)_dbGetValueWithKey:(NSString *)key { + NSString *sql = @"select inline_data from manifest where key = ?1;"; + sqlite3_stmt *stmt = [self _dbPrepareStmt:sql]; + if (!stmt) return nil; + sqlite3_bind_text(stmt, 1, key.UTF8String, -1, NULL); + + int result = sqlite3_step(stmt); + if (result == SQLITE_ROW) { + const void *inline_data = sqlite3_column_blob(stmt, 0); + int inline_data_bytes = sqlite3_column_bytes(stmt, 0); + if (!inline_data || inline_data_bytes <= 0) return nil; + return [NSData dataWithBytes:inline_data length:inline_data_bytes]; + } else { + if (result != SQLITE_DONE) { + if (_errorLogsEnabled) NSLog(@"%s line:%d sqlite query error (%d): %s", __FUNCTION__, __LINE__, result, sqlite3_errmsg(_db)); + } + return nil; + } +} + +- (NSString *)_dbGetFilenameWithKey:(NSString *)key { + NSString *sql = @"select filename from manifest where key = ?1;"; + sqlite3_stmt *stmt = [self _dbPrepareStmt:sql]; + if (!stmt) return nil; + sqlite3_bind_text(stmt, 1, key.UTF8String, -1, NULL); + int result = sqlite3_step(stmt); + if (result == SQLITE_ROW) { + char *filename = (char *)sqlite3_column_text(stmt, 0); + if (filename && *filename != 0) { + return [NSString stringWithUTF8String:filename]; + } + } else { + if (result != SQLITE_DONE) { + if (_errorLogsEnabled) NSLog(@"%s line:%d sqlite query error (%d): %s", __FUNCTION__, __LINE__, result, sqlite3_errmsg(_db)); + } + } + return nil; +} + +- (NSMutableArray *)_dbGetFilenameWithKeys:(NSArray *)keys { + if (![self _dbCheck]) return nil; + NSString *sql = [NSString stringWithFormat:@"select filename from manifest where key in (%@);", [self _dbJoinedKeys:keys]]; + sqlite3_stmt *stmt = NULL; + int result = sqlite3_prepare_v2(_db, sql.UTF8String, -1, &stmt, NULL); + if (result != SQLITE_OK) { + if (_errorLogsEnabled) NSLog(@"%s line:%d sqlite stmt prepare error (%d): %s", __FUNCTION__, __LINE__, result, sqlite3_errmsg(_db)); + return nil; + } + + [self _dbBindJoinedKeys:keys stmt:stmt fromIndex:1]; + NSMutableArray *filenames = [NSMutableArray new]; + do { + result = sqlite3_step(stmt); + if (result == SQLITE_ROW) { + char *filename = (char *)sqlite3_column_text(stmt, 0); + if (filename && *filename != 0) { + NSString *name = [NSString stringWithUTF8String:filename]; + if (name) [filenames addObject:name]; + } + } else if (result == SQLITE_DONE) { + break; + } else { + if (_errorLogsEnabled) NSLog(@"%s line:%d sqlite query error (%d): %s", __FUNCTION__, __LINE__, result, sqlite3_errmsg(_db)); + filenames = nil; + break; + } + } while (1); + sqlite3_finalize(stmt); + return filenames; +} + +- (NSMutableArray *)_dbGetFilenamesWithSizeLargerThan:(int)size { + NSString *sql = @"select filename from manifest where size > ?1 and filename is not null;"; + sqlite3_stmt *stmt = [self _dbPrepareStmt:sql]; + if (!stmt) return nil; + sqlite3_bind_int(stmt, 1, size); + + NSMutableArray *filenames = [NSMutableArray new]; + do { + int result = sqlite3_step(stmt); + if (result == SQLITE_ROW) { + char *filename = (char *)sqlite3_column_text(stmt, 0); + if (filename && *filename != 0) { + NSString *name = [NSString stringWithUTF8String:filename]; + if (name) [filenames addObject:name]; + } + } else if (result == SQLITE_DONE) { + break; + } else { + if (_errorLogsEnabled) NSLog(@"%s line:%d sqlite query error (%d): %s", __FUNCTION__, __LINE__, result, sqlite3_errmsg(_db)); + filenames = nil; + break; + } + } while (1); + return filenames; +} + +- (NSMutableArray *)_dbGetFilenamesWithTimeEarlierThan:(int)time { + NSString *sql = @"select filename from manifest where last_access_time < ?1 and filename is not null;"; + sqlite3_stmt *stmt = [self _dbPrepareStmt:sql]; + if (!stmt) return nil; + sqlite3_bind_int(stmt, 1, time); + + NSMutableArray *filenames = [NSMutableArray new]; + do { + int result = sqlite3_step(stmt); + if (result == SQLITE_ROW) { + char *filename = (char *)sqlite3_column_text(stmt, 0); + if (filename && *filename != 0) { + NSString *name = [NSString stringWithUTF8String:filename]; + if (name) [filenames addObject:name]; + } + } else if (result == SQLITE_DONE) { + break; + } else { + if (_errorLogsEnabled) NSLog(@"%s line:%d sqlite query error (%d): %s", __FUNCTION__, __LINE__, result, sqlite3_errmsg(_db)); + filenames = nil; + break; + } + } while (1); + return filenames; +} + +- (NSMutableArray *)_dbGetItemSizeInfoOrderByTimeAscWithLimit:(int)count { + NSString *sql = @"select key, filename, size from manifest order by last_access_time asc limit ?1;"; + sqlite3_stmt *stmt = [self _dbPrepareStmt:sql]; + if (!stmt) return nil; + sqlite3_bind_int(stmt, 1, count); + + NSMutableArray *items = [NSMutableArray new]; + do { + int result = sqlite3_step(stmt); + if (result == SQLITE_ROW) { + char *key = (char *)sqlite3_column_text(stmt, 0); + char *filename = (char *)sqlite3_column_text(stmt, 1); + int size = sqlite3_column_int(stmt, 2); + NSString *keyStr = key ? [NSString stringWithUTF8String:key] : nil; + if (keyStr) { + YYKVStorageItem *item = [YYKVStorageItem new]; + item.key = key ? [NSString stringWithUTF8String:key] : nil; + item.filename = filename ? [NSString stringWithUTF8String:filename] : nil; + item.size = size; + [items addObject:item]; + } + } else if (result == SQLITE_DONE) { + break; + } else { + if (_errorLogsEnabled) NSLog(@"%s line:%d sqlite query error (%d): %s", __FUNCTION__, __LINE__, result, sqlite3_errmsg(_db)); + items = nil; + break; + } + } while (1); + return items; +} + +- (int)_dbGetItemCountWithKey:(NSString *)key { + NSString *sql = @"select count(key) from manifest where key = ?1;"; + sqlite3_stmt *stmt = [self _dbPrepareStmt:sql]; + if (!stmt) return -1; + sqlite3_bind_text(stmt, 1, key.UTF8String, -1, NULL); + int result = sqlite3_step(stmt); + if (result != SQLITE_ROW) { + if (_errorLogsEnabled) NSLog(@"%s line:%d sqlite query error (%d): %s", __FUNCTION__, __LINE__, result, sqlite3_errmsg(_db)); + return -1; + } + return sqlite3_column_int(stmt, 0); +} + +- (int)_dbGetTotalItemSize { + NSString *sql = @"select sum(size) from manifest;"; + sqlite3_stmt *stmt = [self _dbPrepareStmt:sql]; + if (!stmt) return -1; + int result = sqlite3_step(stmt); + if (result != SQLITE_ROW) { + if (_errorLogsEnabled) NSLog(@"%s line:%d sqlite query error (%d): %s", __FUNCTION__, __LINE__, result, sqlite3_errmsg(_db)); + return -1; + } + return sqlite3_column_int(stmt, 0); +} + +- (int)_dbGetTotalItemCount { + NSString *sql = @"select count(*) from manifest;"; + sqlite3_stmt *stmt = [self _dbPrepareStmt:sql]; + if (!stmt) return -1; + int result = sqlite3_step(stmt); + if (result != SQLITE_ROW) { + if (_errorLogsEnabled) NSLog(@"%s line:%d sqlite query error (%d): %s", __FUNCTION__, __LINE__, result, sqlite3_errmsg(_db)); + return -1; + } + return sqlite3_column_int(stmt, 0); +} + + +#pragma mark - file + +- (BOOL)_fileWriteWithName:(NSString *)filename data:(NSData *)data { + NSString *path = [_dataPath stringByAppendingPathComponent:filename]; + return [data writeToFile:path atomically:NO]; +} + +- (NSData *)_fileReadWithName:(NSString *)filename { + NSString *path = [_dataPath stringByAppendingPathComponent:filename]; + NSData *data = [NSData dataWithContentsOfFile:path]; + return data; +} + +- (BOOL)_fileDeleteWithName:(NSString *)filename { + NSString *path = [_dataPath stringByAppendingPathComponent:filename]; + return [[NSFileManager defaultManager] removeItemAtPath:path error:NULL]; +} + +- (BOOL)_fileMoveAllToTrash { + CFUUIDRef uuidRef = CFUUIDCreate(NULL); + CFStringRef uuid = CFUUIDCreateString(NULL, uuidRef); + CFRelease(uuidRef); + NSString *tmpPath = [_trashPath stringByAppendingPathComponent:(__bridge NSString *)(uuid)]; + BOOL suc = [[NSFileManager defaultManager] moveItemAtPath:_dataPath toPath:tmpPath error:nil]; + if (suc) { + suc = [[NSFileManager defaultManager] createDirectoryAtPath:_dataPath withIntermediateDirectories:YES attributes:nil error:NULL]; + } + CFRelease(uuid); + return suc; +} + +- (void)_fileEmptyTrashInBackground { + NSString *trashPath = _trashPath; + dispatch_queue_t queue = _trashQueue; + dispatch_async(queue, ^{ + NSFileManager *manager = [NSFileManager new]; + NSArray *directoryContents = [manager contentsOfDirectoryAtPath:trashPath error:NULL]; + for (NSString *path in directoryContents) { + NSString *fullPath = [trashPath stringByAppendingPathComponent:path]; + [manager removeItemAtPath:fullPath error:NULL]; + } + }); +} + + +#pragma mark - private + +/** + Delete all files and empty in background. + Make sure the db is closed. + */ +- (void)_reset { + [[NSFileManager defaultManager] removeItemAtPath:[_path stringByAppendingPathComponent:kDBFileName] error:nil]; + [[NSFileManager defaultManager] removeItemAtPath:[_path stringByAppendingPathComponent:kDBShmFileName] error:nil]; + [[NSFileManager defaultManager] removeItemAtPath:[_path stringByAppendingPathComponent:kDBWalFileName] error:nil]; + [self _fileMoveAllToTrash]; + [self _fileEmptyTrashInBackground]; +} + +#pragma mark - public + +- (instancetype)init { + @throw [NSException exceptionWithName:@"YYKVStorage init error" reason:@"Please use the designated initializer and pass the 'path' and 'type'." userInfo:nil]; + return [self initWithPath:@"" type:YYKVStorageTypeFile]; +} + +- (instancetype)initWithPath:(NSString *)path type:(YYKVStorageType)type { + if (path.length == 0 || path.length > kPathLengthMax) { + NSLog(@"YYKVStorage init error: invalid path: [%@].", path); + return nil; + } + if (type > YYKVStorageTypeMixed) { + NSLog(@"YYKVStorage init error: invalid type: %lu.", (unsigned long)type); + return nil; + } + + self = [super init]; + _path = path.copy; + _type = type; + _dataPath = [path stringByAppendingPathComponent:kDataDirectoryName]; + _trashPath = [path stringByAppendingPathComponent:kTrashDirectoryName]; + _trashQueue = dispatch_queue_create("com.ibireme.cache.disk.trash", DISPATCH_QUEUE_SERIAL); + _dbPath = [path stringByAppendingPathComponent:kDBFileName]; + _errorLogsEnabled = YES; + NSError *error = nil; + if (![[NSFileManager defaultManager] createDirectoryAtPath:path + withIntermediateDirectories:YES + attributes:nil + error:&error] || + ![[NSFileManager defaultManager] createDirectoryAtPath:[path stringByAppendingPathComponent:kDataDirectoryName] + withIntermediateDirectories:YES + attributes:nil + error:&error] || + ![[NSFileManager defaultManager] createDirectoryAtPath:[path stringByAppendingPathComponent:kTrashDirectoryName] + withIntermediateDirectories:YES + attributes:nil + error:&error]) { + NSLog(@"YYKVStorage init error:%@", error); + return nil; + } + + if (![self _dbOpen] || ![self _dbInitialize]) { + // db file may broken... + [self _dbClose]; + [self _reset]; // rebuild + if (![self _dbOpen] || ![self _dbInitialize]) { + [self _dbClose]; + NSLog(@"YYKVStorage init error: fail to open sqlite db."); + return nil; + } + } + [self _fileEmptyTrashInBackground]; // empty the trash if failed at last time + return self; +} + +- (void)dealloc { + UIBackgroundTaskIdentifier taskID = [_YYSharedApplication() beginBackgroundTaskWithExpirationHandler:^{}]; + [self _dbClose]; + if (taskID != UIBackgroundTaskInvalid) { + [_YYSharedApplication() endBackgroundTask:taskID]; + } +} + +- (BOOL)saveItem:(YYKVStorageItem *)item { + return [self saveItemWithKey:item.key value:item.value filename:item.filename extendedData:item.extendedData]; +} + +- (BOOL)saveItemWithKey:(NSString *)key value:(NSData *)value { + return [self saveItemWithKey:key value:value filename:nil extendedData:nil]; +} + +- (BOOL)saveItemWithKey:(NSString *)key value:(NSData *)value filename:(NSString *)filename extendedData:(NSData *)extendedData { + if (key.length == 0 || value.length == 0) return NO; + if (_type == YYKVStorageTypeFile && filename.length == 0) { + return NO; + } + + if (filename.length) { + if (![self _fileWriteWithName:filename data:value]) { + return NO; + } + if (![self _dbSaveWithKey:key value:value fileName:filename extendedData:extendedData]) { + [self _fileDeleteWithName:filename]; + return NO; + } + return YES; + } else { + if (_type != YYKVStorageTypeSQLite) { + NSString *filename = [self _dbGetFilenameWithKey:key]; + if (filename) { + [self _fileDeleteWithName:filename]; + } + } + return [self _dbSaveWithKey:key value:value fileName:nil extendedData:extendedData]; + } +} + +- (BOOL)removeItemForKey:(NSString *)key { + if (key.length == 0) return NO; + switch (_type) { + case YYKVStorageTypeSQLite: { + return [self _dbDeleteItemWithKey:key]; + } break; + case YYKVStorageTypeFile: + case YYKVStorageTypeMixed: { + NSString *filename = [self _dbGetFilenameWithKey:key]; + if (filename) { + [self _fileDeleteWithName:filename]; + } + return [self _dbDeleteItemWithKey:key]; + } break; + default: return NO; + } +} + +- (BOOL)removeItemForKeys:(NSArray *)keys { + if (keys.count == 0) return NO; + switch (_type) { + case YYKVStorageTypeSQLite: { + return [self _dbDeleteItemWithKeys:keys]; + } break; + case YYKVStorageTypeFile: + case YYKVStorageTypeMixed: { + NSArray *filenames = [self _dbGetFilenameWithKeys:keys]; + for (NSString *filename in filenames) { + [self _fileDeleteWithName:filename]; + } + return [self _dbDeleteItemWithKeys:keys]; + } break; + default: return NO; + } +} + +- (BOOL)removeItemsLargerThanSize:(int)size { + if (size == INT_MAX) return YES; + if (size <= 0) return [self removeAllItems]; + + switch (_type) { + case YYKVStorageTypeSQLite: { + if ([self _dbDeleteItemsWithSizeLargerThan:size]) { + [self _dbCheckpoint]; + return YES; + } + } break; + case YYKVStorageTypeFile: + case YYKVStorageTypeMixed: { + NSArray *filenames = [self _dbGetFilenamesWithSizeLargerThan:size]; + for (NSString *name in filenames) { + [self _fileDeleteWithName:name]; + } + if ([self _dbDeleteItemsWithSizeLargerThan:size]) { + [self _dbCheckpoint]; + return YES; + } + } break; + } + return NO; +} + +- (BOOL)removeItemsEarlierThanTime:(int)time { + if (time <= 0) return YES; + if (time == INT_MAX) return [self removeAllItems]; + + switch (_type) { + case YYKVStorageTypeSQLite: { + if ([self _dbDeleteItemsWithTimeEarlierThan:time]) { + [self _dbCheckpoint]; + return YES; + } + } break; + case YYKVStorageTypeFile: + case YYKVStorageTypeMixed: { + NSArray *filenames = [self _dbGetFilenamesWithTimeEarlierThan:time]; + for (NSString *name in filenames) { + [self _fileDeleteWithName:name]; + } + if ([self _dbDeleteItemsWithTimeEarlierThan:time]) { + [self _dbCheckpoint]; + return YES; + } + } break; + } + return NO; +} + +- (BOOL)removeItemsToFitSize:(int)maxSize { + if (maxSize == INT_MAX) return YES; + if (maxSize <= 0) return [self removeAllItems]; + + int total = [self _dbGetTotalItemSize]; + if (total < 0) return NO; + if (total <= maxSize) return YES; + + NSArray *items = nil; + BOOL suc = NO; + do { + int perCount = 16; + items = [self _dbGetItemSizeInfoOrderByTimeAscWithLimit:perCount]; + for (YYKVStorageItem *item in items) { + if (total > maxSize) { + if (item.filename) { + [self _fileDeleteWithName:item.filename]; + } + suc = [self _dbDeleteItemWithKey:item.key]; + total -= item.size; + } else { + break; + } + if (!suc) break; + } + } while (total > maxSize && items.count > 0 && suc); + if (suc) [self _dbCheckpoint]; + return suc; +} + +- (BOOL)removeItemsToFitCount:(int)maxCount { + if (maxCount == INT_MAX) return YES; + if (maxCount <= 0) return [self removeAllItems]; + + int total = [self _dbGetTotalItemCount]; + if (total < 0) return NO; + if (total <= maxCount) return YES; + + NSArray *items = nil; + BOOL suc = NO; + do { + int perCount = 16; + items = [self _dbGetItemSizeInfoOrderByTimeAscWithLimit:perCount]; + for (YYKVStorageItem *item in items) { + if (total > maxCount) { + if (item.filename) { + [self _fileDeleteWithName:item.filename]; + } + suc = [self _dbDeleteItemWithKey:item.key]; + total--; + } else { + break; + } + if (!suc) break; + } + } while (total > maxCount && items.count > 0 && suc); + if (suc) [self _dbCheckpoint]; + return suc; +} + +- (BOOL)removeAllItems { + if (![self _dbClose]) return NO; + [self _reset]; + if (![self _dbOpen]) return NO; + if (![self _dbInitialize]) return NO; + return YES; +} + +- (void)removeAllItemsWithProgressBlock:(void(^)(int removedCount, int totalCount))progress + endBlock:(void(^)(BOOL error))end { + + int total = [self _dbGetTotalItemCount]; + if (total <= 0) { + if (end) end(total < 0); + } else { + int left = total; + int perCount = 32; + NSArray *items = nil; + BOOL suc = NO; + do { + items = [self _dbGetItemSizeInfoOrderByTimeAscWithLimit:perCount]; + for (YYKVStorageItem *item in items) { + if (left > 0) { + if (item.filename) { + [self _fileDeleteWithName:item.filename]; + } + suc = [self _dbDeleteItemWithKey:item.key]; + left--; + } else { + break; + } + if (!suc) break; + } + if (progress) progress(total - left, total); + } while (left > 0 && items.count > 0 && suc); + if (suc) [self _dbCheckpoint]; + if (end) end(!suc); + } +} + +- (YYKVStorageItem *)getItemForKey:(NSString *)key { + if (key.length == 0) return nil; + YYKVStorageItem *item = [self _dbGetItemWithKey:key excludeInlineData:NO]; + if (item) { + [self _dbUpdateAccessTimeWithKey:key]; + if (item.filename) { + item.value = [self _fileReadWithName:item.filename]; + if (!item.value) { + [self _dbDeleteItemWithKey:key]; + item = nil; + } + } + } + return item; +} + +- (YYKVStorageItem *)getItemInfoForKey:(NSString *)key { + if (key.length == 0) return nil; + YYKVStorageItem *item = [self _dbGetItemWithKey:key excludeInlineData:YES]; + return item; +} + +- (NSData *)getItemValueForKey:(NSString *)key { + if (key.length == 0) return nil; + NSData *value = nil; + switch (_type) { + case YYKVStorageTypeFile: { + NSString *filename = [self _dbGetFilenameWithKey:key]; + if (filename) { + value = [self _fileReadWithName:filename]; + if (!value) { + [self _dbDeleteItemWithKey:key]; + value = nil; + } + } + } break; + case YYKVStorageTypeSQLite: { + value = [self _dbGetValueWithKey:key]; + } break; + case YYKVStorageTypeMixed: { + NSString *filename = [self _dbGetFilenameWithKey:key]; + if (filename) { + value = [self _fileReadWithName:filename]; + if (!value) { + [self _dbDeleteItemWithKey:key]; + value = nil; + } + } else { + value = [self _dbGetValueWithKey:key]; + } + } break; + } + if (value) { + [self _dbUpdateAccessTimeWithKey:key]; + } + return value; +} + +- (NSArray *)getItemForKeys:(NSArray *)keys { + if (keys.count == 0) return nil; + NSMutableArray *items = [self _dbGetItemWithKeys:keys excludeInlineData:NO]; + if (_type != YYKVStorageTypeSQLite) { + for (NSInteger i = 0, max = items.count; i < max; i++) { + YYKVStorageItem *item = items[i]; + if (item.filename) { + item.value = [self _fileReadWithName:item.filename]; + if (!item.value) { + if (item.key) [self _dbDeleteItemWithKey:item.key]; + [items removeObjectAtIndex:i]; + i--; + max--; + } + } + } + } + if (items.count > 0) { + [self _dbUpdateAccessTimeWithKeys:keys]; + } + return items.count ? items : nil; +} + +- (NSArray *)getItemInfoForKeys:(NSArray *)keys { + if (keys.count == 0) return nil; + return [self _dbGetItemWithKeys:keys excludeInlineData:YES]; +} + +- (NSDictionary *)getItemValueForKeys:(NSArray *)keys { + NSMutableArray *items = (NSMutableArray *)[self getItemForKeys:keys]; + NSMutableDictionary *kv = [NSMutableDictionary new]; + for (YYKVStorageItem *item in items) { + if (item.key && item.value) { + [kv setObject:item.value forKey:item.key]; + } + } + return kv.count ? kv : nil; +} + +- (BOOL)itemExistsForKey:(NSString *)key { + if (key.length == 0) return NO; + return [self _dbGetItemCountWithKey:key] > 0; +} + +- (int)getItemsCount { + return [self _dbGetTotalItemCount]; +} + +- (int)getItemsSize { + return [self _dbGetTotalItemSize]; +} + +@end diff --git a/Ifish/YYWebImage/Cache/YYMemoryCache.h b/Ifish/YYWebImage/Cache/YYMemoryCache.h new file mode 100644 index 0000000..ded8440 --- /dev/null +++ b/Ifish/YYWebImage/Cache/YYMemoryCache.h @@ -0,0 +1,213 @@ +// +// YYMemoryCache.h +// YYCache +// +// Created by ibireme on 15/2/7. +// Copyright (c) 2015 ibireme. +// +// This source code is licensed under the MIT-style license found in the +// LICENSE file in the root directory of this source tree. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +/** + YYMemoryCache is a fast in-memory cache that stores key-value pairs. + In contrast to NSDictionary, keys are retained and not copied. + The API and performance is similar to `NSCache`, all methods are thread-safe. + + YYMemoryCache objects differ from NSCache in a few ways: + + * It uses LRU (least-recently-used) to remove objects; NSCache's eviction method + is non-deterministic. + * It can be controlled by cost, count and age; NSCache's limits are imprecise. + * It can be configured to automatically evict objects when receive memory + warning or app enter background. + + The time of `Access Methods` in YYMemoryCache is typically in constant time (O(1)). + */ +@interface YYMemoryCache : NSObject + +#pragma mark - Attribute +///============================================================================= +/// @name Attribute +///============================================================================= + +/** The name of the cache. Default is nil. */ +@property (nullable, copy) NSString *name; + +/** The number of objects in the cache (read-only) */ +@property (readonly) NSUInteger totalCount; + +/** The total cost of objects in the cache (read-only). */ +@property (readonly) NSUInteger totalCost; + + +#pragma mark - Limit +///============================================================================= +/// @name Limit +///============================================================================= + +/** + The maximum number of objects the cache should hold. + + @discussion The default value is NSUIntegerMax, which means no limit. + This is not a strict limit—if the cache goes over the limit, some objects in the + cache could be evicted later in backgound thread. + */ +@property NSUInteger countLimit; + +/** + The maximum total cost that the cache can hold before it starts evicting objects. + + @discussion The default value is NSUIntegerMax, which means no limit. + This is not a strict limit—if the cache goes over the limit, some objects in the + cache could be evicted later in backgound thread. + */ +@property NSUInteger costLimit; + +/** + The maximum expiry time of objects in cache. + + @discussion The default value is DBL_MAX, which means no limit. + This is not a strict limit—if an object goes over the limit, the object could + be evicted later in backgound thread. + */ +@property NSTimeInterval ageLimit; + +/** + The auto trim check time interval in seconds. Default is 5.0. + + @discussion The cache holds an internal timer to check whether the cache reaches + its limits, and if the limit is reached, it begins to evict objects. + */ +@property NSTimeInterval autoTrimInterval; + +/** + If `YES`, the cache will remove all objects when the app receives a memory warning. + The default value is `YES`. + */ +@property BOOL shouldRemoveAllObjectsOnMemoryWarning; + +/** + If `YES`, The cache will remove all objects when the app enter background. + The default value is `YES`. + */ +@property BOOL shouldRemoveAllObjectsWhenEnteringBackground; + +/** + A block to be executed when the app receives a memory warning. + The default value is nil. + */ +@property (nullable, copy) void(^didReceiveMemoryWarningBlock)(YYMemoryCache *cache); + +/** + A block to be executed when the app enter background. + The default value is nil. + */ +@property (nullable, copy) void(^didEnterBackgroundBlock)(YYMemoryCache *cache); + +/** + If `YES`, the key-value pair will be released on main thread, otherwise on + background thread. Default is NO. + + @discussion You may set this value to `YES` if the key-value object contains + the instance which should be released in main thread (such as UIView/CALayer). + */ +@property BOOL releaseOnMainThread; + +/** + If `YES`, the key-value pair will be released asynchronously to avoid blocking + the access methods, otherwise it will be released in the access method + (such as removeObjectForKey:). Default is YES. + */ +@property BOOL releaseAsynchronously; + + +#pragma mark - Access Methods +///============================================================================= +/// @name Access Methods +///============================================================================= + +/** + Returns a Boolean value that indicates whether a given key is in cache. + + @param key An object identifying the value. If nil, just return `NO`. + @return Whether the key is in cache. + */ +- (BOOL)containsObjectForKey:(id)key; + +/** + 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:(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:(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:(id)key withCost:(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:(id)key; + +/** + Empties the cache immediately. + */ +- (void)removeAllObjects; + + +#pragma mark - Trim +///============================================================================= +/// @name Trim +///============================================================================= + +/** + Removes objects from the cache with LRU, until the `totalCount` is below or equal to + the specified value. + @param count The total count allowed to remain after the cache has been trimmed. + */ +- (void)trimToCount:(NSUInteger)count; + +/** + Removes objects from the cache with LRU, until the `totalCost` is or equal to + the specified value. + @param cost The total cost allowed to remain after the cache has been trimmed. + */ +- (void)trimToCost:(NSUInteger)cost; + +/** + Removes objects from the cache with LRU, until all expiry objects removed by the + specified value. + @param age The maximum age (in seconds) of objects. + */ +- (void)trimToAge:(NSTimeInterval)age; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Ifish/YYWebImage/Cache/YYMemoryCache.m b/Ifish/YYWebImage/Cache/YYMemoryCache.m new file mode 100644 index 0000000..9042d9b --- /dev/null +++ b/Ifish/YYWebImage/Cache/YYMemoryCache.m @@ -0,0 +1,505 @@ +// +// YYMemoryCache.m +// YYCache +// +// Created by ibireme on 15/2/7. +// Copyright (c) 2015 ibireme. +// +// This source code is licensed under the MIT-style license found in the +// LICENSE file in the root directory of this source tree. +// + +#import "YYMemoryCache.h" +#import +#import +#import +#import + + +static inline dispatch_queue_t YYMemoryCacheGetReleaseQueue() { + return dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0); +} + +/** + A node in linked map. + Typically, you should not use this class directly. + */ +@interface _YYLinkedMapNode : NSObject { + @package + __unsafe_unretained _YYLinkedMapNode *_prev; // retained by dic + __unsafe_unretained _YYLinkedMapNode *_next; // retained by dic + id _key; + id _value; + NSUInteger _cost; + NSTimeInterval _time; +} +@end + +@implementation _YYLinkedMapNode +@end + + +/** + A linked map used by YYMemoryCache. + It's not thread-safe and does not validate the parameters. + + Typically, you should not use this class directly. + */ +@interface _YYLinkedMap : NSObject { + @package + CFMutableDictionaryRef _dic; // do not set object directly + NSUInteger _totalCost; + NSUInteger _totalCount; + _YYLinkedMapNode *_head; // MRU, do not change it directly + _YYLinkedMapNode *_tail; // LRU, do not change it directly + BOOL _releaseOnMainThread; + BOOL _releaseAsynchronously; +} + +/// Insert a node at head and update the total cost. +/// Node and node.key should not be nil. +- (void)insertNodeAtHead:(_YYLinkedMapNode *)node; + +/// Bring a inner node to header. +/// Node should already inside the dic. +- (void)bringNodeToHead:(_YYLinkedMapNode *)node; + +/// Remove a inner node and update the total cost. +/// Node should already inside the dic. +- (void)removeNode:(_YYLinkedMapNode *)node; + +/// Remove tail node if exist. +- (_YYLinkedMapNode *)removeTailNode; + +/// Remove all node in background queue. +- (void)removeAll; + +@end + +@implementation _YYLinkedMap + +- (instancetype)init { + self = [super init]; + _dic = CFDictionaryCreateMutable(CFAllocatorGetDefault(), 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); + _releaseOnMainThread = NO; + _releaseAsynchronously = YES; + return self; +} + +- (void)dealloc { + CFRelease(_dic); +} + +- (void)insertNodeAtHead:(_YYLinkedMapNode *)node { + CFDictionarySetValue(_dic, (__bridge const void *)(node->_key), (__bridge const void *)(node)); + _totalCost += node->_cost; + _totalCount++; + if (_head) { + node->_next = _head; + _head->_prev = node; + _head = node; + } else { + _head = _tail = node; + } +} + +- (void)bringNodeToHead:(_YYLinkedMapNode *)node { + if (_head == node) return; + + if (_tail == node) { + _tail = node->_prev; + _tail->_next = nil; + } else { + node->_next->_prev = node->_prev; + node->_prev->_next = node->_next; + } + node->_next = _head; + node->_prev = nil; + _head->_prev = node; + _head = node; +} + +- (void)removeNode:(_YYLinkedMapNode *)node { + CFDictionaryRemoveValue(_dic, (__bridge const void *)(node->_key)); + _totalCost -= node->_cost; + _totalCount--; + if (node->_next) node->_next->_prev = node->_prev; + if (node->_prev) node->_prev->_next = node->_next; + if (_head == node) _head = node->_next; + if (_tail == node) _tail = node->_prev; +} + +- (_YYLinkedMapNode *)removeTailNode { + if (!_tail) return nil; + _YYLinkedMapNode *tail = _tail; + CFDictionaryRemoveValue(_dic, (__bridge const void *)(_tail->_key)); + _totalCost -= _tail->_cost; + _totalCount--; + if (_head == _tail) { + _head = _tail = nil; + } else { + _tail = _tail->_prev; + _tail->_next = nil; + } + return tail; +} + +- (void)removeAll { + _totalCost = 0; + _totalCount = 0; + _head = nil; + _tail = nil; + if (CFDictionaryGetCount(_dic) > 0) { + CFMutableDictionaryRef holder = _dic; + _dic = CFDictionaryCreateMutable(CFAllocatorGetDefault(), 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); + + if (_releaseAsynchronously) { + dispatch_queue_t queue = _releaseOnMainThread ? dispatch_get_main_queue() : YYMemoryCacheGetReleaseQueue(); + dispatch_async(queue, ^{ + CFRelease(holder); // hold and release in specified queue + }); + } else if (_releaseOnMainThread && !pthread_main_np()) { + dispatch_async(dispatch_get_main_queue(), ^{ + CFRelease(holder); // hold and release in specified queue + }); + } else { + CFRelease(holder); + } + } +} + +@end + + + +@implementation YYMemoryCache { + pthread_mutex_t _lock; + _YYLinkedMap *_lru; + dispatch_queue_t _queue; +} + +- (void)_trimRecursively { + __weak typeof(self) _self = self; + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(_autoTrimInterval * NSEC_PER_SEC)), dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{ + __strong typeof(_self) self = _self; + if (!self) return; + [self _trimInBackground]; + [self _trimRecursively]; + }); +} + +- (void)_trimInBackground { + dispatch_async(_queue, ^{ + [self _trimToCost:self->_costLimit]; + [self _trimToCount:self->_countLimit]; + [self _trimToAge:self->_ageLimit]; + }); +} + +- (void)_trimToCost:(NSUInteger)costLimit { + BOOL finish = NO; + pthread_mutex_lock(&_lock); + if (costLimit == 0) { + [_lru removeAll]; + finish = YES; + } else if (_lru->_totalCost <= costLimit) { + finish = YES; + } + pthread_mutex_unlock(&_lock); + if (finish) return; + + NSMutableArray *holder = [NSMutableArray new]; + while (!finish) { + if (pthread_mutex_trylock(&_lock) == 0) { + if (_lru->_totalCost > costLimit) { + _YYLinkedMapNode *node = [_lru removeTailNode]; + if (node) [holder addObject:node]; + } else { + finish = YES; + } + pthread_mutex_unlock(&_lock); + } else { + usleep(10 * 1000); //10 ms + } + } + if (holder.count) { + dispatch_queue_t queue = _lru->_releaseOnMainThread ? dispatch_get_main_queue() : YYMemoryCacheGetReleaseQueue(); + dispatch_async(queue, ^{ + [holder count]; // release in queue + }); + } +} + +- (void)_trimToCount:(NSUInteger)countLimit { + BOOL finish = NO; + pthread_mutex_lock(&_lock); + if (countLimit == 0) { + [_lru removeAll]; + finish = YES; + } else if (_lru->_totalCount <= countLimit) { + finish = YES; + } + pthread_mutex_unlock(&_lock); + if (finish) return; + + NSMutableArray *holder = [NSMutableArray new]; + while (!finish) { + if (pthread_mutex_trylock(&_lock) == 0) { + if (_lru->_totalCount > countLimit) { + _YYLinkedMapNode *node = [_lru removeTailNode]; + if (node) [holder addObject:node]; + } else { + finish = YES; + } + pthread_mutex_unlock(&_lock); + } else { + usleep(10 * 1000); //10 ms + } + } + if (holder.count) { + dispatch_queue_t queue = _lru->_releaseOnMainThread ? dispatch_get_main_queue() : YYMemoryCacheGetReleaseQueue(); + dispatch_async(queue, ^{ + [holder count]; // release in queue + }); + } +} + +- (void)_trimToAge:(NSTimeInterval)ageLimit { + BOOL finish = NO; + NSTimeInterval now = CACurrentMediaTime(); + pthread_mutex_lock(&_lock); + if (ageLimit <= 0) { + [_lru removeAll]; + finish = YES; + } else if (!_lru->_tail || (now - _lru->_tail->_time) <= ageLimit) { + finish = YES; + } + pthread_mutex_unlock(&_lock); + if (finish) return; + + NSMutableArray *holder = [NSMutableArray new]; + while (!finish) { + if (pthread_mutex_trylock(&_lock) == 0) { + if (_lru->_tail && (now - _lru->_tail->_time) > ageLimit) { + _YYLinkedMapNode *node = [_lru removeTailNode]; + if (node) [holder addObject:node]; + } else { + finish = YES; + } + pthread_mutex_unlock(&_lock); + } else { + usleep(10 * 1000); //10 ms + } + } + if (holder.count) { + dispatch_queue_t queue = _lru->_releaseOnMainThread ? dispatch_get_main_queue() : YYMemoryCacheGetReleaseQueue(); + dispatch_async(queue, ^{ + [holder count]; // release in queue + }); + } +} + +- (void)_appDidReceiveMemoryWarningNotification { + if (self.didReceiveMemoryWarningBlock) { + self.didReceiveMemoryWarningBlock(self); + } + if (self.shouldRemoveAllObjectsOnMemoryWarning) { + [self removeAllObjects]; + } +} + +- (void)_appDidEnterBackgroundNotification { + if (self.didEnterBackgroundBlock) { + self.didEnterBackgroundBlock(self); + } + if (self.shouldRemoveAllObjectsWhenEnteringBackground) { + [self removeAllObjects]; + } +} + +#pragma mark - public + +- (instancetype)init { + self = super.init; + pthread_mutex_init(&_lock, NULL); + _lru = [_YYLinkedMap new]; + _queue = dispatch_queue_create("com.ibireme.cache.memory", DISPATCH_QUEUE_SERIAL); + + _countLimit = NSUIntegerMax; + _costLimit = NSUIntegerMax; + _ageLimit = DBL_MAX; + _autoTrimInterval = 5.0; + _shouldRemoveAllObjectsOnMemoryWarning = YES; + _shouldRemoveAllObjectsWhenEnteringBackground = YES; + + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_appDidReceiveMemoryWarningNotification) name:UIApplicationDidReceiveMemoryWarningNotification object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_appDidEnterBackgroundNotification) name:UIApplicationDidEnterBackgroundNotification object:nil]; + + [self _trimRecursively]; + return self; +} + +- (void)dealloc { + [[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationDidReceiveMemoryWarningNotification object:nil]; + [[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationDidEnterBackgroundNotification object:nil]; + [_lru removeAll]; + pthread_mutex_destroy(&_lock); +} + +- (NSUInteger)totalCount { + pthread_mutex_lock(&_lock); + NSUInteger count = _lru->_totalCount; + pthread_mutex_unlock(&_lock); + return count; +} + +- (NSUInteger)totalCost { + pthread_mutex_lock(&_lock); + NSUInteger totalCost = _lru->_totalCost; + pthread_mutex_unlock(&_lock); + return totalCost; +} + +- (BOOL)releaseOnMainThread { + pthread_mutex_lock(&_lock); + BOOL releaseOnMainThread = _lru->_releaseOnMainThread; + pthread_mutex_unlock(&_lock); + return releaseOnMainThread; +} + +- (void)setReleaseOnMainThread:(BOOL)releaseOnMainThread { + pthread_mutex_lock(&_lock); + _lru->_releaseOnMainThread = releaseOnMainThread; + pthread_mutex_unlock(&_lock); +} + +- (BOOL)releaseAsynchronously { + pthread_mutex_lock(&_lock); + BOOL releaseAsynchronously = _lru->_releaseAsynchronously; + pthread_mutex_unlock(&_lock); + return releaseAsynchronously; +} + +- (void)setReleaseAsynchronously:(BOOL)releaseAsynchronously { + pthread_mutex_lock(&_lock); + _lru->_releaseAsynchronously = releaseAsynchronously; + pthread_mutex_unlock(&_lock); +} + +- (BOOL)containsObjectForKey:(id)key { + if (!key) return NO; + pthread_mutex_lock(&_lock); + BOOL contains = CFDictionaryContainsKey(_lru->_dic, (__bridge const void *)(key)); + pthread_mutex_unlock(&_lock); + return contains; +} + +- (id)objectForKey:(id)key { + if (!key) return nil; + pthread_mutex_lock(&_lock); + _YYLinkedMapNode *node = CFDictionaryGetValue(_lru->_dic, (__bridge const void *)(key)); + if (node) { + node->_time = CACurrentMediaTime(); + [_lru bringNodeToHead:node]; + } + pthread_mutex_unlock(&_lock); + return node ? node->_value : nil; +} + +- (void)setObject:(id)object forKey:(id)key { + [self setObject:object forKey:key withCost:0]; +} + +- (void)setObject:(id)object forKey:(id)key withCost:(NSUInteger)cost { + if (!key) return; + if (!object) { + [self removeObjectForKey:key]; + return; + } + pthread_mutex_lock(&_lock); + _YYLinkedMapNode *node = CFDictionaryGetValue(_lru->_dic, (__bridge const void *)(key)); + NSTimeInterval now = CACurrentMediaTime(); + if (node) { + _lru->_totalCost -= node->_cost; + _lru->_totalCost += cost; + node->_cost = cost; + node->_time = now; + node->_value = object; + [_lru bringNodeToHead:node]; + } else { + node = [_YYLinkedMapNode new]; + node->_cost = cost; + node->_time = now; + node->_key = key; + node->_value = object; + [_lru insertNodeAtHead:node]; + } + if (_lru->_totalCost > _costLimit) { + dispatch_async(_queue, ^{ + [self trimToCost:_costLimit]; + }); + } + if (_lru->_totalCount > _countLimit) { + _YYLinkedMapNode *node = [_lru removeTailNode]; + if (_lru->_releaseAsynchronously) { + dispatch_queue_t queue = _lru->_releaseOnMainThread ? dispatch_get_main_queue() : YYMemoryCacheGetReleaseQueue(); + dispatch_async(queue, ^{ + [node class]; //hold and release in queue + }); + } else if (_lru->_releaseOnMainThread && !pthread_main_np()) { + dispatch_async(dispatch_get_main_queue(), ^{ + [node class]; //hold and release in queue + }); + } + } + pthread_mutex_unlock(&_lock); +} + +- (void)removeObjectForKey:(id)key { + if (!key) return; + pthread_mutex_lock(&_lock); + _YYLinkedMapNode *node = CFDictionaryGetValue(_lru->_dic, (__bridge const void *)(key)); + if (node) { + [_lru removeNode:node]; + if (_lru->_releaseAsynchronously) { + dispatch_queue_t queue = _lru->_releaseOnMainThread ? dispatch_get_main_queue() : YYMemoryCacheGetReleaseQueue(); + dispatch_async(queue, ^{ + [node class]; //hold and release in queue + }); + } else if (_lru->_releaseOnMainThread && !pthread_main_np()) { + dispatch_async(dispatch_get_main_queue(), ^{ + [node class]; //hold and release in queue + }); + } + } + pthread_mutex_unlock(&_lock); +} + +- (void)removeAllObjects { + pthread_mutex_lock(&_lock); + [_lru removeAll]; + pthread_mutex_unlock(&_lock); +} + +- (void)trimToCount:(NSUInteger)count { + if (count == 0) { + [self removeAllObjects]; + return; + } + [self _trimToCount:count]; +} + +- (void)trimToCost:(NSUInteger)cost { + [self _trimToCost:cost]; +} + +- (void)trimToAge:(NSTimeInterval)age { + [self _trimToAge:age]; +} + +- (NSString *)description { + if (_name) return [NSString stringWithFormat:@"<%@: %p> (%@)", self.class, self, _name]; + else return [NSString stringWithFormat:@"<%@: %p>", self.class, self]; +} + +@end diff --git a/Ifish/controllers/FishTinkController/maincontroller/CenterontrolControllers/XuTo/Xuanduo2DataUtility.m b/Ifish/controllers/FishTinkController/maincontroller/CenterontrolControllers/XuTo/Xuanduo2DataUtility.m index 7da8df2..64e8a38 100644 --- a/Ifish/controllers/FishTinkController/maincontroller/CenterontrolControllers/XuTo/Xuanduo2DataUtility.m +++ b/Ifish/controllers/FishTinkController/maincontroller/CenterontrolControllers/XuTo/Xuanduo2DataUtility.m @@ -12,21 +12,28 @@ +(void)readSocketDataWithBackMsgModel:(Xuanduo2Model*)xuanduoModel addWithBackData:(NSData*)data{ NSString *dataString = [dataContorl dataToHexString:data];// 转十六进制 - xuanduoModel.gasPump = [dataString substringWithRange:NSMakeRange(30, 4)]; - xuanduoModel.light1 = [dataString substringWithRange:NSMakeRange(34, 4)]; - xuanduoModel.light2 = [dataString substringWithRange:NSMakeRange(38, 4)]; - xuanduoModel.waterPump = [dataString substringWithRange:NSMakeRange(42, 4)]; - xuanduoModel.uvLamp = [dataString substringWithRange:NSMakeRange(46, 4)]; - xuanduoModel.waveMakingPump = [dataString substringWithRange:NSMakeRange(50, 4)]; - xuanduoModel.status = [dataString substringWithRange:NSMakeRange(54, 4)]; - xuanduoModel.heatStatus = [dataString substringWithRange:NSMakeRange(58, 2)]; - xuanduoModel.waterTemperature = [dataString substringWithRange:NSMakeRange(60, 4)]; - xuanduoModel.heatingTemperature = [dataString substringWithRange:NSMakeRange(64, 4)]; - xuanduoModel.huliLight = [dataString substringWithRange:NSMakeRange(68, 2)]; - xuanduoModel.electricity = [dataString substringWithRange:NSMakeRange(70, 4)]; - xuanduoModel.alarmSwitch = [dataString substringWithRange:NSMakeRange(74, 2)]; - xuanduoModel.miniTemp = [dataString substringWithRange:NSMakeRange(76, 4)]; - xuanduoModel.maxTemp = [dataString substringWithRange:NSMakeRange(80, 4)]; + @try { + xuanduoModel.gasPump = [dataString substringWithRange:NSMakeRange(30, 4)]; + xuanduoModel.light1 = [dataString substringWithRange:NSMakeRange(34, 4)]; + xuanduoModel.light2 = [dataString substringWithRange:NSMakeRange(38, 4)]; + xuanduoModel.waterPump = [dataString substringWithRange:NSMakeRange(42, 4)]; + xuanduoModel.uvLamp = [dataString substringWithRange:NSMakeRange(46, 4)]; + xuanduoModel.waveMakingPump = [dataString substringWithRange:NSMakeRange(50, 4)]; + xuanduoModel.status = [dataString substringWithRange:NSMakeRange(54, 4)]; + xuanduoModel.heatStatus = [dataString substringWithRange:NSMakeRange(58, 2)]; + xuanduoModel.waterTemperature = [dataString substringWithRange:NSMakeRange(60, 4)]; + xuanduoModel.heatingTemperature = [dataString substringWithRange:NSMakeRange(64, 4)]; + xuanduoModel.huliLight = [dataString substringWithRange:NSMakeRange(68, 2)]; + xuanduoModel.electricity = [dataString substringWithRange:NSMakeRange(70, 4)]; + xuanduoModel.alarmSwitch = [dataString substringWithRange:NSMakeRange(74, 2)]; + xuanduoModel.miniTemp = [dataString substringWithRange:NSMakeRange(76, 4)]; + xuanduoModel.maxTemp = [dataString substringWithRange:NSMakeRange(80, 4)]; + } @catch (NSException *exception) { + + } @finally { + + } + } +(void)resetNewXuanduoButtonState:(UIButton*)uvLightBtn gasPumpLight:(UIButton*)gasLightBtn light1:(UIButton*)light1Btn light2:(UIButton*)light2Btn waveLight:(UIButton*)waveLightBtn huliLight:(UIButton*)huliLightBtn waterLight:(UIButton*)waterLightBtn heatLight:(UIButton*)heatLightBtn withModel:(Xuanduo2Model*)backModel{ diff --git a/Ifish/controllers/FishTinkController/maincontroller/CenterontrolControllers/XuTo/Xuanduo2fController.m b/Ifish/controllers/FishTinkController/maincontroller/CenterontrolControllers/XuTo/Xuanduo2fController.m index c3d2fac..cdd512e 100644 --- a/Ifish/controllers/FishTinkController/maincontroller/CenterontrolControllers/XuTo/Xuanduo2fController.m +++ b/Ifish/controllers/FishTinkController/maincontroller/CenterontrolControllers/XuTo/Xuanduo2fController.m @@ -99,7 +99,7 @@ [self initCHNames]; [Socketsingleton sharedInstance].communiteDelegate = self; UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tempSwitch)]; - [self.tempLabel addGestureRecognizer:tap]; + // [self.tempLabel addGestureRecognizer:tap]; [self creatRefreshView]; } diff --git a/Ifish/controllers/IfishTabControllers/IfishADTimerViewController.m b/Ifish/controllers/IfishTabControllers/IfishADTimerViewController.m index aba61c9..4e6c3cd 100644 --- a/Ifish/controllers/IfishTabControllers/IfishADTimerViewController.m +++ b/Ifish/controllers/IfishTabControllers/IfishADTimerViewController.m @@ -12,6 +12,7 @@ #import "IfishMianTabViewController.h" #import "IfishAlibcWebViewController.h" #import +#import "RegistViewController.h" @interface IfishADTimerViewController () @property(nonatomic)UIActivityIndicatorView*indicatorView; @property(nonatomic,strong) NSString *adUrl; @@ -166,8 +167,23 @@ //设置根视图 -(void)setAppTabRoot{ - IfishMianTabViewController *mianVC=[[IfishMianTabViewController alloc] init]; - [UIApplication sharedApplication].delegate.window.rootViewController=mianVC; + UserModel*model=[dataContorl getUserInfo]; + NSUserDefaults*userdefult=[NSUserDefaults standardUserDefaults]; + BOOL skiped =[userdefult boolForKey:[CommonUtils getNotNilStr:model.unionId]]; + if (!skiped&&[CommonUtils getNotNilStr:model.phoneNumber].length==0&&[CommonUtils getNotNilStr:model.unionId].length) + { + + RegistViewController*revv=[[RegistViewController alloc]init]; + revv.isBind=YES; + revv.isFromLogin=YES; + [self.navigationController pushViewController:revv animated:YES]; + } + else + { + IfishMianTabViewController *mianVC=[[IfishMianTabViewController alloc] init]; + [UIApplication sharedApplication].delegate.window.rootViewController=mianVC; + } + } diff --git a/Ifish/controllers/IfishTabControllers/我的/mineControllers/IfishMeViewController.m b/Ifish/controllers/IfishTabControllers/我的/mineControllers/IfishMeViewController.m index c6313de..0881ad2 100644 --- a/Ifish/controllers/IfishTabControllers/我的/mineControllers/IfishMeViewController.m +++ b/Ifish/controllers/IfishTabControllers/我的/mineControllers/IfishMeViewController.m @@ -238,7 +238,9 @@ -(void)initImageView{ + UserModel*userModel=[[DataCenter defaultDtacenter]valueForKey:@"UserLogIn"]; + NSString*wechatImgUrl=[[NSUserDefaults standardUserDefaults] stringForKey:@"wechatImgUrl"]; NSString*fullpath=[[NSHomeDirectory() stringByAppendingPathComponent:@"Documents"]stringByAppendingPathComponent:@"avatar.png"]; UIImage*saveImage=[[UIImage alloc]initWithContentsOfFile:fullpath]; if (saveImage==nil) { @@ -260,14 +262,28 @@ // [_iconImageButton setBackgroundImage:[UIImage imageNamed:[NSString stringWithFormat:@"userIcon%d.png",i]] forState:UIControlStateNormal]; NSString*str=[NSString stringWithFormat:@"%@%@",kGetIconUrl,userModel.userImg]; + if (wechatImgUrl.length) + { + str=wechatImgUrl; + } + + + [self.userImg sd_setImageWithURL:[NSURL URLWithString:str] completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) { + NSLog(@"error=%@,%@",error,image); + }]; + + - [self.userImg sd_setImageWithURL:[NSURL URLWithString:str]]; } } }else{ NSString*str=[NSString stringWithFormat:@"%@%@",kGetIconUrl,userModel.userImg]; + if (wechatImgUrl.length) + { + str=wechatImgUrl; + } if ([str isEqualToString:kGetIconUrl]) { //int i = (arc4random()%7) + 1;// 设置随机头像 int i = 1; diff --git a/Ifish/controllers/IfishTabControllers/我的/mineControllers/IfishSetViewController.m b/Ifish/controllers/IfishTabControllers/我的/mineControllers/IfishSetViewController.m index 8ddffa6..3f090ce 100644 --- a/Ifish/controllers/IfishTabControllers/我的/mineControllers/IfishSetViewController.m +++ b/Ifish/controllers/IfishTabControllers/我的/mineControllers/IfishSetViewController.m @@ -14,7 +14,7 @@ #define TUICHUAlertTAg 4100 #import "IfishUserDefaultHelper.h" #import "SettingResetViewController.h" - +#import "RegistViewController.h" @interface IfishSetViewController () @property(nonatomic,strong)UITableView *tableView; @@ -34,9 +34,23 @@ extern BOOL firstLogIn; } -(void)loadData{ - self.titles=@[@[@"更换手机",@"修改密码",@"恢复出厂模式"],@[@"切换账号"]]; - self.imgs = @[@[@"personal_iocn_replace",@"replace_iocn_code",@"setting-reset"],@[@"personal_iocn_switch"]]; + + self.titles=@[@[@"更换手机",@"修改密码",@"恢复出厂模式"],@[@"切换账号",@"绑定手机"]]; + self.imgs = @[@[@"personal_iocn_replace",@"replace_iocn_code",@"setting-reset"],@[@"personal_iocn_switch",@"renyuan"]]; + UserModel*model=[dataContorl getUserInfo]; + if ([CommonUtils getNotNilStr:model.phoneNumber].length) + { + self.titles=@[@[@"更换手机",@"修改密码",@"恢复出厂模式"],@[@"切换账号"]]; + self.imgs = @[@[@"personal_iocn_replace",@"replace_iocn_code",@"setting-reset"],@[@"personal_iocn_switch"]]; + } + +} +-(void)viewWillAppear:(BOOL)animated +{ + [super viewWillAppear:animated]; + [self loadData]; + [self.tableView reloadData]; } -(void)creatTab{ @@ -130,6 +144,15 @@ extern BOOL firstLogIn; [alert show]; } + else if (indexPath.section==1&&indexPath.row==1){ + + RegistViewController*revc=[[RegistViewController alloc]init]; + revc.hidesBottomBarWhenPushed=YES; + revc.isBind=YES; + [self.navigationController pushViewController:revc animated:YES]; + + + } } diff --git a/Ifish/controllers/IfishTabControllers/我的/mineControllers/pushSetControllrs/AboutUsViewController.m b/Ifish/controllers/IfishTabControllers/我的/mineControllers/pushSetControllrs/AboutUsViewController.m index 136f471..0077557 100644 --- a/Ifish/controllers/IfishTabControllers/我的/mineControllers/pushSetControllrs/AboutUsViewController.m +++ b/Ifish/controllers/IfishTabControllers/我的/mineControllers/pushSetControllrs/AboutUsViewController.m @@ -25,6 +25,7 @@ // CFShow((__bridge CFTypeRef)(infoDic)); NSString *app_Version=[infoDic objectForKey:@"CFBundleShortVersionString"]; NSLog(@"app_Version%@",app_Version); + app_Version=@"4.7.4"; NSString *versionStr = [NSString stringWithFormat:@"v%@",app_Version]; NSString *buildVersion = [infoDic objectForKey:@"CFBundleVersion"]; if (buildVersion.length > 0) { diff --git a/Ifish/controllers/IfishTabControllers/探索/IfishTanSuoViewCell.m b/Ifish/controllers/IfishTabControllers/探索/IfishTanSuoViewCell.m index 92cef78..0b621db 100644 --- a/Ifish/controllers/IfishTabControllers/探索/IfishTanSuoViewCell.m +++ b/Ifish/controllers/IfishTabControllers/探索/IfishTanSuoViewCell.m @@ -37,8 +37,12 @@ attch.image = [UIImage imageNamed:@"explore_iocn_authentication"]; attch.bounds = CGRectMake(0,0, 12, 10); } - NSAttributedString *str=[NSAttributedString attributedStringWithAttachment:attch]; - [attri appendAttributedString:str]; + if (attch.image) + { + NSAttributedString *str=[NSAttributedString attributedStringWithAttachment:attch]; + [attri appendAttributedString:str]; + } + self.tanSuoTitle.attributedText = attri; } diff --git a/Ifish/controllers/IfishTabControllers/设备/IfishDeviceViewController.m b/Ifish/controllers/IfishTabControllers/设备/IfishDeviceViewController.m index d886be0..236a04e 100644 --- a/Ifish/controllers/IfishTabControllers/设备/IfishDeviceViewController.m +++ b/Ifish/controllers/IfishTabControllers/设备/IfishDeviceViewController.m @@ -108,6 +108,7 @@ Assign BOOL isPush; [self creatReatRefreshView];//上拉加载更多 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(deleteCurDevice) name:@"DeleteCurDevice" object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(updateDevice) name:@"updateDevice" object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(updateUserInfobyValidation) name:@"updateUserInfobyValidation" object:nil]; } -(void)updateDevice{ @@ -117,8 +118,45 @@ Assign BOOL isPush; -(void)dealloc{ [[NSNotificationCenter defaultCenter] removeObserver:self name:@"DeleteCurDevice" object:nil]; [[NSNotificationCenter defaultCenter] removeObserver:self name:@"updateDevice" object:nil]; + [[NSNotificationCenter defaultCenter] removeObserver:self name:@"updateUserInfobyValidation" object:nil]; +} +-(void)updateUserInfobyValidation +{ + [self addDataRequestQueue]; + UserModel*model=[dataContorl getUserInfo]; + if (model.unionId) + { + [AFHttpTool requestWihtMethod:RequestMethodTypePost + url:kUserWechatValidation + params:@{@"unionId":[CommonUtils getNotNilStr:model.unionId]} + success:^(id response) { + if (!response) { + return ; + } + NSDictionary*dict=[NSJSONSerialization JSONObjectWithData:response options:NSJSONReadingMutableContainers error:nil]; + NSString *result=dict[@"result"]; + + if ([result isEqualToString:@"100"]) { + + // 登录成功 + NSDictionary*dataDic=dict[@"data"]; + + NSDictionary *userDic=dataDic[@"userInfo"]; + UserModel *model=[[UserModel alloc] initWithDict:userDic]; + [[DataCenter defaultDtacenter]setValue:model forKey:@"UserLogIn"]; + NSDictionary *userAssetDic=dataDic[@"userAsset"]; + IfishUserAsset *userAsset =[[IfishUserAsset alloc] initWithDict:userAssetDic]; + [[DataCenter defaultDtacenter]setValue:userAsset forKey:@"IfishUserAsset"]; + [self getUsernameAddImg]; + } + + } failure:^(NSError *err) { + + }]; + } + + } - -(void)addDataRequestQueue { //创建异步任务队列 避免UI更新受影响 @@ -518,11 +556,12 @@ Assign BOOL isPush; } -(void)getUsernameAddImg{ + IfishUserAsset *userAsset = [dataContorl getAllIfishUserAsset]; UserModel*umodel=[dataContorl getUserInfo]; + NSString*wechatImgUrl=[[NSUserDefaults standardUserDefaults] stringForKey:@"wechatImgUrl"]; _userNameLabel.text = umodel.nickName; [_userNameLabel sizeToFit]; - CGFloat btnH = 40*KWidth_Scale; CGFloat btnW =100*KWidth_Scale; _levelBtn.frame = CGRectMake(CGRectGetMaxX(_userNameLabel.frame) + 2, CGRectGetMaxY(_userNameLabel.frame) - btnH,btnW, btnH); @@ -545,7 +584,13 @@ Assign BOOL isPush; [_userImgView setImage:[UIImage imageNamed:[NSString stringWithFormat:@"userIcon%d.png",i]]]; - }else{ + }else if (wechatImgUrl.length){ + + + [_userImgView sd_setImageWithURL:[NSURL URLWithString:wechatImgUrl]]; + + } + else{ NSLog(@"%@",[NSString stringWithFormat:@"%@%@",kGetIconUrl,umodel.userImg]); [_userImgView sd_setImageWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@%@",kGetIconUrl,umodel.userImg]]]; diff --git a/Ifish/controllers/IfishYooseeFile/IfishYooseeControlller/YooseeNextConnectViewController.mm b/Ifish/controllers/IfishYooseeFile/IfishYooseeControlller/YooseeNextConnectViewController.mm index 764f3c6..f6a534c 100644 --- a/Ifish/controllers/IfishYooseeFile/IfishYooseeControlller/YooseeNextConnectViewController.mm +++ b/Ifish/controllers/IfishYooseeFile/IfishYooseeControlller/YooseeNextConnectViewController.mm @@ -313,7 +313,11 @@ self.attentionLabel.text=@"1、请长按摄像头背后复位孔,复位摄像 [self.navigationController pushViewController:vc animated:YES]; } -(void)sBtn:(UIButton*)btn{ - NSString *ssidName = [self.wifiName substringWithRange:NSMakeRange(self.wifiName.length-2, 2)]; + NSString *ssidName =@""; + if (self.wifiName.length>2) { + ssidName= [self.wifiName substringWithRange:NSMakeRange(self.wifiName.length-2, 2)]; + } + if ([ssidName.uppercaseString isEqualToString:@"5G"]) { UIAlertView *alert= [[UIAlertView alloc] initWithTitle:@"" message:@"仅支持2.4G WI-Fi网络,请重新选择" delegate:nil cancelButtonTitle:@"去更改" otherButtonTitles:nil, nil]; [alert show]; diff --git a/Ifish/controllers/IfishYooseeFile/IfishYooseeControlller/yooseFishTankView/MonitorBootmView.m b/Ifish/controllers/IfishYooseeFile/IfishYooseeControlller/yooseFishTankView/MonitorBootmView.m index 5543f02..2342975 100644 --- a/Ifish/controllers/IfishYooseeFile/IfishYooseeControlller/yooseFishTankView/MonitorBootmView.m +++ b/Ifish/controllers/IfishYooseeFile/IfishYooseeControlller/yooseFishTankView/MonitorBootmView.m @@ -1436,19 +1436,19 @@ }else if ([self.device.type isEqualToString:DECICE_TYPE_SONGNEWBD]){ //self.btnNameArr = @[@"灯1",@"灯2",@"水泵",@"氧泵",@"加热棒"]; SongNuo86Name* songNuo = [UserExtendataArchaver currentSongNuo86:self.device.macAddress]; - self.btnNameArr = @[songNuo.light1,songNuo.light2,songNuo.waterPump,songNuo.airPump,songNuo.guideng,songNuo.jiaRe]; + self.btnNameArr = @[songNuo.light1,songNuo.light2,songNuo.waterPump,songNuo.airPump,songNuo.guideng,songNuo.jiaRe,songNuo.jiaRe]; self.btnImgArr = @[LXImageWithImageName(@"bootview_light_off"), LXImageWithImageName(@"bootview_light_off"), LXImageWithImageName(@"bootview_pump_off"), LXImageWithImageName(@"bootview_022_off"), - LXImageWithImageName(@"bootview_heat_off")]; + LXImageWithImageName(@"bootview_heat_off"),LXImageWithImageName(@"bootview_heat_off")]; self.btnOnImgArr = @[LXImageWithImageName(@"bootview_light_on"), LXImageWithImageName(@"bootview_light_on"), LXImageWithImageName(@"bootview_pump_on"), LXImageWithImageName(@"bootview_022_on"), - LXImageWithImageName(@"bootview_heat_on")]; + LXImageWithImageName(@"bootview_heat_on"),LXImageWithImageName(@"bootview_heat_on")]; } else if ([self.device.type isEqualToString:DECICE_TYPE_RUIMEI]){ //self.btnNameArr = @[@"灯1",@"灯2",@"水泵",@"氧泵",@"加热棒"]; diff --git a/Ifish/controllers/leftcontrollers/SecondConnectWifiController.h b/Ifish/controllers/leftcontrollers/SecondConnectWifiController.h index c485389..516714f 100644 --- a/Ifish/controllers/leftcontrollers/SecondConnectWifiController.h +++ b/Ifish/controllers/leftcontrollers/SecondConnectWifiController.h @@ -21,6 +21,7 @@ @property (weak, nonatomic) IBOutlet UILabel *attentionLabel; @property(nonatomic,strong)NSString*ssid; +@property(nonatomic,strong)NSString*wifiPass; @property(nonatomic,strong)NSString*bssid; @property(nonatomic,strong)NSString*deviceBssid; @property (weak, nonatomic) IBOutlet UIButton *shareButton; diff --git a/Ifish/controllers/leftcontrollers/SecondConnectWifiController.m b/Ifish/controllers/leftcontrollers/SecondConnectWifiController.m index 4e62661..cf4f4c0 100644 --- a/Ifish/controllers/leftcontrollers/SecondConnectWifiController.m +++ b/Ifish/controllers/leftcontrollers/SecondConnectWifiController.m @@ -395,8 +395,21 @@ extern BOOL isfromCameraView; - (IBAction)makeSureButton:(id)sender { + if (!_ssid.length) + { + [self.view makeToast:@"未能获取到WiFi名称,请确认地理位置权限是否打开"]; + return; + } + if (!_wifiTextFiled.text.length) + { + [self.view makeToast:@"请输入WiFi密码!"]; + return; + } [_wifiTextFiled resignFirstResponder]; - NSString *ssidName = [_ssid substringWithRange:NSMakeRange(_ssid.length-2, 2)]; + NSString *ssidName = @""; + if (_ssid.length>2) { + ssidName= [_ssid substringWithRange:NSMakeRange(_ssid.length-2, 2)]; + } if ([ssidName.uppercaseString isEqualToString:@"5G"]) { UIAlertView *alert= [[UIAlertView alloc] initWithTitle:@"" message:@"仅支持2.4G WI-Fi网络,请重新选择" delegate:nil cancelButtonTitle:@"去更改" otherButtonTitles:nil, nil]; [alert show]; @@ -527,6 +540,7 @@ extern BOOL isfromCameraView; NSUserDefaults*userdefult=[NSUserDefaults standardUserDefaults]; [userdefult setObject:self.wifiTextFiled.text forKey:@"wifiPass"]; + self.wifiPass=self.wifiTextFiled.text; [userdefult synchronize]; } diff --git a/Ifish/controllers/logAddRegistController/LogInViewController.m b/Ifish/controllers/logAddRegistController/LogInViewController.m index 4aae2f8..4685912 100644 --- a/Ifish/controllers/logAddRegistController/LogInViewController.m +++ b/Ifish/controllers/logAddRegistController/LogInViewController.m @@ -34,7 +34,8 @@ #import "AccountResult.h" #import "LoginResult.h" #import "RegisterResult.h" - +#import "WXApi.h" +#import "WXApiManager.h" #import "UIView+Toast.h" #import "IfishNewsModel.h" //#import @@ -42,7 +43,7 @@ //#import #import #import "IfishUserDataUnity.h" -@interface LogInViewController () +@interface LogInViewController () @property (weak, nonatomic) IBOutlet UIButton *logInButton; @property(nonatomic,strong)UIActivityIndicatorView*indicatorView; //@property(nonatomic)BMKLocationService*locService; @@ -51,6 +52,10 @@ @property(nonatomic,copy) NSString *adderss; @property (nonatomic,strong ) CLLocationManager *locationManager;//定位服务 @property (nonatomic,copy) NSString *currentCity;//城市 +@property (nonatomic,copy) NSDictionary *expara;//城市 +@property (weak, nonatomic) IBOutlet UIView *styleView; +@property (weak, nonatomic) IBOutlet NSLayoutConstraint *wechatCons; + @end extern BOOL firstLogIn; BOOL formLogIn;// //连接页面是否来自登录界面初始化 @@ -112,6 +117,14 @@ self.loginPhoneNumberTextField.text = name; } + if ([WXApi isWXAppInstalled]) + { + self.styleView.hidden=NO; + if ([CommonUtils isIphoneX]) + { + //self.wechatCons.constant=-30; + } + } } @@ -255,8 +268,12 @@ btn.userInteractionEnabled = NO; btn.backgroundColor = [UIColor lightGrayColor]; [_indicatorView startAnimating]; - - NSString*tokenStr=[MyMD5 md5:self.loginPasswordTextField.text ]; + NSString*tokenStr; + if (self.loginPasswordTextField.text.length) + { + tokenStr=[MyMD5 md5:self.loginPasswordTextField.text ]; + } + if (!self.adderss) { NSLog(@"addressnil"); self.adderss = @"暂时未获取到地址信息"; @@ -272,7 +289,7 @@ } __weak typeof (self) weakSelf=self; - [AFHttpTool userLogInWithPhoneNumber:self.loginPhoneNumberTextField.text password:tokenStr phoneType:@"ios" address:self.adderss + [AFHttpTool userLogInWithPhoneNumber:[CommonUtils getNotNilStr:self.loginPhoneNumberTextField.text] password:tokenStr phoneType:@"ios" address:self.adderss longitude:self.longitude latitude:self.latitude success:^(id response) { @@ -326,9 +343,19 @@ NSString *errstr = [NSString stringWithFormat:@"%@",err]; BLYLog(BuglyLogLevelWarn, errstr); - }]; + } expara:self.expara]; } +- (IBAction)wechatAuthority:(UIButton *)sender { + AppDelegate*del=(AppDelegate*)[UIApplication sharedApplication].delegate; + del.isWechatLogin=YES; + [WXApiManager sharedManager].delegate=self; + SendAuthReq* req =[[SendAuthReq alloc]init]; + req.scope = @"snsapi_userinfo"; + req.state = @"ifish7"; + + [WXApi sendReq:req]; +} - (void)tagsAliasCallback:(int)iResCode tags:(NSSet*)tags alias:(NSString*)alias { @@ -336,6 +363,17 @@ } +#pragma mark - WXApiManagerDelegate +- (void)managerDidRecvAuthResponse:(SendAuthResp *)response +{ + if (response.errCode==0) + { + self.expara=@{@"code":response.code}; + [self LogIn:nil]; + } + AppDelegate*del=(AppDelegate*)[UIApplication sharedApplication].delegate; + del.isWechatLogin=NO; +} #pragma mark - 注册摄像头成功后 登陆摄像头服务器 已去 -(void)logInYooseeServerWith:(NSString*)email addpassword:(NSString*)password{ @@ -444,7 +482,7 @@ //视图下沉恢复原状 [UIView animateWithDuration:duration animations:^{ - self.view.frame = CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height); + self.view.frame = CGRectMake(0, NavigationBarHeight, self.view.frame.size.width, self.view.frame.size.height); }]; } diff --git a/Ifish/controllers/logAddRegistController/LogInViewController.xib b/Ifish/controllers/logAddRegistController/LogInViewController.xib index 96d8645..3015e70 100644 --- a/Ifish/controllers/logAddRegistController/LogInViewController.xib +++ b/Ifish/controllers/logAddRegistController/LogInViewController.xib @@ -1,11 +1,9 @@ - - - - + + - + @@ -14,23 +12,25 @@ + + - + - + - + - + @@ -54,14 +54,14 @@ - + + + + + + + + + + + + + + + + - + + + + - + - + + diff --git a/Ifish/controllers/logAddRegistController/RegistViewController.h b/Ifish/controllers/logAddRegistController/RegistViewController.h index af08602..a67dd5c 100644 --- a/Ifish/controllers/logAddRegistController/RegistViewController.h +++ b/Ifish/controllers/logAddRegistController/RegistViewController.h @@ -28,5 +28,8 @@ - (IBAction)verifyBtn:(id)sender; @property (weak, nonatomic) IBOutlet UIButton *countrySelectBtn; +@property (assign, nonatomic) BOOL isBind; +@property (assign, nonatomic) BOOL isFromLogin; + @end diff --git a/Ifish/controllers/logAddRegistController/RegistViewController.mm b/Ifish/controllers/logAddRegistController/RegistViewController.mm index 19340c9..e6e3389 100644 --- a/Ifish/controllers/logAddRegistController/RegistViewController.mm +++ b/Ifish/controllers/logAddRegistController/RegistViewController.mm @@ -17,7 +17,8 @@ #import "AgreementViewController.h" #import "MyIntroductionViewController.h" #import "ConnectWifiViewController.h" - +#import "WXApi.h" +#import "WXApiManager.h" #import "ChatroomModel.h" //#import //#import @@ -36,7 +37,7 @@ #import #import "XWCountryCodeController.h" #import -@interface RegistViewController () +@interface RegistViewController () { BOOL _showed;//显示过了 @@ -48,6 +49,7 @@ @property (weak, nonatomic) IBOutlet UIButton *timeBtn; @property(nonatomic,copy)NSString*verifyData; @property(nonatomic,copy) NSString *areaCode; +@property (weak, nonatomic) IBOutlet UIButton *resignBtn; @property (weak, nonatomic) IBOutlet UIButton *registBtn; - (IBAction)agreementBtn:(id)sender; @@ -63,7 +65,9 @@ @property(nonatomic,copy) NSString *adderss; @property (weak, nonatomic) IBOutlet UILabel *qrcodeSwitchLbl; - +@property (nonatomic,copy) NSDictionary *expara;//城市 +@property (weak, nonatomic) IBOutlet UIView *styleView; +@property (weak, nonatomic) IBOutlet NSLayoutConstraint *wechatConstraints; @end extern BOOL formLogIn; @@ -73,7 +77,8 @@ extern BOOL formLogIn; { self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; if (self) { - + self.isBind=NO; + self.isFromLogin=NO; } return self; @@ -104,6 +109,15 @@ extern BOOL formLogIn; self.passwordTextField.delegate=self; self.navigationItem.hidesBackButton=YES; [self getLocation]; + if ([WXApi isWXAppInstalled]&&!self.isBind) + { + self.styleView.hidden=NO; + + if ([CommonUtils isIphoneX]) + { + //self.wechatConstraints.constant=-30; + } + } } #pragma mark 定位 @@ -284,14 +298,25 @@ extern BOOL formLogIn; } #pragma mark-设置导航按钮 -(void)addNaviItem{ - UILabel*labe=[[UILabel alloc]initWithFrame:CGRectMake(0, 0, 60, 44)]; + UILabel*labe=[[UILabel alloc]initWithFrame:CGRectMake((SCREEN_WIDTH-200)/2.0, 0, 200, 44)]; labe.text=@"注册"; + labe.textAlignment=NSTextAlignmentCenter; labe.textColor=[UIColor whiteColor]; + self.navigationItem.titleView=labe; - + + BOOL skiped=NO; + NSUserDefaults*userDefsult=[NSUserDefaults standardUserDefaults]; + UserModel*model=[dataContorl getUserInfo]; + if (model.unionId) + { + skiped =[userDefsult boolForKey:model.unionId]; + } + UIButton*rightButton = [[UIButton alloc]initWithFrame:CGRectMake(25,0,60,60)]; [rightButton setTitle:@"登录" forState:UIControlStateNormal]; + rightButton.backgroundColor=[UIColor clearColor]; [rightButton.titleLabel setFont:[UIFont systemFontOfSize:14]]; [rightButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; @@ -300,13 +325,59 @@ extern BOOL formLogIn; UIBarButtonItem*rightItem= [[UIBarButtonItem alloc] initWithCustomView:rightButton]; // rightItem.tintColor=[UIColor whiteColor]; // [rightItem setTintColor:[UIColor whiteColor]]; - self.navigationItem.rightBarButtonItem= rightItem; + + if (self.isBind) + { + labe.text=@"绑定手机"; + [self.resignBtn setTitle:@"确定" forState:UIControlStateNormal]; + if (!skiped&&self.isFromLogin) + { + [rightButton setTitle:@"跳过" forState:UIControlStateNormal]; + self.navigationItem.rightBarButtonItem= rightItem; + } + else + { + UIButton* _bakbutton = [UIButton buttonWithType:UIButtonTypeCustom]; + _bakbutton.frame = CGRectMake(0,0,48,44); + [_bakbutton setImage:[UIImage imageNamed:@"back_btn"] forState:UIControlStateNormal]; + _bakbutton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentLeft; + [_bakbutton addTarget: self action: @selector(goBackAction) forControlEvents: UIControlEventTouchUpInside]; + // [_bakbutton setContentEdgeInsets:UIEdgeInsetsMake(0, 10, 0, -10)]; + UIBarButtonItem*_back =[[UIBarButtonItem alloc] initWithCustomView:_bakbutton]; + UIBarButtonItem *fixedButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace target:nil action:nil]; + fixedButtonItem.width = -kSizeFrom750(30); + self.navigationItem.leftBarButtonItems = @[fixedButtonItem, _back]; + } + + + } + else + { + self.navigationItem.rightBarButtonItem= rightItem; + } + [self.navigationController.navigationBar setBackgroundImage:[UIImage imageNamed:@"blackbar.png"] forBarMetrics:UIBarMetricsDefault]; // [self.navigationItem.rightBarButtonItem setTitleTextAttributes:[NSDictionary dictionaryWithObjectsAndKeys:[UIFont systemFontOfSize:14],UITextAttributeFont, [UIColor whiteColor], UITextAttributeTextColor, nil] forState:UIControlStateNormal]; } -(void)rightButtonClick:(UIButton *)sender{ - LogInViewController *login=[[LogInViewController alloc]init]; - [self.navigationController pushViewController:login animated:YES]; + if (self.isBind) + { + [[IfishUserDataUnity shareDataInstance] setAppTabRoot]; + NSUserDefaults*userDefsult=[NSUserDefaults standardUserDefaults]; + UserModel*model=[dataContorl getUserInfo]; + if (model.unionId) + { + [userDefsult setBool:YES forKey:model.unionId]; + [userDefsult synchronize]; + } + } + + else + { + LogInViewController *login=[[LogInViewController alloc]init]; + [self.navigationController pushViewController:login animated:YES]; + } + } @@ -380,7 +451,15 @@ extern BOOL formLogIn; { NSLog(@"验证成功"); - [self ifishAddUser]; + if (self.isBind) + { + [self bindPhone]; + } + else + { + [self ifishAddUser]; + } + } else @@ -462,6 +541,73 @@ extern BOOL formLogIn; } +-(void)bindPhone +{ + UserModel*user=[dataContorl getUserInfo]; + if (user.unionId) + { + NSMutableDictionary*para=[[NSMutableDictionary alloc]initWithDictionary:@{@"unionId":user.unionId,@"phoneNum":self.phoneNumberTextField.text}]; + if (self.passwordTextField.text.length) + { + para[@"password"]=[MyMD5 md5:self.passwordTextField.text]; + } + [AFHttpTool requestWihtMethod:RequestMethodTypePost + url:kUserBindPhone + params:para + success:^(id response) { + if (response) { + NSDictionary*resultDic=[NSJSONSerialization JSONObjectWithData:response options:NSJSONReadingMutableContainers error:nil]; + NSLog(@"resultDic:%@",resultDic); + [[NSNotificationCenter defaultCenter] postNotificationName:@"updateUserInfobyValidation" object:nil]; + if ([resultDic[@"result"] isEqualToString:@"100"]) + { + + NSUserDefaults*userdefult=[NSUserDefaults standardUserDefaults]; + NSString*userName=self.phoneNumberTextField.text; + NSString*password=self.passwordTextField.text; + + [userdefult setObject:password forKey:@"password"]; + [userdefult setObject:userName forKey:@"name"]; + //是否退出登陆 + [userdefult setObject:@"0" forKey:@"isExit"]; + [userdefult synchronize]; + user.phoneNumber=self.phoneNumberTextField.text; + [[DataCenter defaultDtacenter]setValue:user forKey:@"UserLogIn"]; + [self.view makeToast:@"绑定成功"]; + + if (self.isFromLogin) + { + [[IfishUserDataUnity shareDataInstance] setAppTabRoot]; + } + else + { + + [self.navigationController popViewControllerAnimated:YES]; + } + + + + }else if ([resultDic[@"result"] isEqualToString:@"204"]){ + + [self.view makeToast:@"验证码错误"]; + + }else{ + + [self.view makeToast:@"修改失败"]; + + } + } + + } failure:^(NSError *err) { + + }]; + } + +} +-(void)goBackAction{ + + [self.navigationController popViewControllerAnimated:YES]; +} #pragma mark- 极光别名注册 - (void)tagsAliasCallback:(int)iResCode tags:(NSSet*)tags alias:(NSString*)alias { @@ -497,7 +643,7 @@ extern BOOL formLogIn; //视图下沉恢复原状 [UIView animateWithDuration:duration animations:^{ - self.view.frame = CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height); + self.view.frame = CGRectMake(0, NavigationBarHeight, self.view.frame.size.width, self.view.frame.size.height); }]; } @@ -673,8 +819,11 @@ extern BOOL formLogIn; NSUserDefaults*userDefsult=[NSUserDefaults standardUserDefaults]; NSString*name=[userDefsult objectForKey:@"name"]; NSString*password=[userDefsult objectForKey:@"password"]; - NSString*tokenStr=[MyMD5 md5:password]; - + NSString*tokenStr=@""; + if (password.length) + { + tokenStr=[MyMD5 md5:password]; + } [AFHttpTool userLogInWithPhoneNumber:name password:tokenStr phoneType:@"ios" address:self.adderss longitude:self.longitude latitude:self.latitude success:^(id response) { @@ -717,10 +866,31 @@ extern BOOL formLogIn; NSString *erstr =[NSString stringWithFormat:@"%@",err]; BLYLog(BuglyLogLevelError, erstr); - }]; + } expara:self.expara]; } +- (IBAction)wechatAuthority:(id)sender { + AppDelegate*del=(AppDelegate*)[UIApplication sharedApplication].delegate; + del.isWechatLogin=YES; + [WXApiManager sharedManager].delegate=self; + SendAuthReq* req =[[SendAuthReq alloc]init]; + req.scope = @"snsapi_userinfo"; + req.state = @"ifish7"; + + [WXApi sendReq:req]; +} +#pragma mark - WXApiManagerDelegate +- (void)managerDidRecvAuthResponse:(SendAuthResp *)response +{ + if (response.errCode==0) + { + self.expara=@{@"code":response.code}; + [self logIn]; + } + AppDelegate*del=(AppDelegate*)[UIApplication sharedApplication].delegate; + del.isWechatLogin=NO; +} -(void)creatMyindicaterView{ _indicatorView=[[UIActivityIndicatorView alloc]initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge]; diff --git a/Ifish/controllers/logAddRegistController/RegistViewController.xib b/Ifish/controllers/logAddRegistController/RegistViewController.xib index f3f82f0..2bccb6e 100644 --- a/Ifish/controllers/logAddRegistController/RegistViewController.xib +++ b/Ifish/controllers/logAddRegistController/RegistViewController.xib @@ -1,11 +1,9 @@ - - - - + + - + @@ -17,18 +15,21 @@ + + + - + - - + + + - + + - + - + - - + + + diff --git a/Ifish/ifishImgSouce/.DS_Store b/Ifish/ifishImgSouce/.DS_Store index 38dbcbb..3b2244c 100644 Binary files a/Ifish/ifishImgSouce/.DS_Store and b/Ifish/ifishImgSouce/.DS_Store differ diff --git a/Ifish/ifishImgSouce/icon/wechatlogin.png b/Ifish/ifishImgSouce/icon/wechatlogin.png new file mode 100644 index 0000000..0ee3429 Binary files /dev/null and b/Ifish/ifishImgSouce/icon/wechatlogin.png differ diff --git a/Ifish/ifishImgSouce/ifishWodeImgs/renyuan.png b/Ifish/ifishImgSouce/ifishWodeImgs/renyuan.png new file mode 100644 index 0000000..bb77334 Binary files /dev/null and b/Ifish/ifishImgSouce/ifishWodeImgs/renyuan.png differ diff --git a/Ifish/models/ifishUserModel/UserModel.h b/Ifish/models/ifishUserModel/UserModel.h index efef577..cb2f88e 100644 --- a/Ifish/models/ifishUserModel/UserModel.h +++ b/Ifish/models/ifishUserModel/UserModel.h @@ -32,6 +32,8 @@ @property(nonatomic,copy) NSString *callId;//技威处理后的Id //云信token @property(nonatomic,copy) NSString *neteaseToken; +@property(nonatomic,copy) NSString *unionId;//微信登陆时的unionId +@property(nonatomic,copy) NSString *wechatImgUrl;//微信登陆时的unionId //v4.2 后已去字段 //@property(nonatomic,copy)NSString*updateTime;//用户信息最后一次更新时间 //@property(nonatomic,strong)NSNumber*timestamp;//服务器时间戳,用于APP内置时钟 diff --git a/Ifish/models/ifishUserModel/UserModel.m b/Ifish/models/ifishUserModel/UserModel.m index 71b63f9..5ca10b6 100644 --- a/Ifish/models/ifishUserModel/UserModel.m +++ b/Ifish/models/ifishUserModel/UserModel.m @@ -11,22 +11,24 @@ @implementation UserModel // 归档时调用 -(void)encodeWithCoder:(NSCoder*)aCoder{ - [aCoder encodeObject:self forKey:@"phoneNumber"]; - [aCoder encodeObject:self forKey:@"userId"]; - [aCoder encodeObject:self forKey:@"nickName"]; - [aCoder encodeObject:self forKey:@"userSex"]; - [aCoder encodeObject:self forKey:@"userImg"]; + [aCoder encodeObject:self.phoneNumber forKey:@"phoneNumber"]; + [aCoder encodeObject:self.userId forKey:@"userId"]; + [aCoder encodeObject:self.nickName forKey:@"nickName"]; + [aCoder encodeObject:self.userSex forKey:@"userSex"]; + [aCoder encodeObject:self.userImg forKey:@"userImg"]; [aCoder encodeObject:self forKey:@"signature"]; - [aCoder encodeObject:self forKey:@"P2PVerifyCode1"]; - [aCoder encodeObject:self forKey:@"P2PVerifyCode2"]; - [aCoder encodeObject:self forKey:@"sessionID"]; - [aCoder encodeObject:self forKey:@"sessionID2"]; + [aCoder encodeObject:self.P2PVerifyCode1 forKey:@"P2PVerifyCode1"]; + [aCoder encodeObject:self.P2PVerifyCode2 forKey:@"P2PVerifyCode2"]; + [aCoder encodeObject:self.sessionID forKey:@"sessionID"]; + [aCoder encodeObject:self.sessionID2 forKey:@"sessionID2"]; - [aCoder encodeObject:self forKey:@"gwellUserID"]; - [aCoder encodeObject:self forKey:@"shopsUserId"]; - [aCoder encodeObject:self forKey:@"userType"]; - [aCoder encodeObject:self forKey:@"neteaseToken"]; - [aCoder encodeObject:self forKey:@"messageIsRead"]; + [aCoder encodeObject:self.gwellUserID forKey:@"gwellUserID"]; + [aCoder encodeObject:self.shopsUserId forKey:@"shopsUserId"]; + [aCoder encodeObject:self.userType forKey:@"userType"]; + [aCoder encodeObject:self.neteaseToken forKey:@"neteaseToken"]; + [aCoder encodeObject:self.messageIsRead forKey:@"messageIsRead"]; + [aCoder encodeObject:self.unionId forKey:@"unionId"]; + [aCoder encodeObject:self.wechatImgUrl forKey:@"wechatImgUrl"]; } //解挡时调用 @@ -49,6 +51,8 @@ self.userType = [aDecoder decodeObjectForKey:@"userType"]; self.neteaseToken = [aDecoder decodeObjectForKey:@"neteaseToken"]; self.messageIsRead = [aDecoder decodeObjectForKey:@"messageIsRead"]; + self.unionId = [aDecoder decodeObjectForKey:@"unionId"]; + self.wechatImgUrl = [aDecoder decodeObjectForKey:@"wechatImgUrl"]; } return self; @@ -72,6 +76,8 @@ _userType = [dict objectForKey:@"userType"]; _neteaseToken = [dict objectForKey:@"neteaseToken"]; _messageIsRead = [dict objectForKey:@"messageIsRead"]; + _unionId = [CommonUtils getNotNilStr:[dict objectForKey:@"unionId"]]; + _wechatImgUrl=[CommonUtils getNotNilStr:[dict objectForKey:@"wechatImgUrl"]]; } return self; } diff --git a/IfishTests/Info.plist b/IfishTests/Info.plist index ba72822..209a450 100644 --- a/IfishTests/Info.plist +++ b/IfishTests/Info.plist @@ -2,6 +2,11 @@ + NSAppTransportSecurity + + NSAllowsArbitraryLoads + + CFBundleDevelopmentRegion en CFBundleExecutable diff --git a/IfishUITests/Info.plist b/IfishUITests/Info.plist index ba72822..464d91d 100644 --- a/IfishUITests/Info.plist +++ b/IfishUITests/Info.plist @@ -4,6 +4,11 @@ CFBundleDevelopmentRegion en + NSAppTransportSecurity + + NSAllowsArbitraryLoads + + CFBundleExecutable $(EXECUTABLE_NAME) CFBundleIdentifier