新建basetool下面的文件夹
This commit is contained in:
@@ -694,6 +694,17 @@
|
|||||||
18FDEDCF2A50353A005EB21D /* DynamicSendLocationView.m in Sources */ = {isa = PBXBuildFile; fileRef = 18FDEDCE2A50353A005EB21D /* DynamicSendLocationView.m */; };
|
18FDEDCF2A50353A005EB21D /* DynamicSendLocationView.m in Sources */ = {isa = PBXBuildFile; fileRef = 18FDEDCE2A50353A005EB21D /* DynamicSendLocationView.m */; };
|
||||||
2358F57D2B230B4A0038453C /* DDVideoEncodeManage.m in Sources */ = {isa = PBXBuildFile; fileRef = 2358F57C2B230B4A0038453C /* DDVideoEncodeManage.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 */; };
|
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 */; };
|
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 */; };
|
8CE4939C2B23F45C00CA14D5 /* NSArray+DDSafe.m in Sources */ = {isa = PBXBuildFile; fileRef = 8CE4939B2B23F45C00CA14D5 /* NSArray+DDSafe.m */; };
|
||||||
8CE493A02B23F5FA00CA14D5 /* DDUploadFile.m in Sources */ = {isa = PBXBuildFile; fileRef = 8CE4939F2B23F5FA00CA14D5 /* DDUploadFile.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; };
|
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>"; };
|
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>"; };
|
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; };
|
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>"; };
|
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>"; };
|
8CE493982B23F44800CA14D5 /* NSMutableDictionary+DDSafe.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "NSMutableDictionary+DDSafe.m"; sourceTree = "<group>"; };
|
||||||
@@ -4973,38 +5007,149 @@
|
|||||||
path = Pods;
|
path = Pods;
|
||||||
sourceTree = "<group>";
|
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 */ = {
|
8CE493952B23F2B400CA14D5 /* DDBaseTool */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
8C2C3EEB2B27D17C002C3C34 /* DDThirdTool */,
|
||||||
|
8C2C3EE02B27CC5B002C3C34 /* DDSecurity */,
|
||||||
|
8C2C3EDC2B27C39C002C3C34 /* DDCountDownHelper */,
|
||||||
|
8C2C3ED82B279208002C3C34 /* DDCategory */,
|
||||||
|
8C2C3EC62B277E4F002C3C34 /* DDIAPHelper */,
|
||||||
8CE493B12B240AE900CA14D5 /* DDTimeStamp */,
|
8CE493B12B240AE900CA14D5 /* DDTimeStamp */,
|
||||||
8CE493AD2B2404C400CA14D5 /* DDGCDHelper */,
|
8CE493AD2B2404C400CA14D5 /* DDGCDHelper */,
|
||||||
8CE493A92B24017D00CA14D5 /* DDSystemTool */,
|
8CE493A92B24017D00CA14D5 /* DDSystemTool */,
|
||||||
8CE493A52B23FD5100CA14D5 /* DDSVGAParser */,
|
8CE493A52B23FD5100CA14D5 /* DDSVGAParser */,
|
||||||
8CE493A12B23F7DA00CA14D5 /* DDWeakTimer */,
|
8CE493A12B23F7DA00CA14D5 /* DDWeakTimer */,
|
||||||
8CE4939D2B23F5D800CA14D5 /* DDUploadFile */,
|
8CE4939D2B23F5D800CA14D5 /* DDUpload */,
|
||||||
8CE493962B23F40500CA14D5 /* DDSafe */,
|
|
||||||
);
|
);
|
||||||
path = DDBaseTool;
|
path = DDBaseTool;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
8CE493962B23F40500CA14D5 /* DDSafe */ = {
|
8CE4939D2B23F5D800CA14D5 /* DDUpload */ = {
|
||||||
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 */ = {
|
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
8CE4939E2B23F5FA00CA14D5 /* DDUploadFile.h */,
|
8CE4939E2B23F5FA00CA14D5 /* DDUploadFile.h */,
|
||||||
8CE4939F2B23F5FA00CA14D5 /* DDUploadFile.m */,
|
8CE4939F2B23F5FA00CA14D5 /* DDUploadFile.m */,
|
||||||
|
8C2C3ECE2B278C9E002C3C34 /* DDUploadImage.h */,
|
||||||
|
8C2C3ECF2B278C9E002C3C34 /* DDUploadImage.m */,
|
||||||
);
|
);
|
||||||
path = DDUploadFile;
|
path = DDUpload;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
8CE493A12B23F7DA00CA14D5 /* DDWeakTimer */ = {
|
8CE493A12B23F7DA00CA14D5 /* DDWeakTimer */ = {
|
||||||
@@ -5523,6 +5668,7 @@
|
|||||||
isa = PBXSourcesBuildPhase;
|
isa = PBXSourcesBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
|
8C2C3EC92B277E7F002C3C34 /* DDIAPHelper.m in Sources */,
|
||||||
1802B3CB2A540F870036DCEF /* DDProtocolView.m in Sources */,
|
1802B3CB2A540F870036DCEF /* DDProtocolView.m in Sources */,
|
||||||
18660CD92A21921F0032D0C9 /* NetTipView.m in Sources */,
|
18660CD92A21921F0032D0C9 /* NetTipView.m in Sources */,
|
||||||
188AF5982A273CE9004DD4CF /* DDStorePageVC.m in Sources */,
|
188AF5982A273CE9004DD4CF /* DDStorePageVC.m in Sources */,
|
||||||
@@ -5548,7 +5694,10 @@
|
|||||||
1876962D2A2AE83700C87777 /* DDNormalTextViewController.m in Sources */,
|
1876962D2A2AE83700C87777 /* DDNormalTextViewController.m in Sources */,
|
||||||
1867776B2A4286DB0096D802 /* CreatRoomViewController.m in Sources */,
|
1867776B2A4286DB0096D802 /* CreatRoomViewController.m in Sources */,
|
||||||
18660CD82A21921F0032D0C9 /* Reachability.m in Sources */,
|
18660CD82A21921F0032D0C9 /* Reachability.m in Sources */,
|
||||||
|
8C2C3ED02B278C9E002C3C34 /* DDUploadImage.m in Sources */,
|
||||||
18C833632A25A1480090BF65 /* DDMyInfoGiftWallView.m in Sources */,
|
18C833632A25A1480090BF65 /* DDMyInfoGiftWallView.m in Sources */,
|
||||||
|
8C2C3EE32B27CC6E002C3C34 /* DDBase64.m in Sources */,
|
||||||
|
8C2C3ECC2B2784DE002C3C34 /* DDIAPRechargeStorage.m in Sources */,
|
||||||
1812ECA82A54FE7100FF2AC0 /* DDRoomSendGiftCountView.m in Sources */,
|
1812ECA82A54FE7100FF2AC0 /* DDRoomSendGiftCountView.m in Sources */,
|
||||||
18B5E5972A4D20790089CEB1 /* DDShoppingCell.m in Sources */,
|
18B5E5972A4D20790089CEB1 /* DDShoppingCell.m in Sources */,
|
||||||
188EC1432A47CF3300060F03 /* HXPhotoEditClippingToolBar.m in Sources */,
|
188EC1432A47CF3300060F03 /* HXPhotoEditClippingToolBar.m in Sources */,
|
||||||
@@ -5589,6 +5738,7 @@
|
|||||||
2358F57D2B230B4A0038453C /* DDVideoEncodeManage.m in Sources */,
|
2358F57D2B230B4A0038453C /* DDVideoEncodeManage.m in Sources */,
|
||||||
18C833602A25A12A0090BF65 /* DDMyInfoGiftWallCollectionViewCell.m in Sources */,
|
18C833602A25A12A0090BF65 /* DDMyInfoGiftWallCollectionViewCell.m in Sources */,
|
||||||
18660DCD2A21E54B0032D0C9 /* RoomViewController.m in Sources */,
|
18660DCD2A21E54B0032D0C9 /* RoomViewController.m in Sources */,
|
||||||
|
8C2C3EE62B27CC7D002C3C34 /* DDDESEncrypt.m in Sources */,
|
||||||
188EC0EC2A47CF3200060F03 /* DDMEmoticonCell.m in Sources */,
|
188EC0EC2A47CF3200060F03 /* DDMEmoticonCell.m in Sources */,
|
||||||
18660D4E2A2193C50032D0C9 /* NSDictionary+Custom.m in Sources */,
|
18660D4E2A2193C50032D0C9 /* NSDictionary+Custom.m in Sources */,
|
||||||
186EBFB72A402F33005623CC /* DynamicCommentViewController.m in Sources */,
|
186EBFB72A402F33005623CC /* DynamicCommentViewController.m in Sources */,
|
||||||
@@ -5647,6 +5797,7 @@
|
|||||||
188EC10E2A47CF3200060F03 /* NSDate+HXExtension.m in Sources */,
|
188EC10E2A47CF3200060F03 /* NSDate+HXExtension.m in Sources */,
|
||||||
188EC12A2A47CF3200060F03 /* HXPhotoBottomSelectView.m in Sources */,
|
188EC12A2A47CF3200060F03 /* HXPhotoBottomSelectView.m in Sources */,
|
||||||
186EBFC42A40363A005623CC /* UIViewController+XPSemiModal.m in Sources */,
|
186EBFC42A40363A005623CC /* UIViewController+XPSemiModal.m in Sources */,
|
||||||
|
8C2C3EEF2B27D1B5002C3C34 /* SSKeychain.m in Sources */,
|
||||||
183864482A28A17B005BF235 /* ZLCollectionCell.m in Sources */,
|
183864482A28A17B005BF235 /* ZLCollectionCell.m in Sources */,
|
||||||
18AFFEC02A4BD4E0008F6478 /* DDTopAndBottomView.m in Sources */,
|
18AFFEC02A4BD4E0008F6478 /* DDTopAndBottomView.m in Sources */,
|
||||||
189569AF2A233BCD00DCF149 /* RoomTipView.m in Sources */,
|
189569AF2A233BCD00DCF149 /* RoomTipView.m in Sources */,
|
||||||
@@ -5673,6 +5824,7 @@
|
|||||||
1802B3DB2A541B6B0036DCEF /* DDLoginTextView.m in Sources */,
|
1802B3DB2A541B6B0036DCEF /* DDLoginTextView.m in Sources */,
|
||||||
186A897B2A41B272001DE99E /* DDAuthorStatusTableViewCell.m in Sources */,
|
186A897B2A41B272001DE99E /* DDAuthorStatusTableViewCell.m in Sources */,
|
||||||
186A88E42A415291001DE99E /* DDMyLevelViewController.m in Sources */,
|
186A88E42A415291001DE99E /* DDMyLevelViewController.m in Sources */,
|
||||||
|
8C2C3EF92B27D94A002C3C34 /* YYUtility.m in Sources */,
|
||||||
18C905042A2305A600F7CAFD /* ResourcePickerToolsObject.m in Sources */,
|
18C905042A2305A600F7CAFD /* ResourcePickerToolsObject.m in Sources */,
|
||||||
186A89052A41603C001DE99E /* DDNobleTableViewCell.m in Sources */,
|
186A89052A41603C001DE99E /* DDNobleTableViewCell.m in Sources */,
|
||||||
18E94E802A2740890055E8F0 /* RoomGiftModel.m in Sources */,
|
18E94E802A2740890055E8F0 /* RoomGiftModel.m in Sources */,
|
||||||
@@ -5710,6 +5862,7 @@
|
|||||||
186A89162A41A1E8001DE99E /* DDRealNameModel.m in Sources */,
|
186A89162A41A1E8001DE99E /* DDRealNameModel.m in Sources */,
|
||||||
186777752A4293460096D802 /* CreatRoomCoverViewCell.m in Sources */,
|
186777752A4293460096D802 /* CreatRoomCoverViewCell.m in Sources */,
|
||||||
1882ADC82A52A3F1009081FE /* DDMsgInputView.m in Sources */,
|
1882ADC82A52A3F1009081FE /* DDMsgInputView.m in Sources */,
|
||||||
|
8C2C3EEA2B27D163002C3C34 /* YYReachability.m in Sources */,
|
||||||
1848C22B2A4D11F00031F734 /* RoomAirPlaneContentView.m in Sources */,
|
1848C22B2A4D11F00031F734 /* RoomAirPlaneContentView.m in Sources */,
|
||||||
1826B9D12A497F730023408A /* WebViewJavascriptBridgeBase.m in Sources */,
|
1826B9D12A497F730023408A /* WebViewJavascriptBridgeBase.m in Sources */,
|
||||||
18660CF82A2193750032D0C9 /* JXTAlertView.m in Sources */,
|
18660CF82A2193750032D0C9 /* JXTAlertView.m in Sources */,
|
||||||
@@ -5833,6 +5986,7 @@
|
|||||||
186777812A4294040096D802 /* CreatRoomCancleViewCell.m in Sources */,
|
186777812A4294040096D802 /* CreatRoomCancleViewCell.m in Sources */,
|
||||||
188EC12F2A47CF3200060F03 /* HXCustomCollectionReusableView.m in Sources */,
|
188EC12F2A47CF3200060F03 /* HXCustomCollectionReusableView.m in Sources */,
|
||||||
1826C6102A24B76200A5AFDB /* DDMyInformationHeaderView.m in Sources */,
|
1826C6102A24B76200A5AFDB /* DDMyInformationHeaderView.m in Sources */,
|
||||||
|
8C2C3ED72B279141002C3C34 /* NSString+DDUtils.m in Sources */,
|
||||||
188EC1352A47CF3300060F03 /* HXPreviewVideoView.m in Sources */,
|
188EC1352A47CF3300060F03 /* HXPreviewVideoView.m in Sources */,
|
||||||
18660D592A2193C50032D0C9 /* NSDate+Custom.m in Sources */,
|
18660D592A2193C50032D0C9 /* NSDate+Custom.m in Sources */,
|
||||||
182F076E2A28316D002BC893 /* RoomSmallView.m in Sources */,
|
182F076E2A28316D002BC893 /* RoomSmallView.m in Sources */,
|
||||||
@@ -5984,6 +6138,7 @@
|
|||||||
18E659C42A564F6B0017854A /* DDSearchHeaderView.m in Sources */,
|
18E659C42A564F6B0017854A /* DDSearchHeaderView.m in Sources */,
|
||||||
188EC1172A47CF3200060F03 /* HXPhotoManager.m in Sources */,
|
188EC1172A47CF3200060F03 /* HXPhotoManager.m in Sources */,
|
||||||
188AF5A02A273D28004DD4CF /* DDStoreNumberView.m in Sources */,
|
188AF5A02A273D28004DD4CF /* DDStoreNumberView.m in Sources */,
|
||||||
|
8C2C3EDF2B27C3B8002C3C34 /* DDCountDownHelper.m in Sources */,
|
||||||
18B5E5A12A4D2EA50089CEB1 /* DDShoppingShowView.m in Sources */,
|
18B5E5A12A4D2EA50089CEB1 /* DDShoppingShowView.m in Sources */,
|
||||||
188EC1532A47CF3300060F03 /* HXPhotoEditStickerItemView.m in Sources */,
|
188EC1532A47CF3300060F03 /* HXPhotoEditStickerItemView.m in Sources */,
|
||||||
188EC1052A47CF3200060F03 /* HXPhotoViewTransition.m in Sources */,
|
188EC1052A47CF3200060F03 /* HXPhotoViewTransition.m in Sources */,
|
||||||
@@ -6054,6 +6209,7 @@
|
|||||||
189569A92A232EF700DCF149 /* RoomOnlineUserListView.m in Sources */,
|
189569A92A232EF700DCF149 /* RoomOnlineUserListView.m in Sources */,
|
||||||
18660D4C2A2193C50032D0C9 /* UITextView+Placeholder.m in Sources */,
|
18660D4C2A2193C50032D0C9 /* UITextView+Placeholder.m in Sources */,
|
||||||
189569A32A232EA100DCF149 /* RoomUserManagementView.m in Sources */,
|
189569A32A232EA100DCF149 /* RoomUserManagementView.m in Sources */,
|
||||||
|
8C2C3EF32B27D224002C3C34 /* NSObject+DDExtension.m in Sources */,
|
||||||
188EC13F2A47CF3300060F03 /* HXPhotoClippingView.m in Sources */,
|
188EC13F2A47CF3300060F03 /* HXPhotoClippingView.m in Sources */,
|
||||||
188AF5A42A273D45004DD4CF /* DDStoreCell.m in Sources */,
|
188AF5A42A273D45004DD4CF /* DDStoreCell.m in Sources */,
|
||||||
186777782A42935D0096D802 /* CreatRoomTypeViewCell.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
|
PODFILE CHECKSUM: 4a3e8c3e3691165802b43178346af03c39e4ae9b
|
||||||
|
|
||||||
COCOAPODS: 1.12.1
|
COCOAPODS: 1.14.2
|
||||||
|
Reference in New Issue
Block a user