新建basetool下面的文件夹
This commit is contained in:
@@ -694,6 +694,17 @@
|
||||
18FDEDCF2A50353A005EB21D /* DynamicSendLocationView.m in Sources */ = {isa = PBXBuildFile; fileRef = 18FDEDCE2A50353A005EB21D /* DynamicSendLocationView.m */; };
|
||||
2358F57D2B230B4A0038453C /* DDVideoEncodeManage.m in Sources */ = {isa = PBXBuildFile; fileRef = 2358F57C2B230B4A0038453C /* DDVideoEncodeManage.m */; };
|
||||
2358F5812B230C350038453C /* UILabel+DDFactory.m in Sources */ = {isa = PBXBuildFile; fileRef = 2358F5802B230C350038453C /* UILabel+DDFactory.m */; };
|
||||
8C2C3EC92B277E7F002C3C34 /* DDIAPHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 8C2C3EC82B277E7F002C3C34 /* DDIAPHelper.m */; };
|
||||
8C2C3ECC2B2784DE002C3C34 /* DDIAPRechargeStorage.m in Sources */ = {isa = PBXBuildFile; fileRef = 8C2C3ECB2B2784DE002C3C34 /* DDIAPRechargeStorage.m */; };
|
||||
8C2C3ED02B278C9E002C3C34 /* DDUploadImage.m in Sources */ = {isa = PBXBuildFile; fileRef = 8C2C3ECF2B278C9E002C3C34 /* DDUploadImage.m */; };
|
||||
8C2C3ED72B279141002C3C34 /* NSString+DDUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = 8C2C3ED62B279141002C3C34 /* NSString+DDUtils.m */; };
|
||||
8C2C3EDF2B27C3B8002C3C34 /* DDCountDownHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 8C2C3EDE2B27C3B8002C3C34 /* DDCountDownHelper.m */; };
|
||||
8C2C3EE32B27CC6E002C3C34 /* DDBase64.m in Sources */ = {isa = PBXBuildFile; fileRef = 8C2C3EE22B27CC6E002C3C34 /* DDBase64.m */; };
|
||||
8C2C3EE62B27CC7D002C3C34 /* DDDESEncrypt.m in Sources */ = {isa = PBXBuildFile; fileRef = 8C2C3EE52B27CC7D002C3C34 /* DDDESEncrypt.m */; };
|
||||
8C2C3EEA2B27D163002C3C34 /* YYReachability.m in Sources */ = {isa = PBXBuildFile; fileRef = 8C2C3EE92B27D163002C3C34 /* YYReachability.m */; };
|
||||
8C2C3EEF2B27D1B5002C3C34 /* SSKeychain.m in Sources */ = {isa = PBXBuildFile; fileRef = 8C2C3EEE2B27D1B5002C3C34 /* SSKeychain.m */; };
|
||||
8C2C3EF32B27D224002C3C34 /* NSObject+DDExtension.m in Sources */ = {isa = PBXBuildFile; fileRef = 8C2C3EF22B27D224002C3C34 /* NSObject+DDExtension.m */; };
|
||||
8C2C3EF92B27D94A002C3C34 /* YYUtility.m in Sources */ = {isa = PBXBuildFile; fileRef = 8C2C3EF82B27D94A002C3C34 /* YYUtility.m */; };
|
||||
8CE493992B23F44800CA14D5 /* NSMutableDictionary+DDSafe.m in Sources */ = {isa = PBXBuildFile; fileRef = 8CE493982B23F44800CA14D5 /* NSMutableDictionary+DDSafe.m */; };
|
||||
8CE4939C2B23F45C00CA14D5 /* NSArray+DDSafe.m in Sources */ = {isa = PBXBuildFile; fileRef = 8CE4939B2B23F45C00CA14D5 /* NSArray+DDSafe.m */; };
|
||||
8CE493A02B23F5FA00CA14D5 /* DDUploadFile.m in Sources */ = {isa = PBXBuildFile; fileRef = 8CE4939F2B23F5FA00CA14D5 /* DDUploadFile.m */; };
|
||||
@@ -1973,6 +1984,29 @@
|
||||
2411BE5187E529C085E77220 /* libPods-DingDangAppTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-DingDangAppTests.a"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
42F5E7CEE31217A32E19E10E /* Pods-DingDangApp-DingDangAppUITests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-DingDangApp-DingDangAppUITests.debug.xcconfig"; path = "Target Support Files/Pods-DingDangApp-DingDangAppUITests/Pods-DingDangApp-DingDangAppUITests.debug.xcconfig"; sourceTree = "<group>"; };
|
||||
688E5912F2E950A95FC1EE55 /* Pods-DingDangAppTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-DingDangAppTests.release.xcconfig"; path = "Target Support Files/Pods-DingDangAppTests/Pods-DingDangAppTests.release.xcconfig"; sourceTree = "<group>"; };
|
||||
8C2C3EC72B277E7F002C3C34 /* DDIAPHelper.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DDIAPHelper.h; sourceTree = "<group>"; };
|
||||
8C2C3EC82B277E7F002C3C34 /* DDIAPHelper.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = DDIAPHelper.m; sourceTree = "<group>"; };
|
||||
8C2C3ECA2B2784DE002C3C34 /* DDIAPRechargeStorage.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DDIAPRechargeStorage.h; sourceTree = "<group>"; };
|
||||
8C2C3ECB2B2784DE002C3C34 /* DDIAPRechargeStorage.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = DDIAPRechargeStorage.m; sourceTree = "<group>"; };
|
||||
8C2C3ECE2B278C9E002C3C34 /* DDUploadImage.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DDUploadImage.h; sourceTree = "<group>"; };
|
||||
8C2C3ECF2B278C9E002C3C34 /* DDUploadImage.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = DDUploadImage.m; sourceTree = "<group>"; };
|
||||
8C2C3ED52B279141002C3C34 /* NSString+DDUtils.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "NSString+DDUtils.h"; sourceTree = "<group>"; };
|
||||
8C2C3ED62B279141002C3C34 /* NSString+DDUtils.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "NSString+DDUtils.m"; sourceTree = "<group>"; };
|
||||
8C2C3EDD2B27C3B8002C3C34 /* DDCountDownHelper.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DDCountDownHelper.h; sourceTree = "<group>"; };
|
||||
8C2C3EDE2B27C3B8002C3C34 /* DDCountDownHelper.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = DDCountDownHelper.m; sourceTree = "<group>"; };
|
||||
8C2C3EE12B27CC6E002C3C34 /* DDBase64.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DDBase64.h; sourceTree = "<group>"; };
|
||||
8C2C3EE22B27CC6E002C3C34 /* DDBase64.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = DDBase64.m; sourceTree = "<group>"; };
|
||||
8C2C3EE42B27CC7D002C3C34 /* DDDESEncrypt.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DDDESEncrypt.h; sourceTree = "<group>"; };
|
||||
8C2C3EE52B27CC7D002C3C34 /* DDDESEncrypt.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = DDDESEncrypt.m; sourceTree = "<group>"; };
|
||||
8C2C3EE82B27D163002C3C34 /* YYReachability.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = YYReachability.h; sourceTree = "<group>"; };
|
||||
8C2C3EE92B27D163002C3C34 /* YYReachability.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = YYReachability.m; sourceTree = "<group>"; };
|
||||
8C2C3EED2B27D1B5002C3C34 /* SSKeychain.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SSKeychain.h; sourceTree = "<group>"; };
|
||||
8C2C3EEE2B27D1B5002C3C34 /* SSKeychain.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SSKeychain.m; sourceTree = "<group>"; };
|
||||
8C2C3EF12B27D224002C3C34 /* NSObject+DDExtension.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "NSObject+DDExtension.h"; sourceTree = "<group>"; };
|
||||
8C2C3EF22B27D224002C3C34 /* NSObject+DDExtension.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "NSObject+DDExtension.m"; sourceTree = "<group>"; };
|
||||
8C2C3EF62B27D8CB002C3C34 /* CarrierIdentifier.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CarrierIdentifier.h; sourceTree = "<group>"; };
|
||||
8C2C3EF72B27D94A002C3C34 /* YYUtility.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = YYUtility.h; sourceTree = "<group>"; };
|
||||
8C2C3EF82B27D94A002C3C34 /* YYUtility.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = YYUtility.m; sourceTree = "<group>"; };
|
||||
8CAB97312B2259EA00ED8639 /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = System/Library/Frameworks/Security.framework; sourceTree = SDKROOT; };
|
||||
8CE493972B23F44800CA14D5 /* NSMutableDictionary+DDSafe.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "NSMutableDictionary+DDSafe.h"; sourceTree = "<group>"; };
|
||||
8CE493982B23F44800CA14D5 /* NSMutableDictionary+DDSafe.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "NSMutableDictionary+DDSafe.m"; sourceTree = "<group>"; };
|
||||
@@ -4973,38 +5007,149 @@
|
||||
path = Pods;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
8C2C3EC62B277E4F002C3C34 /* DDIAPHelper */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
8C2C3EC72B277E7F002C3C34 /* DDIAPHelper.h */,
|
||||
8C2C3EC82B277E7F002C3C34 /* DDIAPHelper.m */,
|
||||
8C2C3ECA2B2784DE002C3C34 /* DDIAPRechargeStorage.h */,
|
||||
8C2C3ECB2B2784DE002C3C34 /* DDIAPRechargeStorage.m */,
|
||||
);
|
||||
path = DDIAPHelper;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
8C2C3ED82B279208002C3C34 /* DDCategory */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
8C2C3EF02B27D1D7002C3C34 /* NSObject */,
|
||||
8C2C3EDB2B279265002C3C34 /* NSString */,
|
||||
8C2C3EDA2B27924E002C3C34 /* NSArray */,
|
||||
8C2C3ED92B279222002C3C34 /* NSMutableDictionary */,
|
||||
);
|
||||
path = DDCategory;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
8C2C3ED92B279222002C3C34 /* NSMutableDictionary */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
8CE493972B23F44800CA14D5 /* NSMutableDictionary+DDSafe.h */,
|
||||
8CE493982B23F44800CA14D5 /* NSMutableDictionary+DDSafe.m */,
|
||||
);
|
||||
path = NSMutableDictionary;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
8C2C3EDA2B27924E002C3C34 /* NSArray */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
8CE4939A2B23F45C00CA14D5 /* NSArray+DDSafe.h */,
|
||||
8CE4939B2B23F45C00CA14D5 /* NSArray+DDSafe.m */,
|
||||
);
|
||||
path = NSArray;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
8C2C3EDB2B279265002C3C34 /* NSString */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
8C2C3ED52B279141002C3C34 /* NSString+DDUtils.h */,
|
||||
8C2C3ED62B279141002C3C34 /* NSString+DDUtils.m */,
|
||||
);
|
||||
path = NSString;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
8C2C3EDC2B27C39C002C3C34 /* DDCountDownHelper */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
8C2C3EDD2B27C3B8002C3C34 /* DDCountDownHelper.h */,
|
||||
8C2C3EDE2B27C3B8002C3C34 /* DDCountDownHelper.m */,
|
||||
);
|
||||
path = DDCountDownHelper;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
8C2C3EE02B27CC5B002C3C34 /* DDSecurity */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
8C2C3EE12B27CC6E002C3C34 /* DDBase64.h */,
|
||||
8C2C3EE22B27CC6E002C3C34 /* DDBase64.m */,
|
||||
8C2C3EE42B27CC7D002C3C34 /* DDDESEncrypt.h */,
|
||||
8C2C3EE52B27CC7D002C3C34 /* DDDESEncrypt.m */,
|
||||
);
|
||||
path = DDSecurity;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
8C2C3EE72B27D13A002C3C34 /* YYReachability */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
8C2C3EE82B27D163002C3C34 /* YYReachability.h */,
|
||||
8C2C3EE92B27D163002C3C34 /* YYReachability.m */,
|
||||
);
|
||||
path = YYReachability;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
8C2C3EEB2B27D17C002C3C34 /* DDThirdTool */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
8C2C3EF42B27D66C002C3C34 /* YYUtility */,
|
||||
8C2C3EEC2B27D199002C3C34 /* SSKeyChain */,
|
||||
8C2C3EE72B27D13A002C3C34 /* YYReachability */,
|
||||
);
|
||||
path = DDThirdTool;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
8C2C3EEC2B27D199002C3C34 /* SSKeyChain */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
8C2C3EED2B27D1B5002C3C34 /* SSKeychain.h */,
|
||||
8C2C3EEE2B27D1B5002C3C34 /* SSKeychain.m */,
|
||||
);
|
||||
path = SSKeyChain;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
8C2C3EF02B27D1D7002C3C34 /* NSObject */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
8C2C3EF12B27D224002C3C34 /* NSObject+DDExtension.h */,
|
||||
8C2C3EF22B27D224002C3C34 /* NSObject+DDExtension.m */,
|
||||
);
|
||||
path = NSObject;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
8C2C3EF42B27D66C002C3C34 /* YYUtility */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
8C2C3EF62B27D8CB002C3C34 /* CarrierIdentifier.h */,
|
||||
8C2C3EF72B27D94A002C3C34 /* YYUtility.h */,
|
||||
8C2C3EF82B27D94A002C3C34 /* YYUtility.m */,
|
||||
);
|
||||
path = YYUtility;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
8CE493952B23F2B400CA14D5 /* DDBaseTool */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
8C2C3EEB2B27D17C002C3C34 /* DDThirdTool */,
|
||||
8C2C3EE02B27CC5B002C3C34 /* DDSecurity */,
|
||||
8C2C3EDC2B27C39C002C3C34 /* DDCountDownHelper */,
|
||||
8C2C3ED82B279208002C3C34 /* DDCategory */,
|
||||
8C2C3EC62B277E4F002C3C34 /* DDIAPHelper */,
|
||||
8CE493B12B240AE900CA14D5 /* DDTimeStamp */,
|
||||
8CE493AD2B2404C400CA14D5 /* DDGCDHelper */,
|
||||
8CE493A92B24017D00CA14D5 /* DDSystemTool */,
|
||||
8CE493A52B23FD5100CA14D5 /* DDSVGAParser */,
|
||||
8CE493A12B23F7DA00CA14D5 /* DDWeakTimer */,
|
||||
8CE4939D2B23F5D800CA14D5 /* DDUploadFile */,
|
||||
8CE493962B23F40500CA14D5 /* DDSafe */,
|
||||
8CE4939D2B23F5D800CA14D5 /* DDUpload */,
|
||||
);
|
||||
path = DDBaseTool;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
8CE493962B23F40500CA14D5 /* DDSafe */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
8CE493972B23F44800CA14D5 /* NSMutableDictionary+DDSafe.h */,
|
||||
8CE493982B23F44800CA14D5 /* NSMutableDictionary+DDSafe.m */,
|
||||
8CE4939A2B23F45C00CA14D5 /* NSArray+DDSafe.h */,
|
||||
8CE4939B2B23F45C00CA14D5 /* NSArray+DDSafe.m */,
|
||||
);
|
||||
path = DDSafe;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
8CE4939D2B23F5D800CA14D5 /* DDUploadFile */ = {
|
||||
8CE4939D2B23F5D800CA14D5 /* DDUpload */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
8CE4939E2B23F5FA00CA14D5 /* DDUploadFile.h */,
|
||||
8CE4939F2B23F5FA00CA14D5 /* DDUploadFile.m */,
|
||||
8C2C3ECE2B278C9E002C3C34 /* DDUploadImage.h */,
|
||||
8C2C3ECF2B278C9E002C3C34 /* DDUploadImage.m */,
|
||||
);
|
||||
path = DDUploadFile;
|
||||
path = DDUpload;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
8CE493A12B23F7DA00CA14D5 /* DDWeakTimer */ = {
|
||||
@@ -5523,6 +5668,7 @@
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
8C2C3EC92B277E7F002C3C34 /* DDIAPHelper.m in Sources */,
|
||||
1802B3CB2A540F870036DCEF /* DDProtocolView.m in Sources */,
|
||||
18660CD92A21921F0032D0C9 /* NetTipView.m in Sources */,
|
||||
188AF5982A273CE9004DD4CF /* DDStorePageVC.m in Sources */,
|
||||
@@ -5548,7 +5694,10 @@
|
||||
1876962D2A2AE83700C87777 /* DDNormalTextViewController.m in Sources */,
|
||||
1867776B2A4286DB0096D802 /* CreatRoomViewController.m in Sources */,
|
||||
18660CD82A21921F0032D0C9 /* Reachability.m in Sources */,
|
||||
8C2C3ED02B278C9E002C3C34 /* DDUploadImage.m in Sources */,
|
||||
18C833632A25A1480090BF65 /* DDMyInfoGiftWallView.m in Sources */,
|
||||
8C2C3EE32B27CC6E002C3C34 /* DDBase64.m in Sources */,
|
||||
8C2C3ECC2B2784DE002C3C34 /* DDIAPRechargeStorage.m in Sources */,
|
||||
1812ECA82A54FE7100FF2AC0 /* DDRoomSendGiftCountView.m in Sources */,
|
||||
18B5E5972A4D20790089CEB1 /* DDShoppingCell.m in Sources */,
|
||||
188EC1432A47CF3300060F03 /* HXPhotoEditClippingToolBar.m in Sources */,
|
||||
@@ -5589,6 +5738,7 @@
|
||||
2358F57D2B230B4A0038453C /* DDVideoEncodeManage.m in Sources */,
|
||||
18C833602A25A12A0090BF65 /* DDMyInfoGiftWallCollectionViewCell.m in Sources */,
|
||||
18660DCD2A21E54B0032D0C9 /* RoomViewController.m in Sources */,
|
||||
8C2C3EE62B27CC7D002C3C34 /* DDDESEncrypt.m in Sources */,
|
||||
188EC0EC2A47CF3200060F03 /* DDMEmoticonCell.m in Sources */,
|
||||
18660D4E2A2193C50032D0C9 /* NSDictionary+Custom.m in Sources */,
|
||||
186EBFB72A402F33005623CC /* DynamicCommentViewController.m in Sources */,
|
||||
@@ -5647,6 +5797,7 @@
|
||||
188EC10E2A47CF3200060F03 /* NSDate+HXExtension.m in Sources */,
|
||||
188EC12A2A47CF3200060F03 /* HXPhotoBottomSelectView.m in Sources */,
|
||||
186EBFC42A40363A005623CC /* UIViewController+XPSemiModal.m in Sources */,
|
||||
8C2C3EEF2B27D1B5002C3C34 /* SSKeychain.m in Sources */,
|
||||
183864482A28A17B005BF235 /* ZLCollectionCell.m in Sources */,
|
||||
18AFFEC02A4BD4E0008F6478 /* DDTopAndBottomView.m in Sources */,
|
||||
189569AF2A233BCD00DCF149 /* RoomTipView.m in Sources */,
|
||||
@@ -5673,6 +5824,7 @@
|
||||
1802B3DB2A541B6B0036DCEF /* DDLoginTextView.m in Sources */,
|
||||
186A897B2A41B272001DE99E /* DDAuthorStatusTableViewCell.m in Sources */,
|
||||
186A88E42A415291001DE99E /* DDMyLevelViewController.m in Sources */,
|
||||
8C2C3EF92B27D94A002C3C34 /* YYUtility.m in Sources */,
|
||||
18C905042A2305A600F7CAFD /* ResourcePickerToolsObject.m in Sources */,
|
||||
186A89052A41603C001DE99E /* DDNobleTableViewCell.m in Sources */,
|
||||
18E94E802A2740890055E8F0 /* RoomGiftModel.m in Sources */,
|
||||
@@ -5710,6 +5862,7 @@
|
||||
186A89162A41A1E8001DE99E /* DDRealNameModel.m in Sources */,
|
||||
186777752A4293460096D802 /* CreatRoomCoverViewCell.m in Sources */,
|
||||
1882ADC82A52A3F1009081FE /* DDMsgInputView.m in Sources */,
|
||||
8C2C3EEA2B27D163002C3C34 /* YYReachability.m in Sources */,
|
||||
1848C22B2A4D11F00031F734 /* RoomAirPlaneContentView.m in Sources */,
|
||||
1826B9D12A497F730023408A /* WebViewJavascriptBridgeBase.m in Sources */,
|
||||
18660CF82A2193750032D0C9 /* JXTAlertView.m in Sources */,
|
||||
@@ -5833,6 +5986,7 @@
|
||||
186777812A4294040096D802 /* CreatRoomCancleViewCell.m in Sources */,
|
||||
188EC12F2A47CF3200060F03 /* HXCustomCollectionReusableView.m in Sources */,
|
||||
1826C6102A24B76200A5AFDB /* DDMyInformationHeaderView.m in Sources */,
|
||||
8C2C3ED72B279141002C3C34 /* NSString+DDUtils.m in Sources */,
|
||||
188EC1352A47CF3300060F03 /* HXPreviewVideoView.m in Sources */,
|
||||
18660D592A2193C50032D0C9 /* NSDate+Custom.m in Sources */,
|
||||
182F076E2A28316D002BC893 /* RoomSmallView.m in Sources */,
|
||||
@@ -5984,6 +6138,7 @@
|
||||
18E659C42A564F6B0017854A /* DDSearchHeaderView.m in Sources */,
|
||||
188EC1172A47CF3200060F03 /* HXPhotoManager.m in Sources */,
|
||||
188AF5A02A273D28004DD4CF /* DDStoreNumberView.m in Sources */,
|
||||
8C2C3EDF2B27C3B8002C3C34 /* DDCountDownHelper.m in Sources */,
|
||||
18B5E5A12A4D2EA50089CEB1 /* DDShoppingShowView.m in Sources */,
|
||||
188EC1532A47CF3300060F03 /* HXPhotoEditStickerItemView.m in Sources */,
|
||||
188EC1052A47CF3200060F03 /* HXPhotoViewTransition.m in Sources */,
|
||||
@@ -6054,6 +6209,7 @@
|
||||
189569A92A232EF700DCF149 /* RoomOnlineUserListView.m in Sources */,
|
||||
18660D4C2A2193C50032D0C9 /* UITextView+Placeholder.m in Sources */,
|
||||
189569A32A232EA100DCF149 /* RoomUserManagementView.m in Sources */,
|
||||
8C2C3EF32B27D224002C3C34 /* NSObject+DDExtension.m in Sources */,
|
||||
188EC13F2A47CF3300060F03 /* HXPhotoClippingView.m in Sources */,
|
||||
188AF5A42A273D45004DD4CF /* DDStoreCell.m in Sources */,
|
||||
186777782A42935D0096D802 /* CreatRoomTypeViewCell.m in Sources */,
|
||||
|
@@ -0,0 +1,51 @@
|
||||
//
|
||||
// NSObject+DDExtension.h
|
||||
// DingDangApp
|
||||
//
|
||||
// Created by 触海 on 2023/12/11.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface NSObject (DDExtension)
|
||||
|
||||
/// 根据Json数组初始化一个实例数组
|
||||
/// - Parameter jsonArray: json数组
|
||||
+ (NSArray *)DD_ModelsWithArray:(id)jsonArray;
|
||||
|
||||
|
||||
/// 根据字典初始化一个实例
|
||||
/// - Parameter dict: 字典
|
||||
+ (instancetype)DD_ModelWithDict:(NSDictionary *)dict;
|
||||
|
||||
|
||||
/// 根据JSON对象初始化一个实例
|
||||
/// - Parameter json: json数据
|
||||
+ (instancetype)DD_ModeWithJSON:(id)json;
|
||||
|
||||
|
||||
/// model 转字典
|
||||
- (NSDictionary *)dd_modelDictionary;
|
||||
|
||||
|
||||
/// 转 json string
|
||||
- (NSString *)dd_toJSONString;
|
||||
|
||||
|
||||
/// 转json object
|
||||
- (id)dd_toJSONObject;
|
||||
|
||||
|
||||
/// 扩展方法 按需索取 重写即可
|
||||
/// 如果一个模型中 包含一个数组 数组中是另一个模型
|
||||
+ (NSDictionary *)DD_ObjectClassInArray;
|
||||
|
||||
|
||||
/// 如果一个模型中需要字段映射的话 比如 id -> ID name -> other,name
|
||||
+ (NSDictionary *)DD_ReplaceKeyFromPropertyName;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
@@ -0,0 +1,77 @@
|
||||
//
|
||||
// NSObject+DDExtension.m
|
||||
// DingDangApp
|
||||
//
|
||||
// Created by 触海 on 2023/12/11.
|
||||
//
|
||||
|
||||
#import "NSObject+DDExtension.h"
|
||||
#import <MJExtension/MJExtension.h>
|
||||
|
||||
@implementation NSObject (DDExtension)
|
||||
|
||||
#pragma mark - Public Method
|
||||
/// 根据Json数组初始化一个实例数组
|
||||
/// - Parameter jsonArray: json数组
|
||||
+ (NSArray *)DD_ModelsWithArray:(id)jsonArray {
|
||||
return [self mj_objectArrayWithKeyValuesArray:jsonArray];
|
||||
}
|
||||
|
||||
|
||||
/// 根据字典初始化一个实例
|
||||
/// - Parameter dict: 字典
|
||||
+ (instancetype)DD_ModelWithDict:(NSDictionary *)dict {
|
||||
return [self mj_objectWithKeyValues:dict];
|
||||
}
|
||||
|
||||
|
||||
/// 根据JSON对象初始化一个实例
|
||||
/// - Parameter json: json数据
|
||||
+ (instancetype)DD_ModeWithJSON:(id)json {
|
||||
return [self mj_objectWithKeyValues:json];
|
||||
}
|
||||
|
||||
|
||||
/// model 转字典
|
||||
- (NSDictionary *)dd_modelDictionary {
|
||||
return [[self mj_keyValues] copy];
|
||||
}
|
||||
|
||||
/// 转 json string
|
||||
- (NSString *)dd_toJSONString {
|
||||
return [self mj_JSONString];
|
||||
}
|
||||
|
||||
/// 转json object
|
||||
- (id)dd_toJSONObject {
|
||||
return [self mj_JSONObject];
|
||||
}
|
||||
|
||||
|
||||
/// 扩展方法 按需索取 重写即可
|
||||
/// 如果一个模型中 包含一个数组 数组中是另一个模型
|
||||
+ (NSDictionary *)DD_ObjectClassInArray {
|
||||
return @{};
|
||||
}
|
||||
|
||||
/// 如果一个模型中需要字段映射的话 比如 id -> ID name -> other,name
|
||||
+ (NSDictionary *)DD_ReplaceKeyFromPropertyName {
|
||||
return @{};
|
||||
}
|
||||
|
||||
|
||||
#pragma mark - Super Method
|
||||
/// 如果模型中包含数组的话
|
||||
+ (NSDictionary *)mj_objectClassInArray {
|
||||
return [self DD_ObjectClassInArray];
|
||||
}
|
||||
|
||||
/// 模型中需要映射 重写整个方法
|
||||
+ (NSDictionary *)mj_replacedKeyFromPropertyName {
|
||||
return [self DD_ReplaceKeyFromPropertyName];
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@end
|
@@ -0,0 +1,36 @@
|
||||
//
|
||||
// NSString+DDUtils.h
|
||||
// DingDangApp
|
||||
//
|
||||
// Created by 触海 on 2023/12/11.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface NSString (DDUtils)
|
||||
|
||||
/// 是否是正确的手机号码
|
||||
- (BOOL)dd_isPhoneNumber;
|
||||
/// MD5加密
|
||||
- (NSString *)dd_MD5String;
|
||||
|
||||
/// 判断新旧版本号
|
||||
+ (BOOL)DD_VersionCompareOldString:(NSString *)oldStr newString:(NSString *)newStr;
|
||||
|
||||
/// 数字转换为万
|
||||
+ (NSString *)DD_GetDealNumWithString:(NSString *)string;
|
||||
+ (NSString *)DD_GetDealNumWithString:(NSString *)string text:(NSString *)text;
|
||||
|
||||
/// 时间戳转换为需要显示的内容
|
||||
+ (NSString *)DD_StringToTimerStamp:(NSString *)timerStamp;
|
||||
|
||||
/// Url字符串转换
|
||||
+ (NSString *)DD_GetCharmImageUrl:(NSString *)url;
|
||||
+ (NSString *)DD_GetWealthImageUrl:(NSString *)url;
|
||||
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
@@ -0,0 +1,177 @@
|
||||
//
|
||||
// NSString+DDUtils.m
|
||||
// DingDangApp
|
||||
//
|
||||
// Created by 触海 on 2023/12/11.
|
||||
//
|
||||
|
||||
#import "NSString+DDUtils.h"
|
||||
#import <CommonCrypto/CommonDigest.h>
|
||||
|
||||
@implementation NSString (DDUtils)
|
||||
|
||||
///是否是正确的手机号
|
||||
- (BOOL)dd_isPhoneNumber {
|
||||
NSString *regex =@"^((1[3-9][0-9])|(147)|(15[^4,\\D])|(18[0,5-9]))\\d{8}$";
|
||||
NSPredicate *pred = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", regex];
|
||||
return [pred evaluateWithObject:self];
|
||||
}
|
||||
|
||||
/// MD5加密
|
||||
- (NSString *)dd_MD5String {
|
||||
const char *cstr = [self UTF8String];
|
||||
unsigned char result[16];
|
||||
CC_MD5(cstr, (CC_LONG)strlen(cstr), 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]
|
||||
];
|
||||
}
|
||||
|
||||
/// 判断新旧版本号
|
||||
+ (BOOL)DD_VersionCompareOldString:(NSString *)oldStr newString:(NSString *)newStr {
|
||||
return [oldStr compare:newStr options:NSNumericSearch] != NSOrderedAscending;
|
||||
}
|
||||
|
||||
|
||||
///数字转化为万
|
||||
+ (NSString *)DD_GetDealNumWithString:(NSString *)string {
|
||||
if (string.floatValue < 10000.0) {
|
||||
return [NSString stringWithFormat:@"%@.0",string];
|
||||
}
|
||||
|
||||
NSString *numString = [self DD_ChangeDealNumberWithString:string];
|
||||
return [NSString stringWithFormat:@"%@万", numString];
|
||||
}
|
||||
|
||||
/// 数字转换成万
|
||||
+ (NSString *)DD_GetDealNumWithString:(NSString *)string text:(NSString *)text {
|
||||
if (string.floatValue < 10000.0) {
|
||||
return [NSString stringWithFormat:@"%@.0",string];
|
||||
}
|
||||
|
||||
if (string.floatValue > 9990000) {
|
||||
return @"999w+";
|
||||
}
|
||||
|
||||
NSString *numString = [self DD_ChangeDealNumberWithString:string];
|
||||
return [NSString stringWithFormat:@"%@%@", numString, text];
|
||||
|
||||
}
|
||||
|
||||
/// 时间戳转换为需要显示的内容
|
||||
+ (NSString *)DD_StringToTimerStamp:(NSString *)timerStamp {
|
||||
return [self DD_StringWithTimeStamp:timerStamp];
|
||||
}
|
||||
|
||||
/// 拼接字符串
|
||||
+ (NSString *)DD_GetCharmImageUrl:(NSString *)url {
|
||||
return [self DD_AddStringWithImageUrl:url componet:@"charm_"];
|
||||
}
|
||||
|
||||
+ (NSString *)DD_GetWealthImageUrl:(NSString *)url {
|
||||
return [self DD_AddStringWithImageUrl:url componet:@"wealth_"];
|
||||
}
|
||||
|
||||
|
||||
#pragma mark - Private Method
|
||||
+ (NSString *)DD_ChangeDealNumberWithString:(NSString *)string {
|
||||
NSDecimalNumber *customNum = [NSDecimalNumber decimalNumberWithString:string];
|
||||
NSDecimalNumber *defalutNum = [NSDecimalNumber decimalNumberWithString:@"10000"];
|
||||
|
||||
/**
|
||||
NSDecimalNumberHandler 参数 :
|
||||
1 - RoundingMode: 一个取舍枚举值
|
||||
2 - scale:处理范围
|
||||
3 - raiseOnExactness:精确出现异常是否抛出原因
|
||||
4 - raiseOnOverflow:上溢出是否抛出原因
|
||||
5 - raiseOnUnderflow:下溢出是否抛出原因
|
||||
6 - raiseOnDivideByZero:除以0是否抛出原因
|
||||
*/
|
||||
NSDecimalNumberHandler *handler = [NSDecimalNumberHandler decimalNumberHandlerWithRoundingMode:NSRoundDown
|
||||
scale:2
|
||||
raiseOnExactness:NO
|
||||
raiseOnOverflow:NO
|
||||
raiseOnUnderflow:NO
|
||||
raiseOnDivideByZero:NO];
|
||||
NSDecimalNumber *numResult = [customNum decimalNumberByDividingBy:defalutNum withBehavior:handler];
|
||||
NSString *numString = [numResult stringValue];
|
||||
return numString;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
+ (NSDateFormatter *)DD_StringWithFormatterStr:(NSString *)formatterStr {
|
||||
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
|
||||
[dateFormatter setDateFormat:formatterStr];
|
||||
|
||||
return dateFormatter;
|
||||
}
|
||||
|
||||
+ (NSString *)DD_StringWithTimeStamp:(NSString *)timeStamp {
|
||||
NSTimeInterval secondInterval = timeStamp.longLongValue / 1000;
|
||||
NSDate *date = [NSDate dateWithTimeIntervalSince1970:secondInterval];
|
||||
|
||||
// 得到与当前的时间差
|
||||
NSTimeInterval timerInterval = [date timeIntervalSinceNow];
|
||||
timerInterval = -timerInterval;
|
||||
|
||||
long temp = 0;
|
||||
//是否是同一天
|
||||
BOOL is_same_day = [[NSCalendar currentCalendar] isDateInToday:date];
|
||||
if (timerInterval < 60) { //当天,且 timeInterval < 1分钟,显示“刚刚”
|
||||
return [NSString stringWithFormat:@"刚刚"];
|
||||
}
|
||||
|
||||
if ((temp = timerInterval / 60) < 60) { //当天,且1分钟≤ timeInterval <60分钟,显示“n分钟前”
|
||||
return [NSString stringWithFormat:@"%ld分钟前", temp];
|
||||
}
|
||||
|
||||
if ((temp = temp / 60) < 24 && is_same_day) { //当天,且n≥60分钟,显示“xx:xx”
|
||||
return [[self DD_StringWithFormatterStr:@"HH:mm"] stringFromDate:date];
|
||||
}
|
||||
|
||||
if ((temp = temp / 60) < 24 && !is_same_day) { //非当天,且n≥60分钟,显示“xx:xx”;
|
||||
return [[self DD_StringWithFormatterStr:@"MM月dd日"] stringFromDate:date];
|
||||
}
|
||||
|
||||
if ((temp = temp / 30) < 30) { //跨天,且未跨年,显示“mm-dd”
|
||||
return [[self DD_StringWithFormatterStr:@"MM月dd日"] stringFromDate:date];
|
||||
}
|
||||
|
||||
// 跨年,显示“yyyy-mm-dd”
|
||||
return [[self DD_StringWithFormatterStr:@"YYYY年MM月dd日"] stringFromDate:date];
|
||||
}
|
||||
|
||||
|
||||
+ (NSString *)DD_AddStringWithImageUrl:(NSString *)urlString componet:(NSString *)compent {
|
||||
if (![urlString containsString:@"http"]) {
|
||||
return [NSString stringWithFormat:@"%@%@", [self DD_ComponentsByString:compent], urlString];
|
||||
}
|
||||
|
||||
NSString *get_url = @"1";
|
||||
NSArray *urlArray = [urlString componentsSeparatedByString:compent];
|
||||
if(urlArray.count == 2) {
|
||||
NSString *charmUrlString = urlArray[1];
|
||||
for (int i = 0; i < 110; i++) {
|
||||
NSString *charmNum = i < 9 ? [NSString stringWithFormat:@"0%d",i+1] : [NSString stringWithFormat:@"%d", i+1];
|
||||
if ([charmUrlString containsString:charmNum]) {
|
||||
get_url = [NSString stringWithFormat:@"%@%@",[self DD_ComponentsByString:compent], charmNum];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return get_url;
|
||||
|
||||
}
|
||||
|
||||
+ (NSString *)DD_ComponentsByString:(NSString *)string {
|
||||
return [string isEqualToString:@"charm_"] ? @"new_charm_" : @"new_exper_" ;
|
||||
}
|
||||
|
||||
@end
|
@@ -0,0 +1,35 @@
|
||||
//
|
||||
// DDCountDownHelper.h
|
||||
// DingDangApp
|
||||
//
|
||||
// Created by 触海 on 2023/12/11.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@protocol DDCountDownHelperDelegate <NSObject>
|
||||
@optional
|
||||
/// 倒计时结束
|
||||
- (void)dd_onFinishCountDown;
|
||||
/// 进行倒计时中
|
||||
- (void)dd_onOpeningCountDownWithTime:(int)time;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@interface DDCountDownHelper : NSObject
|
||||
|
||||
+ (instancetype)shared;
|
||||
|
||||
/// 根据时间开始倒计时
|
||||
- (void)dd_openCountDownWithTotalTime:(int)totalTime;
|
||||
/// 停止倒计时
|
||||
- (void)dd_stopCountDown;
|
||||
|
||||
@property (nonatomic, weak) id<DDCountDownHelperDelegate> delegate;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
@@ -0,0 +1,71 @@
|
||||
//
|
||||
// DDCountDownHelper.m
|
||||
// DingDangApp
|
||||
//
|
||||
// Created by 触海 on 2023/12/11.
|
||||
//
|
||||
|
||||
#import "DDCountDownHelper.h"
|
||||
|
||||
@interface DDCountDownHelper()
|
||||
@property (nonatomic, strong) dispatch_source_t timer;
|
||||
@end
|
||||
|
||||
@implementation DDCountDownHelper
|
||||
|
||||
#pragma mark - Public Method
|
||||
+ (instancetype)shared {
|
||||
static dispatch_once_t onceToken;
|
||||
static DDCountDownHelper *_instance;
|
||||
dispatch_once(&onceToken, ^{
|
||||
_instance = [[DDCountDownHelper alloc] init];
|
||||
});
|
||||
return _instance;
|
||||
}
|
||||
|
||||
/// 根据时间开始倒计时
|
||||
- (void)dd_openCountDownWithTotalTime:(int)totalTime {
|
||||
if (totalTime <= 0) return;
|
||||
|
||||
__block int timeCount = totalTime;
|
||||
if (self.timer != nil) {
|
||||
dispatch_source_cancel(self.timer);
|
||||
}
|
||||
|
||||
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
|
||||
self.timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);
|
||||
dispatch_source_set_timer(self.timer, dispatch_walltime(NULL, 0), 1.0 * NSEC_PER_SEC, 0);
|
||||
//每秒执行
|
||||
__weak typeof(self) weakSelf = self;
|
||||
dispatch_source_set_event_handler(self.timer, ^{
|
||||
__strong typeof(self) strongSelf = weakSelf;
|
||||
if (timeCount <= 0) { //倒计时结束,关闭倒计时
|
||||
dispatch_source_cancel(self.timer);
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
if (self.delegate && [self.delegate respondsToSelector:@selector(dd_onFinishCountDown)]) {
|
||||
[self.delegate dd_onFinishCountDown];
|
||||
}
|
||||
});
|
||||
} else {
|
||||
timeCount--;
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
//设置按钮显示读秒效果
|
||||
if (self.delegate && [self.delegate respondsToSelector:@selector(dd_onOpeningCountDownWithTime:)]) {
|
||||
[self.delegate dd_onOpeningCountDownWithTime:timeCount];
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
});
|
||||
dispatch_resume(self.timer);
|
||||
}
|
||||
|
||||
/// 停止倒计时
|
||||
- (void)dd_stopCountDown {
|
||||
if (self.timer != nil) {
|
||||
dispatch_source_cancel(self.timer);
|
||||
self.timer = nil;
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
@@ -0,0 +1,35 @@
|
||||
//
|
||||
// DDIAPHelper.h
|
||||
// DingDangApp
|
||||
//
|
||||
// Created by 触海 on 2023/12/11.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
typedef NS_ENUM(NSInteger, DDPaymentStatus) {
|
||||
DD_PaymentStatus_Purchasing = 1, //付款中
|
||||
DD_PaymentStatus_Purchased, //付款操作已完成
|
||||
DD_PaymentStatus_Failed, //付款操作失败
|
||||
DD_PaymentStatus_Deferred //未知状态
|
||||
};
|
||||
|
||||
@protocol DDIAPHelperDelegate <NSObject>
|
||||
/// 当前充值的状态
|
||||
- (void)dd_rechargeProcessStatus:(DDPaymentStatus)status;
|
||||
/// 充值成功回调ID
|
||||
- (void)dd_rechargeSuccessTranscationId:(NSString *)transactionId;
|
||||
@end
|
||||
|
||||
|
||||
@interface DDIAPHelper : NSObject
|
||||
+ (instancetype)shareHelper;
|
||||
/// 代理
|
||||
@property (nonatomic, weak) id<DDIAPHelperDelegate> delegate;
|
||||
/// 购买产品
|
||||
- (void)dd_buyAppProductWithProductId:(NSString *)appProductId;
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
@@ -0,0 +1,85 @@
|
||||
//
|
||||
// DDIAPHelper.m
|
||||
// DingDangApp
|
||||
//
|
||||
// Created by 触海 on 2023/12/11.
|
||||
//
|
||||
|
||||
#import "DDIAPHelper.h"
|
||||
#import <IAPHelper/IAPHelper.h>
|
||||
#import <IAPShare.h>
|
||||
|
||||
@implementation DDIAPHelper
|
||||
|
||||
#pragma mark - Public Method
|
||||
+ (instancetype)shareHelper {
|
||||
static dispatch_once_t onceToken;
|
||||
static DDIAPHelper *_instance;
|
||||
dispatch_once(&onceToken, ^{
|
||||
_instance = [[self alloc] init];
|
||||
});
|
||||
return _instance;
|
||||
}
|
||||
|
||||
/// 购买产品
|
||||
- (void)dd_buyAppProductWithProductId:(NSString *)appProductId {
|
||||
NSSet *appProductSet = [[NSSet alloc] initWithObjects:appProductId, nil];
|
||||
[IAPShare sharedHelper].iap = [[IAPHelper alloc] initWithProductIdentifiers:appProductSet];
|
||||
[[IAPShare sharedHelper].iap requestProductsWithCompletion:^(SKProductsRequest *request, SKProductsResponse *response) {
|
||||
if (response == nil || response.products.count == 0) {
|
||||
if (self.delegate && [self.delegate respondsToSelector:@selector(dd_rechargeProcessStatus:)]) {
|
||||
[self.delegate dd_rechargeProcessStatus:DD_PaymentStatus_Failed];
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (!response.products.firstObject) {
|
||||
return;
|
||||
}
|
||||
|
||||
/// 开始购买产品
|
||||
[[IAPShare sharedHelper].iap buyProduct:response.products.firstObject onCompletion:^(SKPaymentTransaction *transcation) {
|
||||
NSLog(@"%@",transcation.error.description);
|
||||
switch (transcation.transactionState) {
|
||||
case SKPaymentTransactionStatePurchased: {
|
||||
NSLog(@"付款完成状态,要做出相关的处理");
|
||||
[[SKPaymentQueue defaultQueue] finishTransaction:transcation];
|
||||
if(self.delegate && [self.delegate respondsToSelector:@selector(dd_rechargeProcessStatus:)]) {
|
||||
[self.delegate dd_rechargeProcessStatus:DD_PaymentStatus_Purchased];
|
||||
}
|
||||
if (self.delegate && [self.delegate respondsToSelector:@selector(dd_rechargeSuccessTranscationId:)]) {
|
||||
[self.delegate dd_rechargeSuccessTranscationId:transcation.transactionIdentifier];
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case SKPaymentTransactionStateFailed: {
|
||||
[[SKPaymentQueue defaultQueue] finishTransaction:transcation];
|
||||
if (self.delegate && [self.delegate respondsToSelector:@selector(dd_rechargeProcessStatus:)]) {
|
||||
[self.delegate dd_rechargeProcessStatus:DD_PaymentStatus_Failed];
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case SKPaymentTransactionStatePurchasing: {
|
||||
NSLog(@"正在购买中");
|
||||
if (self.delegate && [self.delegate respondsToSelector:@selector(dd_rechargeProcessStatus:)]) {
|
||||
[self.delegate dd_rechargeProcessStatus:DD_PaymentStatus_Purchasing];
|
||||
}
|
||||
}
|
||||
break;
|
||||
default: {
|
||||
NSLog(@"未知状态");
|
||||
[[SKPaymentQueue defaultQueue] finishTransaction:transcation];
|
||||
if (self.delegate && [self.delegate respondsToSelector:@selector(dd_rechargeProcessStatus:)]) {
|
||||
[self.delegate dd_rechargeProcessStatus:DD_PaymentStatus_Deferred];
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}];
|
||||
|
||||
}];
|
||||
}
|
||||
|
||||
@end
|
@@ -0,0 +1,30 @@
|
||||
//
|
||||
// DDIAPRechargeStorage.h
|
||||
// DingDangApp
|
||||
//
|
||||
// Created by 触海 on 2023/12/11.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface DDIAPRechargeStorage : NSObject
|
||||
|
||||
/// 根据商品id保存凭证
|
||||
+ (BOOL)DD_SaveTranscationId:(NSString *)transcationId
|
||||
recipt:(NSString *)recipt
|
||||
uid:(NSString *)uid;
|
||||
|
||||
/// 获取所有凭证
|
||||
+ (NSArray *)DD_GetAllReciptsWithUid:(NSString *)uid;
|
||||
|
||||
/// 根据商品id删除凭证
|
||||
+ (BOOL)DD_DeleteTranscationId:(NSString *)transcationId uid:(NSString *)uid;
|
||||
|
||||
/// 删除所有凭证
|
||||
+ (void)DD_DeleteAllTranscationIdsWithUid:(NSString *)uid;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
@@ -0,0 +1,57 @@
|
||||
//
|
||||
// DDIAPRechargeStorage.m
|
||||
// DingDangApp
|
||||
//
|
||||
// Created by 触海 on 2023/12/11.
|
||||
//
|
||||
|
||||
#import "DDIAPRechargeStorage.h"
|
||||
#import <SSKeychain/SSKeychain.h>
|
||||
|
||||
#define dd_appStoreKey @"dd_appStoreKey"
|
||||
@implementation DDIAPRechargeStorage
|
||||
|
||||
#pragma mark - Public Method
|
||||
/// 根据商品id保存凭证
|
||||
+ (BOOL)DD_SaveTranscationId:(NSString *)transcationId recipt:(NSString *)recipt uid:(NSString *)uid {
|
||||
NSString *key = [NSString stringWithFormat:@"%@_%@", dd_appStoreKey, uid];
|
||||
BOOL isSetPassword = [SSKeychain setPassword:recipt forService:key account:transcationId error:nil];
|
||||
return isSetPassword;
|
||||
}
|
||||
|
||||
/// 获取所有凭证
|
||||
+ (NSArray *)DD_GetAllReciptsWithUid:(NSString *)uid {
|
||||
NSArray *transcationIds = [SSKeychain allAccounts];
|
||||
NSMutableArray *reciptArray = [NSMutableArray array];
|
||||
[transcationIds enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
|
||||
NSString *key = [NSString stringWithFormat:@"%@_%@",dd_appStoreKey, uid];
|
||||
if ([obj[@"svce"] isKindOfClass:[NSString class]] && [obj[@"svce"] isEqualToString:key]) {
|
||||
NSString *recipt = [SSKeychain passwordForService:key account:obj[@"acct"] error:nil];
|
||||
NSData *data = [recipt dataUsingEncoding:NSUTF8StringEncoding];
|
||||
NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
|
||||
[reciptArray addObject:json];
|
||||
}
|
||||
}];
|
||||
return reciptArray;
|
||||
}
|
||||
|
||||
/// 根据商品id删除凭证
|
||||
+ (BOOL)DD_DeleteTranscationId:(NSString *)transcationId uid:(NSString *)uid {
|
||||
NSString *key = [NSString stringWithFormat:@"%@_%@",dd_appStoreKey, uid];
|
||||
BOOL isSetPassword = [SSKeychain deletePasswordForService:key account:transcationId error:nil];
|
||||
return isSetPassword;
|
||||
}
|
||||
|
||||
/// 删除所有凭证
|
||||
+ (void)DD_DeleteAllTranscationIdsWithUid:(NSString *)uid {
|
||||
NSArray *transcationIds = [SSKeychain allAccounts];
|
||||
[transcationIds enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
|
||||
NSString *key = [NSString stringWithFormat:@"%@_%@",dd_appStoreKey, uid];
|
||||
if ([obj[@"svce"] isKindOfClass:[NSString class]] && [obj[@"svce"] isEqualToString:key]) {
|
||||
[SSKeychain deletePasswordForService:key account:obj[@"acct"]];
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
|
||||
@end
|
@@ -0,0 +1,20 @@
|
||||
//
|
||||
// DDBase64.h
|
||||
// DingDangApp
|
||||
//
|
||||
// Created by 触海 on 2023/12/11.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface DDBase64 : NSObject
|
||||
|
||||
/// 加密
|
||||
+ (NSString *)DD_EncodeWithData:(NSData *)data;
|
||||
/// 解密
|
||||
+ (NSData *)DD_DecodeWithString:(NSString *)dataString;
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
@@ -0,0 +1,138 @@
|
||||
//
|
||||
// DDBase64.m
|
||||
// DingDangApp
|
||||
//
|
||||
// Created by 触海 on 2023/12/11.
|
||||
//
|
||||
|
||||
#import "DDBase64.h"
|
||||
|
||||
@interface DDBase64()
|
||||
|
||||
+ (int)DD_CharToInt:(char)charString;
|
||||
|
||||
@end
|
||||
|
||||
static const char encodingTable[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||
|
||||
@implementation DDBase64
|
||||
|
||||
#pragma mark - Public Method
|
||||
/// 加密
|
||||
+ (NSString *)DD_EncodeWithData:(NSData *)data {
|
||||
if (data.length == 0) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
char *characters = malloc(data.length * 3 / 2);
|
||||
if (characters == NULL) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
int end = data.length - 3;
|
||||
int index = 0;
|
||||
int charCount = 0;
|
||||
int n = 0;
|
||||
while (index <= end) {
|
||||
int d = (((int)(((char *)[data bytes])[index]) & 0x0ff) << 16)
|
||||
| (((int)(((char *)[data bytes])[index + 1]) & 0x0ff) << 8)
|
||||
| ((int)(((char *)[data bytes])[index + 2]) & 0x0ff);
|
||||
|
||||
characters[charCount++] = encodingTable[(d >> 18) & 63];
|
||||
characters[charCount++] = encodingTable[(d >> 12) & 63];
|
||||
characters[charCount++] = encodingTable[(d >> 6) & 63];
|
||||
characters[charCount++] = encodingTable[d & 63];
|
||||
|
||||
index += 3;
|
||||
|
||||
if(n++ >= 14)
|
||||
{
|
||||
n = 0;
|
||||
characters[charCount++] = ' ';
|
||||
}
|
||||
}
|
||||
|
||||
if(index == data.length - 2) {
|
||||
int d = (((int)(((char *)[data bytes])[index]) & 0x0ff) << 16)
|
||||
| (((int)(((char *)[data bytes])[index + 1]) & 255) << 8);
|
||||
characters[charCount++] = encodingTable[(d >> 18) & 63];
|
||||
characters[charCount++] = encodingTable[(d >> 12) & 63];
|
||||
characters[charCount++] = encodingTable[(d >> 6) & 63];
|
||||
characters[charCount++] = '=';
|
||||
} else if(index == data.length - 1) {
|
||||
int d = ((int)(((char *)[data bytes])[index]) & 0x0ff) << 16;
|
||||
characters[charCount++] = encodingTable[(d >> 18) & 63];
|
||||
characters[charCount++] = encodingTable[(d >> 12) & 63];
|
||||
characters[charCount++] = '=';
|
||||
characters[charCount++] = '=';
|
||||
}
|
||||
NSString * rtnStr = [[NSString alloc] initWithBytesNoCopy:characters length:charCount encoding:NSUTF8StringEncoding freeWhenDone:YES];
|
||||
return rtnStr;
|
||||
}
|
||||
|
||||
|
||||
/// 解密
|
||||
+ (NSData *)DD_DecodeWithString:(NSString *)dataString {
|
||||
if(dataString == nil || dataString.length <= 0) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
NSMutableData *rtnData = [[NSMutableData alloc]init];
|
||||
int slen = dataString.length;
|
||||
int index = 0;
|
||||
while (true) {
|
||||
while (index < slen && [dataString characterAtIndex:index] <= ' ') {
|
||||
index++;
|
||||
}
|
||||
if (index >= slen || index + 3 >= slen) {
|
||||
break;
|
||||
}
|
||||
|
||||
int byte = ([self DD_CharToInt:[dataString characterAtIndex:index]] << 18) + ([self DD_CharToInt:[dataString characterAtIndex:index + 1]] << 12) + ([self DD_CharToInt:[dataString characterAtIndex:index + 2]] << 6) + [self DD_CharToInt:[dataString characterAtIndex:index + 3]];
|
||||
Byte temp1 = (byte >> 16) & 255;
|
||||
[rtnData appendBytes:&temp1 length:1];
|
||||
if([dataString characterAtIndex:index + 2] == '=') {
|
||||
break;
|
||||
}
|
||||
Byte temp2 = (byte >> 8) & 255;
|
||||
[rtnData appendBytes:&temp2 length:1];
|
||||
if([dataString characterAtIndex:index + 3] == '=') {
|
||||
break;
|
||||
}
|
||||
Byte temp3 = byte & 255;
|
||||
[rtnData appendBytes:&temp3 length:1];
|
||||
index += 4;
|
||||
}
|
||||
return [rtnData copy];
|
||||
|
||||
}
|
||||
|
||||
#pragma mark - Private Method
|
||||
+ (int)DD_CharToInt:(char)charString {
|
||||
if (charString >= 'A' && charString <= 'Z') {
|
||||
return charString - 65;;
|
||||
}
|
||||
|
||||
if (charString >= 'a' && charString <= 'z') {
|
||||
return charString - 97 + 26;
|
||||
}
|
||||
|
||||
if (charString >= '0' && charString <= '9') {
|
||||
return charString - 48 + 26 + 26;
|
||||
}
|
||||
|
||||
switch (charString) {
|
||||
case '+':
|
||||
return 62;
|
||||
case '/':
|
||||
return 63;
|
||||
case '=':
|
||||
return 0;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@end
|
@@ -0,0 +1,20 @@
|
||||
//
|
||||
// DDDESEncrypt.h
|
||||
// DingDangApp
|
||||
//
|
||||
// Created by 触海 on 2023/12/11.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface DDDESEncrypt : NSObject
|
||||
/// 加密方法
|
||||
+ (NSString *)DD_EncryptUseDES:(NSString *)plainText key:(NSString *)key;
|
||||
|
||||
/// 解密方法
|
||||
+ (NSString *)DD_DecryptUseDES:(NSString *)cipherText key:(NSString *)key;
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
@@ -0,0 +1,63 @@
|
||||
//
|
||||
// DDDESEncrypt.m
|
||||
// DingDangApp
|
||||
//
|
||||
// Created by 触海 on 2023/12/11.
|
||||
//
|
||||
|
||||
#import "DDDESEncrypt.h"
|
||||
#import <CommonCrypto/CommonCrypto.h>
|
||||
#import "DDBase64.h"
|
||||
|
||||
@implementation DDDESEncrypt
|
||||
const Byte iv[] = {1,2,3,4,5,6,7,8};
|
||||
|
||||
#pragma mark - Public Method
|
||||
/// 加密方法
|
||||
+ (NSString *)DD_EncryptUseDES:(NSString *)plainText key:(NSString *)key {
|
||||
NSString *ciphertext = nil;
|
||||
NSData *textData = [plainText dataUsingEncoding:NSUTF8StringEncoding];
|
||||
NSUInteger dataLength = [textData length];
|
||||
unsigned char buffer[200000];
|
||||
memset(buffer, 0, sizeof(char));
|
||||
size_t numBytesEncrypted = 0;
|
||||
CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, kCCAlgorithmDES,
|
||||
kCCOptionPKCS7Padding|kCCOptionECBMode,
|
||||
[key UTF8String], kCCKeySizeDES,
|
||||
iv,
|
||||
[textData bytes], dataLength,
|
||||
buffer, 200000,
|
||||
&numBytesEncrypted);
|
||||
if (cryptStatus == kCCSuccess) {
|
||||
NSData *data = [NSData dataWithBytes:buffer length:(NSUInteger)numBytesEncrypted];
|
||||
ciphertext = [DDBase64 DD_EncodeWithData:data];
|
||||
}
|
||||
return ciphertext;
|
||||
|
||||
}
|
||||
|
||||
/// 解密方法
|
||||
+ (NSString *)DD_DecryptUseDES:(NSString *)cipherText key:(NSString *)key {
|
||||
NSString *plaintext = nil;
|
||||
NSData *cipherdata = [DDBase64 DD_DecodeWithString:cipherText];
|
||||
unsigned char buffer[200000];
|
||||
memset(buffer, 0, sizeof(char));
|
||||
size_t numBytesDecrypted = 0;
|
||||
// kCCOptionPKCS7Padding|kCCOptionECBMode 最主要在这步
|
||||
CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt, kCCAlgorithmDES,
|
||||
kCCOptionPKCS7Padding|kCCOptionECBMode,
|
||||
[key UTF8String], kCCKeySizeDES,
|
||||
iv,
|
||||
[cipherdata bytes], [cipherdata length],
|
||||
buffer, 200000,
|
||||
&numBytesDecrypted);
|
||||
if(cryptStatus == kCCSuccess) {
|
||||
NSData *plaindata = [NSData dataWithBytes:buffer length:(NSUInteger)numBytesDecrypted];
|
||||
plaintext = [[NSString alloc]initWithData:plaindata encoding:NSUTF8StringEncoding];
|
||||
}
|
||||
return plaintext;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@end
|
@@ -0,0 +1,357 @@
|
||||
//
|
||||
// SSKeychain.h
|
||||
// SSToolkit
|
||||
//
|
||||
// Created by Sam Soffes on 5/19/10.
|
||||
// Copyright (c) 2009-2011 Sam Soffes. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <Security/Security.h>
|
||||
|
||||
/** Error codes that can be returned in NSError objects. */
|
||||
typedef enum {
|
||||
/** No error. */
|
||||
SSKeychainErrorNone = noErr,
|
||||
|
||||
/** Some of the arguments were invalid. */
|
||||
SSKeychainErrorBadArguments = -1001,
|
||||
|
||||
/** There was no password. */
|
||||
SSKeychainErrorNoPassword = -1002,
|
||||
|
||||
/** One or more parameters passed internally were not valid. */
|
||||
SSKeychainErrorInvalidParameter = errSecParam,
|
||||
|
||||
/** Failed to allocate memory. */
|
||||
SSKeychainErrorFailedToAllocated = errSecAllocate,
|
||||
|
||||
/** No trust results are available. */
|
||||
SSKeychainErrorNotAvailable = errSecNotAvailable,
|
||||
|
||||
/** Authorization/Authentication failed. */
|
||||
SSKeychainErrorAuthorizationFailed = errSecAuthFailed,
|
||||
|
||||
/** The item already exists. */
|
||||
SSKeychainErrorDuplicatedItem = errSecDuplicateItem,
|
||||
|
||||
/** The item cannot be found.*/
|
||||
SSKeychainErrorNotFound = errSecItemNotFound,
|
||||
|
||||
/** Interaction with the Security Server is not allowed. */
|
||||
SSKeychainErrorInteractionNotAllowed = errSecInteractionNotAllowed,
|
||||
|
||||
/** Unable to decode the provided data. */
|
||||
SSKeychainErrorFailedToDecode = errSecDecode
|
||||
} SSKeychainErrorCode;
|
||||
|
||||
extern NSString *const kSSKeychainErrorDomain;
|
||||
|
||||
/** Account name. */
|
||||
extern NSString *const kSSKeychainAccountKey;
|
||||
|
||||
/**
|
||||
Time the item was created.
|
||||
|
||||
The value will be a string.
|
||||
*/
|
||||
extern NSString *const kSSKeychainCreatedAtKey;
|
||||
|
||||
/** Item class. */
|
||||
extern NSString *const kSSKeychainClassKey;
|
||||
|
||||
/** Item description. */
|
||||
extern NSString *const kSSKeychainDescriptionKey;
|
||||
|
||||
/** Item label. */
|
||||
extern NSString *const kSSKeychainLabelKey;
|
||||
|
||||
/** Time the item was last modified.
|
||||
|
||||
The value will be a string.
|
||||
*/
|
||||
extern NSString *const kSSKeychainLastModifiedKey;
|
||||
|
||||
/** Where the item was created. */
|
||||
extern NSString *const kSSKeychainWhereKey;
|
||||
|
||||
/**
|
||||
Simple wrapper for accessing accounts, getting passwords, setting passwords, and deleting passwords using the system
|
||||
Keychain on Mac OS X and iOS.
|
||||
|
||||
This was originally inspired by EMKeychain and SDKeychain (both of which are now gone). Thanks to the authors.
|
||||
SSKeychain has since switched to a simpler implementation that was abstracted from [SSToolkit](http://sstoolk.it).
|
||||
*/
|
||||
@interface SSKeychain : NSObject
|
||||
|
||||
///-----------------------
|
||||
/// @name Getting Accounts
|
||||
///-----------------------
|
||||
|
||||
/**
|
||||
Returns an array containing the Keychain's accounts, or `nil` if the Keychain has no accounts.
|
||||
|
||||
See the `NSString` constants declared in SSKeychain.h for a list of keys that can be used when accessing the
|
||||
dictionaries returned by this method.
|
||||
|
||||
@return An array of dictionaries containing the Keychain's accounts, or `nil` if the Keychain doesn't have any
|
||||
accounts. The order of the objects in the array isn't defined.
|
||||
|
||||
@see allAccounts:
|
||||
*/
|
||||
+ (NSArray *)allAccounts;
|
||||
|
||||
/**
|
||||
Returns an array containing the Keychain's accounts, or `nil` if the Keychain doesn't have any
|
||||
accounts.
|
||||
|
||||
See the `NSString` constants declared in SSKeychain.h for a list of keys that can be used when accessing the
|
||||
dictionaries returned by this method.
|
||||
|
||||
@param error If accessing the accounts fails, upon return contains an error that describes the problem.
|
||||
|
||||
@return An array of dictionaries containing the Keychain's accounts, or `nil` if the Keychain doesn't have any
|
||||
accounts. The order of the objects in the array isn't defined.
|
||||
|
||||
@see allAccounts
|
||||
*/
|
||||
+ (NSArray *)allAccounts:(NSError **)error;
|
||||
|
||||
/**
|
||||
Returns an array containing the Keychain's accounts for a given service, or `nil` if the Keychain doesn't have any
|
||||
accounts for the given service.
|
||||
|
||||
See the `NSString` constants declared in SSKeychain.h for a list of keys that can be used when accessing the
|
||||
dictionaries returned by this method.
|
||||
|
||||
@param serviceName The service for which to return the corresponding accounts.
|
||||
|
||||
@return An array of dictionaries containing the Keychain's accountsfor a given `serviceName`, or `nil` if the Keychain
|
||||
doesn't have any accounts for the given `serviceName`. The order of the objects in the array isn't defined.
|
||||
|
||||
@see accountsForService:error:
|
||||
*/
|
||||
+ (NSArray *)accountsForService:(NSString *)serviceName;
|
||||
|
||||
/**
|
||||
Returns an array containing the Keychain's accounts for a given service, or `nil` if the Keychain doesn't have any
|
||||
accounts for the given service.
|
||||
|
||||
@param serviceName The service for which to return the corresponding accounts.
|
||||
|
||||
@param error If accessing the accounts fails, upon return contains an error that describes the problem.
|
||||
|
||||
@return An array of dictionaries containing the Keychain's accountsfor a given `serviceName`, or `nil` if the Keychain
|
||||
doesn't have any accounts for the given `serviceName`. The order of the objects in the array isn't defined.
|
||||
|
||||
@see accountsForService:
|
||||
*/
|
||||
+ (NSArray *)accountsForService:(NSString *)serviceName error:(NSError **)error;
|
||||
|
||||
|
||||
///------------------------
|
||||
/// @name Getting Passwords
|
||||
///------------------------
|
||||
|
||||
/**
|
||||
Returns a string containing the password for a given account and service, or `nil` if the Keychain doesn't have a
|
||||
password for the given parameters.
|
||||
|
||||
@param serviceName The service for which to return the corresponding password.
|
||||
|
||||
@param account The account for which to return the corresponding password.
|
||||
|
||||
@return Returns a string containing the password for a given account and service, or `nil` if the Keychain doesn't
|
||||
have a password for the given parameters.
|
||||
|
||||
@see passwordForService:account:error:
|
||||
*/
|
||||
+ (NSString *)passwordForService:(NSString *)serviceName account:(NSString *)account;
|
||||
|
||||
/**
|
||||
Returns a string containing the password for a given account and service, or `nil` if the Keychain doesn't have a
|
||||
password for the given parameters.
|
||||
|
||||
@param serviceName The service for which to return the corresponding password.
|
||||
|
||||
@param account The account for which to return the corresponding password.
|
||||
|
||||
@param error If accessing the password fails, upon return contains an error that describes the problem.
|
||||
|
||||
@return Returns a string containing the password for a given account and service, or `nil` if the Keychain doesn't
|
||||
have a password for the given parameters.
|
||||
|
||||
@see passwordForService:account:
|
||||
*/
|
||||
+ (NSString *)passwordForService:(NSString *)serviceName account:(NSString *)account error:(NSError **)error;
|
||||
|
||||
/**
|
||||
Returns the password data for a given account and service, or `nil` if the Keychain doesn't have data
|
||||
for the given parameters.
|
||||
|
||||
@param serviceName The service for which to return the corresponding password.
|
||||
|
||||
@param account The account for which to return the corresponding password.
|
||||
|
||||
@param error If accessing the password fails, upon return contains an error that describes the problem.
|
||||
|
||||
@return Returns a the password data for the given account and service, or `nil` if the Keychain doesn't
|
||||
have data for the given parameters.
|
||||
|
||||
@see passwordDataForService:account:error:
|
||||
*/
|
||||
+ (NSData *)passwordDataForService:(NSString *)serviceName account:(NSString *)account;
|
||||
|
||||
/**
|
||||
Returns the password data for a given account and service, or `nil` if the Keychain doesn't have data
|
||||
for the given parameters.
|
||||
|
||||
@param serviceName The service for which to return the corresponding password.
|
||||
|
||||
@param account The account for which to return the corresponding password.
|
||||
|
||||
@param error If accessing the password fails, upon return contains an error that describes the problem.
|
||||
|
||||
@return Returns a the password data for the given account and service, or `nil` if the Keychain doesn't
|
||||
have a password for the given parameters.
|
||||
|
||||
@see passwordDataForService:account:
|
||||
*/
|
||||
+ (NSData *)passwordDataForService:(NSString *)serviceName account:(NSString *)account error:(NSError **)error;
|
||||
|
||||
|
||||
///-------------------------
|
||||
/// @name Deleting Passwords
|
||||
///-------------------------
|
||||
|
||||
/**
|
||||
Deletes a password from the Keychain.
|
||||
|
||||
@param serviceName The service for which to delete the corresponding password.
|
||||
|
||||
@param account The account for which to delete the corresponding password.
|
||||
|
||||
@return Returns `YES` on success, or `NO` on failure.
|
||||
|
||||
@see deletePasswordForService:account:error:
|
||||
*/
|
||||
+ (BOOL)deletePasswordForService:(NSString *)serviceName account:(NSString *)account;
|
||||
|
||||
/**
|
||||
Deletes a password from the Keychain.
|
||||
|
||||
@param serviceName The service for which to delete the corresponding password.
|
||||
|
||||
@param account The account for which to delete the corresponding password.
|
||||
|
||||
@param error If deleting the password fails, upon return contains an error that describes the problem.
|
||||
|
||||
@return Returns `YES` on success, or `NO` on failure.
|
||||
|
||||
@see deletePasswordForService:account:
|
||||
*/
|
||||
+ (BOOL)deletePasswordForService:(NSString *)serviceName account:(NSString *)account error:(NSError **)error;
|
||||
|
||||
|
||||
///------------------------
|
||||
/// @name Setting Passwords
|
||||
///------------------------
|
||||
|
||||
/**
|
||||
Sets a password in the Keychain.
|
||||
|
||||
@param password The password to store in the Keychain.
|
||||
|
||||
@param serviceName The service for which to set the corresponding password.
|
||||
|
||||
@param account The account for which to set the corresponding password.
|
||||
|
||||
@return Returns `YES` on success, or `NO` on failure.
|
||||
|
||||
@see setPassword:forService:account:error:
|
||||
*/
|
||||
+ (BOOL)setPassword:(NSString *)password forService:(NSString *)serviceName account:(NSString *)account;
|
||||
|
||||
/**
|
||||
Sets a password in the Keychain.
|
||||
|
||||
@param password The password to store in the Keychain.
|
||||
|
||||
@param serviceName The service for which to set the corresponding password.
|
||||
|
||||
@param account The account for which to set the corresponding password.
|
||||
|
||||
@param error If setting the password fails, upon return contains an error that describes the problem.
|
||||
|
||||
@return Returns `YES` on success, or `NO` on failure.
|
||||
|
||||
@see setPassword:forService:account:
|
||||
*/
|
||||
+ (BOOL)setPassword:(NSString *)password forService:(NSString *)serviceName account:(NSString *)account error:(NSError **)error;
|
||||
|
||||
/**
|
||||
Sets arbirary data in the Keychain.
|
||||
|
||||
@param password The data to store in the Keychain.
|
||||
|
||||
@param serviceName The service for which to set the corresponding password.
|
||||
|
||||
@param account The account for which to set the corresponding password.
|
||||
|
||||
@param error If setting the password fails, upon return contains an error that describes the problem.
|
||||
|
||||
@return Returns `YES` on success, or `NO` on failure.
|
||||
|
||||
@see setPasswordData:forService:account:error:
|
||||
*/
|
||||
+ (BOOL)setPasswordData:(NSData *)password forService:(NSString *)serviceName account:(NSString *)account;
|
||||
|
||||
/**
|
||||
Sets arbirary data in the Keychain.
|
||||
|
||||
@param password The data to store in the Keychain.
|
||||
|
||||
@param serviceName The service for which to set the corresponding password.
|
||||
|
||||
@param account The account for which to set the corresponding password.
|
||||
|
||||
@param error If setting the password fails, upon return contains an error that describes the problem.
|
||||
|
||||
@return Returns `YES` on success, or `NO` on failure.
|
||||
|
||||
@see setPasswordData:forService:account:
|
||||
*/
|
||||
+ (BOOL)setPasswordData:(NSData *)password forService:(NSString *)serviceName account:(NSString *)account error:(NSError **)error;
|
||||
|
||||
|
||||
///--------------------
|
||||
/// @name Configuration
|
||||
///--------------------
|
||||
|
||||
#if __IPHONE_4_0 && TARGET_OS_IPHONE
|
||||
/**
|
||||
Returns the accessibility type for all future passwords saved to the Keychain.
|
||||
|
||||
@return Returns the accessibility type.
|
||||
|
||||
The return value will be `NULL` or one of the "Keychain Item Accessibility Constants" used for determining when a
|
||||
keychain item should be readable.
|
||||
|
||||
@see accessibilityType
|
||||
*/
|
||||
+ (CFTypeRef)accessibilityType;
|
||||
|
||||
/**
|
||||
Sets the accessibility type for all future passwords saved to the Keychain.
|
||||
|
||||
@param accessibilityType One of the "Keychain Item Accessibility Constants" used for determining when a keychain item
|
||||
should be readable.
|
||||
|
||||
If the value is `NULL` (the default), the Keychain default will be used.
|
||||
|
||||
@see accessibilityType
|
||||
*/
|
||||
+ (void)setAccessibilityType:(CFTypeRef)accessibilityType;
|
||||
#endif
|
||||
|
||||
@end
|
@@ -0,0 +1,262 @@
|
||||
//
|
||||
// SSKeychain.m
|
||||
// SSToolkit
|
||||
//
|
||||
// Created by Sam Soffes on 5/19/10.
|
||||
// Copyright (c) 2009-2011 Sam Soffes. All rights reserved.
|
||||
//
|
||||
|
||||
#import "SSKeychain.h"
|
||||
|
||||
NSString *const kSSKeychainErrorDomain = @"com.samsoffes.sskeychain";
|
||||
|
||||
NSString *const kSSKeychainAccountKey = @"acct";
|
||||
NSString *const kSSKeychainCreatedAtKey = @"cdat";
|
||||
NSString *const kSSKeychainClassKey = @"labl";
|
||||
NSString *const kSSKeychainDescriptionKey = @"desc";
|
||||
NSString *const kSSKeychainLabelKey = @"labl";
|
||||
NSString *const kSSKeychainLastModifiedKey = @"mdat";
|
||||
NSString *const kSSKeychainWhereKey = @"svce";
|
||||
|
||||
#if __IPHONE_4_0 && TARGET_OS_IPHONE
|
||||
CFTypeRef SSKeychainAccessibilityType = NULL;
|
||||
#endif
|
||||
|
||||
@interface SSKeychain ()
|
||||
+ (NSMutableDictionary *)_queryForService:(NSString *)service account:(NSString *)account;
|
||||
@end
|
||||
|
||||
@implementation SSKeychain
|
||||
|
||||
#pragma mark - Getting Accounts
|
||||
|
||||
+ (NSArray *)allAccounts {
|
||||
return [self accountsForService:nil error:nil];
|
||||
}
|
||||
|
||||
|
||||
+ (NSArray *)allAccounts:(NSError **)error {
|
||||
return [self accountsForService:nil error:error];
|
||||
}
|
||||
|
||||
|
||||
+ (NSArray *)accountsForService:(NSString *)service {
|
||||
return [self accountsForService:service error:nil];
|
||||
}
|
||||
|
||||
|
||||
+ (NSArray *)accountsForService:(NSString *)service error:(NSError **)error {
|
||||
OSStatus status = SSKeychainErrorBadArguments;
|
||||
NSMutableDictionary *query = [self _queryForService:service account:nil];
|
||||
#if __has_feature(objc_arc)
|
||||
[query setObject:(__bridge id)kCFBooleanTrue forKey:(__bridge id)kSecReturnAttributes];
|
||||
[query setObject:(__bridge id)kSecMatchLimitAll forKey:(__bridge id)kSecMatchLimit];
|
||||
#else
|
||||
[query setObject:(id)kCFBooleanTrue forKey:(id)kSecReturnAttributes];
|
||||
[query setObject:(id)kSecMatchLimitAll forKey:(id)kSecMatchLimit];
|
||||
#endif
|
||||
|
||||
CFTypeRef result = NULL;
|
||||
#if __has_feature(objc_arc)
|
||||
status = SecItemCopyMatching((__bridge CFDictionaryRef)query, &result);
|
||||
#else
|
||||
status = SecItemCopyMatching((CFDictionaryRef)query, &result);
|
||||
#endif
|
||||
if (status != noErr && error != NULL) {
|
||||
*error = [NSError errorWithDomain:kSSKeychainErrorDomain code:status userInfo:nil];
|
||||
return nil;
|
||||
}
|
||||
|
||||
#if __has_feature(objc_arc)
|
||||
return (__bridge_transfer NSArray *)result;
|
||||
#else
|
||||
return [(NSArray *)result autorelease];
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#pragma mark - Getting Passwords
|
||||
|
||||
+ (NSString *)passwordForService:(NSString *)service account:(NSString *)account {
|
||||
return [self passwordForService:service account:account error:nil];
|
||||
}
|
||||
|
||||
|
||||
+ (NSString *)passwordForService:(NSString *)service account:(NSString *)account error:(NSError **)error {
|
||||
NSData *data = [self passwordDataForService:service account:account error:error];
|
||||
if (data.length > 0) {
|
||||
NSString *string = [[NSString alloc] initWithData:(NSData *)data encoding:NSUTF8StringEncoding];
|
||||
#if !__has_feature(objc_arc)
|
||||
[string autorelease];
|
||||
#endif
|
||||
return string;
|
||||
}
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
|
||||
+ (NSData *)passwordDataForService:(NSString *)service account:(NSString *)account {
|
||||
return [self passwordDataForService:service account:account error:nil];
|
||||
}
|
||||
|
||||
|
||||
+ (NSData *)passwordDataForService:(NSString *)service account:(NSString *)account error:(NSError **)error {
|
||||
OSStatus status = SSKeychainErrorBadArguments;
|
||||
if (!service || !account) {
|
||||
if (error) {
|
||||
*error = [NSError errorWithDomain:kSSKeychainErrorDomain code:status userInfo:nil];
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
CFTypeRef result = NULL;
|
||||
NSMutableDictionary *query = [self _queryForService:service account:account];
|
||||
#if __has_feature(objc_arc)
|
||||
[query setObject:(__bridge id)kCFBooleanTrue forKey:(__bridge id)kSecReturnData];
|
||||
[query setObject:(__bridge id)kSecMatchLimitOne forKey:(__bridge id)kSecMatchLimit];
|
||||
status = SecItemCopyMatching((__bridge CFDictionaryRef)query, &result);
|
||||
#else
|
||||
[query setObject:(id)kCFBooleanTrue forKey:(id)kSecReturnData];
|
||||
[query setObject:(id)kSecMatchLimitOne forKey:(id)kSecMatchLimit];
|
||||
status = SecItemCopyMatching((CFDictionaryRef)query, &result);
|
||||
#endif
|
||||
|
||||
if (status != noErr && error != NULL) {
|
||||
*error = [NSError errorWithDomain:kSSKeychainErrorDomain code:status userInfo:nil];
|
||||
return nil;
|
||||
}
|
||||
|
||||
#if __has_feature(objc_arc)
|
||||
return (__bridge_transfer NSData *)result;
|
||||
#else
|
||||
return [(NSData *)result autorelease];
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#pragma mark - Deleting Passwords
|
||||
|
||||
+ (BOOL)deletePasswordForService:(NSString *)service account:(NSString *)account {
|
||||
return [self deletePasswordForService:service account:account error:nil];
|
||||
}
|
||||
|
||||
|
||||
+ (BOOL)deletePasswordForService:(NSString *)service account:(NSString *)account error:(NSError **)error {
|
||||
OSStatus status = SSKeychainErrorBadArguments;
|
||||
if (service && account) {
|
||||
NSMutableDictionary *query = [self _queryForService:service account:account];
|
||||
#if __has_feature(objc_arc)
|
||||
status = SecItemDelete((__bridge CFDictionaryRef)query);
|
||||
#else
|
||||
status = SecItemDelete((CFDictionaryRef)query);
|
||||
#endif
|
||||
}
|
||||
if (status != noErr && error != NULL) {
|
||||
*error = [NSError errorWithDomain:kSSKeychainErrorDomain code:status userInfo:nil];
|
||||
}
|
||||
return (status == noErr);
|
||||
|
||||
}
|
||||
|
||||
|
||||
#pragma mark - Setting Passwords
|
||||
|
||||
+ (BOOL)setPassword:(NSString *)password forService:(NSString *)service account:(NSString *)account {
|
||||
return [self setPassword:password forService:service account:account error:nil];
|
||||
}
|
||||
|
||||
|
||||
+ (BOOL)setPassword:(NSString *)password forService:(NSString *)service account:(NSString *)account error:(NSError **)error {
|
||||
NSData *data = [password dataUsingEncoding:NSUTF8StringEncoding];
|
||||
return [self setPasswordData:data forService:service account:account error:error];
|
||||
}
|
||||
|
||||
|
||||
+ (BOOL)setPasswordData:(NSData *)password forService:(NSString *)service account:(NSString *)account {
|
||||
return [self setPasswordData:password forService:service account:account error:nil];
|
||||
}
|
||||
|
||||
|
||||
+ (BOOL)setPasswordData:(NSData *)password forService:(NSString *)service account:(NSString *)account error:(NSError **)error {
|
||||
OSStatus status = SSKeychainErrorBadArguments;
|
||||
if (password && service && account) {
|
||||
[self deletePasswordForService:service account:account];
|
||||
NSMutableDictionary *query = [self _queryForService:service account:account];
|
||||
#if __has_feature(objc_arc)
|
||||
[query setObject:password forKey:(__bridge id)kSecValueData];
|
||||
#else
|
||||
[query setObject:password forKey:(id)kSecValueData];
|
||||
#endif
|
||||
|
||||
#if __IPHONE_4_0 && TARGET_OS_IPHONE
|
||||
if (SSKeychainAccessibilityType) {
|
||||
#if __has_feature(objc_arc)
|
||||
[query setObject:(id)[self accessibilityType] forKey:(__bridge id)kSecAttrAccessible];
|
||||
#else
|
||||
[query setObject:(id)[self accessibilityType] forKey:(id)kSecAttrAccessible];
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#if __has_feature(objc_arc)
|
||||
status = SecItemAdd((__bridge CFDictionaryRef)query, NULL);
|
||||
#else
|
||||
status = SecItemAdd((CFDictionaryRef)query, NULL);
|
||||
#endif
|
||||
}
|
||||
if (status != noErr && error != NULL) {
|
||||
*error = [NSError errorWithDomain:kSSKeychainErrorDomain code:status userInfo:nil];
|
||||
}
|
||||
return (status == noErr);
|
||||
}
|
||||
|
||||
|
||||
#pragma mark - Configuration
|
||||
|
||||
#if __IPHONE_4_0 && TARGET_OS_IPHONE
|
||||
+ (CFTypeRef)accessibilityType {
|
||||
return SSKeychainAccessibilityType;
|
||||
}
|
||||
|
||||
|
||||
+ (void)setAccessibilityType:(CFTypeRef)accessibilityType {
|
||||
CFRetain(accessibilityType);
|
||||
if (SSKeychainAccessibilityType) {
|
||||
CFRelease(SSKeychainAccessibilityType);
|
||||
}
|
||||
SSKeychainAccessibilityType = accessibilityType;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#pragma mark - Private
|
||||
|
||||
+ (NSMutableDictionary *)_queryForService:(NSString *)service account:(NSString *)account {
|
||||
NSMutableDictionary *dictionary = [NSMutableDictionary dictionaryWithCapacity:3];
|
||||
#if __has_feature(objc_arc)
|
||||
[dictionary setObject:(__bridge id)kSecClassGenericPassword forKey:(__bridge id)kSecClass];
|
||||
#else
|
||||
[dictionary setObject:(id)kSecClassGenericPassword forKey:(id)kSecClass];
|
||||
#endif
|
||||
|
||||
if (service) {
|
||||
#if __has_feature(objc_arc)
|
||||
[dictionary setObject:service forKey:(__bridge id)kSecAttrService];
|
||||
#else
|
||||
[dictionary setObject:service forKey:(id)kSecAttrService];
|
||||
#endif
|
||||
}
|
||||
|
||||
if (account) {
|
||||
#if __has_feature(objc_arc)
|
||||
[dictionary setObject:account forKey:(__bridge id)kSecAttrAccount];
|
||||
#else
|
||||
[dictionary setObject:account forKey:(id)kSecAttrAccount];
|
||||
#endif
|
||||
}
|
||||
|
||||
return dictionary;
|
||||
}
|
||||
|
||||
@end
|
@@ -0,0 +1,109 @@
|
||||
/*
|
||||
Copyright (c) 2011, Tony Million.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <SystemConfiguration/SystemConfiguration.h>
|
||||
|
||||
#import <sys/socket.h>
|
||||
#import <netinet/in.h>
|
||||
#import <netinet6/in6.h>
|
||||
#import <arpa/inet.h>
|
||||
#import <ifaddrs.h>
|
||||
#import <netdb.h>
|
||||
|
||||
/**
|
||||
* Does ARC support GCD objects?
|
||||
* It does if the minimum deployment target is iOS 6+ or Mac OS X 8+
|
||||
*
|
||||
* @see http://opensource.apple.com/source/libdispatch/libdispatch-228.18/os/object.h
|
||||
**/
|
||||
#if OS_OBJECT_USE_OBJC
|
||||
#define NEEDS_DISPATCH_RETAIN_RELEASE 0
|
||||
#else
|
||||
#define NEEDS_DISPATCH_RETAIN_RELEASE 1
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Create NS_ENUM macro if it does not exist on the targeted version of iOS or OS X.
|
||||
*
|
||||
* @see http://nshipster.com/ns_enum-ns_options/
|
||||
**/
|
||||
#ifndef NS_ENUM
|
||||
#define NS_ENUM(_type, _name) enum _name : _type _name; enum _name : _type
|
||||
#endif
|
||||
|
||||
extern NSString *const kYYReachabilityChangedNotification;
|
||||
|
||||
typedef NS_ENUM(NSInteger, NetworkStatus) {
|
||||
// Apple NetworkStatus Compatible Names.
|
||||
NotReachable = 0,
|
||||
ReachableViaWiFi = 2,
|
||||
ReachableViaWWAN = 1
|
||||
};
|
||||
|
||||
@class YYReachability;
|
||||
|
||||
typedef void (^NetworkReachable)(YYReachability * reachability);
|
||||
typedef void (^NetworkUnreachable)(YYReachability * reachability);
|
||||
|
||||
@interface YYReachability : NSObject
|
||||
|
||||
@property (nonatomic, copy) NetworkReachable reachableBlock;
|
||||
@property (nonatomic, copy) NetworkUnreachable unreachableBlock;
|
||||
|
||||
|
||||
@property (nonatomic, assign) BOOL reachableOnWWAN;
|
||||
|
||||
+(YYReachability*)reachabilityWithHostname:(NSString*)hostname;
|
||||
+(YYReachability*)reachabilityForInternetConnection;
|
||||
+(YYReachability*)reachabilityWithAddress:(const struct sockaddr_in*)hostAddress;
|
||||
+(YYReachability*)reachabilityForLocalWiFi;
|
||||
|
||||
-(YYReachability *)initWithReachabilityRef:(SCNetworkReachabilityRef)ref;
|
||||
|
||||
-(BOOL)startNotifier;
|
||||
-(void)stopNotifier;
|
||||
|
||||
-(BOOL)isReachable;
|
||||
-(BOOL)isReachableViaWWAN;
|
||||
-(BOOL)isReachableViaWiFi;
|
||||
|
||||
// WWAN may be available, but not active until a connection has been established.
|
||||
// WiFi may require a connection for VPN on Demand.
|
||||
-(BOOL)isConnectionRequired; // Identical DDG variant.
|
||||
-(BOOL)connectionRequired; // Apple's routine.
|
||||
// Dynamic, on demand connection?
|
||||
-(BOOL)isConnectionOnDemand;
|
||||
// Is user intervention required?
|
||||
-(BOOL)isInterventionRequired;
|
||||
|
||||
-(NetworkStatus)currentReachabilityStatus;
|
||||
-(SCNetworkReachabilityFlags)reachabilityFlags;
|
||||
-(NSString*)currentReachabilityString;
|
||||
-(NSString*)currentReachabilityFlags;
|
||||
|
||||
@end
|
@@ -0,0 +1,527 @@
|
||||
/*
|
||||
Copyright (c) 2011, Tony Million.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#import "YYReachability.h"
|
||||
|
||||
|
||||
NSString *const kYYReachabilityChangedNotification = @"kYYReachabilityChangedNotification";
|
||||
|
||||
@interface YYReachability ()
|
||||
|
||||
@property (nonatomic, assign) SCNetworkReachabilityRef reachabilityRef;
|
||||
|
||||
|
||||
#if NEEDS_DISPATCH_RETAIN_RELEASE
|
||||
@property (nonatomic, assign) dispatch_queue_t reachabilitySerialQueue;
|
||||
#else
|
||||
@property (nonatomic, strong) dispatch_queue_t reachabilitySerialQueue;
|
||||
#endif
|
||||
|
||||
|
||||
@property (nonatomic, strong) id reachabilityObject;
|
||||
|
||||
-(void)reachabilityChanged:(SCNetworkReachabilityFlags)flags;
|
||||
-(BOOL)isReachableWithFlags:(SCNetworkReachabilityFlags)flags;
|
||||
|
||||
@end
|
||||
|
||||
static NSString *reachabilityFlags(SCNetworkReachabilityFlags flags)
|
||||
{
|
||||
return [NSString stringWithFormat:@"%c%c %c%c%c%c%c%c%c",
|
||||
#if TARGET_OS_IPHONE
|
||||
(flags & kSCNetworkReachabilityFlagsIsWWAN) ? 'W' : '-',
|
||||
#else
|
||||
'X',
|
||||
#endif
|
||||
(flags & kSCNetworkReachabilityFlagsReachable) ? 'R' : '-',
|
||||
(flags & kSCNetworkReachabilityFlagsConnectionRequired) ? 'c' : '-',
|
||||
(flags & kSCNetworkReachabilityFlagsTransientConnection) ? 't' : '-',
|
||||
(flags & kSCNetworkReachabilityFlagsInterventionRequired) ? 'i' : '-',
|
||||
(flags & kSCNetworkReachabilityFlagsConnectionOnTraffic) ? 'C' : '-',
|
||||
(flags & kSCNetworkReachabilityFlagsConnectionOnDemand) ? 'D' : '-',
|
||||
(flags & kSCNetworkReachabilityFlagsIsLocalAddress) ? 'l' : '-',
|
||||
(flags & kSCNetworkReachabilityFlagsIsDirect) ? 'd' : '-'];
|
||||
}
|
||||
|
||||
// Start listening for reachability notifications on the current run loop
|
||||
static void TMReachabilityCallback(SCNetworkReachabilityRef target, SCNetworkReachabilityFlags flags, void* info)
|
||||
{
|
||||
#pragma unused (target)
|
||||
#if __has_feature(objc_arc)
|
||||
YYReachability *reachability = ((__bridge YYReachability*)info);
|
||||
#else
|
||||
YYReachability *reachability = ((YYReachability*)info);
|
||||
#endif
|
||||
|
||||
// We probably don't need an autoreleasepool here, as GCD docs state each queue has its own autorelease pool,
|
||||
// but what the heck eh?
|
||||
@autoreleasepool
|
||||
{
|
||||
[reachability reachabilityChanged:flags];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@implementation YYReachability
|
||||
|
||||
@synthesize reachabilityRef;
|
||||
@synthesize reachabilitySerialQueue;
|
||||
|
||||
@synthesize reachableOnWWAN;
|
||||
|
||||
@synthesize reachableBlock;
|
||||
@synthesize unreachableBlock;
|
||||
|
||||
@synthesize reachabilityObject;
|
||||
|
||||
#pragma mark - Class Constructor Methods
|
||||
|
||||
+(YYReachability*)reachabilityWithHostName:(NSString*)hostname
|
||||
{
|
||||
return [YYReachability reachabilityWithHostname:hostname];
|
||||
}
|
||||
|
||||
+(YYReachability*)reachabilityWithHostname:(NSString*)hostname
|
||||
{
|
||||
SCNetworkReachabilityRef ref = SCNetworkReachabilityCreateWithName(NULL, [hostname UTF8String]);
|
||||
if (ref)
|
||||
{
|
||||
id reachability = [[self alloc] initWithReachabilityRef:ref];
|
||||
|
||||
#if __has_feature(objc_arc)
|
||||
return reachability;
|
||||
#else
|
||||
return [reachability autorelease];
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
+(YYReachability *)reachabilityWithAddress:(const struct sockaddr_in *)hostAddress
|
||||
{
|
||||
SCNetworkReachabilityRef ref = SCNetworkReachabilityCreateWithAddress(kCFAllocatorDefault, (const struct sockaddr*)hostAddress);
|
||||
if (ref)
|
||||
{
|
||||
id reachability = [[self alloc] initWithReachabilityRef:ref];
|
||||
|
||||
#if __has_feature(objc_arc)
|
||||
return reachability;
|
||||
#else
|
||||
return [reachability autorelease];
|
||||
#endif
|
||||
}
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
+(YYReachability *)reachabilityForInternetConnection
|
||||
{
|
||||
struct sockaddr_in zeroAddress;
|
||||
bzero(&zeroAddress, sizeof(zeroAddress));
|
||||
zeroAddress.sin_len = sizeof(zeroAddress);
|
||||
zeroAddress.sin_family = AF_INET;
|
||||
|
||||
return [self reachabilityWithAddress:&zeroAddress];
|
||||
}
|
||||
|
||||
+(YYReachability*)reachabilityForLocalWiFi
|
||||
{
|
||||
struct sockaddr_in localWifiAddress;
|
||||
bzero(&localWifiAddress, sizeof(localWifiAddress));
|
||||
localWifiAddress.sin_len = sizeof(localWifiAddress);
|
||||
localWifiAddress.sin_family = AF_INET;
|
||||
// IN_LINKLOCALNETNUM is defined in <netinet/in.h> as 169.254.0.0
|
||||
localWifiAddress.sin_addr.s_addr = htonl(IN_LINKLOCALNETNUM);
|
||||
|
||||
return [self reachabilityWithAddress:&localWifiAddress];
|
||||
}
|
||||
|
||||
|
||||
// Initialization methods
|
||||
|
||||
-(YYReachability *)initWithReachabilityRef:(SCNetworkReachabilityRef)ref
|
||||
{
|
||||
self = [super init];
|
||||
if (self != nil)
|
||||
{
|
||||
self.reachableOnWWAN = YES;
|
||||
self.reachabilityRef = ref;
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
-(void)dealloc
|
||||
{
|
||||
[self stopNotifier];
|
||||
|
||||
if(self.reachabilityRef)
|
||||
{
|
||||
CFRelease(self.reachabilityRef);
|
||||
self.reachabilityRef = nil;
|
||||
}
|
||||
|
||||
self.reachableBlock = nil;
|
||||
self.unreachableBlock = nil;
|
||||
|
||||
#if !(__has_feature(objc_arc))
|
||||
[super dealloc];
|
||||
#endif
|
||||
|
||||
|
||||
}
|
||||
|
||||
#pragma mark - Notifier Methods
|
||||
|
||||
// Notifier
|
||||
// NOTE: This uses GCD to trigger the blocks - they *WILL NOT* be called on THE MAIN THREAD
|
||||
// - In other words DO NOT DO ANY UI UPDATES IN THE BLOCKS.
|
||||
// INSTEAD USE dispatch_async(dispatch_get_main_queue(), ^{UISTUFF}) (or dispatch_sync if you want)
|
||||
|
||||
-(BOOL)startNotifier
|
||||
{
|
||||
SCNetworkReachabilityContext context = { 0, NULL, NULL, NULL, NULL };
|
||||
|
||||
// this should do a retain on ourself, so as long as we're in notifier mode we shouldn't disappear out from under ourselves
|
||||
// woah
|
||||
self.reachabilityObject = self;
|
||||
|
||||
|
||||
|
||||
// First, we need to create a serial queue.
|
||||
// We allocate this once for the lifetime of the notifier.
|
||||
self.reachabilitySerialQueue = dispatch_queue_create("com.tonymillion.reachability", NULL);
|
||||
if(!self.reachabilitySerialQueue)
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
|
||||
#if __has_feature(objc_arc)
|
||||
context.info = (__bridge void *)self;
|
||||
#else
|
||||
context.info = (void *)self;
|
||||
#endif
|
||||
|
||||
if (!SCNetworkReachabilitySetCallback(self.reachabilityRef, TMReachabilityCallback, &context))
|
||||
{
|
||||
#ifdef DEBUG
|
||||
NSLog(@"SCNetworkReachabilitySetCallback() failed: %s", SCErrorString(SCError()));
|
||||
#endif
|
||||
|
||||
// Clear out the dispatch queue
|
||||
if(self.reachabilitySerialQueue)
|
||||
{
|
||||
#if NEEDS_DISPATCH_RETAIN_RELEASE
|
||||
dispatch_release(self.reachabilitySerialQueue);
|
||||
#endif
|
||||
self.reachabilitySerialQueue = nil;
|
||||
}
|
||||
|
||||
self.reachabilityObject = nil;
|
||||
|
||||
return NO;
|
||||
}
|
||||
|
||||
// Set it as our reachability queue, which will retain the queue
|
||||
if(!SCNetworkReachabilitySetDispatchQueue(self.reachabilityRef, self.reachabilitySerialQueue))
|
||||
{
|
||||
#ifdef DEBUG
|
||||
NSLog(@"SCNetworkReachabilitySetDispatchQueue() failed: %s", SCErrorString(SCError()));
|
||||
#endif
|
||||
|
||||
// UH OH - FAILURE!
|
||||
|
||||
// First stop, any callbacks!
|
||||
SCNetworkReachabilitySetCallback(self.reachabilityRef, NULL, NULL);
|
||||
|
||||
// Then clear out the dispatch queue.
|
||||
if(self.reachabilitySerialQueue)
|
||||
{
|
||||
#if NEEDS_DISPATCH_RETAIN_RELEASE
|
||||
dispatch_release(self.reachabilitySerialQueue);
|
||||
#endif
|
||||
self.reachabilitySerialQueue = nil;
|
||||
}
|
||||
|
||||
self.reachabilityObject = nil;
|
||||
|
||||
return NO;
|
||||
}
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
-(void)stopNotifier
|
||||
{
|
||||
// First stop, any callbacks!
|
||||
SCNetworkReachabilitySetCallback(self.reachabilityRef, NULL, NULL);
|
||||
|
||||
// Unregister target from the GCD serial dispatch queue.
|
||||
SCNetworkReachabilitySetDispatchQueue(self.reachabilityRef, NULL);
|
||||
|
||||
if(self.reachabilitySerialQueue)
|
||||
{
|
||||
#if NEEDS_DISPATCH_RETAIN_RELEASE
|
||||
dispatch_release(self.reachabilitySerialQueue);
|
||||
#endif
|
||||
self.reachabilitySerialQueue = nil;
|
||||
}
|
||||
|
||||
self.reachabilityObject = nil;
|
||||
}
|
||||
|
||||
#pragma mark - reachability tests
|
||||
|
||||
// This is for the case where you flick the airplane mode;
|
||||
// you end up getting something like this:
|
||||
//Reachability: WR ct-----
|
||||
//Reachability: -- -------
|
||||
//Reachability: WR ct-----
|
||||
//Reachability: -- -------
|
||||
// We treat this as 4 UNREACHABLE triggers - really apple should do better than this
|
||||
|
||||
#define testcase (kSCNetworkReachabilityFlagsConnectionRequired | kSCNetworkReachabilityFlagsTransientConnection)
|
||||
|
||||
-(BOOL)isReachableWithFlags:(SCNetworkReachabilityFlags)flags
|
||||
{
|
||||
BOOL connectionUP = YES;
|
||||
|
||||
if(!(flags & kSCNetworkReachabilityFlagsReachable))
|
||||
connectionUP = NO;
|
||||
|
||||
if( (flags & testcase) == testcase )
|
||||
connectionUP = NO;
|
||||
|
||||
#if TARGET_OS_IPHONE
|
||||
if(flags & kSCNetworkReachabilityFlagsIsWWAN)
|
||||
{
|
||||
// We're on 3G.
|
||||
if(!self.reachableOnWWAN)
|
||||
{
|
||||
// We don't want to connect when on 3G.
|
||||
connectionUP = NO;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return connectionUP;
|
||||
}
|
||||
|
||||
-(BOOL)isReachable
|
||||
{
|
||||
SCNetworkReachabilityFlags flags;
|
||||
|
||||
if(!SCNetworkReachabilityGetFlags(self.reachabilityRef, &flags))
|
||||
return NO;
|
||||
|
||||
return [self isReachableWithFlags:flags];
|
||||
}
|
||||
|
||||
-(BOOL)isReachableViaWWAN
|
||||
{
|
||||
#if TARGET_OS_IPHONE
|
||||
|
||||
SCNetworkReachabilityFlags flags = 0;
|
||||
|
||||
if(SCNetworkReachabilityGetFlags(reachabilityRef, &flags))
|
||||
{
|
||||
// Check we're REACHABLE
|
||||
if(flags & kSCNetworkReachabilityFlagsReachable)
|
||||
{
|
||||
// Now, check we're on WWAN
|
||||
if(flags & kSCNetworkReachabilityFlagsIsWWAN)
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return NO;
|
||||
}
|
||||
|
||||
-(BOOL)isReachableViaWiFi
|
||||
{
|
||||
SCNetworkReachabilityFlags flags = 0;
|
||||
|
||||
if(SCNetworkReachabilityGetFlags(reachabilityRef, &flags))
|
||||
{
|
||||
// Check we're reachable
|
||||
if((flags & kSCNetworkReachabilityFlagsReachable))
|
||||
{
|
||||
#if TARGET_OS_IPHONE
|
||||
// Check we're NOT on WWAN
|
||||
if((flags & kSCNetworkReachabilityFlagsIsWWAN))
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
#endif
|
||||
return YES;
|
||||
}
|
||||
}
|
||||
|
||||
return NO;
|
||||
}
|
||||
|
||||
|
||||
// WWAN may be available, but not active until a connection has been established.
|
||||
// WiFi may require a connection for VPN on Demand.
|
||||
-(BOOL)isConnectionRequired
|
||||
{
|
||||
return [self connectionRequired];
|
||||
}
|
||||
|
||||
-(BOOL)connectionRequired
|
||||
{
|
||||
SCNetworkReachabilityFlags flags;
|
||||
|
||||
if(SCNetworkReachabilityGetFlags(reachabilityRef, &flags))
|
||||
{
|
||||
return (flags & kSCNetworkReachabilityFlagsConnectionRequired);
|
||||
}
|
||||
|
||||
return NO;
|
||||
}
|
||||
|
||||
// Dynamic, on demand connection?
|
||||
-(BOOL)isConnectionOnDemand
|
||||
{
|
||||
SCNetworkReachabilityFlags flags;
|
||||
|
||||
if (SCNetworkReachabilityGetFlags(reachabilityRef, &flags))
|
||||
{
|
||||
return ((flags & kSCNetworkReachabilityFlagsConnectionRequired) &&
|
||||
(flags & (kSCNetworkReachabilityFlagsConnectionOnTraffic | kSCNetworkReachabilityFlagsConnectionOnDemand)));
|
||||
}
|
||||
|
||||
return NO;
|
||||
}
|
||||
|
||||
// Is user intervention required?
|
||||
-(BOOL)isInterventionRequired
|
||||
{
|
||||
SCNetworkReachabilityFlags flags;
|
||||
|
||||
if (SCNetworkReachabilityGetFlags(reachabilityRef, &flags))
|
||||
{
|
||||
return ((flags & kSCNetworkReachabilityFlagsConnectionRequired) &&
|
||||
(flags & kSCNetworkReachabilityFlagsInterventionRequired));
|
||||
}
|
||||
|
||||
return NO;
|
||||
}
|
||||
|
||||
|
||||
#pragma mark - reachability status stuff
|
||||
|
||||
-(NetworkStatus)currentReachabilityStatus
|
||||
{
|
||||
if([self isReachable])
|
||||
{
|
||||
if([self isReachableViaWiFi])
|
||||
return ReachableViaWiFi;
|
||||
|
||||
#if TARGET_OS_IPHONE
|
||||
return ReachableViaWWAN;
|
||||
#endif
|
||||
}
|
||||
|
||||
return NotReachable;
|
||||
}
|
||||
|
||||
-(SCNetworkReachabilityFlags)reachabilityFlags
|
||||
{
|
||||
SCNetworkReachabilityFlags flags = 0;
|
||||
|
||||
if(SCNetworkReachabilityGetFlags(reachabilityRef, &flags))
|
||||
{
|
||||
return flags;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
-(NSString*)currentReachabilityString
|
||||
{
|
||||
NetworkStatus temp = [self currentReachabilityStatus];
|
||||
|
||||
if(temp == reachableOnWWAN)
|
||||
{
|
||||
// Updated for the fact that we have CDMA phones now!
|
||||
return NSLocalizedString(@"Cellular", @"");
|
||||
}
|
||||
if (temp == ReachableViaWiFi)
|
||||
{
|
||||
return NSLocalizedString(@"WiFi", @"");
|
||||
}
|
||||
|
||||
return NSLocalizedString(@"No Connection", @"");
|
||||
}
|
||||
|
||||
-(NSString*)currentReachabilityFlags
|
||||
{
|
||||
return reachabilityFlags([self reachabilityFlags]);
|
||||
}
|
||||
|
||||
#pragma mark - Callback function calls this method
|
||||
|
||||
-(void)reachabilityChanged:(SCNetworkReachabilityFlags)flags
|
||||
{
|
||||
if([self isReachableWithFlags:flags])
|
||||
{
|
||||
if(self.reachableBlock)
|
||||
{
|
||||
self.reachableBlock(self);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(self.unreachableBlock)
|
||||
{
|
||||
self.unreachableBlock(self);
|
||||
}
|
||||
}
|
||||
|
||||
// this makes sure the change notification happens on the MAIN THREAD
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:kYYReachabilityChangedNotification
|
||||
object:self];
|
||||
});
|
||||
}
|
||||
|
||||
#pragma mark - Debug Description
|
||||
|
||||
- (NSString *) description
|
||||
{
|
||||
NSString *description = [NSString stringWithFormat:@"<%@: %#x>",
|
||||
NSStringFromClass([self class]), (unsigned int) self];
|
||||
return description;
|
||||
}
|
||||
|
||||
@end
|
@@ -0,0 +1,21 @@
|
||||
//
|
||||
// CarrierIdentifier.h
|
||||
// YYMobileFramework
|
||||
//
|
||||
// Created by wuwei on 14-5-30.
|
||||
// Copyright (c) 2014年 YY Inc. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
// 运营商类型
|
||||
typedef NS_ENUM(NSUInteger, CarrierIdentifier)
|
||||
{
|
||||
CarrierIdentifier_Unknown = 0, // 未知, 网络不可用(未插SIM卡/无信号/飞行模式)
|
||||
|
||||
CarrierIdentifier_ChinaMobile = 1, // 中国移动
|
||||
CarrierIdentifier_ChinaUnicom = 2, // 中国联通
|
||||
CarrierIdentifier_ChinaTelecom = 3, // 中国电信
|
||||
|
||||
CarrierIdentifier_Otherwise = 0x0000FFFF, // 其他运营商
|
||||
};
|
@@ -0,0 +1,225 @@
|
||||
//
|
||||
// YYUtility.h
|
||||
// YYMobileFramework
|
||||
//
|
||||
// Created by wuwei on 14/6/11.
|
||||
// Copyright (c) 2014年 YY.inc. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@class CTCarrier;
|
||||
|
||||
@interface YYUtility : NSObject
|
||||
|
||||
@end
|
||||
|
||||
/*==============================*/
|
||||
/* App Utilities */
|
||||
/*==============================*/
|
||||
@interface YYUtility (App)
|
||||
|
||||
/**
|
||||
* 从YYMobile-Info.plist中读取字段
|
||||
*
|
||||
* @param key 键
|
||||
*
|
||||
* @return 值
|
||||
*/
|
||||
+ (id)valueInPlistForKey:(NSString *)key;
|
||||
|
||||
/**
|
||||
* 获取App版本号, 从plist从读取CFBundleShortVersion
|
||||
*/
|
||||
+ (NSString *)appVersion;
|
||||
|
||||
/**
|
||||
* 获取AppBuild号, 从plist中读取CFBundleVersion
|
||||
*/
|
||||
+ (NSString *)appBuild;
|
||||
|
||||
/**
|
||||
* 当前构建出的版本在svn中的版本号
|
||||
*/
|
||||
+ (NSString *)svnVersion;
|
||||
|
||||
/**
|
||||
获取appName
|
||||
|
||||
@return app的名称
|
||||
*/
|
||||
+ (NSString *)appName;
|
||||
|
||||
/**
|
||||
* 获取bundle id
|
||||
*
|
||||
* @return bundle id
|
||||
*/
|
||||
+ (NSString *)appBundleId;
|
||||
|
||||
/**
|
||||
* 获取YYMobileFrameworkRes.bundle的URL
|
||||
*/
|
||||
+ (NSURL *)URLForMobileFrameworkResourceBundle;
|
||||
|
||||
/**
|
||||
* 获取YYMobileFrameworkRes.bundle的路径
|
||||
*/
|
||||
+ (NSString *)pathForMobileFrameworkResourceBundle;
|
||||
|
||||
+ (BOOL)addSkipBackupAttributeToItemAtURL:(NSURL *)fileURL;
|
||||
|
||||
/**
|
||||
* 获取当前的构建类型(DEBUG/RELEASE)
|
||||
*
|
||||
* @return 构建类型
|
||||
*/
|
||||
+ (NSString *)buildType;
|
||||
|
||||
/**
|
||||
* 获取平台渠道
|
||||
*/
|
||||
+ (NSString *)getAppSource;
|
||||
|
||||
/**
|
||||
* 是否来自appstore
|
||||
*/
|
||||
+ (BOOL)isFromAppStore;
|
||||
|
||||
@end
|
||||
|
||||
/*==============================*/
|
||||
/* Carrier Utilities */
|
||||
/*==============================*/
|
||||
@interface YYUtility (Carrier)
|
||||
|
||||
|
||||
/**
|
||||
获取设备唯一标识
|
||||
|
||||
@return 唯一标识
|
||||
*/
|
||||
+ (NSString *)deviceUniqueIdentification;
|
||||
|
||||
/**
|
||||
* 获取运营商
|
||||
*/
|
||||
+ (CTCarrier *)carrier;
|
||||
|
||||
/**
|
||||
* 获取运营商类型
|
||||
*/
|
||||
+ (NSInteger)carrierIdentifier;
|
||||
|
||||
/**
|
||||
* 获取运营商名称
|
||||
*/
|
||||
+ (NSString *)carrierName;
|
||||
|
||||
/**
|
||||
* 从CTCarrier对象获取网络类型
|
||||
* @param carrier - CTCarrier对象
|
||||
* @return CarrierType
|
||||
*/
|
||||
+ (NSInteger)identifierOfCarrier:(CTCarrier *)carrier;
|
||||
|
||||
@end
|
||||
|
||||
/*==============================*/
|
||||
/* Device Utilities */
|
||||
/*==============================*/
|
||||
@interface YYUtility (Device)
|
||||
|
||||
/**
|
||||
* 获取modelName, 如iPhone5,2
|
||||
*/
|
||||
+ (NSString *)modelName;
|
||||
|
||||
|
||||
/**
|
||||
获取设备类型
|
||||
|
||||
@return 设备类型
|
||||
*/
|
||||
+ (NSString*)modelType;
|
||||
|
||||
/**
|
||||
* 获取系统版本
|
||||
*/
|
||||
+ (NSString *)systemVersion;
|
||||
|
||||
/**
|
||||
* 获取当前设备的 IDFV,IDFV 在某些情况下会变,不建议将其作为设备标识
|
||||
*/
|
||||
+ (NSString *)identifierForVendor NS_AVAILABLE_IOS(6_0);
|
||||
|
||||
/**
|
||||
* 获取当前的设备标识,会使用海度 SDK 中的 OpenUDID
|
||||
*
|
||||
* @return 海度 SDK 缓存的 OpenUDID
|
||||
*/
|
||||
+ (NSString *)deviceID;
|
||||
|
||||
/**
|
||||
* 获取当前网络状态
|
||||
*/
|
||||
+ (NSInteger)networkStatus;
|
||||
|
||||
/**
|
||||
* 获取当前IP地址
|
||||
*/
|
||||
+ (NSString *)ipAddress;
|
||||
|
||||
/**
|
||||
* 获取当前IP地址
|
||||
*
|
||||
* @param preferIPv4 优先取IPv4的地址
|
||||
*/
|
||||
+ (NSString *)ipAddress:(BOOL)preferIPv4;
|
||||
|
||||
/**
|
||||
* 检查Camera是否可用, 可用则调用available; 若隐私设置中禁用了本app对相机
|
||||
* 的访问, 则调用denied; 否则视为被限制, 调用restriction
|
||||
*
|
||||
* @param available 可用
|
||||
* @param denied 不可用
|
||||
* @param restriction 受限制
|
||||
*/
|
||||
+ (void)checkCameraAvailable:(void (^)(void))available denied:(void(^)(void))denied restriction:(void(^)(void))restriction;
|
||||
|
||||
/**
|
||||
* 检查相册是否可用, 可用则调用available; 若隐私设置中禁用了本app对相册
|
||||
* 的访问, 则调用denied; 否则视为被限制, 调用restriction
|
||||
*
|
||||
* @param available 可用
|
||||
* @param denied 不可用
|
||||
* @param restriction 受限制
|
||||
*/
|
||||
+ (void)checkAssetsLibrayAvailable:(void (^)(void))available denied:(void(^)(void))denied restriction:(void(^)(void))restriction;
|
||||
|
||||
/**
|
||||
检查麦克风权限
|
||||
|
||||
@param resultBlock 结果处理block
|
||||
*/
|
||||
+ (void)checkMicPrivacy:(void(^)(BOOL succeed))resultBlock;
|
||||
|
||||
+ (NSString *)macAddresss;
|
||||
+ (NSString *)idfa;
|
||||
|
||||
/**
|
||||
* 初始化信令sdk,imsdk所用到的appName
|
||||
*
|
||||
* @return app name
|
||||
*/
|
||||
+ (NSString *)appName;
|
||||
|
||||
|
||||
/**
|
||||
当前设备是否低于, 等于 iPhone6
|
||||
|
||||
@return 当前设备是否低于, 等于 iPhone6
|
||||
*/
|
||||
+ (BOOL)isIphone6AndLow;
|
||||
|
||||
@end
|
@@ -0,0 +1,13 @@
|
||||
//
|
||||
// YYUtility.m
|
||||
// YYMobileFramework
|
||||
//
|
||||
// Created by wuwei on 14-5-30.
|
||||
// Copyright (c) 2014年 YY Inc. All rights reserved.
|
||||
//
|
||||
|
||||
#import "YYUtility.h"
|
||||
|
||||
@implementation YYUtility
|
||||
|
||||
@end
|
@@ -0,0 +1,40 @@
|
||||
//
|
||||
// DDUploadImage.h
|
||||
// DingDangApp
|
||||
//
|
||||
// Created by 触海 on 2023/12/11.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface DDUploadImage : NSObject
|
||||
|
||||
/// 上传一个Image
|
||||
/// @param image 图片
|
||||
/// @param imageName 图片的名字
|
||||
/// @param token token
|
||||
/// @param success 成功
|
||||
/// @param failure 失败
|
||||
+ (void)DD_UploadSingleImage:(UIImage *)image
|
||||
imageName:(NSString *)imageName
|
||||
token:(NSString *)token
|
||||
success:(void (^)(NSString *key, NSDictionary *resp))success
|
||||
failure:(void (^)(NSNumber *resCode, NSString *message))failure;
|
||||
|
||||
|
||||
/// 上传一个Gif图片
|
||||
/// @param data 图片
|
||||
/// @param imageName 图片的名字
|
||||
/// @param token token
|
||||
/// @param success 成功
|
||||
/// @param failure 失败
|
||||
+ (void)DD_UploadSingleGifImageData:(NSData *)data
|
||||
imageName:(NSString *)imageName
|
||||
token:(NSString *)token
|
||||
success:(void (^)(NSString *key, NSDictionary *resp))success
|
||||
failure:(void (^)(NSNumber *resCode, NSString *message))failure;
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
@@ -0,0 +1,69 @@
|
||||
//
|
||||
// DDUploadImage.m
|
||||
// DingDangApp
|
||||
//
|
||||
// Created by 触海 on 2023/12/11.
|
||||
//
|
||||
|
||||
#import "DDUploadImage.h"
|
||||
#import <Qiniu/QiniuSDK.h>
|
||||
|
||||
@implementation DDUploadImage
|
||||
|
||||
#pragma mark - Public Method
|
||||
/// 上传一个Image
|
||||
/// @param image 图片
|
||||
/// @param imageName 图片的名字
|
||||
/// @param token token
|
||||
/// @param success 成功
|
||||
/// @param failure 失败
|
||||
+ (void)DD_UploadSingleImage:(UIImage *)image
|
||||
imageName:(NSString *)imageName
|
||||
token:(NSString *)token
|
||||
success:(void (^)(NSString * _Nonnull, NSDictionary * _Nonnull))success
|
||||
failure:(void (^)(NSNumber * _Nonnull, NSString * _Nonnull))failure {
|
||||
NSData *data = UIImageJPEGRepresentation(image, 0.5);
|
||||
[self DD_PutDataWithUploadImageData:data named:imageName token:token success:success failure:failure];
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// 上传一个gif图片
|
||||
/// @param data 图片
|
||||
/// @param imageName 图片的名字
|
||||
/// @param token token
|
||||
/// @param success 成功
|
||||
/// @param failure 失败
|
||||
+ (void)DD_UploadSingleGifImageData:(NSData *)data
|
||||
imageName:(NSString *)imageName
|
||||
token:(NSString *)token
|
||||
success:(void (^)(NSString * _Nonnull, NSDictionary * _Nonnull))success
|
||||
failure:(void (^)(NSNumber * _Nonnull, NSString * _Nonnull))failure {
|
||||
[self DD_PutDataWithUploadImageData:data named:imageName token:token success:success failure:failure];
|
||||
}
|
||||
|
||||
|
||||
|
||||
#pragma mark - Private Method
|
||||
+ (void)DD_PutDataWithUploadImageData:(NSData *)data
|
||||
named:(NSString *)imageName
|
||||
token:(NSString *)token
|
||||
success:(void (^)(NSString *key, NSDictionary *resp))success
|
||||
failure:(void (^)(NSNumber *resCode, NSString *message))failure {
|
||||
QNConfiguration *config = [QNConfiguration build:^(QNConfigurationBuilder *builder) {
|
||||
builder.zone = [QNFixedZone zone2];
|
||||
|
||||
}];
|
||||
QNUploadManager *upManager = [[QNUploadManager alloc] initWithConfiguration:config];
|
||||
[upManager putData:data key:imageName token:token complete:^(QNResponseInfo *info, NSString *key, NSDictionary *resp) {
|
||||
if (resp) {
|
||||
success(key, resp);
|
||||
} else {
|
||||
failure(@(info.statusCode), info.error.localizedDescription);
|
||||
}
|
||||
|
||||
} option:nil];
|
||||
}
|
||||
|
||||
|
||||
@end
|
@@ -591,4 +591,4 @@ SPEC CHECKSUMS:
|
||||
|
||||
PODFILE CHECKSUM: 4a3e8c3e3691165802b43178346af03c39e4ae9b
|
||||
|
||||
COCOAPODS: 1.12.1
|
||||
COCOAPODS: 1.14.2
|
||||
|
Reference in New Issue
Block a user