Compare commits

..

64 Commits

Author SHA1 Message Date
1f625585b9 - upgrade libraries
- add + (instancetype _Nonnull) formDataFromFilepath:(NSString * _Nonnull) filePath name:(NSString * _Nonnull) name fileName:(NSString * _Nonnull) fileName mimeType:(NSString * _Nonnull) mimeType;
- add + (instancetype _Nonnull) formDataFromFileUrl:(NSURL * _Nonnull) fileUrl name:(NSString * _Nonnull) name fileName:(NSString * _Nonnull) fileName mimeType:(NSString * _Nonnull) mimeType;
2018-01-12 15:59:30 +01:00
872d8a78dd - add getEnvironment in PNObjectConfig 2018-01-10 17:34:16 +01:00
f42c646dcb - Uniform facebookID to facebookId naming in all classes 2017-08-27 17:39:25 +02:00
304c38f5e5 - Upgrade libraries 2017-08-27 17:20:52 +02:00
b38733b07a
- Upgrade libraries 2017-08-27 17:20:31 +02:00
d799b6eead - Fix Facebook user 2017-02-14 21:09:28 +01:00
0f7d60d908 - Fix Facebook 2017-02-14 21:00:03 +01:00
24fe937fac - Release 1.3.0 2017-02-02 17:20:19 +01:00
dad497ee5f - Upgrade libraries
- Disable NSLog
2017-01-26 19:28:07 +01:00
1ce4f9bc2d Merge branch 'develop'
* develop:
  - Update Project to 1.2.1
  - Fix Installation Date
2017-01-16 14:50:31 +01:00
3fec685098 Merge branch 'develop-installation' into develop
* develop-installation:
  - Update Project to 1.2.1
  - Fix Installation Date
  1.2.0
2017-01-16 14:50:08 +01:00
fd430c9e9f - Update Project to 1.2.1 2017-01-16 14:49:54 +01:00
37c04b3399 Merge branch 'master' into develop-installation
* master:
  1.2.0
  no message
  - Release 1.1.5
  - Aggiornato readme

# Conflicts:
#	PNObject.podspec
2017-01-16 14:44:14 +01:00
d45c68f35b - Fix Installation Date 2017-01-16 14:41:36 +01:00
da079b0cd0 1.2.0 2017-01-11 01:33:12 +01:00
e25c99b3e7 Merge branch 'develop'
* develop:
  no message
2017-01-11 01:31:07 +01:00
6ef2dd01c3 no message 2017-01-11 01:30:25 +01:00
7cd3419a3a - Release 1.1.5 2017-01-11 01:18:07 +01:00
866880eaa9 - Aggiornato readme 2017-01-11 01:14:46 +01:00
d6bc683799 Merge commit 'c06c89899d06ccd259724eac106166149a407912' into develop
* commit 'c06c89899d06ccd259724eac106166149a407912':
  - Fix facebook BirthDate bind with PNUser

# Conflicts:
#	PNObject/Classes/PNClasses/PNUser.m
2017-01-10 13:15:23 +01:00
a8c96aef44 - Fix facebook BirthDate bind with PNUser 2017-01-10 13:14:27 +01:00
c06c89899d - Fix facebook BirthDate bind with PNUser 2017-01-10 13:02:00 +01:00
3bac17f9df - Add support for parsing date ISO8601 2017-01-04 13:14:06 +01:00
13801d0aa3 - Fix 2017-01-04 00:12:53 +01:00
520b729123 - Fix NSDate parsing 2017-01-03 23:29:07 +01:00
72d6135f67 Merge branch 'dev-fix-warning' into develop
* dev-fix-warning:
  no message

# Conflicts:
#	Example/Podfile.lock
#	Example/Pods/Local Podspecs/PNObject.podspec.json
#	Example/Pods/Manifest.lock
#	PNObject.podspec
#	PNObject/Classes/PNObjectConfig.h
2017-01-03 22:21:32 +01:00
9aa1e8b380 no message 2017-01-03 22:18:59 +01:00
99ad2b456b - Fix Crash in SetEnvironment 2017-01-03 12:24:46 +01:00
b645dbf27f - Fix crash 2017-01-03 12:19:24 +01:00
Giuseppe Nucifora
f152085009 Merge branch 'dev-OauthMode' into 'develop'
Dev oauth mode

See merge request !35
2017-01-03 11:55:08 +01:00
6a3b7f41df no message 2017-01-03 11:53:49 +01:00
360ad75a13 - Remove Security dependency 2016-12-29 16:19:16 +01:00
87b4f742e3 - Remove AeroGear-Crypto
- Add NSData-AES
2016-12-29 16:18:35 +01:00
0b0803f3f9 no message 2016-12-29 15:47:15 +01:00
Giuseppe Nucifora
5bdac671f9 Merge branch 'dev-remove-cocoasecurity' into 'master'
no message

See merge request !34
2016-12-29 01:18:00 +01:00
41801c0ab7 no message 2016-12-29 01:16:06 +01:00
99eb4a9b7a - Fix 2016-12-29 00:33:26 +01:00
6a904179a0 - Fix vari
- Release
2016-12-28 19:51:53 +01:00
cc11f1efac - fix facebook connection 2016-12-28 19:42:56 +01:00
0c2b3f1c25 - Upgrade to 1.0 2016-12-28 18:49:02 +01:00
4e66c377fd - update 2016-12-20 16:02:27 +01:00
1bf4b9ef1d -Fix crash 2016-05-03 20:56:37 +02:00
6134edbd12 no message 2016-05-03 17:57:01 +02:00
5a768fcda5 no message 2016-05-03 17:39:03 +02:00
560aa24515 - fix JSONFormObject 2016-05-03 16:48:15 +02:00
e024e9ec53 - Add NSInteger in reverse mapping 2016-05-03 16:00:39 +02:00
dd24fd5a70 - Fix JSONFormObject 2016-05-02 15:51:11 +02:00
3afa4a9459 - Fix NSDate in JSONFormObjectMathod 2016-05-02 13:31:52 +02:00
4eca983cf6 - Update Pod
- Fix setUser in PNinstallation
2016-05-02 10:47:29 +02:00
7f4757d9e0 no message 2016-05-02 10:43:35 +02:00
0c37caed5c - Fix setUser method in PNInstallation 2016-05-02 10:41:10 +02:00
c2c6e9a299 no message 2016-04-29 17:07:45 +02:00
33672c87eb - Fix class naming in default classes
- Add User in PNInstallation
- Varius fix
2016-04-29 11:26:44 +02:00
a5550fb7c2 no message 2016-04-29 10:40:09 +02:00
def9c0fd06 - add badge management 2016-04-29 10:26:42 +02:00
052fa21981 - add last update in PNInstallation object 2016-04-29 10:13:10 +02:00
eafe9188c3 - fix facebook refresh token 2016-04-28 15:16:39 +02:00
ff25846a8f no message 2016-04-28 11:56:30 +02:00
2085bea970 - Release 0.7.6 2016-04-28 01:02:36 +02:00
4c469e404c - Fix release 0.7.5 2016-04-27 18:08:20 +02:00
eb4ae3b4db no message 2016-04-26 15:46:13 +02:00
499520c1f6 - Fix NSNumber populate
- Fix
2016-04-26 15:45:48 +02:00
531bd9966a - ADD isFacebookUser
- MOD isFacebookUser Property to facebookUser
2016-04-21 12:29:24 +02:00
a62ec71f98 - fix populate object mapping error 2016-04-20 23:23:45 +02:00
893 changed files with 26763 additions and 25930 deletions

1
.swift-version Normal file
View File

@ -0,0 +1 @@
2.3

View File

@ -12,16 +12,18 @@
6003F592195388D20070C39A /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6003F591195388D20070C39A /* UIKit.framework */; };
6003F598195388D20070C39A /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 6003F596195388D20070C39A /* InfoPlist.strings */; };
6003F59A195388D20070C39A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 6003F599195388D20070C39A /* main.m */; };
6003F59E195388D20070C39A /* PNObjectAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 6003F59D195388D20070C39A /* PNObjectAppDelegate.m */; };
6003F5A7195388D20070C39A /* PNObjectViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 6003F5A6195388D20070C39A /* PNObjectViewController.m */; };
6003F59E195388D20070C39A /* PNObjAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 6003F59D195388D20070C39A /* PNObjAppDelegate.m */; };
6003F5A7195388D20070C39A /* PNObjViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 6003F5A6195388D20070C39A /* PNObjViewController.m */; };
6003F5A9195388D20070C39A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 6003F5A8195388D20070C39A /* Images.xcassets */; };
6003F5B0195388D20070C39A /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6003F5AF195388D20070C39A /* XCTest.framework */; };
6003F5B1195388D20070C39A /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6003F58D195388D20070C39A /* Foundation.framework */; };
6003F5B2195388D20070C39A /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6003F591195388D20070C39A /* UIKit.framework */; };
6003F5BA195388D20070C39A /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 6003F5B8195388D20070C39A /* InfoPlist.strings */; };
6003F5BC195388D20070C39A /* Tests.m in Sources */ = {isa = PBXBuildFile; fileRef = 6003F5BB195388D20070C39A /* Tests.m */; };
DA43246C4FB8B8B587FC2343 /* Pods_PNObject_Tests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5CB6B6AE8DC4C8FBEC56DD55 /* Pods_PNObject_Tests.framework */; };
E1806AD43C05C089D52D136E /* Pods_PNObject_Example.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D73089A9DA261B19C7C342EA /* Pods_PNObject_Example.framework */; };
68119C961E155BAA00E066C7 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 68119C951E155BAA00E066C7 /* Security.framework */; };
873B8AEB1B1F5CCA007FD442 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 873B8AEA1B1F5CCA007FD442 /* Main.storyboard */; };
BCF991672BE36A8FE7F43A6B /* libPods-PNObject_Tests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E7FCF35EF87A5BDD07CA6CD2 /* libPods-PNObject_Tests.a */; };
C52729592D50CEDEC002ADC9 /* libPods-PNObject_Example.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 0ABF8340F735722CEE937FA3 /* libPods-PNObject_Example.a */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
@ -35,9 +37,10 @@
/* End PBXContainerItemProxy section */
/* Begin PBXFileReference section */
02B34A3054AF72076F57C9F2 /* Pods-PNObject_Example.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-PNObject_Example.release.xcconfig"; path = "Pods/Target Support Files/Pods-PNObject_Example/Pods-PNObject_Example.release.xcconfig"; sourceTree = "<group>"; };
0D4ADFA41B2B242C25CEC692 /* Pods-PNObject_Tests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-PNObject_Tests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-PNObject_Tests/Pods-PNObject_Tests.debug.xcconfig"; sourceTree = "<group>"; };
5CB6B6AE8DC4C8FBEC56DD55 /* Pods_PNObject_Tests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_PNObject_Tests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
0ABF8340F735722CEE937FA3 /* libPods-PNObject_Example.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-PNObject_Example.a"; sourceTree = BUILT_PRODUCTS_DIR; };
116AF818F8117B91EF290C9A /* Pods-PNObject_Example.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-PNObject_Example.release.xcconfig"; path = "Pods/Target Support Files/Pods-PNObject_Example/Pods-PNObject_Example.release.xcconfig"; sourceTree = "<group>"; };
2661CEE1F223361CD1DACC25 /* PNObject.podspec */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = PNObject.podspec; path = ../PNObject.podspec; sourceTree = "<group>"; };
3E392C278361604C1602CAF0 /* README.md */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = net.daringfireball.markdown; name = README.md; path = ../README.md; sourceTree = "<group>"; };
6003F58A195388D20070C39A /* PNObject_Example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = PNObject_Example.app; sourceTree = BUILT_PRODUCTS_DIR; };
6003F58D195388D20070C39A /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
6003F58F195388D20070C39A /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; };
@ -46,10 +49,10 @@
6003F597195388D20070C39A /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = "<group>"; };
6003F599195388D20070C39A /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
6003F59B195388D20070C39A /* PNObject-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "PNObject-Prefix.pch"; sourceTree = "<group>"; };
6003F59C195388D20070C39A /* PNObjectAppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PNObjectAppDelegate.h; sourceTree = "<group>"; };
6003F59D195388D20070C39A /* PNObjectAppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = PNObjectAppDelegate.m; sourceTree = "<group>"; };
6003F5A5195388D20070C39A /* PNObjectViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PNObjectViewController.h; sourceTree = "<group>"; };
6003F5A6195388D20070C39A /* PNObjectViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = PNObjectViewController.m; sourceTree = "<group>"; };
6003F59C195388D20070C39A /* PNObjAppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PNObjAppDelegate.h; sourceTree = "<group>"; };
6003F59D195388D20070C39A /* PNObjAppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = PNObjAppDelegate.m; sourceTree = "<group>"; };
6003F5A5195388D20070C39A /* PNObjViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PNObjViewController.h; sourceTree = "<group>"; };
6003F5A6195388D20070C39A /* PNObjViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = PNObjViewController.m; sourceTree = "<group>"; };
6003F5A8195388D20070C39A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = "<group>"; };
6003F5AE195388D20070C39A /* PNObject_Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = PNObject_Tests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
6003F5AF195388D20070C39A /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; };
@ -57,13 +60,14 @@
6003F5B9195388D20070C39A /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = "<group>"; };
6003F5BB195388D20070C39A /* Tests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = Tests.m; sourceTree = "<group>"; };
606FC2411953D9B200FFA9A0 /* Tests-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Tests-Prefix.pch"; sourceTree = "<group>"; };
6ADA851464A35438E6A21617 /* Pods-PNObject_Example.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-PNObject_Example.debug.xcconfig"; path = "Pods/Target Support Files/Pods-PNObject_Example/Pods-PNObject_Example.debug.xcconfig"; sourceTree = "<group>"; };
75FCB4EFD17838CCA4C93E4A /* LICENSE */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = LICENSE; path = ../LICENSE; sourceTree = "<group>"; };
8C017F9292D546DE8DBC84F8 /* PNObject.podspec */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = PNObject.podspec; path = ../PNObject.podspec; sourceTree = "<group>"; };
9984F97E974B595ED43BA3E3 /* Pods-PNObject_Tests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-PNObject_Tests.release.xcconfig"; path = "Pods/Target Support Files/Pods-PNObject_Tests/Pods-PNObject_Tests.release.xcconfig"; sourceTree = "<group>"; };
BA17B1571B43FAFAA8B45B6D /* README.md */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = net.daringfireball.markdown; name = README.md; path = ../README.md; sourceTree = "<group>"; };
D73089A9DA261B19C7C342EA /* Pods_PNObject_Example.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_PNObject_Example.framework; sourceTree = BUILT_PRODUCTS_DIR; };
DE7587A588720F0590F50755 /* Pods.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods.framework; sourceTree = BUILT_PRODUCTS_DIR; };
68119C951E155BAA00E066C7 /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = System/Library/Frameworks/Security.framework; sourceTree = SDKROOT; };
681A32481E2CFB7300DF98BF /* PNObject_Example.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = PNObject_Example.entitlements; sourceTree = "<group>"; };
873B8AEA1B1F5CCA007FD442 /* Main.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = Main.storyboard; sourceTree = "<group>"; };
A90E0E5930707E3F83662328 /* Pods-PNObject_Tests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-PNObject_Tests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-PNObject_Tests/Pods-PNObject_Tests.debug.xcconfig"; sourceTree = "<group>"; };
C0F786F6B0C2234E3B3A5F30 /* Pods-PNObject_Tests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-PNObject_Tests.release.xcconfig"; path = "Pods/Target Support Files/Pods-PNObject_Tests/Pods-PNObject_Tests.release.xcconfig"; sourceTree = "<group>"; };
C6D958A9E3E6FFB7818A72C7 /* LICENSE */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = LICENSE; path = ../LICENSE; sourceTree = "<group>"; };
E20844B85780704FB196FA2A /* Pods-PNObject_Example.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-PNObject_Example.debug.xcconfig"; path = "Pods/Target Support Files/Pods-PNObject_Example/Pods-PNObject_Example.debug.xcconfig"; sourceTree = "<group>"; };
E7FCF35EF87A5BDD07CA6CD2 /* libPods-PNObject_Tests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-PNObject_Tests.a"; sourceTree = BUILT_PRODUCTS_DIR; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@ -71,10 +75,11 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
68119C961E155BAA00E066C7 /* Security.framework in Frameworks */,
6003F590195388D20070C39A /* CoreGraphics.framework in Frameworks */,
6003F592195388D20070C39A /* UIKit.framework in Frameworks */,
6003F58E195388D20070C39A /* Foundation.framework in Frameworks */,
E1806AD43C05C089D52D136E /* Pods_PNObject_Example.framework in Frameworks */,
C52729592D50CEDEC002ADC9 /* libPods-PNObject_Example.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -85,7 +90,7 @@
6003F5B0195388D20070C39A /* XCTest.framework in Frameworks */,
6003F5B2195388D20070C39A /* UIKit.framework in Frameworks */,
6003F5B1195388D20070C39A /* Foundation.framework in Frameworks */,
DA43246C4FB8B8B587FC2343 /* Pods_PNObject_Tests.framework in Frameworks */,
BCF991672BE36A8FE7F43A6B /* libPods-PNObject_Tests.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -95,12 +100,13 @@
6003F581195388D10070C39A = {
isa = PBXGroup;
children = (
681A32481E2CFB7300DF98BF /* PNObject_Example.entitlements */,
60FF7A9C1954A5C5007DD14C /* Podspec Metadata */,
6003F593195388D20070C39A /* Example for PNObject */,
6003F5B5195388D20070C39A /* Tests */,
6003F58C195388D20070C39A /* Frameworks */,
6003F58B195388D20070C39A /* Products */,
700947C2A719D2A125954296 /* Pods */,
977F1D998CB9116027C75157 /* Pods */,
);
sourceTree = "<group>";
};
@ -116,13 +122,13 @@
6003F58C195388D20070C39A /* Frameworks */ = {
isa = PBXGroup;
children = (
68119C951E155BAA00E066C7 /* Security.framework */,
6003F58D195388D20070C39A /* Foundation.framework */,
6003F58F195388D20070C39A /* CoreGraphics.framework */,
6003F591195388D20070C39A /* UIKit.framework */,
6003F5AF195388D20070C39A /* XCTest.framework */,
DE7587A588720F0590F50755 /* Pods.framework */,
D73089A9DA261B19C7C342EA /* Pods_PNObject_Example.framework */,
5CB6B6AE8DC4C8FBEC56DD55 /* Pods_PNObject_Tests.framework */,
0ABF8340F735722CEE937FA3 /* libPods-PNObject_Example.a */,
E7FCF35EF87A5BDD07CA6CD2 /* libPods-PNObject_Tests.a */,
);
name = Frameworks;
sourceTree = "<group>";
@ -130,10 +136,11 @@
6003F593195388D20070C39A /* Example for PNObject */ = {
isa = PBXGroup;
children = (
6003F59C195388D20070C39A /* PNObjectAppDelegate.h */,
6003F59D195388D20070C39A /* PNObjectAppDelegate.m */,
6003F5A5195388D20070C39A /* PNObjectViewController.h */,
6003F5A6195388D20070C39A /* PNObjectViewController.m */,
6003F59C195388D20070C39A /* PNObjAppDelegate.h */,
6003F59D195388D20070C39A /* PNObjAppDelegate.m */,
873B8AEA1B1F5CCA007FD442 /* Main.storyboard */,
6003F5A5195388D20070C39A /* PNObjViewController.h */,
6003F5A6195388D20070C39A /* PNObjViewController.m */,
6003F5A8195388D20070C39A /* Images.xcassets */,
6003F594195388D20070C39A /* Supporting Files */,
);
@ -174,20 +181,20 @@
60FF7A9C1954A5C5007DD14C /* Podspec Metadata */ = {
isa = PBXGroup;
children = (
8C017F9292D546DE8DBC84F8 /* PNObject.podspec */,
BA17B1571B43FAFAA8B45B6D /* README.md */,
75FCB4EFD17838CCA4C93E4A /* LICENSE */,
2661CEE1F223361CD1DACC25 /* PNObject.podspec */,
3E392C278361604C1602CAF0 /* README.md */,
C6D958A9E3E6FFB7818A72C7 /* LICENSE */,
);
name = "Podspec Metadata";
sourceTree = "<group>";
};
700947C2A719D2A125954296 /* Pods */ = {
977F1D998CB9116027C75157 /* Pods */ = {
isa = PBXGroup;
children = (
6ADA851464A35438E6A21617 /* Pods-PNObject_Example.debug.xcconfig */,
02B34A3054AF72076F57C9F2 /* Pods-PNObject_Example.release.xcconfig */,
0D4ADFA41B2B242C25CEC692 /* Pods-PNObject_Tests.debug.xcconfig */,
9984F97E974B595ED43BA3E3 /* Pods-PNObject_Tests.release.xcconfig */,
E20844B85780704FB196FA2A /* Pods-PNObject_Example.debug.xcconfig */,
116AF818F8117B91EF290C9A /* Pods-PNObject_Example.release.xcconfig */,
A90E0E5930707E3F83662328 /* Pods-PNObject_Tests.debug.xcconfig */,
C0F786F6B0C2234E3B3A5F30 /* Pods-PNObject_Tests.release.xcconfig */,
);
name = Pods;
sourceTree = "<group>";
@ -199,13 +206,12 @@
isa = PBXNativeTarget;
buildConfigurationList = 6003F5BF195388D20070C39A /* Build configuration list for PBXNativeTarget "PNObject_Example" */;
buildPhases = (
647B517E2FE18AF68E8B23C3 /* 📦 Check Pods Manifest.lock */,
E4CE079F616C61EA34D08B8B /* [CP] Check Pods Manifest.lock */,
6003F586195388D20070C39A /* Sources */,
6003F587195388D20070C39A /* Frameworks */,
6003F588195388D20070C39A /* Resources */,
43252B3B955A9E6FDF55EF8C /* 📦 Embed Pods Frameworks */,
12D318BA313DC2FC036858CF /* 📦 Copy Pods Resources */,
5B0DE642CBEC93B376D9DE7D /* Embed Pods Frameworks */,
C40CC8D7B1996A567BE82827 /* [CP] Embed Pods Frameworks */,
614EA73ED5E0ED0F8684468C /* [CP] Copy Pods Resources */,
);
buildRules = (
);
@ -220,13 +226,12 @@
isa = PBXNativeTarget;
buildConfigurationList = 6003F5C2195388D20070C39A /* Build configuration list for PBXNativeTarget "PNObject_Tests" */;
buildPhases = (
13BC374C48C25E4BE960A7C4 /* 📦 Check Pods Manifest.lock */,
3FF38AA7E586B22171D1A118 /* [CP] Check Pods Manifest.lock */,
6003F5AA195388D20070C39A /* Sources */,
6003F5AB195388D20070C39A /* Frameworks */,
6003F5AC195388D20070C39A /* Resources */,
66B08B1481C5994108A958AF /* 📦 Embed Pods Frameworks */,
5B13AE8F18948BE84DDA2DC9 /* 📦 Copy Pods Resources */,
1B536F1CF4938475D823C8DD /* Embed Pods Frameworks */,
746A765B48FD98342716D81F /* [CP] Embed Pods Frameworks */,
21411FBE0FE21EC75B6AB1E3 /* [CP] Copy Pods Resources */,
);
buildRules = (
);
@ -244,8 +249,8 @@
6003F582195388D10070C39A /* Project object */ = {
isa = PBXProject;
attributes = {
CLASSPREFIX = PNObject;
LastUpgradeCheck = 0720;
CLASSPREFIX = PNObj;
LastUpgradeCheck = 0820;
ORGANIZATIONNAME = "Giuseppe Nucifora";
TargetAttributes = {
6003F589195388D20070C39A = {
@ -285,6 +290,7 @@
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
873B8AEB1B1F5CCA007FD442 /* Main.storyboard in Resources */,
6003F5A9195388D20070C39A /* Images.xcassets in Resources */,
6003F598195388D20070C39A /* InfoPlist.strings in Resources */,
);
@ -301,89 +307,14 @@
/* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */
12D318BA313DC2FC036858CF /* 📦 Copy Pods Resources */ = {
21411FBE0FE21EC75B6AB1E3 /* [CP] Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "📦 Copy Pods Resources";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-PNObject_Example/Pods-PNObject_Example-resources.sh\"\n";
showEnvVarsInLog = 0;
};
13BC374C48C25E4BE960A7C4 /* 📦 Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "📦 Check Pods Manifest.lock";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [[ $? != 0 ]] ; then\n cat << EOM\nerror: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\nEOM\n exit 1\nfi\n";
showEnvVarsInLog = 0;
};
1B536F1CF4938475D823C8DD /* Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "Embed Pods Frameworks";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-PNObject_Tests/Pods-PNObject_Tests-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
43252B3B955A9E6FDF55EF8C /* 📦 Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 12;
files = (
);
inputPaths = (
);
name = "📦 Embed Pods Frameworks";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-PNObject_Example/Pods-PNObject_Example-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
5B0DE642CBEC93B376D9DE7D /* Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "Embed Pods Frameworks";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-PNObject_Example/Pods-PNObject_Example-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
5B13AE8F18948BE84DDA2DC9 /* 📦 Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "📦 Copy Pods Resources";
name = "[CP] Copy Pods Resources";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
@ -391,29 +322,50 @@
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-PNObject_Tests/Pods-PNObject_Tests-resources.sh\"\n";
showEnvVarsInLog = 0;
};
647B517E2FE18AF68E8B23C3 /* 📦 Check Pods Manifest.lock */ = {
3FF38AA7E586B22171D1A118 /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
"${PODS_ROOT}/Manifest.lock",
);
name = "📦 Check Pods Manifest.lock";
name = "[CP] Check Pods Manifest.lock";
outputPaths = (
"$(DERIVED_FILE_DIR)/Pods-PNObject_Tests-checkManifestLockResult.txt",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [[ $? != 0 ]] ; then\n cat << EOM\nerror: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\nEOM\n exit 1\nfi\n";
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
66B08B1481C5994108A958AF /* 📦 Embed Pods Frameworks */ = {
614EA73ED5E0ED0F8684468C /* [CP] Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
"${SRCROOT}/Pods/Target Support Files/Pods-PNObject_Example/Pods-PNObject_Example-resources.sh",
"${PODS_ROOT}/FBSDKCoreKit/FacebookSDKStrings.bundle",
);
name = "[CP] Copy Pods Resources";
outputPaths = (
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-PNObject_Example/Pods-PNObject_Example-resources.sh\"\n";
showEnvVarsInLog = 0;
};
746A765B48FD98342716D81F /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "📦 Embed Pods Frameworks";
name = "[CP] Embed Pods Frameworks";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
@ -421,6 +373,39 @@
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-PNObject_Tests/Pods-PNObject_Tests-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
C40CC8D7B1996A567BE82827 /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "[CP] Embed Pods Frameworks";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-PNObject_Example/Pods-PNObject_Example-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
E4CE079F616C61EA34D08B8B /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
"${PODS_ROOT}/Manifest.lock",
);
name = "[CP] Check Pods Manifest.lock";
outputPaths = (
"$(DERIVED_FILE_DIR)/Pods-PNObject_Example-checkManifestLockResult.txt",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
@ -428,8 +413,8 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
6003F59E195388D20070C39A /* PNObjectAppDelegate.m in Sources */,
6003F5A7195388D20070C39A /* PNObjectViewController.m in Sources */,
6003F59E195388D20070C39A /* PNObjAppDelegate.m in Sources */,
6003F5A7195388D20070C39A /* PNObjViewController.m in Sources */,
6003F59A195388D20070C39A /* main.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
@ -485,27 +470,31 @@
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
IPHONEOS_DEPLOYMENT_TARGET = 8.3;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
TARGETED_DEVICE_FAMILY = "1,2";
@ -525,20 +514,25 @@
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = YES;
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
IPHONEOS_DEPLOYMENT_TARGET = 8.3;
SDKROOT = iphoneos;
TARGETED_DEVICE_FAMILY = "1,2";
VALIDATE_PRODUCT = YES;
@ -547,14 +541,15 @@
};
6003F5C0195388D20070C39A /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 6ADA851464A35438E6A21617 /* Pods-PNObject_Example.debug.xcconfig */;
baseConfigurationReference = E20844B85780704FB196FA2A /* Pods-PNObject_Example.debug.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
CODE_SIGN_ENTITLEMENTS = PNObject_Example.entitlements;
DEVELOPMENT_TEAM = 825G85A28E;
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = "PNObject/PNObject-Prefix.pch";
INFOPLIST_FILE = "PNObject/PNObject-Info.plist";
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
MODULE_NAME = ExampleApp;
PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.demo.${PRODUCT_NAME:rfc1034identifier}";
PRODUCT_NAME = "$(TARGET_NAME)";
@ -564,14 +559,15 @@
};
6003F5C1195388D20070C39A /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 02B34A3054AF72076F57C9F2 /* Pods-PNObject_Example.release.xcconfig */;
baseConfigurationReference = 116AF818F8117B91EF290C9A /* Pods-PNObject_Example.release.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
CODE_SIGN_ENTITLEMENTS = PNObject_Example.entitlements;
DEVELOPMENT_TEAM = 825G85A28E;
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = "PNObject/PNObject-Prefix.pch";
INFOPLIST_FILE = "PNObject/PNObject-Info.plist";
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
MODULE_NAME = ExampleApp;
PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.demo.${PRODUCT_NAME:rfc1034identifier}";
PRODUCT_NAME = "$(TARGET_NAME)";
@ -581,7 +577,7 @@
};
6003F5C3195388D20070C39A /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 0D4ADFA41B2B242C25CEC692 /* Pods-PNObject_Tests.debug.xcconfig */;
baseConfigurationReference = A90E0E5930707E3F83662328 /* Pods-PNObject_Tests.debug.xcconfig */;
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
FRAMEWORK_SEARCH_PATHS = (
@ -605,7 +601,7 @@
};
6003F5C4195388D20070C39A /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 9984F97E974B595ED43BA3E3 /* Pods-PNObject_Tests.release.xcconfig */;
baseConfigurationReference = C0F786F6B0C2234E3B3A5F30 /* Pods-PNObject_Tests.release.xcconfig */;
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
FRAMEWORK_SEARCH_PATHS = (

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0730"
LastUpgradeVersion = "0820"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
@ -71,29 +71,7 @@
ReferencedContainer = "container:PNObject.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
<EnvironmentVariables>
<EnvironmentVariable
key = "NSZombieEnabled"
value = "YES"
isEnabled = "YES">
</EnvironmentVariable>
<EnvironmentVariable
key = "NSAutoreleaseFreedObjectCheckEnabled"
value = "YES"
isEnabled = "YES">
</EnvironmentVariable>
<EnvironmentVariable
key = "NSDebugEnabled"
value = "YES"
isEnabled = "YES">
</EnvironmentVariable>
</EnvironmentVariables>
<AdditionalOptions>
<AdditionalOption
key = "NSZombieEnabled"
value = "YES"
isEnabled = "YES">
</AdditionalOption>
</AdditionalOptions>
</LaunchAction>
<ProfileAction

View File

@ -1,30 +0,0 @@
{
"DVTSourceControlWorkspaceBlueprintPrimaryRemoteRepositoryKey" : "0D16AB9035733B66D1E42542FCF79AEB110EE3F1",
"DVTSourceControlWorkspaceBlueprintWorkingCopyRepositoryLocationsKey" : {
},
"DVTSourceControlWorkspaceBlueprintWorkingCopyStatesKey" : {
"0D16AB9035733B66D1E42542FCF79AEB110EE3F1" : 0,
"AEB0552E99BCD7202184FC09F243A3865259D36E" : 0
},
"DVTSourceControlWorkspaceBlueprintIdentifierKey" : "F9984EE9-FBF8-4451-8C8E-EB0CA1AB5EC0",
"DVTSourceControlWorkspaceBlueprintWorkingCopyPathsKey" : {
"0D16AB9035733B66D1E42542FCF79AEB110EE3F1" : "PNObject\/",
"AEB0552E99BCD7202184FC09F243A3865259D36E" : "..\/..\/..\/Purplenetwork\/GIT\/iOS\/packman-ios"
},
"DVTSourceControlWorkspaceBlueprintNameKey" : "PNObject",
"DVTSourceControlWorkspaceBlueprintVersion" : 204,
"DVTSourceControlWorkspaceBlueprintRelativePathToProjectKey" : "Example\/PNObject.xcworkspace",
"DVTSourceControlWorkspaceBlueprintRemoteRepositoriesKey" : [
{
"DVTSourceControlWorkspaceBlueprintRemoteRepositoryURLKey" : "git.giuseppenucifora.com:giuseppenucifora\/PNObject.git",
"DVTSourceControlWorkspaceBlueprintRemoteRepositorySystemKey" : "com.apple.dt.Xcode.sourcecontrol.Git",
"DVTSourceControlWorkspaceBlueprintRemoteRepositoryIdentifierKey" : "0D16AB9035733B66D1E42542FCF79AEB110EE3F1"
},
{
"DVTSourceControlWorkspaceBlueprintRemoteRepositoryURLKey" : "git.giuseppenucifora.com:purplenetwork\/packman-ios.git",
"DVTSourceControlWorkspaceBlueprintRemoteRepositorySystemKey" : "com.apple.dt.Xcode.sourcecontrol.Git",
"DVTSourceControlWorkspaceBlueprintRemoteRepositoryIdentifierKey" : "AEB0552E99BCD7202184FC09F243A3865259D36E"
}
]
}

View File

@ -1,128 +1,152 @@
{
"info" : {
"author" : "xcode",
"version" : 1
},
"images" : [
{
"size" : "29x29",
"idiom" : "iphone",
"filename" : "Icon-Small.png",
"scale" : "1x"
},
{
"size" : "29x29",
"idiom" : "iphone",
"filename" : "Icon-Small@2x.png",
"scale" : "2x"
},
{
"size" : "29x29",
"idiom" : "iphone",
"filename" : "Icon-Small@3x.png",
"scale" : "3x"
},
{
"size" : "40x40",
"idiom" : "iphone",
"filename" : "Icon-40@2x.png",
"scale" : "2x"
},
{
"size" : "40x40",
"idiom" : "iphone",
"filename" : "Icon-40@3x.png",
"scale" : "3x"
},
{
"size" : "57x57",
"idiom" : "iphone",
"filename" : "Icon.png",
"scale" : "1x"
},
{
"size" : "57x57",
"idiom" : "iphone",
"filename" : "Icon@2x.png",
"scale" : "2x"
},
{
"size" : "60x60",
"idiom" : "iphone",
"filename" : "Icon-60@2x.png",
"scale" : "2x"
},
{
"size" : "60x60",
"idiom" : "iphone",
"filename" : "Icon-60@3x.png",
"scale" : "3x"
},
{
"size" : "29x29",
"idiom" : "ipad",
"filename" : "Icon-Small.png",
"scale" : "1x"
},
{
"size" : "29x29",
"idiom" : "ipad",
"filename" : "Icon-Small@2x.png",
"scale" : "2x"
},
{
"size" : "40x40",
"idiom" : "ipad",
"filename" : "Icon-40.png",
"scale" : "1x"
},
{
"size" : "40x40",
"idiom" : "ipad",
"scale" : "1x"
},
{
"filename" : "Icon-40@2x.png",
"size" : "40x40",
"idiom" : "ipad",
"scale" : "2x"
},
{
"size" : "50x50",
"idiom" : "ipad",
"filename" : "Icon-Small-50.png",
"scale" : "1x"
},
{
"size" : "50x50",
"idiom" : "ipad",
"filename" : "Icon-Small-50@2x.png",
"filename" : "Icon-60@2x.png",
"size" : "60x60",
"idiom" : "iphone",
"scale" : "2x"
},
{
"size" : "72x72",
"idiom" : "ipad",
"filename" : "Icon-72.png",
"scale" : "1x"
},
{
"size" : "72x72",
"idiom" : "ipad",
"filename" : "Icon-72@2x.png",
"scale" : "2x"
},
{
"size" : "76x76",
"idiom" : "ipad",
"filename" : "Icon-76.png",
"scale" : "1x"
},
{
"size" : "76x76",
"filename" : "Icon-72@2x.png",
"size" : "72x72",
"idiom" : "ipad",
"filename" : "Icon-76@2x.png",
"scale" : "2x"
},
{
"filename" : "Icon-76.png",
"size" : "76x76",
"idiom" : "ipad",
"scale" : "1x"
},
{
"filename" : "Icon-76@2x.png",
"size" : "76x76",
"idiom" : "ipad",
"scale" : "2x"
},
{
"filename" : "Icon-Small-50.png",
"size" : "50x50",
"idiom" : "ipad",
"scale" : "1x"
},
{
"filename" : "Icon-Small-50@2x.png",
"size" : "50x50",
"idiom" : "ipad",
"scale" : "2x"
},
{
"filename" : "Icon-Small.png",
"size" : "29x29",
"idiom" : "iphone",
"scale" : "1x"
},
{
"filename" : "Icon-Small@2x.png",
"size" : "29x29",
"idiom" : "iphone",
"scale" : "2x"
},
{
"filename" : "Icon.png",
"size" : "57x57",
"idiom" : "iphone",
"scale" : "1x"
},
{
"filename" : "Icon@2x.png",
"size" : "57x57",
"idiom" : "iphone",
"scale" : "2x"
},
{
"filename" : "Icon-Small@3x.png",
"size" : "29x29",
"idiom" : "iphone",
"scale" : "3x"
},
{
"filename" : "Icon-40@3x.png",
"size" : "40x40",
"idiom" : "iphone",
"scale" : "3x"
},
{
"filename" : "Icon-60@3x.png",
"size" : "60x60",
"idiom" : "iphone",
"scale" : "3x"
},
{
"filename" : "Icon-40@2x.png",
"size" : "40x40",
"idiom" : "iphone",
"scale" : "2x"
},
{
"filename" : "Icon-Small.png",
"size" : "29x29",
"idiom" : "ipad",
"scale" : "1x"
},
{
"filename" : "Icon-Small@2x.png",
"size" : "29x29",
"idiom" : "ipad",
"scale" : "2x"
},
{
"filename" : "Icon-83.5@2x.png",
"size" : "83.5x83.5",
"idiom" : "ipad",
"filename" : "Icon-83.5@2x.png",
"scale" : "2x"
},
{
"filename" : "NotificationIcon@2x.png",
"size" : "20x20",
"idiom" : "iphone",
"scale" : "2x"
},
{
"filename" : "NotificationIcon@3x.png",
"size" : "20x20",
"idiom" : "iphone",
"scale" : "3x"
},
{
"filename" : "NotificationIcon~ipad.png",
"size" : "20x20",
"idiom" : "ipad",
"scale" : "1x"
},
{
"filename" : "NotificationIcon~ipad@2x.png",
"size" : "20x20",
"idiom" : "ipad",
"scale" : "2x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
]
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 188 B

After

Width:  |  Height:  |  Size: 163 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 353 B

After

Width:  |  Height:  |  Size: 286 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 523 B

After

Width:  |  Height:  |  Size: 466 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 523 B

After

Width:  |  Height:  |  Size: 466 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 958 B

After

Width:  |  Height:  |  Size: 816 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 317 B

After

Width:  |  Height:  |  Size: 281 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 722 B

After

Width:  |  Height:  |  Size: 581 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 341 B

After

Width:  |  Height:  |  Size: 283 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 782 B

After

Width:  |  Height:  |  Size: 609 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 899 B

After

Width:  |  Height:  |  Size: 656 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 245 B

After

Width:  |  Height:  |  Size: 180 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 458 B

After

Width:  |  Height:  |  Size: 387 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 170 B

After

Width:  |  Height:  |  Size: 127 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 263 B

After

Width:  |  Height:  |  Size: 225 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 387 B

After

Width:  |  Height:  |  Size: 285 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 261 B

After

Width:  |  Height:  |  Size: 159 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 505 B

After

Width:  |  Height:  |  Size: 448 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 163 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 238 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 106 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 163 B

View File

@ -1,162 +1,162 @@
{
"info" : {
"author" : "xcode",
"version" : 1
},
"images" : [
{
"extent" : "full-screen",
"idiom" : "iphone",
"orientation" : "portrait",
"filename" : "Default.png",
"orientation" : "portrait",
"scale" : "1x"
},
{
"extent" : "full-screen",
"idiom" : "iphone",
"filename" : "Default@2x.png",
"minimum-system-version" : "7.0",
"orientation" : "portrait",
"scale" : "2x"
"scale" : "1x",
"extent" : "full-screen"
},
{
"extent" : "full-screen",
"orientation" : "portrait",
"filename" : "Default@2x.png",
"idiom" : "iphone",
"scale" : "2x",
"minimum-system-version" : "7.0",
"extent" : "full-screen"
},
{
"orientation" : "portrait",
"filename" : "Default-568h@2x.png",
"idiom" : "iphone",
"subtype" : "retina4",
"filename" : "Default-568h@2x.png",
"orientation" : "portrait",
"scale" : "2x"
"scale" : "2x",
"extent" : "full-screen"
},
{
"extent" : "full-screen",
"orientation" : "portrait",
"filename" : "Default-568h@2x.png",
"idiom" : "iphone",
"subtype" : "retina4",
"filename" : "Default-568h@2x.png",
"scale" : "2x",
"minimum-system-version" : "7.0",
"orientation" : "portrait",
"scale" : "2x"
"extent" : "full-screen"
},
{
"extent" : "full-screen",
"idiom" : "iphone",
"orientation" : "portrait",
"filename" : "Default@2x.png",
"orientation" : "portrait",
"scale" : "2x"
"idiom" : "iphone",
"scale" : "2x",
"extent" : "full-screen"
},
{
"extent" : "to-status-bar",
"idiom" : "ipad",
"orientation" : "portrait",
"filename" : "Default~ipad.png",
"orientation" : "portrait",
"scale" : "1x"
"idiom" : "ipad",
"scale" : "1x",
"extent" : "to-status-bar"
},
{
"extent" : "to-status-bar",
"idiom" : "ipad",
"orientation" : "portrait",
"filename" : "Default~ipad@2x.png",
"orientation" : "portrait",
"scale" : "2x"
"idiom" : "ipad",
"scale" : "2x",
"extent" : "to-status-bar"
},
{
"extent" : "to-status-bar",
"idiom" : "ipad",
"orientation" : "landscape",
"filename" : "Default~ipad~landscape.png",
"orientation" : "landscape",
"scale" : "1x"
"idiom" : "ipad",
"scale" : "1x",
"extent" : "to-status-bar"
},
{
"extent" : "to-status-bar",
"idiom" : "ipad",
"orientation" : "landscape",
"filename" : "Default~ipad~landscape@2x.png",
"orientation" : "landscape",
"scale" : "2x"
"idiom" : "ipad",
"scale" : "2x",
"extent" : "to-status-bar"
},
{
"extent" : "full-screen",
"idiom" : "ipad",
"orientation" : "portrait",
"filename" : "Default~ipad~nostatusbar.png",
"idiom" : "ipad",
"scale" : "1x",
"minimum-system-version" : "7.0",
"orientation" : "portrait",
"scale" : "1x"
"extent" : "full-screen"
},
{
"extent" : "full-screen",
"idiom" : "ipad",
"orientation" : "portrait",
"filename" : "Default~ipad~nostatusbar.png",
"orientation" : "portrait",
"scale" : "1x"
"idiom" : "ipad",
"scale" : "1x",
"extent" : "full-screen"
},
{
"extent" : "full-screen",
"idiom" : "ipad",
"orientation" : "portrait",
"filename" : "Default~ipad~nostatusbar@2x.png",
"idiom" : "ipad",
"scale" : "2x",
"minimum-system-version" : "7.0",
"orientation" : "portrait",
"scale" : "2x"
"extent" : "full-screen"
},
{
"extent" : "full-screen",
"idiom" : "ipad",
"orientation" : "portrait",
"filename" : "Default~ipad~nostatusbar@2x.png",
"idiom" : "ipad",
"scale" : "2x",
"extent" : "full-screen"
},
{
"orientation" : "landscape",
"filename" : "Default~ipad~landscape~nostatusbar.png",
"idiom" : "ipad",
"scale" : "1x",
"minimum-system-version" : "7.0",
"extent" : "full-screen"
},
{
"orientation" : "landscape",
"filename" : "Default~ipad~landscape~nostatusbar.png",
"idiom" : "ipad",
"scale" : "1x",
"extent" : "full-screen"
},
{
"orientation" : "landscape",
"filename" : "Default~ipad~landscape~nostatusbar@2x.png",
"idiom" : "ipad",
"scale" : "2x",
"minimum-system-version" : "7.0",
"extent" : "full-screen"
},
{
"orientation" : "landscape",
"filename" : "Default~ipad~landscape~nostatusbar@2x.png",
"idiom" : "ipad",
"scale" : "2x",
"extent" : "full-screen"
},
{
"orientation" : "portrait",
"scale" : "2x"
},
{
"extent" : "full-screen",
"idiom" : "ipad",
"filename" : "Default~ipad~landscape~nostatusbar.png",
"minimum-system-version" : "7.0",
"orientation" : "landscape",
"scale" : "1x"
},
{
"extent" : "full-screen",
"idiom" : "ipad",
"filename" : "Default~ipad~landscape~nostatusbar.png",
"orientation" : "landscape",
"scale" : "1x"
},
{
"extent" : "full-screen",
"idiom" : "ipad",
"filename" : "Default~ipad~landscape~nostatusbar@2x.png",
"minimum-system-version" : "7.0",
"orientation" : "landscape",
"scale" : "2x"
},
{
"extent" : "full-screen",
"idiom" : "ipad",
"filename" : "Default~ipad~landscape~nostatusbar@2x.png",
"orientation" : "landscape",
"scale" : "2x"
},
{
"extent" : "full-screen",
"idiom" : "iphone",
"subtype" : "736h",
"filename" : "Default-Portrait-736h@3x.png",
"minimum-system-version" : "8.0",
"orientation" : "portrait",
"scale" : "3x"
},
{
"extent" : "full-screen",
"idiom" : "iphone",
"subtype" : "736h",
"filename" : "Default-Landscape-736h@3x.png",
"scale" : "3x",
"minimum-system-version" : "8.0",
"orientation" : "landscape",
"scale" : "3x"
"extent" : "full-screen"
},
{
"extent" : "full-screen",
"orientation" : "landscape",
"filename" : "Default-Landscape-736h@3x.png",
"idiom" : "iphone",
"subtype" : "736h",
"scale" : "3x",
"minimum-system-version" : "8.0",
"extent" : "full-screen"
},
{
"orientation" : "portrait",
"filename" : "Default-667h@2x.png",
"idiom" : "iphone",
"subtype" : "667h",
"filename" : "Default-667h@2x.png",
"scale" : "2x",
"minimum-system-version" : "8.0",
"orientation" : "portrait",
"scale" : "2x"
"extent" : "full-screen"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
]
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 50 KiB

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 52 KiB

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.5 KiB

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 9.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 57 KiB

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 56 KiB

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 57 KiB

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 58 KiB

After

Width:  |  Height:  |  Size: 44 KiB

View File

@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="7706" systemVersion="14D136" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="whP-gf-Uak">
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="7703"/>
</dependencies>
<scenes>
<!--View Controller-->
<scene sceneID="wQg-tq-qST">
<objects>
<viewController id="whP-gf-Uak" customClass="PNObjViewController" sceneMemberID="viewController">
<layoutGuides>
<viewControllerLayoutGuide type="top" id="uEw-UM-LJ8"/>
<viewControllerLayoutGuide type="bottom" id="Mvr-aV-6Um"/>
</layoutGuides>
<view key="view" contentMode="scaleToFill" id="TpU-gO-2f1">
<rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
</view>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="tc2-Qw-aMS" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="305" y="433"/>
</scene>
</scenes>
</document>

View File

@ -0,0 +1,15 @@
//
// PNObjAppDelegate.h
// PNObject
//
// Created by Giuseppe Nucifora on 12/28/2016.
// Copyright (c) 2016 Giuseppe Nucifora. All rights reserved.
//
@import UIKit;
@interface PNObjAppDelegate : UIResponder <UIApplicationDelegate>
@property (strong, nonatomic) UIWindow *window;
@end

View File

@ -1,28 +1,27 @@
//
// PNObjectAppDelegate.m
// PNObjAppDelegate.m
// PNObject
//
// Created by Giuseppe Nucifora on 12/28/2015.
// Copyright (c) 2015 Giuseppe Nucifora. All rights reserved.
// Created by Giuseppe Nucifora on 12/28/2016.
// Copyright (c) 2016 Giuseppe Nucifora. All rights reserved.
//
#import "PNObjectAppDelegate.h"
#import "PNObjectViewController.h"
#import "PNObjAppDelegate.h"
#import "PNObject.h"
#import "PNUser.h"
#import "PNAddress.h"
#import "PNObject+PNObjectConnection.h"
#import <PNObject/PNUser.h>
#import <PNObject/PNAddress.h>
#import <PNObject/PNObject+PNObjectConnection.h>
#import "PNObjViewController.h"
#import <FBSDKCoreKit/FBSDKCoreKit.h>
#import <FBSDKLoginKit/FBSDKLoginKit.h>
#import <FBSDKShareKit/FBSDKShareKit.h>
#import "UIDevice-Hardware.h"
#import "PNInstallation.h"
#import <PNObject/PNInstallation.h>
#import <NSDate_Utils/NSDate+NSDate_Util.h>
@implementation PNObjectAppDelegate
@implementation PNObjAppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
@ -34,18 +33,24 @@
_window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
[PNObjectConfig initSharedInstanceForEnvironments:@{EnvironmentDevelopment : @"http://packman.local/app_dev.php/api/v1/",
EnvironmentStage : @"https://packman.ppreview.it/app_stage.php/api/v1/",
EnvironmentProduction : @"http://packman.ppreview.it/app_stage.php/api/v1/"
} userSubclass:[PNUser class] withOauth:YES];
[[PNObjectConfig sharedInstance] setHTTPHeaderValue:@"application/x-www-form-urlencoded" forKey:@"Content-Type"];
[[PNObjectConfig sharedInstance] setClientID:@"1_pqjo2w5k7j4g8skco408oc048w8so0ws840gcg8k8gwsgk0g4" clientSecret:@"10w0vg2v6eggooc4wks4w4s0wkwok0wkck0w888so0o80g88w8" forEnv:EnvironmentProduction];
#ifdef DEBUG
[PNObjectConfig initSharedInstanceForEnvironments:@{EnvironmentDevelopment : @{BaseUrl:@"http://pnobject.local/",EndpointPath:@"api/v1/"},
EnvironmentStage : @{BaseUrl:@"http://pnobject.stage.it/",EndpointPath:@"api/v1/"},
EnvironmentProduction : @{BaseUrl:@"http://pnobject.prod.it/",EndpointPath:@"api/v1/"},
} userSubclass:[PNUser class] withOauthMode:OAuthModeClientCredential];
[[PNObjectConfig sharedInstance] setClientID:@"xxxxxxxxx" clientSecret:@"xxxxxxxxxxxx" forEnv:EnvironmentStage];
[[PNObjectConfig sharedInstance] setClientID:@"xxxxxxxxx" clientSecret:@"xxxxxxxxxxxx" forEnv:EnvironmentProduction];
[[PNObjectConfig sharedInstance] setEnvironment:EnvironmentStage];
#endif
//[[PNObjectConfig sharedInstance] setHTTPHeaderValue:@"XMLHttpRequest" forKey:@"X-Request-With"];
NSLogDebug(@"%@",[[PNObjectConfig sharedInstance] baseUrl]);
NSLogDebug(@"%@",[[PNObjectConfig sharedInstance] endPointPath]);
NSLogDebug(@"%@",[[PNObjectConfig sharedInstance] endPointUrl]);
PNObjectViewController *viewController = [[PNObjectViewController alloc] init];
PNObjViewController *viewController = [[PNObjViewController alloc] init];
switch ([[UIDevice currentDevice] deviceFamily]) {
case UIDeviceFamilyiPhone:
@ -69,6 +74,23 @@
_window.backgroundColor = [UIColor whiteColor];
[_window makeKeyAndVisible];
/*[PNUser loginCurrentUserWithEmail:@"socials2@giuseppenucifora.com" password:@"asdasdasd" withBlockSuccess:^(PNUser * _Nullable responseObject) {
} failure:^(NSError * _Nonnull error) {
}];*/
if ([PNUser currentUser] && [[PNUser currentUser] isAuthenticated]) {
NSLogDebug(@"Login in corso...");
[[PNUser currentUser] reloadFormServerWithBlockSuccess:^(PNUser * _Nullable currentUser) {
NSLogDebug(@"Login Success...");
} failure:^(NSError * _Nonnull error) {
NSLogDebug(@"Login in error...");
}];
}
return YES;
}
@ -89,8 +111,10 @@
// Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
}
- (void)applicationDidBecomeActive:(UIApplication *)application {
- (void)applicationDidBecomeActive:(UIApplication *)application
{
[FBSDKAppEvents activateApp];
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
}
- (void)applicationWillTerminate:(UIApplication *)application
@ -108,7 +132,6 @@
annotation:annotation];
}
#pragma mark - Remote Notification
- (void) application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
@ -118,25 +141,70 @@
[installation saveLocally];
NSLog(@"%@",installation);
NSLogDebug(@"%@",installation);
NSLog(@"%@",[installation JSONFormObject]);
NSLogDebug(@"%@",[installation JSONFormObject]);
//[installation setUser:nil];
[self updateDeviceUser];
}
- (void) updateDeviceUser {
if ([PNUser currentUser] && [[PNUser currentUser] isAuthenticated]) {
[[PNInstallation currentInstallation] setUser:[PNUser currentUser]];
}
else {
[[PNInstallation currentInstallation] setUser:nil];
}
if (![[PNInstallation currentInstallation] registeredAt] || [[NSDate date] isLaterThanDate:[[[PNInstallation currentInstallation] lastTokenUpdate] dateByAddingDays:1]]) {
[self registerRemoteDevice];
}
else if ([[PNInstallation currentInstallation] updatedAt] || [[NSDate date] isLaterThanDate:[[[PNInstallation currentInstallation] updatedAt] dateByAddingMinutes:30]]) {
[self updateRemoteDevice];
}
}
- (void) registerRemoteDevice {
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[[PNInstallation currentInstallation] registerDeviceWithBlockProgress:^(NSProgress * _Nonnull uploadProgress) {
} Success:^(BOOL response) {
NSLogDebug(@"device registrato");
} failure:^(NSError * _Nonnull error) {
NSLogDebug(@"device non registrato");
}];
});
}
- (void) updateRemoteDevice {
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[[PNInstallation currentInstallation] updateDeviceWithBlockProgress:^(NSProgress * _Nonnull uploadProgress) {
} Success:^(BOOL response) {
NSLogDebug(@"device aggiornato");
} failure:^(NSError * _Nonnull error) {
NSLogDebug(@"device non aggiornato");
}];
});
}
- (void) application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings {
NSLog(@"%@",notificationSettings);
NSLogDebug(@"%@",notificationSettings);
}
- (void) application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
NSLog(@"%@",userInfo);
NSLogDebug(@"%@",userInfo);
}
- (void) application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
NSLog(@"%@",userInfo);
NSLogDebug(@"%@",userInfo);
}
#pragma mark -

View File

@ -0,0 +1,13 @@
//
// PNObjViewController.h
// PNObject
//
// Created by Giuseppe Nucifora on 12/28/2016.
// Copyright (c) 2016 Giuseppe Nucifora. All rights reserved.
//
@import UIKit;
@interface PNObjViewController : UIViewController
@end

View File

@ -1,19 +1,19 @@
//
// PNObjectViewController.m
// PNObjViewController.m
// PNObject
//
// Created by Giuseppe Nucifora on 12/28/2015.
// Copyright (c) 2015 Giuseppe Nucifora. All rights reserved.
// Created by Giuseppe Nucifora on 12/28/2016.
// Copyright (c) 2016 Giuseppe Nucifora. All rights reserved.
//
#import "PNObjectViewController.h"
#import "PNObjViewController.h"
#import <PNObject/PNObject.h>
#import <PNObject/PNUser.h>
#import <PNObject/PNAddress.h>
#import <PNObject/PNObject+PNObjectConnection.h>
#import <PureLayout/PureLayout.h>
#import "PNObject.h"
#import "PNUser.h"
#import "PNAddress.h"
#import "PNObject+PNObjectConnection.h"
@interface PNObjectViewController ()
@interface PNObjViewController ()
@property (nonatomic) BOOL didSetupConstraints;
@ -23,14 +23,14 @@
@property (nonatomic, strong) UIButton *cancelToken;
@end
@implementation PNObjectViewController
@implementation PNObjViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
_refreshToken = [UIButton newAutoLayoutView];
[_refreshToken addTarget:self action:@selector(refreshTokenAction) forControlEvents:UIControlEventTouchUpInside];
@ -102,66 +102,26 @@
- (void) apiCallAction {
/*PNObjcPassword *password = [PNObjcPassword new];
PNObjcPassword *password = [PNObjcPassword new];
[password setPassword:@"asdasdasd"];
[password setConfirmPassword:@"asdasdasd"];
User *user = [User new];
[user setFirstName:@"Giuseppe"];
[user setLastName:@"Nuficora"];
[user setEmail:@"packman5@giuseppenucifora.com"];
PNUser *user = [PNUser new];
[user setFirstName:@"Test"];
[user setLastName:@"Test"];
[user setEmail:@"pnobject@pnobject.com"];
[user setPassword:password];
[user setHasAcceptedNewsletter:YES];
[user setHasAcceptedPrivacy:YES];
*/
//[user saveLocally];
NSLog(@"%@",[[PNUser currentUser] JSONFormObject]);
//NSLog(@"%@",[user JSONObjectMap]);
/*[user registerWithBlockSuccess:^(PNUser * _Nullable responseObject) {
[user saveLocally];
} failure:^(NSError * _Nonnull error) {
NSLogDebug(@"%@",[[PNUser currentUser] JSONFormObject]);
}];*/
/*[[User currentUser] socialLoginWithBlockSuccessFromViewController:self
blockSuccess:^(PNUser * _Nullable responseObject) {
} failure:^(NSError * _Nonnull error) {
}];*/
//User * user = [User currentUser];
//if ([user isAuthenticated]) {
/*[User loginCurrentUserWithEmail:@"demo@packman.example" password:@"demo@packman.example" withBlockSuccess:^(PNUser * _Nullable responseObject) {
NSLog(@"response : %@",responseObject);
NSLog(@"%@",[User currentUser]);
} failure:^(NSError * _Nonnull error) {
NSLog(@"response : %@",error);
}];*/
[PNUser socialLoginWithBlockSuccess:^(PNUser * _Nullable responseObject) {
} failure:^(NSError * _Nonnull error) {
}];
/*[User resetPasswordForEmail:@"packman@giuseppenucifora.com" Progress:^(NSProgress * _Nonnull uploadProgress) {
} Success:^(NSDictionary * _Nullable responseObject) {
} failure:^(NSError * _Nonnull error) {
}];*/
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];

View File

@ -24,6 +24,25 @@
<string>1.0</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>UIMainStoryboardFile</key>
<string>Main</string>
<key>UIRequiredDeviceCapabilities</key>
<array>
<string>armv7</string>
</array>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UISupportedInterfaceOrientations~ipad</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
@ -64,26 +83,6 @@
</dict>
</dict>
</dict>
<key>UIRequiredDeviceCapabilities</key>
<array>
<string>armv7</string>
</array>
<key>UIRequiresFullScreen</key>
<true/>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
</array>
<key>UISupportedInterfaceOrientations~ipad</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>CFBundleURLTypes</key>
<array>
<dict>

View File

@ -1,15 +0,0 @@
//
// PNObjectAppDelegate.h
// PNObject
//
// Created by Giuseppe Nucifora on 12/28/2015.
// Copyright (c) 2015 Giuseppe Nucifora. All rights reserved.
//
@import UIKit;
@interface PNObjectAppDelegate : UIResponder <UIApplicationDelegate>
@property (strong, nonatomic) UIWindow *window;
@end

View File

@ -1,13 +0,0 @@
//
// PNObjectViewController.h
// PNObject
//
// Created by Giuseppe Nucifora on 12/28/2015.
// Copyright (c) 2015 Giuseppe Nucifora. All rights reserved.
//
@import UIKit;
@interface PNObjectViewController : UIViewController
@end

View File

@ -2,16 +2,16 @@
// main.m
// PNObject
//
// Created by Giuseppe Nucifora on 12/28/2015.
// Copyright (c) 2015 Giuseppe Nucifora. All rights reserved.
// Created by Giuseppe Nucifora on 12/28/2016.
// Copyright (c) 2016 Giuseppe Nucifora. All rights reserved.
//
@import UIKit;
#import "PNObjectAppDelegate.h"
#import "PNObjAppDelegate.h"
int main(int argc, char * argv[])
{
@autoreleasepool {
return UIApplicationMain(argc, argv, nil, NSStringFromClass([PNObjectAppDelegate class]));
return UIApplicationMain(argc, argv, nil, NSStringFromClass([PNObjAppDelegate class]));
}
}

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>aps-environment</key>
<string>development</string>
</dict>
</plist>

View File

@ -1,28 +1,13 @@
source 'https://github.com/CocoaPods/Specs.git'
use_frameworks!
platform :ios, '9.0'
target 'PNObject_Example' do
pod "PNObject", :path => "../"
pod 'PEAR-FileManager-iOS'
pod 'NSDate_Utils'
pod 'UIDevice-Utils'
pod 'AFNetworking'
pod 'nv-ios-http-status'
pod 'NSString-Helper'
pod 'CodFis-Helper'
pod 'StrongestPasswordValidator'
pod 'PureLayout'
pod 'FBSDKCoreKit'
pod 'FBSDKShareKit'
pod 'FBSDKLoginKit'
pod 'PNObject', :path => '../'
pod 'PureLayout'
end
target 'PNObject_Tests' do
pod "PNObject", :path => "../"
target 'PNObject_Tests' do
inherit! :search_paths
pod 'Specta'
pod 'Expecta'
pod 'FBSnapshotTestCase'
pod 'Expecta+Snapshots'
pod 'Expecta'
end
end

View File

@ -14,80 +14,57 @@ PODS:
- AFNetworking/Serialization (3.1.0)
- AFNetworking/UIKit (3.1.0):
- AFNetworking/NSURLSession
- Bolts (1.7.0):
- Bolts/AppLinks (= 1.7.0)
- Bolts/Tasks (= 1.7.0)
- Bolts/AppLinks (1.7.0):
- Bolts (1.9.0):
- Bolts/AppLinks (= 1.9.0)
- Bolts/Tasks (= 1.9.0)
- Bolts/AppLinks (1.9.0):
- Bolts/Tasks
- Bolts/Tasks (1.7.0)
- CocoaSecurity (1.2.4)
- Bolts/Tasks (1.9.0)
- CodFis-Helper (0.1.3)
- DJLocalization (1.2.0):
- JRSwizzle
- Expecta (1.0.5)
- Expecta+Snapshots (3.0.0):
- Expecta (~> 1.0)
- FBSnapshotTestCase/Core (~> 2.0)
- Specta (~> 1.0)
- FBSDKCoreKit (4.11.0):
- DDDKeychainWrapper (1.0.0)
- DJLocalization (1.2.2):
- DJLocalization/Core (= 1.2.2)
- DJLocalization/Core (1.2.2)
- Expecta (1.0.6)
- FBSDKCoreKit (4.29.0):
- Bolts (~> 1.7)
- FBSDKLoginKit (4.11.0):
- FBSDKLoginKit (4.29.0):
- FBSDKCoreKit
- FBSDKShareKit (4.11.0):
- FBSDKShareKit (4.29.0):
- FBSDKCoreKit
- FBSnapshotTestCase (2.1.0):
- FBSnapshotTestCase/SwiftSupport (= 2.1.0)
- FBSnapshotTestCase/Core (2.1.0)
- FBSnapshotTestCase/SwiftSupport (2.1.0):
- FBSnapshotTestCase/Core
- JRSwizzle (1.0)
- NACrypto (1.0.6)
- NSDate_Utils (0.1.3)
- NSDataAES (0.2.2)
- NSDate_Utils (1.1.0):
- DJLocalization
- NSString-Helper (1.0.5)
- NSUserDefaults-AESEncryptor (0.0.4):
- CocoaSecurity (~> 1.2.2)
- nv-ios-http-status (0.0.1)
- PEAR-FileManager-iOS (1.3.1)
- PNObject (0.7.0):
- PNObject (1.3.4):
- AFNetworking
- CodFis-Helper
- DDDKeychainWrapper
- DJLocalization
- FBSDKCoreKit
- FBSDKLoginKit
- FBSDKShareKit
- NACrypto
- NSDataAES
- NSDate_Utils
- NSString-Helper
- NSUserDefaults-AESEncryptor
- nv-ios-http-status
- PEAR-FileManager-iOS
- RZDataBinding
- StrongestPasswordValidator
- UIDevice-Utils
- PureLayout (3.0.1)
- RZDataBinding (2.0.3)
- Specta (1.0.5)
- PureLayout (3.0.2)
- RZDataBinding (2.1.0)
- Specta (1.0.7)
- StrongestPasswordValidator (0.1.2)
- UIDevice-Utils (0.1.5)
- UIDevice-Utils (1.0.0)
DEPENDENCIES:
- AFNetworking
- CodFis-Helper
- Expecta
- Expecta+Snapshots
- FBSDKCoreKit
- FBSDKLoginKit
- FBSDKShareKit
- FBSnapshotTestCase
- NSDate_Utils
- NSString-Helper
- nv-ios-http-status
- PEAR-FileManager-iOS
- PNObject (from `../`)
- PureLayout
- Specta
- StrongestPasswordValidator
- UIDevice-Utils
EXTERNAL SOURCES:
PNObject:
@ -95,28 +72,26 @@ EXTERNAL SOURCES:
SPEC CHECKSUMS:
AFNetworking: 5e0e199f73d8626b11e79750991f5d173d1f8b67
Bolts: a0058fa3b331c5a1e4402d534f2dae36dbff31e4
CocoaSecurity: d288a6f87e0f363823d2cb83e753814a6944f71a
Bolts: ac6567323eac61e203f6a9763667d0f711be34c8
CodFis-Helper: 28be4c74d7202542459d72354f59b1215871de87
DJLocalization: 55ab1d1ee4ac2eb3ec4e3a8a93145fd9d10ae6eb
Expecta: e1c022fcd33910b6be89c291d2775b3fe27a89fe
Expecta+Snapshots: c343f410c7a6392f3e22e78f94c44b6c0749a516
FBSDKCoreKit: 686ac982723a14ec9ddb85e2f81235d7706c891b
FBSDKLoginKit: bade9fc78277764149ccc5bfaadbf13c83175c6a
FBSDKShareKit: 2d1746144cfc8a9dbbd24997c34ee0471be51b6a
FBSnapshotTestCase: 366ecd378511d7716c79991cd8067d1eed23578d
JRSwizzle: dd5ead5d913a0f29e7f558200165849f006bb1e3
NACrypto: ce3900f1775f1b0cc27ce7c4953b94c598a74149
NSDate_Utils: 68669d2c81f310ee13026c791f4f0ed227b94c65
DDDKeychainWrapper: e681a4daba6448786fa83b4941f58102a33b1897
DJLocalization: 0c84029af375647d4104a42ae36be87194c46c47
Expecta: 3b6bd90a64b9a1dcb0b70aa0e10a7f8f631667d5
FBSDKCoreKit: 6f139173dc63a1deaff4430a55f2fe5bb222d2af
FBSDKLoginKit: 56a057ca6822535ea0faa25f57a7c41edb697fd4
FBSDKShareKit: 18a2cd118aef11dd657fe7e8b64bae5c719088b2
NSDataAES: 967ea3337476a80e9838a533c25d570a06855ed0
NSDate_Utils: c858a89da6e204ecf53aca48dbccb4da4d25bc9e
NSString-Helper: 459e1b6a62b3bf7db10f01b0d102548608e945c4
NSUserDefaults-AESEncryptor: da02cfef056f1e18ebe2748767915f08b274c9c5
nv-ios-http-status: b6c2b5fc8656cc19e0d3000dadce2080b99d0e2f
PEAR-FileManager-iOS: 3bc403f68a53483f5629aa822f4649e40275c4d3
PNObject: be02023e5a4c9a1110a569e54886dc13bfa9cb82
PureLayout: f35f5384c9c4e4479df041dbe33ad7577b71ddfb
RZDataBinding: 00d468ebe667f02c2bd5416f87b4b5d826188c4d
Specta: ac94d110b865115fe60ff2c6d7281053c6f8e8a2
PNObject: 8dc560680a7a48060ed309b019ca4fc41505cc07
PureLayout: 4d550abe49a94f24c2808b9b95db9131685fe4cd
RZDataBinding: 6981e90ddaae2f5e02028323b1043f8c31013109
Specta: 3e1bd89c3517421982dc4d1c992503e48bd5fe66
StrongestPasswordValidator: 921e42615bdf353513c6f925bffd4fc29865dbd7
UIDevice-Utils: a87bbaed53a74d503deb3e25511c9a4d865b92ea
UIDevice-Utils: ff37bd042127117572d6ce4c5ff074f4f54ab5ed
COCOAPODS: 0.39.0
PODFILE CHECKSUM: fcd5d1cf3426c7c9c5b3e5edcd4b8e5402ee7f2e
COCOAPODS: 1.3.1

View File

@ -17,7 +17,7 @@ NS_ASSUME_NONNULL_BEGIN
/*!
A block that will be called when a token is cancelled.
*/
typedef void(^BFCancellationBlock)();
typedef void(^BFCancellationBlock)(void);
/*!
The consumer view of a CancellationToken.

View File

@ -37,7 +37,7 @@ NS_ASSUME_NONNULL_BEGIN
Returns a new executor that uses the given block to execute continuations.
@param block The block to use.
*/
+ (instancetype)executorWithBlock:(void(^)(void(^block)()))block;
+ (instancetype)executorWithBlock:(void(^)(void(^block)(void)))block;
/*!
Returns a new executor that runs continuations on the given queue.
@ -55,7 +55,7 @@ NS_ASSUME_NONNULL_BEGIN
Runs the given block using this executor's particular strategy.
@param block The block to execute.
*/
- (void)execute:(void(^)())block;
- (void)execute:(void(^)(void))block;
@end

View File

@ -34,12 +34,12 @@ __attribute__((noinline)) static size_t remaining_stack_size(size_t *restrict to
// NOTE: If the function is inlined, this value could be incorrect
uint8_t *frameAddr = __builtin_frame_address(0);
return (*totalSize) - (endStack - frameAddr);
return (*totalSize) - (size_t)(endStack - frameAddr);
}
@interface BFExecutor ()
@property (nonatomic, copy) void(^block)(void(^block)());
@property (nonatomic, copy) void(^block)(void(^block)(void));
@end
@ -51,7 +51,7 @@ __attribute__((noinline)) static size_t remaining_stack_size(size_t *restrict to
static BFExecutor *defaultExecutor = NULL;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
defaultExecutor = [self executorWithBlock:^void(void(^block)()) {
defaultExecutor = [self executorWithBlock:^void(void(^block)(void)) {
// We prefer to run everything possible immediately, so that there is callstack information
// when debugging. However, we don't want the stack to get too deep, so if the remaining stack space
// is less than 10% of the total space, we dispatch to another GCD queue.
@ -74,7 +74,7 @@ __attribute__((noinline)) static size_t remaining_stack_size(size_t *restrict to
static BFExecutor *immediateExecutor = NULL;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
immediateExecutor = [self executorWithBlock:^void(void(^block)()) {
immediateExecutor = [self executorWithBlock:^void(void(^block)(void)) {
block();
}];
});
@ -85,7 +85,7 @@ __attribute__((noinline)) static size_t remaining_stack_size(size_t *restrict to
static BFExecutor *mainThreadExecutor = NULL;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
mainThreadExecutor = [self executorWithBlock:^void(void(^block)()) {
mainThreadExecutor = [self executorWithBlock:^void(void(^block)(void)) {
if (![NSThread isMainThread]) {
dispatch_async(dispatch_get_main_queue(), block);
} else {
@ -98,25 +98,25 @@ __attribute__((noinline)) static size_t remaining_stack_size(size_t *restrict to
return mainThreadExecutor;
}
+ (instancetype)executorWithBlock:(void(^)(void(^block)()))block {
+ (instancetype)executorWithBlock:(void(^)(void(^block)(void)))block {
return [[self alloc] initWithBlock:block];
}
+ (instancetype)executorWithDispatchQueue:(dispatch_queue_t)queue {
return [self executorWithBlock:^void(void(^block)()) {
return [self executorWithBlock:^void(void(^block)(void)) {
dispatch_async(queue, block);
}];
}
+ (instancetype)executorWithOperationQueue:(NSOperationQueue *)queue {
return [self executorWithBlock:^void(void(^block)()) {
return [self executorWithBlock:^void(void(^block)(void)) {
[queue addOperation:[NSBlockOperation blockOperationWithBlock:block]];
}];
}
#pragma mark - Initializer
- (instancetype)initWithBlock:(void(^)(void(^block)()))block {
- (instancetype)initWithBlock:(void(^)(void(^block)(void)))block {
self = [super init];
if (!self) return self;
@ -127,7 +127,7 @@ __attribute__((noinline)) static size_t remaining_stack_size(size_t *restrict to
#pragma mark - Execution
- (void)execute:(void(^)())block {
- (void)execute:(void(^)(void))block {
self.block(block);
}

View File

@ -0,0 +1,25 @@
/*
* Copyright (c) 2014, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*/
#import <Foundation/Foundation.h>
#pragma once
/**
This exists to use along with `BFTask` and `BFTaskCompletionSource`.
Instead of returning a `BFTask` with no generic type, or a generic type of 'NSNull'
when there is no usable result from a task, we use the type 'BFVoid', which will always have a value of `nil`.
This allows you to provide a more enforced API contract to the caller,
as sending any message to `BFVoid` will result in a compile time error.
*/
@class _BFVoid_Nonexistant;
typedef _BFVoid_Nonexistant *BFVoid;

View File

@ -11,6 +11,7 @@
#import <Foundation/Foundation.h>
#import <Bolts/BFCancellationToken.h>
#import <Bolts/BFGeneric.h>
NS_ASSUME_NONNULL_BEGIN
@ -24,23 +25,12 @@ extern NSString *const BFTaskErrorDomain;
*/
extern NSInteger const kBFMultipleErrorsError;
/*!
An exception that is thrown if there was multiple exceptions on <BFTask taskForCompletionOfAllTasks:>.
*/
extern NSString *const BFTaskMultipleExceptionsException;
/*!
An error userInfo key used if there were multiple errors on <BFTask taskForCompletionOfAllTasks:>.
Value type is `NSArray<NSError *> *`.
*/
extern NSString *const BFTaskMultipleErrorsUserInfoKey;
/*!
An error userInfo key used if there were multiple exceptions on <BFTask taskForCompletionOfAllTasks:>.
Value type is `NSArray<NSException *> *`.
*/
extern NSString *const BFTaskMultipleExceptionsUserInfoKey;
@class BFExecutor;
@class BFTask;
@ -54,7 +44,7 @@ extern NSString *const BFTaskMultipleExceptionsUserInfoKey;
/*!
A block that can act as a continuation for a task.
*/
typedef __nullable id(^BFContinuationBlock)(BFTask<ResultType> *task);
typedef __nullable id(^BFContinuationBlock)(BFTask<ResultType> *t);
/*!
Creates a task that is already completed with the given result.
@ -68,12 +58,6 @@ typedef __nullable id(^BFContinuationBlock)(BFTask<ResultType> *task);
*/
+ (instancetype)taskWithError:(NSError *)error;
/*!
Creates a task that is already completed with the given exception.
@param exception The exception for the task.
*/
+ (instancetype)taskWithException:(NSException *)exception;
/*!
Creates a task that is already cancelled.
*/
@ -107,7 +91,7 @@ typedef __nullable id(^BFContinuationBlock)(BFTask<ResultType> *task);
@param millis The approximate number of milliseconds to wait before the
task will be finished (with result == nil).
*/
+ (instancetype)taskWithDelay:(int)millis;
+ (BFTask<BFVoid> *)taskWithDelay:(int)millis;
/*!
Returns a task that will be completed a certain amount of time in the future.
@ -115,7 +99,7 @@ typedef __nullable id(^BFContinuationBlock)(BFTask<ResultType> *task);
task will be finished (with result == nil).
@param token The cancellation token (optional).
*/
+ (instancetype)taskWithDelay:(int)millis cancellationToken:(nullable BFCancellationToken *)token;
+ (BFTask<BFVoid> *)taskWithDelay:(int)millis cancellationToken:(nullable BFCancellationToken *)token;
/*!
Returns a task that will be completed after the given block completes with
@ -127,7 +111,7 @@ typedef __nullable id(^BFContinuationBlock)(BFTask<ResultType> *task);
If block returns a BFTask, then the task returned from
this method will not be completed until that task is completed.
*/
+ (instancetype)taskFromExecutor:(BFExecutor *)executor withBlock:(nullable id (^)())block;
+ (instancetype)taskFromExecutor:(BFExecutor *)executor withBlock:(nullable id (^)(void))block;
// Properties that will be set on the task once it is completed.
@ -141,18 +125,13 @@ typedef __nullable id(^BFContinuationBlock)(BFTask<ResultType> *task);
*/
@property (nullable, nonatomic, strong, readonly) NSError *error;
/*!
The exception of a failed task.
*/
@property (nullable, nonatomic, strong, readonly) NSException *exception;
/*!
Whether this task has been cancelled.
*/
@property (nonatomic, assign, readonly, getter=isCancelled) BOOL cancelled;
/*!
Whether this task has completed due to an error or exception.
Whether this task has completed due to an error.
*/
@property (nonatomic, assign, readonly, getter=isFaulted) BOOL faulted;
@ -172,7 +151,7 @@ typedef __nullable id(^BFContinuationBlock)(BFTask<ResultType> *task);
If block returns a BFTask, then the task returned from
this method will not be completed until that task is completed.
*/
- (BFTask *)continueWithBlock:(BFContinuationBlock)block;
- (BFTask *)continueWithBlock:(BFContinuationBlock)block NS_SWIFT_NAME(continueWith(block:));
/*!
Enqueues the given block to be run once this task is complete.
@ -186,7 +165,8 @@ typedef __nullable id(^BFContinuationBlock)(BFTask<ResultType> *task);
If block returns a BFTask, then the task returned from
this method will not be completed until that task is completed.
*/
- (BFTask *)continueWithBlock:(BFContinuationBlock)block cancellationToken:(nullable BFCancellationToken *)cancellationToken;
- (BFTask *)continueWithBlock:(BFContinuationBlock)block
cancellationToken:(nullable BFCancellationToken *)cancellationToken NS_SWIFT_NAME(continueWith(block:cancellationToken:));
/*!
Enqueues the given block to be run once this task is complete.
@ -197,7 +177,9 @@ typedef __nullable id(^BFContinuationBlock)(BFTask<ResultType> *task);
If block returns a BFTask, then the task returned from
this method will not be completed until that task is completed.
*/
- (BFTask *)continueWithExecutor:(BFExecutor *)executor withBlock:(BFContinuationBlock)block;
- (BFTask *)continueWithExecutor:(BFExecutor *)executor
withBlock:(BFContinuationBlock)block NS_SWIFT_NAME(continueWith(executor:block:));
/*!
Enqueues the given block to be run once this task is complete.
@param executor A BFExecutor responsible for determining how the
@ -210,11 +192,12 @@ typedef __nullable id(^BFContinuationBlock)(BFTask<ResultType> *task);
*/
- (BFTask *)continueWithExecutor:(BFExecutor *)executor
block:(BFContinuationBlock)block
cancellationToken:(nullable BFCancellationToken *)cancellationToken;
cancellationToken:(nullable BFCancellationToken *)cancellationToken
NS_SWIFT_NAME(continueWith(executor:block:cancellationToken:));
/*!
Identical to continueWithBlock:, except that the block is only run
if this task did not produce a cancellation, error, or exception.
if this task did not produce a cancellation or an error.
If it did, then the failure will be propagated to the returned
task.
@param block The block to be run once this task is complete.
@ -222,11 +205,11 @@ typedef __nullable id(^BFContinuationBlock)(BFTask<ResultType> *task);
If block returns a BFTask, then the task returned from
this method will not be completed until that task is completed.
*/
- (BFTask *)continueWithSuccessBlock:(BFContinuationBlock)block;
- (BFTask *)continueWithSuccessBlock:(BFContinuationBlock)block NS_SWIFT_NAME(continueOnSuccessWith(block:));
/*!
Identical to continueWithBlock:, except that the block is only run
if this task did not produce a cancellation, error, or exception.
if this task did not produce a cancellation or an error.
If it did, then the failure will be propagated to the returned
task.
@param block The block to be run once this task is complete.
@ -235,13 +218,14 @@ typedef __nullable id(^BFContinuationBlock)(BFTask<ResultType> *task);
If block returns a BFTask, then the task returned from
this method will not be completed until that task is completed.
*/
- (BFTask *)continueWithSuccessBlock:(BFContinuationBlock)block cancellationToken:(nullable BFCancellationToken *)cancellationToken;
- (BFTask *)continueWithSuccessBlock:(BFContinuationBlock)block
cancellationToken:(nullable BFCancellationToken *)cancellationToken
NS_SWIFT_NAME(continueOnSuccessWith(block:cancellationToken:));
/*!
Identical to continueWithExecutor:withBlock:, except that the block
is only run if this task did not produce a cancellation, error, or
exception. If it did, then the failure will be propagated to the
returned task.
is only run if this task did not produce a cancellation, error, or an error.
If it did, then the failure will be propagated to the returned task.
@param executor A BFExecutor responsible for determining how the
continuation block will be run.
@param block The block to be run once this task is complete.
@ -249,13 +233,13 @@ typedef __nullable id(^BFContinuationBlock)(BFTask<ResultType> *task);
If block returns a BFTask, then the task returned from
this method will not be completed until that task is completed.
*/
- (BFTask *)continueWithExecutor:(BFExecutor *)executor withSuccessBlock:(BFContinuationBlock)block;
- (BFTask *)continueWithExecutor:(BFExecutor *)executor
withSuccessBlock:(BFContinuationBlock)block NS_SWIFT_NAME(continueOnSuccessWith(executor:block:));
/*!
Identical to continueWithExecutor:withBlock:, except that the block
is only run if this task did not produce a cancellation, error, or
exception. If it did, then the failure will be propagated to the
returned task.
is only run if this task did not produce a cancellation or an error.
If it did, then the failure will be propagated to the returned task.
@param executor A BFExecutor responsible for determining how the
continuation block will be run.
@param block The block to be run once this task is complete.
@ -266,7 +250,8 @@ typedef __nullable id(^BFContinuationBlock)(BFTask<ResultType> *task);
*/
- (BFTask *)continueWithExecutor:(BFExecutor *)executor
successBlock:(BFContinuationBlock)block
cancellationToken:(nullable BFCancellationToken *)cancellationToken;
cancellationToken:(nullable BFCancellationToken *)cancellationToken
NS_SWIFT_NAME(continueOnSuccessWith(executor:block:cancellationToken:));
/*!
Waits until this operation is completed.

View File

@ -23,15 +23,12 @@ __attribute__ ((noinline)) void warnBlockingOperationOnMainThread() {
NSString *const BFTaskErrorDomain = @"bolts";
NSInteger const kBFMultipleErrorsError = 80175001;
NSString *const BFTaskMultipleExceptionsException = @"BFMultipleExceptionsException";
NSString *const BFTaskMultipleErrorsUserInfoKey = @"errors";
NSString *const BFTaskMultipleExceptionsUserInfoKey = @"exceptions";
@interface BFTask () {
id _result;
NSError *_error;
NSException *_exception;
}
@property (nonatomic, assign, readwrite, getter=isCancelled) BOOL cancelled;
@ -59,7 +56,7 @@ NSString *const BFTaskMultipleExceptionsUserInfoKey = @"exceptions";
return self;
}
- (instancetype)initWithResult:(id)result {
- (instancetype)initWithResult:(nullable id)result {
self = [super init];
if (!self) return self;
@ -77,15 +74,6 @@ NSString *const BFTaskMultipleExceptionsUserInfoKey = @"exceptions";
return self;
}
- (instancetype)initWithException:(NSException *)exception {
self = [super init];
if (!self) return self;
[self trySetException:exception];
return self;
}
- (instancetype)initCancelled {
self = [super init];
if (!self) return self;
@ -105,10 +93,6 @@ NSString *const BFTaskMultipleExceptionsUserInfoKey = @"exceptions";
return [[self alloc] initWithError:error];
}
+ (instancetype)taskWithException:(NSException *)exception {
return [[self alloc] initWithException:exception];
}
+ (instancetype)cancelledTask {
return [[self alloc] initCancelled];
}
@ -122,35 +106,20 @@ NSString *const BFTaskMultipleExceptionsUserInfoKey = @"exceptions";
__block int32_t cancelled = 0;
NSObject *lock = [[NSObject alloc] init];
NSMutableArray *errors = [NSMutableArray array];
NSMutableArray *exceptions = [NSMutableArray array];
BFTaskCompletionSource *tcs = [BFTaskCompletionSource taskCompletionSource];
for (BFTask *task in tasks) {
[task continueWithBlock:^id(BFTask *task) {
if (task.exception) {
[task continueWithBlock:^id(BFTask *t) {
if (t.error) {
@synchronized (lock) {
[exceptions addObject:task.exception];
[errors addObject:t.error];
}
} else if (task.error) {
@synchronized (lock) {
[errors addObject:task.error];
}
} else if (task.cancelled) {
} else if (t.cancelled) {
OSAtomicIncrement32Barrier(&cancelled);
}
if (OSAtomicDecrement32Barrier(&total) == 0) {
if (exceptions.count > 0) {
if (exceptions.count == 1) {
tcs.exception = [exceptions firstObject];
} else {
NSException *exception =
[NSException exceptionWithName:BFTaskMultipleExceptionsException
reason:@"There were multiple exceptions."
userInfo:@{ BFTaskMultipleExceptionsUserInfoKey: exceptions }];
tcs.exception = exception;
}
} else if (errors.count > 0) {
if (errors.count > 0) {
if (errors.count == 1) {
tcs.error = [errors firstObject];
} else {
@ -172,7 +141,7 @@ NSString *const BFTaskMultipleExceptionsUserInfoKey = @"exceptions";
}
+ (instancetype)taskForCompletionOfAllTasksWithResults:(nullable NSArray<BFTask *> *)tasks {
return [[self taskForCompletionOfAllTasks:tasks] continueWithSuccessBlock:^id(BFTask *task) {
return [[self taskForCompletionOfAllTasks:tasks] continueWithSuccessBlock:^id(BFTask * __unused task) {
return [tasks valueForKey:@"result"];
}];
}
@ -189,24 +158,19 @@ NSString *const BFTaskMultipleExceptionsUserInfoKey = @"exceptions";
NSObject *lock = [NSObject new];
NSMutableArray<NSError *> *errors = [NSMutableArray new];
NSMutableArray<NSException *> *exceptions = [NSMutableArray new];
BFTaskCompletionSource *source = [BFTaskCompletionSource taskCompletionSource];
for (BFTask *task in tasks) {
[task continueWithBlock:^id(BFTask *task) {
if (task.exception != nil) {
[task continueWithBlock:^id(BFTask *t) {
if (t.error != nil) {
@synchronized(lock) {
[exceptions addObject:task.exception];
[errors addObject:t.error];
}
} else if (task.error != nil) {
@synchronized(lock) {
[errors addObject:task.error];
}
} else if (task.cancelled) {
} else if (t.cancelled) {
OSAtomicIncrement32Barrier(&cancelled);
} else {
if(OSAtomicCompareAndSwap32Barrier(0, 1, &completed)) {
[source setResult:task.result];
[source setResult:t.result];
}
}
@ -214,16 +178,6 @@ NSString *const BFTaskMultipleExceptionsUserInfoKey = @"exceptions";
OSAtomicCompareAndSwap32Barrier(0, 1, &completed)) {
if (cancelled > 0) {
[source cancel];
} else if (exceptions.count > 0) {
if (exceptions.count == 1) {
source.exception = exceptions.firstObject;
} else {
NSException *exception =
[NSException exceptionWithName:BFTaskMultipleExceptionsException
reason:@"There were multiple exceptions."
userInfo:@{ @"exceptions": exceptions }];
source.exception = exception;
}
} else if (errors.count > 0) {
if (errors.count == 1) {
source.error = errors.firstObject;
@ -243,7 +197,7 @@ NSString *const BFTaskMultipleExceptionsUserInfoKey = @"exceptions";
}
+ (instancetype)taskWithDelay:(int)millis {
+ (BFTask<BFVoid> *)taskWithDelay:(int)millis {
BFTaskCompletionSource *tcs = [BFTaskCompletionSource taskCompletionSource];
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, millis * NSEC_PER_MSEC);
dispatch_after(popTime, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void){
@ -252,7 +206,7 @@ NSString *const BFTaskMultipleExceptionsUserInfoKey = @"exceptions";
return tcs.task;
}
+ (instancetype)taskWithDelay:(int)millis cancellationToken:(nullable BFCancellationToken *)token {
+ (BFTask<BFVoid> *)taskWithDelay:(int)millis cancellationToken:(nullable BFCancellationToken *)token {
if (token.cancellationRequested) {
return [BFTask cancelledTask];
}
@ -269,7 +223,7 @@ NSString *const BFTaskMultipleExceptionsUserInfoKey = @"exceptions";
return tcs.task;
}
+ (instancetype)taskFromExecutor:(BFExecutor *)executor withBlock:(nullable id (^)())block {
+ (instancetype)taskFromExecutor:(BFExecutor *)executor withBlock:(nullable id (^)(void))block {
return [[self taskWithResult:nil] continueWithExecutor:executor withBlock:^id(BFTask *task) {
return block();
}];
@ -314,25 +268,6 @@ NSString *const BFTaskMultipleExceptionsUserInfoKey = @"exceptions";
}
}
- (nullable NSException *)exception {
@synchronized(self.lock) {
return _exception;
}
}
- (BOOL)trySetException:(NSException *)exception {
@synchronized(self.lock) {
if (self.completed) {
return NO;
}
self.completed = YES;
self.faulted = YES;
_exception = exception;
[self runContinuations];
return YES;
}
}
- (BOOL)isCancelled {
@synchronized(self.lock) {
return _cancelled;
@ -368,7 +303,7 @@ NSString *const BFTaskMultipleExceptionsUserInfoKey = @"exceptions";
[self.condition lock];
[self.condition broadcast];
[self.condition unlock];
for (void (^callback)() in self.callbacks) {
for (void (^callback)(void) in self.callbacks) {
callback();
}
[self.callbacks removeAllObjects];
@ -393,21 +328,12 @@ NSString *const BFTaskMultipleExceptionsUserInfoKey = @"exceptions";
return;
}
id result = nil;
@try {
result = block(self);
} @catch (NSException *exception) {
tcs.exception = exception;
return;
}
id result = block(self);
if ([result isKindOfClass:[BFTask class]]) {
id (^setupWithTask) (BFTask *) = ^id(BFTask *task) {
if (cancellationToken.cancellationRequested || task.cancelled) {
[tcs cancel];
} else if (task.exception) {
tcs.exception = task.exception;
} else if (task.error) {
tcs.error = task.error;
} else {
@ -499,7 +425,11 @@ NSString *const BFTaskMultipleExceptionsUserInfoKey = @"exceptions";
}
[self.condition lock];
}
[self.condition wait];
// TODO: (nlutsenko) Restructure this to use Bolts-Swift thread access synchronization architecture
// In the meantime, it's absolutely safe to get `_completed` aka an ivar, as long as it's a `BOOL` aka less than word size.
while (!_completed) {
[self.condition wait];
}
[self.condition unlock];
}

View File

@ -12,7 +12,7 @@
NS_ASSUME_NONNULL_BEGIN
@class BFTask<ResultType>;
@class BFTask<__covariant ResultType>;
/*!
A BFTaskCompletionSource represents the producer side of tasks.
@ -36,21 +36,14 @@ NS_ASSUME_NONNULL_BEGIN
Attempting to set this for a completed task will raise an exception.
@param result The result of the task.
*/
- (void)setResult:(nullable ResultType)result;
- (void)setResult:(nullable ResultType)result NS_SWIFT_NAME(set(result:));
/*!
Completes the task by setting the error.
Attempting to set this for a completed task will raise an exception.
@param error The error for the task.
*/
- (void)setError:(NSError *)error;
/*!
Completes the task by setting an exception.
Attempting to set this for a completed task will raise an exception.
@param exception The exception for the task.
*/
- (void)setException:(NSException *)exception;
- (void)setError:(NSError *)error NS_SWIFT_NAME(set(error:));
/*!
Completes the task by marking it as cancelled.
@ -62,21 +55,14 @@ NS_ASSUME_NONNULL_BEGIN
Sets the result of the task if it wasn't already completed.
@returns whether the new value was set.
*/
- (BOOL)trySetResult:(nullable ResultType)result;
- (BOOL)trySetResult:(nullable ResultType)result NS_SWIFT_NAME(trySet(result:));
/*!
Sets the error of the task if it wasn't already completed.
@param error The error for the task.
@returns whether the new value was set.
*/
- (BOOL)trySetError:(NSError *)error;
/*!
Sets the exception of the task if it wasn't already completed.
@param exception The exception for the task.
@returns whether the new value was set.
*/
- (BOOL)trySetException:(NSException *)exception;
- (BOOL)trySetError:(NSError *)error NS_SWIFT_NAME(trySet(error:));
/*!
Sets the cancellation state of the task if it wasn't already completed.

View File

@ -18,7 +18,6 @@ NS_ASSUME_NONNULL_BEGIN
- (BOOL)trySetResult:(nullable id)result;
- (BOOL)trySetError:(NSError *)error;
- (BOOL)trySetException:(NSException *)exception;
- (BOOL)trySetCancelled;
@end
@ -56,13 +55,6 @@ NS_ASSUME_NONNULL_BEGIN
}
}
- (void)setException:(NSException *)exception {
if (![self.task trySetException:exception]) {
[NSException raise:NSInternalInconsistencyException
format:@"Cannot set the exception on a completed task."];
}
}
- (void)cancel {
if (![self.task trySetCancelled]) {
[NSException raise:NSInternalInconsistencyException
@ -78,10 +70,6 @@ NS_ASSUME_NONNULL_BEGIN
return [self.task trySetError:error];
}
- (BOOL)trySetException:(NSException *)exception {
return [self.task trySetException:exception];
}
- (BOOL)trySetCancelled {
return [self.task trySetCancelled];
}

View File

@ -12,6 +12,7 @@
#import <Bolts/BFCancellationTokenRegistration.h>
#import <Bolts/BFCancellationTokenSource.h>
#import <Bolts/BFExecutor.h>
#import <Bolts/BFGeneric.h>
#import <Bolts/BFTask.h>
#import <Bolts/BFTaskCompletionSource.h>

View File

@ -12,6 +12,6 @@
NS_ASSUME_NONNULL_BEGIN
NSString *const BoltsFrameworkVersionString = @"1.7.0";
NSString *const BoltsFrameworkVersionString = @"1.9.0";
NS_ASSUME_NONNULL_END

View File

@ -33,6 +33,7 @@ typedef NS_ENUM(NSInteger, BFAppLinkNavigationType) {
custom requests with additional navigation and app data attached to them by
creating BFAppLinkNavigations themselves.
*/
NS_EXTENSION_UNAVAILABLE_IOS("Not available in app extension")
@interface BFAppLinkNavigation : NSObject
/*!
@ -57,6 +58,12 @@ typedef NS_ENUM(NSInteger, BFAppLinkNavigationType) {
extras:(NSDictionary *)extras
appLinkData:(NSDictionary *)appLinkData;
/*!
Creates an NSDictionary with the correct format for iOS callback URLs,
to be used as 'appLinkData' argument in the call to navigationWithAppLink:extras:appLinkData:
*/
+ (NSDictionary *)callbackAppLinkDataForAppWithName:(NSString *)appName url:(NSString *)url;
/*! Performs the navigation */
- (BFAppLinkNavigationType)navigate:(NSError **)error;
@ -69,6 +76,20 @@ typedef NS_ENUM(NSInteger, BFAppLinkNavigationType) {
/*! Navigates to a BFAppLink and returns whether it opened in-app or in-browser */
+ (BFAppLinkNavigationType)navigateToAppLink:(BFAppLink *)link error:(NSError **)error;
/*!
Returns a BFAppLinkNavigationType based on a BFAppLink.
It's essentially a no-side-effect version of navigateToAppLink:error:,
allowing apps to determine flow based on the link type (e.g. open an
internal web view instead of going straight to the browser for regular links.)
*/
+ (BFAppLinkNavigationType)navigationTypeForLink:(BFAppLink *)link;
/*!
Return navigation type for current instance.
No-side-effect version of navigate:
*/
- (BFAppLinkNavigationType)navigationType;
/*! Navigates to a URL (an asynchronous action) and returns a BFNavigationType */
+ (BFTask *)navigateToURLInBackground:(NSURL *)destination;

View File

@ -8,7 +8,7 @@
*
*/
#import <UIKit/UIKit.h>
#import "BFAppLinkNavigation.h"
#import <Bolts/Bolts.h>
@ -20,6 +20,9 @@ FOUNDATION_EXPORT NSString *const BFAppLinkTargetKeyName;
FOUNDATION_EXPORT NSString *const BFAppLinkUserAgentKeyName;
FOUNDATION_EXPORT NSString *const BFAppLinkExtrasKeyName;
FOUNDATION_EXPORT NSString *const BFAppLinkVersionKeyName;
FOUNDATION_EXPORT NSString *const BFAppLinkRefererAppLink;
FOUNDATION_EXPORT NSString *const BFAppLinkRefererAppName;
FOUNDATION_EXPORT NSString *const BFAppLinkRefererUrl;
static id<BFAppLinkResolving> defaultResolver;
@ -43,6 +46,10 @@ static id<BFAppLinkResolving> defaultResolver;
return navigation;
}
+ (NSDictionary *)callbackAppLinkDataForAppWithName:(NSString *)appName url:(NSString *)url {
return @{BFAppLinkRefererAppLink: @{BFAppLinkRefererAppName: appName, BFAppLinkRefererUrl: url}};
}
- (NSString *)stringByEscapingQueryString:(NSString *)string {
#if __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_7_0 || __MAC_OS_X_VERSION_MIN_REQUIRED >= __MAC_10_9
return [string stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
@ -229,6 +236,40 @@ static id<BFAppLinkResolving> defaultResolver;
appLinkData:nil] navigate:error];
}
+ (BFAppLinkNavigationType)navigationTypeForLink:(BFAppLink *)link {
return [[self navigationWithAppLink:link extras:nil appLinkData:nil] navigationType];
}
- (BFAppLinkNavigationType)navigationType {
BFAppLinkTarget *eligibleTarget = nil;
for (BFAppLinkTarget *target in self.appLink.targets) {
if ([[UIApplication sharedApplication] canOpenURL:target.URL]) {
eligibleTarget = target;
break;
}
}
if (eligibleTarget != nil) {
NSURL *appLinkURL = [self appLinkURLWithTargetURL:eligibleTarget.URL error:nil];
if (appLinkURL != nil) {
return BFAppLinkNavigationTypeApp;
} else {
return BFAppLinkNavigationTypeFailure;
}
}
if (self.appLink.webURL != nil) {
NSURL *appLinkURL = [self appLinkURLWithTargetURL:eligibleTarget.URL error:nil];
if (appLinkURL != nil) {
return BFAppLinkNavigationTypeBrowser;
} else {
return BFAppLinkNavigationTypeFailure;
}
}
return BFAppLinkNavigationTypeFailure;
}
+ (id<BFAppLinkResolving>)defaultResolver {
if (defaultResolver) {
return defaultResolver;

View File

@ -25,6 +25,6 @@
@param url The URL to resolve into an App Link.
@returns A BFTask that will return a BFAppLink for the given URL.
*/
- (BFTask *)appLinkFromURLInBackground:(NSURL *)url;
- (BFTask *)appLinkFromURLInBackground:(NSURL *)url NS_EXTENSION_UNAVAILABLE_IOS("Not available in app extension");
@end

View File

@ -40,6 +40,7 @@
A controller class that implements default behavior for a BFAppLinkReturnToRefererView, including
the ability to display the view above the navigation bar for navigation-based apps.
*/
NS_EXTENSION_UNAVAILABLE_IOS("Not available in app extension")
@interface BFAppLinkReturnToRefererController : NSObject <BFAppLinkReturnToRefererViewDelegate>
/*!

View File

@ -48,6 +48,7 @@ typedef NS_ENUM(NSUInteger, BFIncludeStatusBarInSize) {
rather than navigating away. If the view is provided an App Link that does not contain
referer data, it will have zero size and no UI will be displayed.
*/
NS_EXTENSION_UNAVAILABLE_IOS("Not available in app extension")
@interface BFAppLinkReturnToRefererView : UIView
/*!

View File

@ -55,11 +55,11 @@
NSString *refererAppName = refererAppLink[BFAppLinkRefererAppName];
if (refererURLString && refererAppName) {
BFAppLinkTarget *target = [BFAppLinkTarget appLinkTargetWithURL:[NSURL URLWithString:refererURLString]
appStoreId:nil
appName:refererAppName];
BFAppLinkTarget *appLinkTarget = [BFAppLinkTarget appLinkTargetWithURL:[NSURL URLWithString:refererURLString]
appStoreId:nil
appName:refererAppName];
_appLinkReferer = [BFAppLink appLinkWithSourceURL:[NSURL URLWithString:refererURLString]
targets:@[ target ]
targets:@[ appLinkTarget ]
webURL:nil
isBackToReferrer:YES];
}

View File

@ -143,7 +143,7 @@ static NSString *const BFWebViewAppLinkResolverShouldFallbackKey = @"should_fall
}];
}
- (BFTask *)appLinkFromURLInBackground:(NSURL *)url {
- (BFTask *)appLinkFromURLInBackground:(NSURL *)url NS_EXTENSION_UNAVAILABLE_IOS("") {
return [[self followRedirects:url] continueWithExecutor:[BFExecutor mainThreadExecutor]
withSuccessBlock:^id(BFTask *task) {
NSData *responseData = task.result[@"data"];
@ -200,7 +200,7 @@ static NSString *const BFWebViewAppLinkResolverShouldFallbackKey = @"should_fall
continue;
}
NSMutableDictionary *root = al;
for (int i = 1; i < nameComponents.count; i++) {
for (NSUInteger i = 1; i < nameComponents.count; i++) {
NSMutableArray *children = root[nameComponents[i]];
if (!children) {
children = [NSMutableArray array];
@ -237,26 +237,17 @@ static NSString *const BFWebViewAppLinkResolverShouldFallbackKey = @"should_fall
NSMutableArray *linkTargets = [NSMutableArray array];
NSArray *platformData = nil;
switch (UI_USER_INTERFACE_IDIOM()) {
case UIUserInterfaceIdiomPad:
platformData = @[ appLinkDict[BFWebViewAppLinkResolverIPadKey] ?: @{},
appLinkDict[BFWebViewAppLinkResolverIOSKey] ?: @{} ];
break;
case UIUserInterfaceIdiomPhone:
platformData = @[ appLinkDict[BFWebViewAppLinkResolverIPhoneKey] ?: @{},
appLinkDict[BFWebViewAppLinkResolverIOSKey] ?: @{} ];
break;
#ifdef __TVOS_9_0
case UIUserInterfaceIdiomTV:
#endif
#ifdef __IPHONE_9_3
case UIUserInterfaceIdiomCarPlay:
#endif
case UIUserInterfaceIdiomUnspecified:
default:
// Future-proofing. Other User Interface idioms should only hit ios.
platformData = @[ appLinkDict[BFWebViewAppLinkResolverIOSKey] ?: @{} ];
break;
const UIUserInterfaceIdiom idiom = UI_USER_INTERFACE_IDIOM();
if (idiom == UIUserInterfaceIdiomPad) {
platformData = @[ appLinkDict[BFWebViewAppLinkResolverIPadKey] ?: @{},
appLinkDict[BFWebViewAppLinkResolverIOSKey] ?: @{} ];
} else if (idiom == UIUserInterfaceIdiomPhone) {
platformData = @[ appLinkDict[BFWebViewAppLinkResolverIPhoneKey] ?: @{},
appLinkDict[BFWebViewAppLinkResolverIOSKey] ?: @{} ];
} else {
// Future-proofing. Other User Interface idioms should only hit ios.
platformData = @[ appLinkDict[BFWebViewAppLinkResolverIOSKey] ?: @{} ];
}
for (NSArray *platformObjects in platformData) {

View File

@ -1,85 +0,0 @@
/*
CocoaSecurity 1.1
Created by Kelp on 12/5/12.
Copyright (c) 2012 Kelp http://kelp.phate.org/
MIT License
CocoaSecurity is core. It provides AES encrypt, AES decrypt, Hash(MD5, HmacMD5, SHA1~SHA512, HmacSHA1~HmacSHA512) messages.
*/
#import <Foundation/Foundation.h>
#import <Foundation/NSException.h>
#pragma mark - CocoaSecurityResult
@interface CocoaSecurityResult : NSObject
@property (strong, nonatomic, readonly) NSData *data;
@property (strong, nonatomic, readonly) NSString *utf8String;
@property (strong, nonatomic, readonly) NSString *hex;
@property (strong, nonatomic, readonly) NSString *hexLower;
@property (strong, nonatomic, readonly) NSString *base64;
- (id)initWithBytes:(unsigned char[])initData length:(NSUInteger)length;
@end
#pragma mark - CocoaSecurity
@interface CocoaSecurity : NSObject
#pragma mark - AES Encrypt
+ (CocoaSecurityResult *)aesEncrypt:(NSString *)data key:(NSString *)key;
+ (CocoaSecurityResult *)aesEncrypt:(NSString *)data hexKey:(NSString *)key hexIv:(NSString *)iv;
+ (CocoaSecurityResult *)aesEncrypt:(NSString *)data key:(NSData *)key iv:(NSData *)iv;
+ (CocoaSecurityResult *)aesEncryptWithData:(NSData *)data key:(NSData *)key iv:(NSData *)iv;
#pragma mark AES Decrypt
+ (CocoaSecurityResult *)aesDecryptWithBase64:(NSString *)data key:(NSString *)key;
+ (CocoaSecurityResult *)aesDecryptWithBase64:(NSString *)data hexKey:(NSString *)key hexIv:(NSString *)iv;
+ (CocoaSecurityResult *)aesDecryptWithBase64:(NSString *)data key:(NSData *)key iv:(NSData *)iv;
+ (CocoaSecurityResult *)aesDecryptWithData:(NSData *)data key:(NSData *)key iv:(NSData *)iv;
#pragma mark - MD5
+ (CocoaSecurityResult *)md5:(NSString *)hashString;
+ (CocoaSecurityResult *)md5WithData:(NSData *)hashData;
#pragma mark HMAC-MD5
+ (CocoaSecurityResult *)hmacMd5:(NSString *)hashString hmacKey:(NSString *)key;
+ (CocoaSecurityResult *)hmacMd5WithData:(NSData *)hashData hmacKey:(NSString *)key;
#pragma mark - SHA
+ (CocoaSecurityResult *)sha1:(NSString *)hashString;
+ (CocoaSecurityResult *)sha1WithData:(NSData *)hashData;
+ (CocoaSecurityResult *)sha224:(NSString *)hashString;
+ (CocoaSecurityResult *)sha224WithData:(NSData *)hashData;
+ (CocoaSecurityResult *)sha256:(NSString *)hashString;
+ (CocoaSecurityResult *)sha256WithData:(NSData *)hashData;
+ (CocoaSecurityResult *)sha384:(NSString *)hashString;
+ (CocoaSecurityResult *)sha384WithData:(NSData *)hashData;
+ (CocoaSecurityResult *)sha512:(NSString *)hashString;
+ (CocoaSecurityResult *)sha512WithData:(NSData *)hashData;
#pragma mark HMAC-SHA
+ (CocoaSecurityResult *)hmacSha1:(NSString *)hashString hmacKey:(NSString *)key;
+ (CocoaSecurityResult *)hmacSha1WithData:(NSData *)hashData hmacKey:(NSString *)key;
+ (CocoaSecurityResult *)hmacSha224:(NSString *)hashString hmacKey:(NSString *)key;
+ (CocoaSecurityResult *)hmacSha224WithData:(NSData *)hashData hmacKey:(NSString *)key;
+ (CocoaSecurityResult *)hmacSha256:(NSString *)hashString hmacKey:(NSString *)key;
+ (CocoaSecurityResult *)hmacSha256WithData:(NSData *)hashData hmacKey:(NSString *)key;
+ (CocoaSecurityResult *)hmacSha384:(NSString *)hashString hmacKey:(NSString *)key;
+ (CocoaSecurityResult *)hmacSha384WithData:(NSData *)hashData hmacKey:(NSString *)key;
+ (CocoaSecurityResult *)hmacSha512:(NSString *)hashString hmacKey:(NSString *)key;
+ (CocoaSecurityResult *)hmacSha512WithData:(NSData *)hashData hmacKey:(NSString *)key;
@end
#pragma mark - CocoaSecurityEncoder
@interface CocoaSecurityEncoder : NSObject
- (NSString *)base64:(NSData *)data;
- (NSString *)hex:(NSData *)data useLower:(BOOL)isOutputLower;
@end
#pragma mark - CocoaSecurityDecoder
@interface CocoaSecurityDecoder : NSObject
- (NSData *)base64:(NSString *)data;
- (NSData *)hex:(NSString *)data;
@end

View File

@ -1,508 +0,0 @@
//
// CocoaSecurity.m
//
// Created by Kelp on 12/5/12.
// Copyright (c) 2012 Kelp http://kelp.phate.org/
// MIT License
//
#import "CocoaSecurity.h"
#import <CommonCrypto/CommonHMAC.h>
#import <CommonCrypto/CommonCryptor.h>
#import "Base64.h"
#pragma mark - CocoaSecurity
@implementation CocoaSecurity
#pragma mark - AES Encrypt
// default AES Encrypt, key -> SHA384(key).sub(0, 32), iv -> SHA384(key).sub(32, 16)
+ (CocoaSecurityResult *)aesEncrypt:(NSString *)data key:(NSString *)key
{
CocoaSecurityResult * sha = [self sha384:key];
NSData *aesKey = [sha.data subdataWithRange:NSMakeRange(0, 32)];
NSData *aesIv = [sha.data subdataWithRange:NSMakeRange(32, 16)];
return [self aesEncrypt:data key:aesKey iv:aesIv];
}
#pragma mark AES Encrypt 128, 192, 256
+ (CocoaSecurityResult *)aesEncrypt:(NSString *)data hexKey:(NSString *)key hexIv:(NSString *)iv
{
CocoaSecurityDecoder *decoder = [CocoaSecurityDecoder new];
NSData *aesKey = [decoder hex:key];
NSData *aesIv = [decoder hex:iv];
return [self aesEncrypt:data key:aesKey iv:aesIv];
}
+ (CocoaSecurityResult *)aesEncrypt:(NSString *)data key:(NSData *)key iv:(NSData *)iv
{
return [self aesEncryptWithData:[data dataUsingEncoding:NSUTF8StringEncoding] key:key iv:iv];
}
+ (CocoaSecurityResult *)aesEncryptWithData:(NSData *)data key:(NSData *)key iv:(NSData *)iv
{
// check length of key and iv
if ([iv length] != 16) {
@throw [NSException exceptionWithName:@"Cocoa Security"
reason:@"Length of iv is wrong. Length of iv should be 16(128bits)"
userInfo:nil];
}
if ([key length] != 16 && [key length] != 24 && [key length] != 32 ) {
@throw [NSException exceptionWithName:@"Cocoa Security"
reason:@"Length of key is wrong. Length of iv should be 16, 24 or 32(128, 192 or 256bits)"
userInfo:nil];
}
// setup output buffer
size_t bufferSize = [data length] + kCCBlockSizeAES128;
void *buffer = malloc(bufferSize);
// do encrypt
size_t encryptedSize = 0;
CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt,
kCCAlgorithmAES128,
kCCOptionPKCS7Padding,
[key bytes], // Key
[key length], // kCCKeySizeAES
[iv bytes], // IV
[data bytes],
[data length],
buffer,
bufferSize,
&encryptedSize);
if (cryptStatus == kCCSuccess) {
CocoaSecurityResult *result = [[CocoaSecurityResult alloc] initWithBytes:buffer length:encryptedSize];
free(buffer);
return result;
}
else {
free(buffer);
@throw [NSException exceptionWithName:@"Cocoa Security"
reason:@"Encrypt Error!"
userInfo:nil];
return nil;
}
}
#pragma mark - AES Decrypt
// default AES Decrypt, key -> SHA384(key).sub(0, 32), iv -> SHA384(key).sub(32, 16)
+ (CocoaSecurityResult *)aesDecryptWithBase64:(NSString *)data key:(NSString *)key
{
CocoaSecurityResult * sha = [self sha384:key];
NSData *aesKey = [sha.data subdataWithRange:NSMakeRange(0, 32)];
NSData *aesIv = [sha.data subdataWithRange:NSMakeRange(32, 16)];
return [self aesDecryptWithBase64:data key:aesKey iv:aesIv];
}
#pragma mark AES Decrypt 128, 192, 256
+ (CocoaSecurityResult *)aesDecryptWithBase64:(NSString *)data hexKey:(NSString *)key hexIv:(NSString *)iv
{
CocoaSecurityDecoder *decoder = [CocoaSecurityDecoder new];
NSData *aesKey = [decoder hex:key];
NSData *aesIv = [decoder hex:iv];
return [self aesDecryptWithBase64:data key:aesKey iv:aesIv];
}
+ (CocoaSecurityResult *)aesDecryptWithBase64:(NSString *)data key:(NSData *)key iv:(NSData *)iv
{
CocoaSecurityDecoder *decoder = [CocoaSecurityDecoder new];
return [self aesDecryptWithData:[decoder base64:data] key:key iv:iv];
}
+ (CocoaSecurityResult *)aesDecryptWithData:(NSData *)data key:(NSData *)key iv:(NSData *)iv
{
// check length of key and iv
if ([iv length] != 16) {
@throw [NSException exceptionWithName:@"Cocoa Security"
reason:@"Length of iv is wrong. Length of iv should be 16(128bits)"
userInfo:nil];
}
if ([key length] != 16 && [key length] != 24 && [key length] != 32 ) {
@throw [NSException exceptionWithName:@"Cocoa Security"
reason:@"Length of key is wrong. Length of iv should be 16, 24 or 32(128, 192 or 256bits)"
userInfo:nil];
}
// setup output buffer
size_t bufferSize = [data length] + kCCBlockSizeAES128;
void *buffer = malloc(bufferSize);
// do encrypt
size_t encryptedSize = 0;
CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt,
kCCAlgorithmAES128,
kCCOptionPKCS7Padding,
[key bytes], // Key
[key length], // kCCKeySizeAES
[iv bytes], // IV
[data bytes],
[data length],
buffer,
bufferSize,
&encryptedSize);
if (cryptStatus == kCCSuccess) {
CocoaSecurityResult *result = [[CocoaSecurityResult alloc] initWithBytes:buffer length:encryptedSize];
free(buffer);
return result;
}
else {
free(buffer);
@throw [NSException exceptionWithName:@"Cocoa Security"
reason:@"Decrypt Error!"
userInfo:nil];
return nil;
}
}
#pragma mark - MD5
+ (CocoaSecurityResult *)md5:(NSString *)hashString
{
return [self md5WithData:[hashString dataUsingEncoding:NSUTF8StringEncoding]];
}
+ (CocoaSecurityResult *)md5WithData:(NSData *)hashData
{
unsigned char *digest;
digest = malloc(CC_MD5_DIGEST_LENGTH);
CC_MD5([hashData bytes], (CC_LONG)[hashData length], digest);
CocoaSecurityResult *result = [[CocoaSecurityResult alloc] initWithBytes:digest length:CC_MD5_DIGEST_LENGTH];
free(digest);
return result;
}
#pragma mark - HMAC-MD5
+ (CocoaSecurityResult *)hmacMd5:(NSString *)hashString hmacKey:(NSString *)key
{
return [self hmacMd5WithData:[hashString dataUsingEncoding:NSUTF8StringEncoding] hmacKey:key];
}
+ (CocoaSecurityResult *)hmacMd5WithData:(NSData *)hashData hmacKey:(NSString *)key
{
unsigned char *digest;
digest = malloc(CC_MD5_DIGEST_LENGTH);
const char *cKey = [key cStringUsingEncoding:NSUTF8StringEncoding];
CCHmac(kCCHmacAlgMD5, cKey, strlen(cKey), [hashData bytes], [hashData length], digest);
CocoaSecurityResult *result = [[CocoaSecurityResult alloc] initWithBytes:digest length:CC_MD5_DIGEST_LENGTH];
free(digest);
cKey = nil;
return result;
}
#pragma mark - SHA1
+ (CocoaSecurityResult *)sha1:(NSString *)hashString
{
return [self sha1WithData:[hashString dataUsingEncoding:NSUTF8StringEncoding]];
}
+ (CocoaSecurityResult *)sha1WithData:(NSData *)hashData
{
unsigned char *digest;
digest = malloc(CC_SHA1_DIGEST_LENGTH);
CC_SHA1([hashData bytes], (CC_LONG)[hashData length], digest);
CocoaSecurityResult *result = [[CocoaSecurityResult alloc] initWithBytes:digest length:CC_SHA1_DIGEST_LENGTH];
free(digest);
return result;
}
#pragma mark SHA224
+ (CocoaSecurityResult *)sha224:(NSString *)hashString
{
return [self sha224WithData:[hashString dataUsingEncoding:NSUTF8StringEncoding]];
}
+ (CocoaSecurityResult *)sha224WithData:(NSData *)hashData
{
unsigned char *digest;
digest = malloc(CC_SHA224_DIGEST_LENGTH);
CC_SHA224([hashData bytes], (CC_LONG)[hashData length], digest);
CocoaSecurityResult *result = [[CocoaSecurityResult alloc] initWithBytes:digest length:CC_SHA224_DIGEST_LENGTH];
free(digest);
return result;
}
#pragma mark SHA256
+ (CocoaSecurityResult *)sha256:(NSString *)hashString
{
return [self sha256WithData:[hashString dataUsingEncoding:NSUTF8StringEncoding]];
}
+ (CocoaSecurityResult *)sha256WithData:(NSData *)hashData
{
unsigned char *digest;
digest = malloc(CC_SHA256_DIGEST_LENGTH);
CC_SHA256([hashData bytes], (CC_LONG)[hashData length], digest);
CocoaSecurityResult *result = [[CocoaSecurityResult alloc] initWithBytes:digest length:CC_SHA256_DIGEST_LENGTH];
free(digest);
return result;
}
#pragma mark SHA384
+ (CocoaSecurityResult *)sha384:(NSString *)hashString
{
return [self sha384WithData:[hashString dataUsingEncoding:NSUTF8StringEncoding]];
}
+ (CocoaSecurityResult *)sha384WithData:(NSData *)hashData
{
unsigned char *digest;
digest = malloc(CC_SHA384_DIGEST_LENGTH);
CC_SHA384([hashData bytes], (CC_LONG)[hashData length], digest);
CocoaSecurityResult *result = [[CocoaSecurityResult alloc] initWithBytes:digest length:CC_SHA384_DIGEST_LENGTH];
free(digest);
return result;
}
#pragma mark SHA512
+ (CocoaSecurityResult *)sha512:(NSString *)hashString
{
return [self sha512WithData:[hashString dataUsingEncoding:NSUTF8StringEncoding]];
}
+ (CocoaSecurityResult *)sha512WithData:(NSData *)hashData
{
unsigned char *digest;
digest = malloc(CC_SHA512_DIGEST_LENGTH);
CC_SHA512([hashData bytes], (CC_LONG)[hashData length], digest);
CocoaSecurityResult *result = [[CocoaSecurityResult alloc] initWithBytes:digest length:CC_SHA512_DIGEST_LENGTH];
free(digest);
return result;
}
#pragma mark - HMAC-SHA1
+ (CocoaSecurityResult *)hmacSha1:(NSString *)hashString hmacKey:(NSString *)key
{
return [self hmacSha1WithData:[hashString dataUsingEncoding:NSUTF8StringEncoding] hmacKey:key];
}
+ (CocoaSecurityResult *)hmacSha1WithData:(NSData *)hashData hmacKey:(NSString *)key
{
unsigned char *digest;
digest = malloc(CC_SHA1_DIGEST_LENGTH);
const char *cKey = [key cStringUsingEncoding:NSUTF8StringEncoding];
CCHmac(kCCHmacAlgSHA1, cKey, strlen(cKey), [hashData bytes], [hashData length], digest);
CocoaSecurityResult *result = [[CocoaSecurityResult alloc] initWithBytes:digest length:CC_SHA1_DIGEST_LENGTH];
free(digest);
cKey = nil;
return result;
}
#pragma mark HMAC-SHA224
+ (CocoaSecurityResult *)hmacSha224:(NSString *)hashString hmacKey:(NSString *)key
{
return [self hmacSha224WithData:[hashString dataUsingEncoding:NSUTF8StringEncoding] hmacKey:key];
}
+ (CocoaSecurityResult *)hmacSha224WithData:(NSData *)hashData hmacKey:(NSString *)key
{
unsigned char *digest;
digest = malloc(CC_SHA224_DIGEST_LENGTH);
const char *cKey = [key cStringUsingEncoding:NSUTF8StringEncoding];
CCHmac(kCCHmacAlgSHA224, cKey, strlen(cKey), [hashData bytes], [hashData length], digest);
CocoaSecurityResult *result = [[CocoaSecurityResult alloc] initWithBytes:digest length:CC_SHA224_DIGEST_LENGTH];
free(digest);
cKey = nil;
return result;
}
#pragma mark HMAC-SHA256
+ (CocoaSecurityResult *)hmacSha256:(NSString *)hashString hmacKey:(NSString *)key
{
return [self hmacSha256WithData:[hashString dataUsingEncoding:NSUTF8StringEncoding] hmacKey:key];
}
+ (CocoaSecurityResult *)hmacSha256WithData:(NSData *)hashData hmacKey:(NSString *)key
{
unsigned char *digest;
digest = malloc(CC_SHA256_DIGEST_LENGTH);
const char *cKey = [key cStringUsingEncoding:NSUTF8StringEncoding];
CCHmac(kCCHmacAlgSHA256, cKey, strlen(cKey), [hashData bytes], [hashData length], digest);
CocoaSecurityResult *result = [[CocoaSecurityResult alloc] initWithBytes:digest length:CC_SHA256_DIGEST_LENGTH];
free(digest);
cKey = nil;
return result;
}
#pragma mark HMAC-SHA384
+ (CocoaSecurityResult *)hmacSha384:(NSString *)hashString hmacKey:(NSString *)key
{
return [self hmacSha384WithData:[hashString dataUsingEncoding:NSUTF8StringEncoding] hmacKey:key];
}
+ (CocoaSecurityResult *)hmacSha384WithData:(NSData *)hashData hmacKey:(NSString *)key
{
unsigned char *digest;
digest = malloc(CC_SHA384_DIGEST_LENGTH);
const char *cKey = [key cStringUsingEncoding:NSUTF8StringEncoding];
CCHmac(kCCHmacAlgSHA384, cKey, strlen(cKey), [hashData bytes], [hashData length], digest);
CocoaSecurityResult *result = [[CocoaSecurityResult alloc] initWithBytes:digest length:CC_SHA384_DIGEST_LENGTH];
free(digest);
cKey = nil;
return result;
}
#pragma mark HMAC-SHA512
+ (CocoaSecurityResult *)hmacSha512:(NSString *)hashString hmacKey:(NSString *)key
{
return [self hmacSha512WithData:[hashString dataUsingEncoding:NSUTF8StringEncoding] hmacKey:key];
}
+ (CocoaSecurityResult *)hmacSha512WithData:(NSData *)hashData hmacKey:(NSString *)key
{
unsigned char *digest;
digest = malloc(CC_SHA512_DIGEST_LENGTH);
const char *cKey = [key cStringUsingEncoding:NSUTF8StringEncoding];
CCHmac(kCCHmacAlgSHA512, cKey, strlen(cKey), [hashData bytes], [hashData length], digest);
CocoaSecurityResult *result = [[CocoaSecurityResult alloc] initWithBytes:digest length:CC_SHA512_DIGEST_LENGTH];
free(digest);
cKey = nil;
return result;
}
@end
#pragma mark - CocoaSecurityResult
@implementation CocoaSecurityResult
@synthesize data = _data;
#pragma mark - Init
- (id)initWithBytes:(unsigned char[])initData length:(NSUInteger)length
{
self = [super init];
if (self) {
_data = [NSData dataWithBytes:initData length:length];
}
return self;
}
#pragma mark UTF8 String
// convert CocoaSecurityResult to UTF8 string
- (NSString *)utf8String
{
NSString *result = [[NSString alloc] initWithData:_data encoding:NSUTF8StringEncoding];
return result;
}
#pragma mark HEX
// convert CocoaSecurityResult to HEX string
- (NSString *)hex
{
CocoaSecurityEncoder *encoder = [CocoaSecurityEncoder new];
return [encoder hex:_data useLower:false];
}
- (NSString *)hexLower
{
CocoaSecurityEncoder *encoder = [CocoaSecurityEncoder new];
return [encoder hex:_data useLower:true];
}
#pragma mark Base64
// convert CocoaSecurityResult to Base64 string
- (NSString *)base64
{
CocoaSecurityEncoder *encoder = [CocoaSecurityEncoder new];
return [encoder base64:_data];
}
@end
#pragma mark - CocoaSecurityEncoder
@implementation CocoaSecurityEncoder
// convert NSData to Base64
- (NSString *)base64:(NSData *)data
{
return [data base64EncodedString];
}
// convert NSData to hex string
- (NSString *)hex:(NSData *)data useLower:(BOOL)isOutputLower
{
if (data.length == 0) { return nil; }
static const char HexEncodeCharsLower[] = "0123456789abcdef";
static const char HexEncodeChars[] = "0123456789ABCDEF";
char *resultData;
// malloc result data
resultData = malloc([data length] * 2 +1);
// convert imgData(NSData) to char[]
unsigned char *sourceData = ((unsigned char *)[data bytes]);
NSUInteger length = [data length];
if (isOutputLower) {
for (NSUInteger index = 0; index < length; index++) {
// set result data
resultData[index * 2] = HexEncodeCharsLower[(sourceData[index] >> 4)];
resultData[index * 2 + 1] = HexEncodeCharsLower[(sourceData[index] % 0x10)];
}
}
else {
for (NSUInteger index = 0; index < length; index++) {
// set result data
resultData[index * 2] = HexEncodeChars[(sourceData[index] >> 4)];
resultData[index * 2 + 1] = HexEncodeChars[(sourceData[index] % 0x10)];
}
}
resultData[[data length] * 2] = 0;
// convert result(char[]) to NSString
NSString *result = [NSString stringWithCString:resultData encoding:NSASCIIStringEncoding];
sourceData = nil;
free(resultData);
return result;
}
@end
#pragma mark - CocoaSecurityDecoder
@implementation CocoaSecurityDecoder
- (NSData *)base64:(NSString *)string
{
return [NSData dataWithBase64EncodedString:string];
}
- (NSData *)hex:(NSString *)data
{
if (data.length == 0) { return nil; }
static const unsigned char HexDecodeChars[] =
{
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 1, //49
2, 3, 4, 5, 6, 7, 8, 9, 0, 0, //59
0, 0, 0, 0, 0, 10, 11, 12, 13, 14,
15, 0, 0, 0, 0, 0, 0, 0, 0, 0, //79
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 10, 11, 12, //99
13, 14, 15
};
// convert data(NSString) to CString
const char *source = [data cStringUsingEncoding:NSUTF8StringEncoding];
// malloc buffer
unsigned char *buffer;
NSUInteger length = strlen(source) / 2;
buffer = malloc(length);
for (NSUInteger index = 0; index < length; index++) {
buffer[index] = (HexDecodeChars[source[index * 2]] << 4) + (HexDecodeChars[source[index * 2 + 1]]);
}
// init result NSData
NSData *result = [NSData dataWithBytes:buffer length:length];
free(buffer);
source = nil;
return result;
}
@end

View File

@ -1,8 +0,0 @@
The MIT License (MIT)
Copyright (c) 2013 Kelp https://github.com/kelp404
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@ -1,111 +0,0 @@
#CocoaSecurity [![Build Status](https://secure.travis-ci.org/kelp404/CocoaSecurity.png?branch=master)](http://travis-ci.org/#!/kelp404/CocoaSecurity)
Kelp https://twitter.com/kelp404/
[MIT License][mit]
[MIT]: http://www.opensource.org/licenses/mit-license.php
CocoaSecurity include 4 classes, `CocoaSecurity`, `CocoaSecurityResult`, `CocoaSecurityEncoder` and `CocoaSecurityDecoder`.
##CocoaSecurity
CocoaSecurity is core. It provides AES encrypt, AES decrypt, Hash(MD5, HmacMD5, SHA1~SHA512, HmacSHA1~HmacSHA512) messages.
**MD5:**
```objective-c
CocoaSecurityResult *md5 = [CocoaSecurity md5:@"kelp"];
// md5.hex = 'C40C69779E15780ADAE46C45EB451E23'
// md5.hexLower = 'c40c69779e15780adae46c45eb451e23'
// md5.base64 = 'xAxpd54VeAra5GxF60UeIw=='
```
**SHA256:**
```objective-c
CocoaSecurityResult *sha256 = [CocoaSecurity sha256:@"kelp"];
// sha256.hexLower = '280f8bb8c43d532f389ef0e2a5321220b0782b065205dcdfcb8d8f02ed5115b9'
// sha256.base64 = 'KA+LuMQ9Uy84nvDipTISILB4KwZSBdzfy42PAu1RFbk='
```
**default AES Encrypt:**<br/>
key -> SHA384(key).sub(0, 32)<br/>
iv -> SHA384(key).sub(32, 16)
```objective-c
CocoaSecurityResult *aesDefault = [CocoaSecurity aesEncrypt:@"kelp" key:@"key"];
// aesDefault.base64 = 'ez9uubPneV1d2+rpjnabJw=='
```
**AES256 Encrypt & Decrypt:**
```objective-c
CocoaSecurityResult *aes256 = [CocoaSecurity aesEncrypt:@"kelp"
hexKey:@"280f8bb8c43d532f389ef0e2a5321220b0782b065205dcdfcb8d8f02ed5115b9"
hexIv:@"CC0A69779E15780ADAE46C45EB451A23"];
// aes256.base64 = 'WQYg5qvcGyCBY3IF0hPsoQ=='
CocoaSecurityResult *aes256Decrypt = [CocoaSecurity aesDecryptWithBase64:@"WQYg5qvcGyCBY3IF0hPsoQ=="
hexKey:@"280f8bb8c43d532f389ef0e2a5321220b0782b065205dcdfcb8d8f02ed5115b9"
hexIv:@"CC0A69779E15780ADAE46C45EB451A23"];
// aes256Decrypt.utf8String = 'kelp'
```
##CocoaSecurityResult
CocoaSecurityResult is the result class of CocoaSecurity. It provides convert result data to NSData, NSString, HEX string, Base64 string.
```objective-c
@property (strong, nonatomic, readonly) NSData *data;
@property (strong, nonatomic, readonly) NSString *utf8String;
@property (strong, nonatomic, readonly) NSString *hex;
@property (strong, nonatomic, readonly) NSString *hexLower;
@property (strong, nonatomic, readonly) NSString *base64;
```
##CocoaSecurityEncoder
CocoaSecurityEncoder provides convert NSData to HEX string, Base64 string.
```objective-c
- (NSString *)base64:(NSData *)data;
- (NSString *)hex:(NSData *)data useLower:(BOOL)isOutputLower;
```
**example:**
```objective-c
CocoaSecurityEncoder *encoder = [CocoaSecurityEncoder new];
NSString *str1 = [encoder hex:[@"kelp" dataUsingEncoding:NSUTF8StringEncoding] useLower:NO];
// str1 = '6B656C70'
NSString *str2 = [encoder base64:[@"kelp" dataUsingEncoding:NSUTF8StringEncoding]];
// str2 = 'a2VscA=='
```
##CocoaSecurityDecoder
CocoaSecurityEncoder provides convert HEX string or Base64 string to NSData.
```objective-c
- (NSData *)base64:(NSString *)data;
- (NSData *)hex:(NSString *)data;
```
**example:**
```objective-c
CocoaSecurityDecoder *decoder = [CocoaSecurityDecoder new];
NSData *data1 = [decoder hex:@"CC0A69779E15780ADAE46C45EB451A23"];
// data1 = <cc0a6977 9e15780a dae46c45 eb451a23>
NSData *data2 = [decoder base64:@"zT1PS64MnXIUDCUiy13RRg=="];
// data2 = <cd3d4f4b ae0c9d72 140c2522 cb5dd146>
```
##Installation
1. **git:**
```
$ git clone git://github.com/kelp404/CocoaSecurity.git
$ cd CocoaSecurity
$ git submodule update --init
```
2. **<a href="http://cocoapods.org/?q=CocoaSecurity" target="_blank">CocoadPods</a>:**
add `Podfile` in your project path
```
platform :ios
pod 'CocoaSecurity'
```
```
$ pod install
```

View File

@ -1,53 +0,0 @@
//
// Base64.h
//
// Version 1.2
//
// Created by Nick Lockwood on 12/01/2012.
// Copyright (C) 2012 Charcoal Design
//
// Distributed under the permissive zlib License
// Get the latest version from here:
//
// https://github.com/nicklockwood/Base64
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would be
// appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not be
// misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source distribution.
//
#import <Foundation/Foundation.h>
@interface NSData (Base64)
+ (NSData *)dataWithBase64EncodedString:(NSString *)string;
- (NSString *)base64EncodedStringWithWrapWidth:(NSUInteger)wrapWidth;
- (NSString *)base64EncodedString;
@end
@interface NSString (Base64)
+ (NSString *)stringWithBase64EncodedString:(NSString *)string;
- (NSString *)base64EncodedStringWithWrapWidth:(NSUInteger)wrapWidth;
- (NSString *)base64EncodedString;
- (NSString *)base64DecodedString;
- (NSData *)base64DecodedData;
@end

View File

@ -1,167 +0,0 @@
//
// Base64.m
//
// Version 1.2
//
// Created by Nick Lockwood on 12/01/2012.
// Copyright (C) 2012 Charcoal Design
//
// Distributed under the permissive zlib License
// Get the latest version from here:
//
// https://github.com/nicklockwood/Base64
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an aacknowledgment in the product documentation would be
// appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not be
// misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source distribution.
//
#import "Base64.h"
#pragma GCC diagnostic ignored "-Wselector"
#import <Availability.h>
#if !__has_feature(objc_arc)
#error This library requires automatic reference counting
#endif
@implementation NSData (Base64)
+ (NSData *)dataWithBase64EncodedString:(NSString *)string
{
if (![string length]) return nil;
NSData *decoded = nil;
#if __MAC_OS_X_VERSION_MIN_REQUIRED < __MAC_10_9 || __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_7_0
if (![NSData instancesRespondToSelector:@selector(initWithBase64EncodedString:options:)])
{
decoded = [[self alloc] initWithBase64Encoding:[string stringByReplacingOccurrencesOfString:@"[^A-Za-z0-9+/=]" withString:@"" options:NSRegularExpressionSearch range:NSMakeRange(0, [string length])]];
}
else
#endif
{
decoded = [[self alloc] initWithBase64EncodedString:string options:NSDataBase64DecodingIgnoreUnknownCharacters];
}
return [decoded length]? decoded: nil;
}
- (NSString *)base64EncodedStringWithWrapWidth:(NSUInteger)wrapWidth
{
if (![self length]) return nil;
NSString *encoded = nil;
#if __MAC_OS_X_VERSION_MIN_REQUIRED < __MAC_10_9 || __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_7_0
if (![NSData instancesRespondToSelector:@selector(base64EncodedStringWithOptions:)])
{
encoded = [self base64Encoding];
}
else
#endif
{
switch (wrapWidth)
{
case 64:
{
return [self base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength];
}
case 76:
{
return [self base64EncodedStringWithOptions:NSDataBase64Encoding76CharacterLineLength];
}
default:
{
encoded = [self base64EncodedStringWithOptions:(NSDataBase64EncodingOptions)0];
}
}
}
if (!wrapWidth || wrapWidth >= [encoded length])
{
return encoded;
}
wrapWidth = (wrapWidth / 4) * 4;
NSMutableString *result = [NSMutableString string];
for (NSUInteger i = 0; i < [encoded length]; i+= wrapWidth)
{
if (i + wrapWidth >= [encoded length])
{
[result appendString:[encoded substringFromIndex:i]];
break;
}
[result appendString:[encoded substringWithRange:NSMakeRange(i, wrapWidth)]];
[result appendString:@"\r\n"];
}
return result;
}
- (NSString *)base64EncodedString
{
return [self base64EncodedStringWithWrapWidth:0];
}
@end
@implementation NSString (Base64)
+ (NSString *)stringWithBase64EncodedString:(NSString *)string
{
NSData *data = [NSData dataWithBase64EncodedString:string];
if (data)
{
return [[self alloc] initWithData:data encoding:NSUTF8StringEncoding];
}
return nil;
}
- (NSString *)base64EncodedStringWithWrapWidth:(NSUInteger)wrapWidth
{
NSData *data = [self dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:YES];
return [data base64EncodedStringWithWrapWidth:wrapWidth];
}
- (NSString *)base64EncodedString
{
NSData *data = [self dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:YES];
return [data base64EncodedString];
}
- (NSString *)base64DecodedString
{
return [NSString stringWithBase64EncodedString:self];
}
- (NSData *)base64DecodedData
{
return [NSData dataWithBase64EncodedString:self];
}
@end

View File

@ -1,4 +1,4 @@
Copyright (c) 2013 No Zebra Network
Copyright (c) 2014 axldyb <aksel.dybdal@shortcut.no>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

View File

@ -0,0 +1,46 @@
//
// DDDKeychainWrapper.h
// Aksel Dybdal
//
// Created by Aksel Dybdal on 02.04.14.
// Copyright (c) 2014 Aksel Dybdal. All rights reserved.
//
/**
A small wrapper for Keychain access.
Inspired by:
http://useyourloaf.com/blog/2010/03/29/simple-iphone-keychain-access.html
*/
#import <Foundation/Foundation.h>
@interface DDDKeychainWrapper : NSObject
+ (void)setString:(NSString *)string forKey:(NSString *)key;
+ (NSString *)stringForKey:(NSString *)key;
+ (void)setDate:(NSDate *)date forKey:(NSString *)key;
+ (NSDate *)dateForKey:(NSString *)key;
+ (void)setData:(NSData *)data forKey:(NSString *)key;
+ (NSData *)dataForKey:(NSString *)key;
+ (void)setArray:(NSArray *)array forKey:(NSString *)key;
+ (NSArray *)arrayForKey:(NSString *)key;
+ (void)setDictionary:(NSDictionary *)dictionary forKey:(NSString *)key;
+ (NSDictionary *)dictionaryForKey:(NSString *)key;
+ (void)setNumber:(NSNumber *)number forKey:(NSString *)key;
+ (NSNumber *)numberForKey:(NSString *)key;
+ (void)setBoolean:(BOOL)boolean forKey:(NSString *)key;
+ (BOOL)booleanForKey:(NSString *)key;
+ (void)setObject:(id)object forKey:(NSString *)key;
+ (id)objectForKey:(NSString *)key;
+ (void)wipeKeychain;
@end

View File

@ -0,0 +1,373 @@
//
// DDDKeychainWrapper.m
// Aksel Dybdal
//
// Created by Aksel Dybdal on 02.04.14.
// Copyright (c) 2014 Aksel Dybdal. All rights reserved.
//
#import "DDDKeychainWrapper.h"
#import <Security/Security.h>
typedef NS_ENUM(NSUInteger, DDDKeychainWrapperErrorCode) {
DDDKeychainWrapperErrorCreatingKeychainValue = 1,
DDDKeychainWrapperErrorUpdatingKeychainValue,
DDDKeychainWrapperErrorDeletingKeychainValue,
DDDKeychainWrapperErrorSearchingKeychainValue
};
NSString *const kDDDKeychainWrapperServiceName = @"com.dddkeychainwrapper.keychainService";
NSString *const kDDDKeychainWrapperErrorDomain = @"DDDKeychainWrapperErrorDomain";
#ifdef DEBUG
# warning "Including NSLog"
# define DDDLOG(s, ...) NSLog(s, ## __VA_ARGS__)
#else
# define DDDLOG(s, ...) while(0){}
#endif
@implementation DDDKeychainWrapper
#pragma mark - String
+ (void)setString:(NSString *)string forKey:(NSString *)key
{
NSData *stringData = [string dataUsingEncoding:NSUTF8StringEncoding];
[self setData:stringData forIdentifier:key];
}
+ (NSString *)stringForKey:(NSString *)key
{
NSData *stringData = [self dataForIdentifier:key];
return [[NSString alloc] initWithData:stringData encoding:NSUTF8StringEncoding];
}
#pragma mark - Date
+ (void)setDate:(NSDate *)date forKey:(NSString *)key
{
NSData *dateData = [NSKeyedArchiver archivedDataWithRootObject:date];
[self setData:dateData forIdentifier:key];
}
+ (NSDate *)dateForKey:(NSString *)key
{
NSData *dateData = [self dataForIdentifier:key];
return (NSDate *)[NSKeyedUnarchiver unarchiveObjectWithData:dateData];
}
#pragma mark - Data
+ (void)setData:(NSData *)data forKey:(NSString *)key
{
[self setData:data forIdentifier:key];
}
+ (NSData *)dataForKey:(NSString *)key
{
return [self dataForIdentifier:key];
}
#pragma mark - Array
+ (void)setArray:(NSArray *)array forKey:(NSString *)key
{
for (id obj in array) {
NSAssert([obj conformsToProtocol:@protocol(NSCoding)], @"Objects must confirm to NSCoding protocol in order to be stored in keychain");
}
NSData *arrayData = [NSKeyedArchiver archivedDataWithRootObject:array];
[self setData:arrayData forIdentifier:key];
}
+ (NSArray *)arrayForKey:(NSString *)key
{
NSData *arrayData = [self dataForIdentifier:key];
return (NSArray *)[NSKeyedUnarchiver unarchiveObjectWithData:arrayData];
}
#pragma mark - Dictionary
+ (void)setDictionary:(NSDictionary *)dictionary forKey:(NSString *)key
{
[dictionary enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
NSAssert([key conformsToProtocol:@protocol(NSCoding)], @"Keys must confirm to NSCoding protocol in order to be stored in keychain");
NSAssert([obj conformsToProtocol:@protocol(NSCoding)], @"Objects must confirm to NSCoding protocol in order to be stored in keychain");
}];
NSData *dictionaryData = [NSKeyedArchiver archivedDataWithRootObject:dictionary];
[self setData:dictionaryData forIdentifier:key];
}
+ (NSDictionary *)dictionaryForKey:(NSString *)key
{
NSData *dictionaryData = [self dataForIdentifier:key];
return (NSDictionary *)[NSKeyedUnarchiver unarchiveObjectWithData:dictionaryData];
}
#pragma mark - Number
+ (void)setNumber:(NSNumber *)number forKey:(NSString *)key
{
NSData *numberData = [NSKeyedArchiver archivedDataWithRootObject:number];
[self setData:numberData forIdentifier:key];
}
+ (NSNumber *)numberForKey:(NSString *)key
{
NSData *numberData = [self dataForIdentifier:key];
return (NSNumber *)[NSKeyedUnarchiver unarchiveObjectWithData:numberData];
}
#pragma mark - BOOL
+ (void)setBoolean:(BOOL)boolean forKey:(NSString *)key
{
NSNumber *boolNumber = [NSNumber numberWithBool:boolean];
[self setNumber:boolNumber forKey:key];
}
+ (BOOL)booleanForKey:(NSString *)key
{
NSNumber *boolNumber = [self numberForKey:key];
return [boolNumber boolValue];
}
#pragma mark - Object
+ (void)setObject:(id)object forKey:(NSString *)key
{
NSAssert([object conformsToProtocol:@protocol(NSCoding)], @"Object must confirm to NSCoding protocol in order to be stored in keychain");
NSData *objectData = [NSKeyedArchiver archivedDataWithRootObject:object];
[self setData:objectData forIdentifier:key];
}
+ (id)objectForKey:(NSString *)key
{
NSData *objectData = [self dataForIdentifier:key];
return (id)[NSKeyedUnarchiver unarchiveObjectWithData:objectData];
}
#pragma mark - Clear Keychain
+ (void)wipeKeychain
{
NSArray *secItemClasses = @[(__bridge id)kSecClassGenericPassword,
(__bridge id)kSecClassInternetPassword,
(__bridge id)kSecClassCertificate,
(__bridge id)kSecClassKey,
(__bridge id)kSecClassIdentity];
for (id secItemClass in secItemClasses) {
NSDictionary *spec = @{(__bridge id)kSecClass: (id)secItemClass};
SecItemDelete((__bridge CFDictionaryRef)spec);
}
}
#pragma mark - Private
+ (void)setData:(NSData *)data forIdentifier:(NSString *)identifier
{
NSError *error = nil;
// If no data provided we assume we want to delete the value
if (nil == data || NO == [data bytes]) {
[self deleteKeychainValueForIdentifier:identifier error:&error];
if (error) {
DDDLOG(@"Error deleting keychain value for key: \"%@\" Error: %@", identifier, [error localizedDescription]);
}
return;
}
// We first look up the key in order to see if we need to update or create the value
if ([self searchKeychainCopyMatching:identifier error:&error]) {
if (error) {
DDDLOG(@"Error finding keychain value for key: \"%@\" Error: %@", identifier, [error localizedDescription]);
return;
}
if (![self updateKeychainValue:data forIdentifier:identifier error:&error]) {
DDDLOG(@"Error updating keychain value for key: \"%@\" Error: %@", identifier, [error localizedDescription]);
}
} else {
if (![self createKeychainValue:data forIdentifier:identifier error:&error]) {
DDDLOG(@"Error creating keychain value for key: \"%@\" Error: %@", identifier, [error localizedDescription]);
}
}
}
+ (NSData *)dataForIdentifier:(NSString *)identifier
{
NSError *error = nil;
NSData *stringData = [self searchKeychainCopyMatching:identifier error:&error];
if (error) {
DDDLOG(@"Error finding keychain value for key: \"%@\" Error: %@", identifier, [error localizedDescription]);
return nil;
}
return stringData;
}
+ (NSMutableDictionary *)newSearchDictionary:(NSString *)identifier
{
NSMutableDictionary *searchDictionary = [[NSMutableDictionary alloc] init];
[searchDictionary setObject:(__bridge id)kSecClassGenericPassword forKey:(__bridge id)kSecClass];
NSData *encodedIdentifier = [identifier dataUsingEncoding:NSUTF8StringEncoding];
[searchDictionary setObject:encodedIdentifier forKey:(__bridge id)kSecAttrGeneric];
[searchDictionary setObject:encodedIdentifier forKey:(__bridge id)kSecAttrAccount];
[searchDictionary setObject:(__bridge id)kSecAttrAccessibleAfterFirstUnlock forKey:(__bridge id)kSecAttrAccessible];
[searchDictionary setObject:kDDDKeychainWrapperServiceName forKey:(__bridge id)kSecAttrService];
return searchDictionary;
}
+ (NSData *)searchKeychainCopyMatching:(NSString *)identifier error:(NSError **)error
{
NSMutableDictionary *searchDictionary = [self newSearchDictionary:identifier];
[searchDictionary setObject:(__bridge id)kSecMatchLimitOne forKey:(__bridge id)kSecMatchLimit];
[searchDictionary setObject:(__bridge id)kCFBooleanTrue forKey:(__bridge id)kSecReturnData];
CFDataRef result;
OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)searchDictionary, (CFTypeRef *)&result);
if (status != errSecSuccess) {
[self keychainError:error forStatus:status domain:DDDKeychainWrapperErrorSearchingKeychainValue];
return nil;
}
NSData *data = (__bridge NSData *)result;
return data;
}
+ (BOOL)createKeychainValue:(NSData *)data forIdentifier:(NSString *)identifier error:(NSError **)error
{
NSMutableDictionary *dictionary = [self newSearchDictionary:identifier];
[dictionary setObject:data forKey:(__bridge id)kSecValueData];
OSStatus status = SecItemAdd((__bridge CFDictionaryRef)dictionary, NULL);
if (status == errSecSuccess) {
return YES;
}
[self keychainError:error forStatus:status domain:DDDKeychainWrapperErrorCreatingKeychainValue];
return NO;
}
+ (BOOL)updateKeychainValue:(NSData *)data forIdentifier:(NSString *)identifier error:(NSError **)error
{
NSMutableDictionary *searchDictionary = [self newSearchDictionary:identifier];
NSMutableDictionary *updateDictionary = [[NSMutableDictionary alloc] init];
[updateDictionary setObject:data forKey:(__bridge id)kSecValueData];
OSStatus status = SecItemUpdate((__bridge CFDictionaryRef)searchDictionary,
(__bridge CFDictionaryRef)updateDictionary);
if (status == errSecSuccess) {
return YES;
}
[self keychainError:error forStatus:status domain:DDDKeychainWrapperErrorUpdatingKeychainValue];
return NO;
}
+ (BOOL)deleteKeychainValueForIdentifier:(NSString *)identifier error:(NSError **)error
{
NSMutableDictionary *searchDictionary = [self newSearchDictionary:identifier];
OSStatus status = SecItemDelete((__bridge CFDictionaryRef)searchDictionary);
if (status == errSecSuccess) {
return YES;
}
[self keychainError:error forStatus:status domain:DDDKeychainWrapperErrorDeletingKeychainValue];
return NO;
}
#pragma mark - Error
+ (void)keychainError:(NSError **)error forStatus:(OSStatus)status domain:(NSUInteger)domain
{
NSString *errorString = @"";
switch (status) {
case errSecUnimplemented:
errorString = @"Function or operation not implemented.";
break;
case errSecIO:
errorString = @"I/O error (bummers)";
break;
case errSecOpWr:
errorString = @"File already open with write permission";
break;
case errSecParam:
errorString = @"One or more parameters passed to a function where not valid.";
break;
case errSecAllocate:
errorString = @"Failed to allocate memory.";
break;
case errSecUserCanceled:
errorString = @"User canceled the operation.";
break;
case errSecBadReq:
errorString = @"Bad parameter or invalid state for operation.";
break;
case errSecInternalComponent:
errorString = @"errSecInternalComponent";
break;
case errSecNotAvailable:
errorString = @"No keychain is available. You may need to restart your computer.";
break;
case errSecDuplicateItem:
errorString = @"The specified item already exists in the keychain.";
break;
case errSecItemNotFound:
errorString = @"The specified item could not be found in the keychain.";
break;
case errSecInteractionNotAllowed:
errorString = @"User interaction is not allowed.";
break;
case errSecDecode:
errorString = @"Unable to decode the provided data.";
break;
case errSecAuthFailed:
errorString = @"The user name or passphrase you entered is not correct.";
break;
default:
errorString = @"Unknown error";
break;
}
*error = [NSError errorWithDomain:kDDDKeychainWrapperErrorDomain
code:domain
userInfo:@{NSLocalizedDescriptionKey: errorString}];
}
@end

View File

@ -0,0 +1,47 @@
# DDDKeychainWrapper
[![CI Status](http://img.shields.io/travis/axldyb/DDDKeychainWrapper.svg?style=flat)](https://travis-ci.org/axldyb/DDDKeychainWrapper)
[![Version](https://img.shields.io/cocoapods/v/DDDKeychainWrapper.svg?style=flat)](http://cocoadocs.org/docsets/DDDKeychainWrapper)
[![License](https://img.shields.io/cocoapods/l/DDDKeychainWrapper.svg?style=flat)](http://cocoadocs.org/docsets/DDDKeychainWrapper)
[![Platform](https://img.shields.io/cocoapods/p/DDDKeychainWrapper.svg?style=flat)](http://cocoadocs.org/docsets/DDDKeychainWrapper)
## Usage
Storing your sensitive data in the keychain can take up a lot of time and effort. It should be easy to just drop something in there and retrive it with a few simple lines of code. DDDKeychainWrapper offers this simplicity and here is how we do it:
```objective-c
// Writing to the Keychain
[DDDKeychainWrapper setString:@"Secret string" forKey:@"my_key"];
// Reading from the Keychain
NSString *secretString = [DDDKeychainWrapper stringForKey:@"my_key"];
```
DDDKeychainWrapper has support for the following types
* NSString
* NSDate
* NSData
* NSArray
* NSDictionary
* NSNumber
* BOOL
* Objects (Must confirm to NSCoding)
A method for wiping the keychain data inserted via the wrapper exists as well.
## Installation
DDDKeychainWrapper is available through [CocoaPods](http://cocoapods.org). To install
it, simply add the following line to your Podfile:
pod "DDDKeychainWrapper"
## Author
axldyb, aksel.dybdal@shortcut.no
## License
DDDKeychainWrapper is available under the MIT license. See the LICENSE file for more info.

View File

@ -10,7 +10,4 @@
@interface DJLocalizableString : NSString
- (NSUInteger)length;
- (unichar)characterAtIndex:(NSUInteger)index;
@end

View File

@ -11,13 +11,12 @@
@interface DJLocalizationSystem (Private)
/*!
* Special version that tries to load a storyboard string from all the tables
* except Localizable and InfoPlist. Defaults to comment if not found.
* Special version that tries to load a storyboard string from all the tables
* except Localizable and InfoPlist. Defaults to comment if not found.
*
* @param key The localization key
* @param comment The localization value
*
* @return The localized string
* @param key The localization key
* @param comment The localization value
* @return The localized string
*/
- (NSString *)localizedStoryboardStringForKey:(NSString *)key value:(NSString *)comment;

View File

@ -8,14 +8,19 @@
#import <Foundation/Foundation.h>
#define DJLocalizedString(key, comment) \
[DJLocalizationSystem.shared localizedStringForKey:(key) value: @"" table: nil]
#define DJLocalizedStringFromTable(key, tbl, comment) \
[DJLocalizationSystem.shared localizedStringForKey:(key) value: @"" table:(tbl)]
// replace Apple's macros with our own
#undef NSLocalizedString
#define NSLocalizedString(key, comment) \
[DJLocalizationSystem.shared localizedStringForKey:(key) value: @"" table: nil]
DJLocalizedString(key, comment)
#undef NSLocalizedStringFromTable
#define NSLocalizedStringFromTable(key, tbl, comment) \
[DJLocalizationSystem.shared localizedStringForKey:(key) value:@"" table:(tbl)]
DJLocalizedStringFromTable(key, tbl, comment)
@interface DJLocalizationSystem : NSObject
@ -24,7 +29,7 @@
*
* @return A localization system instance
*/
+ (instancetype)shared;
@property (class, nonnull, readonly) DJLocalizationSystem *shared;
/*!
* Get the localized string for a given key/value
@ -34,7 +39,7 @@
* @param tableName The localization table name
* @return The localized string
*/
- (NSString *)localizedStringForKey:(NSString *)key value:(NSString *)comment table:(NSString *)tableName;
- (nonnull NSString *)localizedStringForKey:(nullable NSString *)key value:(nullable NSString *)comment table:(nullable NSString *)tableName;
/*!
* Get the localized string for a given key/value in the specified bundle
@ -44,7 +49,7 @@
* @param bundle The bundle to search in
* @return The localized string
*/
- (NSString *)localizedStringForKey:(NSString *)key value:(NSString *)comment table:(NSString *)tableName bundle:(NSBundle *)bundle;
- (nonnull NSString *)localizedStringForKey:(nullable NSString *)key value:(nullable NSString *)comment table:(nullable NSString *)tableName bundle:(nonnull NSBundle *)bundle;
/*!
* Reset the localization to the system's default language
@ -54,11 +59,11 @@
/*!
* The bundle for the currently active language
*/
@property (nonatomic, readonly) NSBundle *bundle;
@property (nonatomic, readonly, nonnull) NSBundle *bundle;
/*!
* The currently active language
*/
@property (nonatomic, strong) NSString *language;
@property (nonatomic, strong, nonnull) NSString *language;
@end

View File

@ -16,6 +16,6 @@
* @param name The storyboard's name
* @return The desired storyboard
*/
+ (instancetype)dj_storyboardWithName:(NSString *)name;
+ (nonnull instancetype)dj_storyboardWithName:(nonnull NSString *)name;
@end

View File

@ -25,6 +25,11 @@ it, simply add the following line to your Podfile:
pod "DJLocalization"
For Swift, use:
pod "DJLocalization/Swift"
### Manually
_**Important note if your project doesn't use ARC**: you must add the `-fobjc-arc` compiler flag to all 'DJLocalization' files in Target Settings > Build Phases > Compile Sources._
@ -37,11 +42,17 @@ _**Important note if your project doesn't use ARC**: you must add the `-fobjc-ar
Then simply add the following import to your prefix header, or any file where you use the NSLocalizedString macro (or variants).
#import <DJLocalization/DJLocalization.h>
@import DJLocalization;
#####*Important:*
You must import the header wherever you use the NSLocalizedString macro, as this header replaces the default NSLocalizedString macro with a custom one. If you don't, runtime switching of languages won't work.
### Localization
Use your normal localization workflow and everything should work correctly. For code strings use `NSLocalizedString`, for storyboards use Base Internationalization.
As mentioned before, `NSLocalizedString` will only work correctly if you first include the correct headers. If you want a bit more safety, the library provides some extra macros `DJLocalizedString` that provide the same functionality as the overridden `NSLocalizedString` macros. This way you'll get a compilation error if you forget to include the headers.
### Switching languages
At runtime, you can switch the language at any time by setting the language property:

View File

@ -1,14 +0,0 @@
#import <Expecta/Expecta.h>
#import "ExpectaObject+FBSnapshotTest.h"
@interface EXPExpectFBSnapshotTest : NSObject
@end
/// Set the default folder for image tests to run in
extern void setGlobalReferenceImageDir(char *reference);
EXPMatcherInterface(haveValidSnapshot, (void));
EXPMatcherInterface(recordSnapshot, (void));
EXPMatcherInterface(haveValidSnapshotNamed, (NSString *snapshot));
EXPMatcherInterface(recordSnapshotNamed, (NSString *snapshot));

View File

@ -1,284 +0,0 @@
#import "EXPMatchers+FBSnapshotTest.h"
#import <Expecta/EXPMatcherHelpers.h>
#import <FBSnapshotTestCase/FBSnapshotTestController.h>
@interface EXPExpectFBSnapshotTest()
@property (nonatomic, strong) NSString *referenceImagesDirectory;
@end
@implementation EXPExpectFBSnapshotTest
+ (id)instance
{
static EXPExpectFBSnapshotTest *instance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
instance = [[self alloc] init];
});
return instance;
}
+ (BOOL)compareSnapshotOfViewOrLayer:(id)viewOrLayer snapshot:(NSString *)snapshot testCase:(id)testCase record:(BOOL)record referenceDirectory:(NSString *)referenceDirectory error:(NSError **)error
{
FBSnapshotTestController *snapshotController = [[FBSnapshotTestController alloc] initWithTestClass:[testCase class]];
snapshotController.recordMode = record;
snapshotController.referenceImagesDirectory = referenceDirectory;
snapshotController.usesDrawViewHierarchyInRect = [Expecta usesDrawViewHierarchyInRect];
if (! snapshotController.referenceImagesDirectory) {
[NSException raise:@"Missing value for referenceImagesDirectory" format:@"Call [[EXPExpectFBSnapshotTest instance] setReferenceImagesDirectory"];
}
return [snapshotController compareSnapshotOfViewOrLayer:viewOrLayer
selector:NSSelectorFromString(snapshot)
identifier:nil
tolerance:0
error:error];
}
+ (NSString *)combinedError:(NSString *)message test:(NSString *)test error:(NSError *)error
{
NSAssert(message, @"missing message");
NSAssert(test, @"missing test name");
NSMutableArray *ary = [NSMutableArray array];
[ary addObject:[NSString stringWithFormat:@"%@ %@", message, test]];
for(NSString *key in error.userInfo.keyEnumerator) {
[ary addObject:[NSString stringWithFormat:@" %@: %@", key, [error.userInfo valueForKey:key]]];
}
return [ary componentsJoinedByString:@"\n"];
}
@end
void setGlobalReferenceImageDir(char *reference) {
NSString *referenceImagesDirectory = [NSString stringWithFormat:@"%s", reference];
[[EXPExpectFBSnapshotTest instance] setReferenceImagesDirectory:referenceImagesDirectory];
};
@interface EXPExpect(ReferenceDirExtension)
- (NSString *)_getDefaultReferenceDirectory;
@end
@implementation EXPExpect(ReferenceDirExtension)
- (NSString *)_getDefaultReferenceDirectory
{
NSString *globalReference = [[EXPExpectFBSnapshotTest instance] referenceImagesDirectory];
if (globalReference) {
return globalReference;
}
// Search the test file's path to find the first folder with the substring "tests"
// then append "/ReferenceImages" and use that
NSString *testFileName = [NSString stringWithCString:self.fileName encoding:NSUTF8StringEncoding];
NSArray *pathComponents = [testFileName pathComponents];
for (NSString *folder in pathComponents) {
if ([folder.lowercaseString rangeOfString:@"tests"].location != NSNotFound) {
NSArray *folderPathComponents = [pathComponents subarrayWithRange:NSMakeRange(0, [pathComponents indexOfObject:folder] + 1)];
return [NSString stringWithFormat:@"%@/ReferenceImages", [folderPathComponents componentsJoinedByString:@"/"]];
}
}
[NSException raise:@"Could not infer reference image folder" format:@"You should provide a reference dir using setGlobalReferenceImageDir(FB_REFERENCE_IMAGE_DIR);"];
return nil;
}
@end
#import <Specta/Specta.h>
#import <Specta/SpectaUtility.h>
#import <Specta/SPTExample.h>
NSString *sanitizedTestPath();
NSString *sanitizedTestPath(){
id compiledExample = [[NSThread currentThread] threadDictionary][@"SPTCurrentSpec"]; // SPTSpec
NSString *name;
if ([compiledExample respondsToSelector:@selector(name)]) {
// Specta 0.3 syntax
name = [compiledExample performSelector:@selector(name)];
} else if ([compiledExample respondsToSelector:@selector(fileName)]) {
// Specta 0.2 syntax
name = [compiledExample performSelector:@selector(fileName)];
}
name = [[[[name componentsSeparatedByString:@" test_"] lastObject] stringByReplacingOccurrencesOfString:@"__" withString:@"_"] stringByReplacingOccurrencesOfString:@"]" withString:@""];
return name;
}
EXPMatcherImplementationBegin(haveValidSnapshot, (void)){
__block NSError *error = nil;
prerequisite(^BOOL{
return actual;
});
match(^BOOL{
NSString *referenceImageDir = [self _getDefaultReferenceDirectory];
NSString *name = sanitizedTestPath();
if ([actual isKindOfClass:UIViewController.class]) {
[actual beginAppearanceTransition:YES animated:NO];
[actual endAppearanceTransition];
actual = [actual view];
}
return [EXPExpectFBSnapshotTest compareSnapshotOfViewOrLayer:actual snapshot:name testCase:[self testCase] record:NO referenceDirectory:referenceImageDir error:&error];
});
failureMessageForTo(^NSString *{
if (!actual) {
return [EXPExpectFBSnapshotTest combinedError:@"Nil was passed into haveValidSnapshot." test:sanitizedTestPath() error:nil];
}
return [EXPExpectFBSnapshotTest combinedError:@"expected a matching snapshot in" test:sanitizedTestPath() error:error];
});
failureMessageForNotTo(^NSString *{
return [EXPExpectFBSnapshotTest combinedError:@"expected to not have a matching snapshot in" test:sanitizedTestPath() error:error];
});
}
EXPMatcherImplementationEnd
EXPMatcherImplementationBegin(recordSnapshot, (void)) {
__block NSError *error = nil;
BOOL actualIsViewLayerOrViewController = ([actual isKindOfClass:UIView.class] || [actual isKindOfClass:CALayer.class] || [actual isKindOfClass:UIViewController.class]);
prerequisite(^BOOL{
return actual && actualIsViewLayerOrViewController;
});
match(^BOOL{
NSString *referenceImageDir = [self _getDefaultReferenceDirectory];
// For view controllers do the viewWill/viewDid dance, then pass view through
if ([actual isKindOfClass:UIViewController.class]) {
[actual beginAppearanceTransition:YES animated:NO];
[actual endAppearanceTransition];
actual = [actual view];
}
[EXPExpectFBSnapshotTest compareSnapshotOfViewOrLayer:actual snapshot:sanitizedTestPath() testCase:[self testCase] record:YES referenceDirectory:referenceImageDir error:&error];
return NO;
});
failureMessageForTo(^NSString *{
if (!actual) {
return [EXPExpectFBSnapshotTest combinedError:@"Nil was passed into recordSnapshot." test:sanitizedTestPath() error:nil];
}
if (!actualIsViewLayerOrViewController) {
return [EXPExpectFBSnapshotTest combinedError:@"Expected a View, Layer or View Controller." test:sanitizedTestPath() error:nil];
}
if (error) {
return [EXPExpectFBSnapshotTest combinedError:@"expected to record a snapshot in" test:sanitizedTestPath() error:error];
} else {
return [NSString stringWithFormat:@"snapshot %@ successfully recorded, replace recordSnapshot with a check", sanitizedTestPath()];
}
});
failureMessageForNotTo(^NSString *{
if (error) {
return [EXPExpectFBSnapshotTest combinedError:@"expected to record a snapshot in" test:sanitizedTestPath() error:error];
} else {
return [NSString stringWithFormat:@"snapshot %@ successfully recorded, replace recordSnapshot with a check", sanitizedTestPath()];
}
});
}
EXPMatcherImplementationEnd
EXPMatcherImplementationBegin(haveValidSnapshotNamed, (NSString *snapshot)){
BOOL snapshotIsNil = (snapshot == nil);
__block NSError *error = nil;
prerequisite(^BOOL{
return actual && !(snapshotIsNil);
});
match(^BOOL{
NSString *referenceImageDir = [self _getDefaultReferenceDirectory];
if ([actual isKindOfClass:UIViewController.class]) {
[actual beginAppearanceTransition:YES animated:NO];
[actual endAppearanceTransition];
actual = [actual view];
}
return [EXPExpectFBSnapshotTest compareSnapshotOfViewOrLayer:actual snapshot:snapshot testCase:[self testCase] record:NO referenceDirectory:referenceImageDir error:&error];
});
failureMessageForTo(^NSString *{
if (!actual) {
return [EXPExpectFBSnapshotTest combinedError:@"Nil was passed into haveValidSnapshotNamed." test:sanitizedTestPath() error:nil];
}
return [EXPExpectFBSnapshotTest combinedError:@"expected a matching snapshot named" test:snapshot error:error];
});
failureMessageForNotTo(^NSString *{
return [EXPExpectFBSnapshotTest combinedError:@"expected not to have a matching snapshot named" test:snapshot error:error];
});
}
EXPMatcherImplementationEnd
EXPMatcherImplementationBegin(recordSnapshotNamed, (NSString *snapshot)) {
BOOL snapshotExists = (snapshot != nil);
BOOL actualIsViewLayerOrViewController = ([actual isKindOfClass:UIView.class] || [actual isKindOfClass:CALayer.class] || [actual isKindOfClass:UIViewController.class]);
__block NSError *error = nil;
id actualRef = actual;
prerequisite(^BOOL{
return actualRef && snapshotExists && actualIsViewLayerOrViewController;
});
match(^BOOL{
NSString *referenceImageDir = [self _getDefaultReferenceDirectory];
// For view controllers do the viewWill/viewDid dance, then pass view through
if ([actual isKindOfClass:UIViewController.class]) {
[actual beginAppearanceTransition:YES animated:NO];
[actual endAppearanceTransition];
actual = [actual view];
}
[EXPExpectFBSnapshotTest compareSnapshotOfViewOrLayer:actual snapshot:snapshot testCase:[self testCase] record:YES referenceDirectory:referenceImageDir error:&error];
return NO;
});
failureMessageForTo(^NSString *{
if (!actual) {
return [EXPExpectFBSnapshotTest combinedError:@"Nil was passed into recordSnapshotNamed." test:sanitizedTestPath() error:nil];
}
if (!actualIsViewLayerOrViewController) {
return [EXPExpectFBSnapshotTest combinedError:@"Expected a View, Layer or View Controller." test:snapshot error:nil];
}
if (error) {
return [EXPExpectFBSnapshotTest combinedError:@"expected to record a matching snapshot named" test:snapshot error:error];
} else {
return [NSString stringWithFormat:@"snapshot %@ successfully recorded, replace recordSnapshot with a check", snapshot];
}
});
failureMessageForNotTo(^NSString *{
if (!actualIsViewLayerOrViewController) {
return [EXPExpectFBSnapshotTest combinedError:@"Expected a View, Layer or View Controller." test:snapshot error:nil];
}
if (error) {
return [EXPExpectFBSnapshotTest combinedError:@"expected to record a matching snapshot named" test:snapshot error:error];
} else {
return [NSString stringWithFormat:@"snapshot %@ successfully recorded, replace recordSnapshot with a check", snapshot];
}
});
}
EXPMatcherImplementationEnd

View File

@ -1,17 +0,0 @@
//
// ExpectaObject+FBSnapshotTest.h
// Expecta+Snapshots
//
// Created by John Boiles on 8/3/15.
// Copyright (c) 2015 Expecta+Snapshots All rights reserved.
//
#import <Expecta/ExpectaObject.h>
@interface Expecta (FBSnapshotTest)
+ (void)setUsesDrawViewHierarchyInRect:(BOOL)usesDrawViewHierarchyInRect;
+ (BOOL)usesDrawViewHierarchyInRect;
@end

View File

@ -1,25 +0,0 @@
//
// ExpectaObject+FBSnapshotTest.m
// Expecta+Snapshots
//
// Created by John Boiles on 8/3/15.
// Copyright (c) 2015 Expecta+Snapshots All rights reserved.
//
#import "ExpectaObject+FBSnapshotTest.h"
#import <objc/runtime.h>
static NSString const *kUsesDrawViewHierarchyInRectKey = @"ExpectaObject+FBSnapshotTest.usesDrawViewHierarchyInRect";
@implementation Expecta (FBSnapshotTest)
+ (void)setUsesDrawViewHierarchyInRect:(BOOL)usesDrawViewHierarchyInRect {
objc_setAssociatedObject(self, (__bridge const void *)(kUsesDrawViewHierarchyInRectKey), @(usesDrawViewHierarchyInRect), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
+ (BOOL)usesDrawViewHierarchyInRect {
NSNumber *usesDrawViewHierarchyInRect = objc_getAssociatedObject(self, (__bridge const void *)(kUsesDrawViewHierarchyInRectKey));
return usesDrawViewHierarchyInRect.boolValue;
}
@end

View File

@ -1,22 +0,0 @@
MIT License
Copyright (c) 2014 Daniel Doubrovkine, Artsy Inc.
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@ -1,87 +0,0 @@
Expecta Matchers for FBSnapshotTestCase
=======================================
[Expecta](https://github.com/specta/expecta) matchers for [ios-snapshot-test-case](https://github.com/facebook/ios-snapshot-test-case).
[![Build Status](https://travis-ci.org/dblock/ios-snapshot-test-case-expecta.png)](https://travis-ci.org/dblock/ios-snapshot-test-case-expecta)
### Usage
Add `Expecta+Snapshots` to your Podfile, the latest `FBSnapshotTestCase` will come in as a dependency.
``` ruby
pod 'Expecta+Snapshots'
```
### App setup
Use `expect(view).to.recordSnapshotNamed(@"unique snapshot name")` to record a snapshot and `expect(view).to.haveValidSnapshotNamed(@"unique snapshot name")` to check it.
If you project was compiled with Specta included, you have two extra methods that use the spec hierarchy to generate the snapshot name for you: `recordSnapshot()` and `haveValidSnapshot()`. You should only call these once per `it()` block.
If you need the `usesDrawViewHierarchyInRect` property in order to correctly render UIVisualEffect, UIAppearance and Size Classes, call `[Expecta setUsesDrawViewHierarchyInRect:NO];` inside `beforeAll`.
``` Objective-C
#define EXP_SHORTHAND
#include <Specta/Specta.h>
#include <Expecta/Expecta.h>
#include <Expecta+Snapshots/EXPMatchers+FBSnapshotTest.h>
#include "FBExampleView.h"
SpecBegin(FBExampleView)
describe(@"manual matching", ^{
it(@"matches view", ^{
FBExampleView *view = [[FBExampleView alloc] initWithFrame:CGRectMake(0, 0, 64, 64)];
expect(view).to.recordSnapshotNamed(@"FBExampleView");
expect(view).to.haveValidSnapshotNamed(@"FBExampleView");
});
it(@"doesn't match a view", ^{
FBExampleView *view = [[FBExampleView alloc] initWithFrame:CGRectMake(0, 0, 64, 64)];
expect(view).toNot.haveValidSnapshotNamed(@"FBExampleViewDoesNotExist");
});
});
describe(@"test name derived matching", ^{
it(@"matches view", ^{
FBExampleView *view = [[FBExampleView alloc] initWithFrame:CGRectMake(0, 0, 64, 64)];
expect(view).to.recordSnapshot();
expect(view).to.haveValidSnapshot();
});
it(@"doesn't match a view", ^{
FBExampleView *view = [[FBExampleView alloc] initWithFrame:CGRectMake(0, 0, 64, 64)];
expect(view).toNot.haveValidSnapshot();
});
});
SpecEnd
```
### Sane defaults
`EXPMatchers+FBSnapshotTest` will automatically figure out the tests folder, and [add a reference image](https://github.com/dblock/ios-snapshot-test-case-expecta/blob/master/EXPMatchers%2BFBSnapshotTest.m#L84-L85) directory, if you'd like to override this, you should include a `beforeAll` block setting the `setGlobalReferenceImageDir` in each file containing tests.
```
beforeAll(^{
setGlobalReferenceImageDir(FB_REFERENCE_IMAGE_DIR);
});
```
### Example
A complete project can be found in [FBSnapshotTestCaseDemo](FBSnapshotTestCaseDemo).
Notably, take a look at [FBSnapshotTestCaseDemoSpecs.m](FBSnapshotTestCaseDemo/FBSnapshotTestCaseDemoTests/FBSnapshotTestCaseDemoSpecs.m) for a complete example, which is an expanded Specta version version of [FBSnapshotTestCaseDemoTests.m](https://github.com/facebook/ios-snapshot-test-case/blob/master/FBSnapshotTestCaseDemo/FBSnapshotTestCaseDemoTests/FBSnapshotTestCaseDemoTests.m).
Finally you can consult the tests for [ARTiledImageView](https://github.com/dblock/ARTiledImageView/tree/master/IntegrationTests) or [NAMapKit](https://github.com/neilang/NAMapKit/tree/master/Demo/DemoTests).
### License
MIT, see [LICENSE](LICENSE.md)

View File

@ -9,9 +9,9 @@
#ifndef Expecta_EXPDefines_h
#define Expecta_EXPDefines_h
typedef void (^EXPBasicBlock)();
typedef id (^EXPIdBlock)();
typedef BOOL (^EXPBoolBlock)();
typedef NSString *(^EXPStringBlock)();
typedef void (^EXPBasicBlock)(void);
typedef id (^EXPIdBlock)(void);
typedef BOOL (^EXPBoolBlock)(void);
typedef NSString *(^EXPStringBlock)(void);
#endif

View File

@ -10,6 +10,10 @@ EXPMatcherImplementationBegin(respondTo, (SEL expected)) {
});
match(^BOOL {
if ([actual respondsToSelector:@selector(instancesRespondToSelector:)] &&
[actual instancesRespondToSelector:expected]) {
return YES;
}
return [actual respondsToSelector:expected];
});

View File

@ -1,13 +1,8 @@
#Expecta
[![Build Status](http://img.shields.io/travis/specta/expecta/master.svg?style=flat)](https://travis-ci.org/specta/expecta)
[![Pod Version](http://img.shields.io/cocoapods/v/Expecta.svg?style=flat)](http://cocoadocs.org/docsets/Expecta/)
[![Pod Platform](http://img.shields.io/cocoapods/p/Expecta.svg?style=flat)](http://cocoadocs.org/docsets/Expecta/)
[![Pod License](http://img.shields.io/cocoapods/l/Expecta.svg?style=flat)](https://www.apache.org/licenses/LICENSE-2.0.html)
# Expecta [![Build Status](http://img.shields.io/travis/specta/expecta/master.svg?style=flat)](https://travis-ci.org/specta/expecta) [![Pod Version](http://img.shields.io/cocoapods/v/Expecta.svg?style=flat)](http://cocoadocs.org/docsets/Expecta/)
A matcher framework for Objective-C and Cocoa.
## Introduction
## FEATURES
The main advantage of using Expecta over other matcher frameworks is that you do not have to specify the data types. Also, the syntax of Expecta matchers is much more readable and does not suffer from parenthesitis.
@ -18,63 +13,10 @@ expect([bar isBar]).to.equal(YES);
expect(baz).to.equal(3.14159);
```
Expecta is framework-agnostic: it works well with XCTest and XCTest-compatible test frameworks such as [Specta](http://github.com/petejkim/specta/).
Expecta is framework-agnostic: it works well with XCTest and XCTest-compatible test frameworks such as [Specta](http://github.com/petejkim/specta/), or [Kiwi](https://github.com/kiwi-bdd/Kiwi/).
## Installation
You can setup Expecta using [Carthage](https://github.com/Carthage/Carthage), [CocoaPods](http://github.com/CocoaPods/CocoaPods) or [completely manually](#setting-up-manually).
### Carthage
1. Add Expecta to your project's `Cartfile.private`:
```ruby
github "specta/expecta" "master"
```
2. Run `carthage update` in your project directory.
3. Drag the appropriate **Expecta.framework** for your platform (located in `Carthage/Build/`) into your applications Xcode project, and add it to your test target(s).
### CocoaPods
1. Add Expecta to your project's `Podfile`:
```ruby
target :MyApp do
# Your app's dependencies
end
target :MyAppTests do
pod 'Expecta', '~> 1.0.0'
end
```
2. Run `pod update` or `pod install` in your project directory.
### Setting Up Manually
1. Clone Expecta from Github.
2. Run `rake` in your project directory to build the frameworks and libraries.
3. Add a Cocoa or Cocoa Touch Unit Testing Bundle target to your Xcode project if you don't already have one.
4. For **OS X projects**, copy and add `Expecta.framework` in the `Products/osx` folder to your project's test target.
For **iOS projects**, copy and add `Expecta.framework` in the `Products/ios` folder to your project's test target.
You can also use `libExpecta.a` if you prefer to link Expecta as a static library — iOS 7.x and below require this.
6. Add `-ObjC` and `-all_load` to the **Other Linker Flags** build setting for the test target in your Xcode project.
7. You can now use Expecta in your test classes by adding the following import:
```objective-c
@import Expecta; // If you're using Expecta.framework
// OR
#import <Expecta/Expecta.h> // If you're using the static library, or the framework
```
## Built-in Matchers
## MATCHERS
> `expect(x).to.equal(y);` compares objects or primitives x and y and passes if they are identical (==) or equivalent isEqual:).
@ -132,13 +74,13 @@ You can setup Expecta using [Carthage](https://github.com/Carthage/Carthage), [C
> `expect(x).to.match(y);` passes if an instance of NSString `x` matches regular expression (given as NSString) `y` one or more times.
## Inverting Matchers
### Inverting Matchers
Every matcher's criteria can be inverted by prepending `.notTo` or `.toNot`:
>`expect(x).notTo.equal(y);` compares objects or primitives x and y and passes if they are *not* equivalent.
## Asynchronous Testing
### Asynchronous Testing
Every matcher can be made to perform asynchronous testing by prepending `.will`, `.willNot` or `after(...)`:
@ -172,14 +114,14 @@ describe(@"Foo", ^{
});
```
## Forced Failing
### Forced Failing
You can fail a test by using the `failure` attribute. This can be used to test branching.
> `failure(@"This should not happen");` outright fails a test.
## Writing New Matchers
### WRITING NEW MATCHERS
Writing a new matcher is easy with special macros provided by Expecta. Take a look at how `.beKindOf()` matcher is defined:
@ -246,7 +188,7 @@ EXPMatcherImplementationBegin(beKindOf, (Class expected)) {
EXPMatcherImplementationEnd
```
## Dynamic Predicate Matchers
## DYNAMIC PREDICATE MATCHERS
It is possible to add predicate matchers by simply defining the matcher interface, with the matcher implementation being handled at runtime by delegating to the predicate method on your object.
@ -282,6 +224,68 @@ You can now write your assertion as follows:
expect(lightSwitch).isTurnedOn();
```
## INSTALLATION
You can setup Expecta using [CocoaPods](http://github.com/CocoaPods/CocoaPods), [Carthage](https://github.com/Carthage/Carthage) or [completely manually](#setting-up-manually).
### CocoaPods
1. Add Expecta to your project's `Podfile`:
```ruby
target :MyApp do
# your app dependencies
target :MyAppTests do
inherit! search_paths
pod 'Expecta', '~> 1.0'
end
end
```
### Carthage
1. Add Expecta to your project's `Cartfile.private`:
```ruby
github "specta/expecta" "master"
```
2. Run `carthage update` in your project directory.
3. Drag the appropriate **Expecta.framework** for your platform (located in `Carthage/Build/`) into your applications Xcode project, and add it to your test target(s).
2. Run `pod update` or `pod install` in your project directory.
### Setting Up Manually
1. Clone Expecta from Github.
2. Run `rake` in your project directory to build the frameworks and libraries.
3. Add a Cocoa or Cocoa Touch Unit Testing Bundle target to your Xcode project if you don't already have one.
4. For **OS X projects**, copy and add `Expecta.framework` in the `Products/osx` folder to your project's test target.
For **iOS projects**, copy and add `Expecta.framework` in the `Products/ios` folder to your project's test target.
You can also use `libExpecta.a` if you prefer to link Expecta as a static library — iOS 7.x and below require this.
6. Add `-ObjC` and `-all_load` to the **Other Linker Flags** build setting for the test target in your Xcode project.
7. You can now use Expecta in your test classes by adding the following import:
```objective-c
@import Expecta; // If you're using Expecta.framework
// OR
#import <Expecta/Expecta.h> // If you're using the static library, or the framework
```
## STATUS
Expecta, and Specta are considered done projects, there are no plans for _active_ development on the project at the moment aside from ensuring future Xcode compatability.
Therefore it is a stable dependency, but will not be moving into the Swift world. If you are looking for that, we recommend you consider [Quick](https://github.com/quick/quick) and [Nimble](https://github.com/quick/nimble).
## Contribution Guidelines
* Please use only spaces and indent 2 spaces at a time.
@ -290,4 +294,4 @@ expect(lightSwitch).isTurnedOn();
## License
Copyright (c) 2012-2015 [Specta Team](https://github.com/specta?tab=members). This software is licensed under the [MIT License](http://github.com/specta/specta/raw/master/LICENSE).
Copyright (c) 2012-2016 [Specta Team](https://github.com/specta?tab=members). This software is licensed under the [MIT License](http://github.com/specta/specta/raw/master/LICENSE).

View File

@ -22,18 +22,20 @@
#import <FBSDKCoreKit/FBSDKGraphRequestConnection.h>
#import <FBSDKCoreKit/FBSDKMacros.h>
/*!
@abstract Notification indicating that the `currentAccessToken` has changed.
@discussion the userInfo dictionary of the notification will contain keys
/**
Notification indicating that the `currentAccessToken` has changed.
the userInfo dictionary of the notification will contain keys
`FBSDKAccessTokenChangeOldKey` and
`FBSDKAccessTokenChangeNewKey`.
*/
FBSDK_EXTERN NSString *const FBSDKAccessTokenDidChangeNotification;
/*!
@abstract A key in the notification's userInfo that will be set
/**
A key in the notification's userInfo that will be set
if and only if the user ID changed between the old and new tokens.
@discussion Token refreshes can occur automatically with the SDK
Token refreshes can occur automatically with the SDK
which do not change the user. If you're only interested in user
changes (such as logging out), you should check for the existence
of this key. The value is a NSNumber with a boolValue.
@ -45,74 +47,76 @@ FBSDK_EXTERN NSString *const FBSDKAccessTokenDidChangeNotification;
FBSDK_EXTERN NSString *const FBSDKAccessTokenDidChangeUserID;
/*
@abstract key in notification's userInfo object for getting the old token.
@discussion If there was no old token, the key will not be present.
key in notification's userInfo object for getting the old token.
If there was no old token, the key will not be present.
*/
FBSDK_EXTERN NSString *const FBSDKAccessTokenChangeOldKey;
/*
@abstract key in notification's userInfo object for getting the new token.
@discussion If there is no new token, the key will not be present.
key in notification's userInfo object for getting the new token.
If there is no new token, the key will not be present.
*/
FBSDK_EXTERN NSString *const FBSDKAccessTokenChangeNewKey;
/*!
@class FBSDKAccessToken
@abstract Represents an immutable access token for using Facebook services.
/**
Represents an immutable access token for using Facebook services.
*/
@interface FBSDKAccessToken : NSObject<FBSDKCopying, NSSecureCoding>
/*!
@abstract Returns the app ID.
/**
Returns the app ID.
*/
@property (readonly, copy, nonatomic) NSString *appID;
/*!
@abstract Returns the known declined permissions.
/**
Returns the known declined permissions.
*/
@property (readonly, copy, nonatomic) NSSet *declinedPermissions;
/*!
@abstract Returns the expiration date.
/**
Returns the expiration date.
*/
@property (readonly, copy, nonatomic) NSDate *expirationDate;
/*!
@abstract Returns the known granted permissions.
/**
Returns the known granted permissions.
*/
@property (readonly, copy, nonatomic) NSSet *permissions;
/*!
@abstract Returns the date the token was last refreshed.
/**
Returns the date the token was last refreshed.
*/
@property (readonly, copy, nonatomic) NSDate *refreshDate;
/*!
@abstract Returns the opaque token string.
/**
Returns the opaque token string.
*/
@property (readonly, copy, nonatomic) NSString *tokenString;
/*!
@abstract Returns the user ID.
/**
Returns the user ID.
*/
@property (readonly, copy, nonatomic) NSString *userID;
- (instancetype)init NS_UNAVAILABLE;
+ (instancetype)new NS_UNAVAILABLE;
/*!
@abstract Initializes a new instance.
@param tokenString the opaque token string.
@param permissions the granted permissions. Note this is converted to NSSet and is only
/**
Initializes a new instance.
- Parameter tokenString: the opaque token string.
- Parameter permissions: the granted permissions. Note this is converted to NSSet and is only
an NSArray for the convenience of literal syntax.
@param declinedPermissions the declined permissions. Note this is converted to NSSet and is only
- Parameter declinedPermissions: the declined permissions. Note this is converted to NSSet and is only
an NSArray for the convenience of literal syntax.
@param appID the app ID.
@param userID the user ID.
@param expirationDate the optional expiration date (defaults to distantFuture).
@param refreshDate the optional date the token was last refreshed (defaults to today).
@discussion This initializer should only be used for advanced apps that
- Parameter appID: the app ID.
- Parameter userID: the user ID.
- Parameter expirationDate: the optional expiration date (defaults to distantFuture).
- Parameter refreshDate: the optional date the token was last refreshed (defaults to today).
This initializer should only be used for advanced apps that
manage tokens explicitly. Typical login flows only need to use `FBSDKLoginManager`
along with `+currentAccessToken`.
*/
@ -125,38 +129,41 @@ FBSDK_EXTERN NSString *const FBSDKAccessTokenChangeNewKey;
refreshDate:(NSDate *)refreshDate
NS_DESIGNATED_INITIALIZER;
/*!
@abstract Convenience getter to determine if a permission has been granted
@param permission The permission to check.
/**
Convenience getter to determine if a permission has been granted
- Parameter permission: The permission to check.
*/
- (BOOL)hasGranted:(NSString *)permission;
/*!
@abstract Compares the receiver to another FBSDKAccessToken
@param token The other token
@return YES if the receiver's values are equal to the other token's values; otherwise NO
/**
Compares the receiver to another FBSDKAccessToken
- Parameter token: The other token
- Returns: YES if the receiver's values are equal to the other token's values; otherwise NO
*/
- (BOOL)isEqualToAccessToken:(FBSDKAccessToken *)token;
/*!
@abstract Returns the "global" access token that represents the currently logged in user.
@discussion The `currentAccessToken` is a convenient representation of the token of the
/**
Returns the "global" access token that represents the currently logged in user.
The `currentAccessToken` is a convenient representation of the token of the
current user and is used by other SDK components (like `FBSDKLoginManager`).
*/
+ (FBSDKAccessToken *)currentAccessToken;
/*!
@abstract Sets the "global" access token that represents the currently logged in user.
@param token The access token to set.
@discussion This will broadcast a notification and save the token to the app keychain.
/**
Sets the "global" access token that represents the currently logged in user.
- Parameter token: The access token to set.
This will broadcast a notification and save the token to the app keychain.
*/
+ (void)setCurrentAccessToken:(FBSDKAccessToken *)token;
/*!
@abstract Refresh the current access token's permission state and extend the token's expiration date,
/**
Refresh the current access token's permission state and extend the token's expiration date,
if possible.
@param completionHandler an optional callback handler that can surface any errors related to permission refreshing.
@discussion On a successful refresh, the currentAccessToken will be updated so you typically only need to
- Parameter completionHandler: an optional callback handler that can surface any errors related to permission refreshing.
On a successful refresh, the currentAccessToken will be updated so you typically only need to
observe the `FBSDKAccessTokenDidChangeNotification` notification.
If a token is already expired, it cannot be refreshed.

View File

@ -88,7 +88,7 @@ static FBSDKAccessToken *g_currentAccessToken;
g_currentAccessToken = token;
// Only need to keep current session in web view for the case when token is current
// When token is abandoned cookies must to be cleaned up immediatelly
// When token is abandoned cookies must to be cleaned up immediately
if (token == nil) {
[FBSDKInternalUtility deleteFacebookCookies];
}

Some files were not shown because too many files have changed in this diff Show More