Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Merge branch 'CL-148' into CL-151

Conflicts:
	objective-c/3.3/Pubnub/PubNub/CEPubnub.m
  • Loading branch information...
commit a0888fdfb95aa7ae94154a79b6a28a64df367e89 2 parents d8a4eaa + a6396f3
geremy cohen authored
Showing with 5,991 additions and 9 deletions.
  1. +11 −1 objective-c/3.3/Pubnub/PubNub/CEPubnub.m
  2. +328 −0 objective-c/3.3/PubnubTest/PubnubTest.xcodeproj/project.pbxproj
  3. +7 −0 objective-c/3.3/PubnubTest/PubnubTest.xcodeproj/project.xcworkspace/contents.xcworkspacedata
  4. BIN  ...t/PubnubTest.xcodeproj/project.xcworkspace/xcuserdata/dahiwadkar.xcuserdatad/UserInterfaceState.xcuserstate
  5. +5 −0 ...e-c/3.3/PubnubTest/PubnubTest.xcodeproj/xcuserdata/dahiwadkar.xcuserdatad/xcdebugger/Breakpoints.xcbkptlist
  6. +95 −0 ...ctive-c/3.3/PubnubTest/PubnubTest.xcodeproj/xcuserdata/dahiwadkar.xcuserdatad/xcschemes/PubnubTest.xcscheme
  7. +27 −0 ...-c/3.3/PubnubTest/PubnubTest.xcodeproj/xcuserdata/dahiwadkar.xcuserdatad/xcschemes/xcschememanagement.plist
  8. +15 −0 objective-c/3.3/PubnubTest/PubnubTest/AppDelegate.h
  9. +50 −0 objective-c/3.3/PubnubTest/PubnubTest/AppDelegate.m
  10. +23 −0 objective-c/3.3/PubnubTest/PubnubTest/PubNub/Base64.h
  11. +97 −0 objective-c/3.3/PubnubTest/PubnubTest/PubNub/Base64.m
  12. +102 −0 objective-c/3.3/PubnubTest/PubnubTest/PubNub/CEPubnub.h
  13. +903 −0 objective-c/3.3/PubnubTest/PubnubTest/PubNub/CEPubnub.m
  14. +21 −0 objective-c/3.3/PubnubTest/PubnubTest/PubNub/Cipher.h
  15. +107 −0 objective-c/3.3/PubnubTest/PubnubTest/PubNub/Cipher.m
  16. +26 −0 objective-c/3.3/PubnubTest/PubnubTest/PubNub/Common.h
  17. +110 −0 objective-c/3.3/PubnubTest/PubnubTest/PubNub/Common.m
  18. +32 −0 objective-c/3.3/PubnubTest/PubnubTest/PubNub/JSON.h
  19. +94 −0 objective-c/3.3/PubnubTest/PubnubTest/PubNub/JSON.m
  20. +251 −0 objective-c/3.3/PubnubTest/PubnubTest/PubNub/JSONKit.h
  21. +3,111 −0 objective-c/3.3/PubnubTest/PubnubTest/PubNub/JSONKit.m
  22. +40 −0 objective-c/3.3/PubnubTest/PubnubTest/PubnubTest-Info.plist
  23. +15 −0 objective-c/3.3/PubnubTest/PubnubTest/PubnubTest-Prefix.pch
  24. +16 −0 objective-c/3.3/PubnubTest/PubnubTest/ViewController.h
  25. +391 −0 objective-c/3.3/PubnubTest/PubnubTest/ViewController.m
  26. +2 −0  objective-c/3.3/PubnubTest/PubnubTest/en.lproj/InfoPlist.strings
  27. +68 −0 objective-c/3.3/PubnubTest/PubnubTest/en.lproj/MainStoryboard.storyboard
  28. +18 −0 objective-c/3.3/PubnubTest/PubnubTest/main.m
  29. +13 −1 objective-c/README.md
  30. +13 −7 python/README
View
12 objective-c/3.3/Pubnub/PubNub/CEPubnub.m
@@ -557,7 +557,9 @@ - (void) detailedHistory:(NSDictionary * )arg1 {
if ([parameters length] > 0) {
[parameters insertString:@"?" atIndex:0 ];
}
+
[CommonFunction Log: [NSString stringWithFormat:@"In detailedHistory with channel:%@",channel]];
+
NSString* url = [NSString stringWithFormat:@"%@/v2/history/sub-key/%@/channel/%@%@", _host, _subscribeKey, [channel urlEscapedString],[parameters description]];
PubNubConnection* connection = [[PubNubConnection alloc] initWithPubNub:self
url:[NSURL URLWithString:url]
@@ -722,6 +724,7 @@ - (void) connection:(PubNubConnection*)connection didCompleteWithResponse:(id)re
if ([it.channel isEqualToString:connection.channel])
{
[CommonFunction Log:@"In didCompleteWithResponse Test for discnnecting call "];
+
if(it.first && it.connected) {
it.connected=NO;
if ([_delegate respondsToSelector:@selector(pubnub:DisconnectToChannel:)]) {
@@ -737,7 +740,9 @@ - (void) connection:(PubNubConnection*)connection didCompleteWithResponse:(id)re
}else
{
+
[CommonFunction Log:@"In didCompleteWithResponse reconnect call "];
+
if ([_delegate respondsToSelector:@selector(pubnub:Re_ConnectToChannel:)]) {
[_delegate pubnub:self Re_ConnectToChannel:connection.channel];
}
@@ -841,8 +846,9 @@ - (void) connection:(PubNubConnection*)connection didCompleteWithResponse:(id)re
[mainArray addObject:str];
}
}
+
[CommonFunction Log:@"In didCompleteWithResponse FetchDetailHistory "];
- [returnArray replaceObjectAtIndex:0 withObject:mainArray];
+ [returnArray replaceObjectAtIndex:0 withObject:mainArray];
}else if (response) {
NSLog(@"Unexpected history response from PubNub");
@@ -850,12 +856,16 @@ - (void) connection:(PubNubConnection*)connection didCompleteWithResponse:(id)re
if(response)
{
+
[CommonFunction Log:@"In didCompleteWithResponse Sucess FetchDetailHistory "];
+
if ([_delegate respondsToSelector: @selector(pubnub:didFetchDetailedHistory:forChannel:)]) {
[_delegate pubnub:self didFetchDetailedHistory: [NSArray arrayWithArray: returnArray] forChannel: connection.channel];
}
}else {
+
[CommonFunction Log:@"In didCompleteWithResponse Fail FetchDetailHistory "];
+
NSArray* array= [NSArray arrayWithObjects:@"0", @"Fetch History request failed due to missing Internet connection", nil];
if ([_delegate respondsToSelector: @selector(pubnub:didFailFetchDetailedHistoryOnChannel:withError:)]) {
[_delegate pubnub:self didFailFetchDetailedHistoryOnChannel:connection.channel withError:array];
View
328 objective-c/3.3/PubnubTest/PubnubTest.xcodeproj/project.pbxproj
@@ -0,0 +1,328 @@
+// !$*UTF8*$!
+{
+ archiveVersion = 1;
+ classes = {
+ };
+ objectVersion = 46;
+ objects = {
+
+/* Begin PBXBuildFile section */
+ C8F6538915B98D2C008535CE /* Base64.m in Sources */ = {isa = PBXBuildFile; fileRef = C8F6537C15B98D2C008535CE /* Base64.m */; };
+ C8F6538A15B98D2C008535CE /* CEPubnub.m in Sources */ = {isa = PBXBuildFile; fileRef = C8F6537E15B98D2C008535CE /* CEPubnub.m */; };
+ C8F6538B15B98D2C008535CE /* Cipher.m in Sources */ = {isa = PBXBuildFile; fileRef = C8F6538015B98D2C008535CE /* Cipher.m */; };
+ C8F6538C15B98D2C008535CE /* Common.m in Sources */ = {isa = PBXBuildFile; fileRef = C8F6538215B98D2C008535CE /* Common.m */; };
+ C8F6538D15B98D2C008535CE /* JSON.m in Sources */ = {isa = PBXBuildFile; fileRef = C8F6538415B98D2C008535CE /* JSON.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
+ C8F6538E15B98D2C008535CE /* JSONKit.m in Sources */ = {isa = PBXBuildFile; fileRef = C8F6538615B98D2C008535CE /* JSONKit.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
+ C8FD6F4B15B93F9C00A299E6 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C8FD6F4A15B93F9B00A299E6 /* UIKit.framework */; };
+ C8FD6F4D15B93F9C00A299E6 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C8FD6F4C15B93F9C00A299E6 /* Foundation.framework */; };
+ C8FD6F4F15B93F9C00A299E6 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C8FD6F4E15B93F9C00A299E6 /* CoreGraphics.framework */; };
+ C8FD6F5515B93F9C00A299E6 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = C8FD6F5315B93F9C00A299E6 /* InfoPlist.strings */; };
+ C8FD6F5715B93F9C00A299E6 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = C8FD6F5615B93F9C00A299E6 /* main.m */; };
+ C8FD6F5B15B93F9C00A299E6 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = C8FD6F5A15B93F9C00A299E6 /* AppDelegate.m */; };
+ C8FD6F5E15B93F9C00A299E6 /* MainStoryboard.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = C8FD6F5C15B93F9C00A299E6 /* MainStoryboard.storyboard */; };
+ C8FD6F6115B93F9C00A299E6 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = C8FD6F6015B93F9C00A299E6 /* ViewController.m */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXFileReference section */
+ C8F6537B15B98D2C008535CE /* Base64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Base64.h; sourceTree = "<group>"; };
+ C8F6537C15B98D2C008535CE /* Base64.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Base64.m; sourceTree = "<group>"; };
+ C8F6537D15B98D2C008535CE /* CEPubnub.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CEPubnub.h; sourceTree = "<group>"; };
+ C8F6537E15B98D2C008535CE /* CEPubnub.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CEPubnub.m; sourceTree = "<group>"; };
+ C8F6537F15B98D2C008535CE /* Cipher.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Cipher.h; sourceTree = "<group>"; };
+ C8F6538015B98D2C008535CE /* Cipher.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Cipher.m; sourceTree = "<group>"; };
+ C8F6538115B98D2C008535CE /* Common.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Common.h; sourceTree = "<group>"; };
+ C8F6538215B98D2C008535CE /* Common.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Common.m; sourceTree = "<group>"; };
+ C8F6538315B98D2C008535CE /* JSON.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSON.h; sourceTree = "<group>"; };
+ C8F6538415B98D2C008535CE /* JSON.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = JSON.m; sourceTree = "<group>"; };
+ C8F6538515B98D2C008535CE /* JSONKit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSONKit.h; sourceTree = "<group>"; };
+ C8F6538615B98D2C008535CE /* JSONKit.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = JSONKit.m; sourceTree = "<group>"; };
+ C8FD6F4615B93F9B00A299E6 /* PubnubTest.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = PubnubTest.app; sourceTree = BUILT_PRODUCTS_DIR; };
+ C8FD6F4A15B93F9B00A299E6 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };
+ C8FD6F4C15B93F9C00A299E6 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
+ C8FD6F4E15B93F9C00A299E6 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; };
+ C8FD6F5215B93F9C00A299E6 /* PubnubTest-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "PubnubTest-Info.plist"; sourceTree = "<group>"; };
+ C8FD6F5415B93F9C00A299E6 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = "<group>"; };
+ C8FD6F5615B93F9C00A299E6 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
+ C8FD6F5815B93F9C00A299E6 /* PubnubTest-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "PubnubTest-Prefix.pch"; sourceTree = "<group>"; };
+ C8FD6F5915B93F9C00A299E6 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; };
+ C8FD6F5A15B93F9C00A299E6 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; };
+ C8FD6F5D15B93F9C00A299E6 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = en; path = en.lproj/MainStoryboard.storyboard; sourceTree = "<group>"; };
+ C8FD6F5F15B93F9C00A299E6 /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = "<group>"; };
+ C8FD6F6015B93F9C00A299E6 /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = "<group>"; };
+ C8FD6F6815B93F9D00A299E6 /* SenTestingKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SenTestingKit.framework; path = Library/Frameworks/SenTestingKit.framework; sourceTree = DEVELOPER_DIR; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+ C8FD6F4315B93F9B00A299E6 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ C8FD6F4B15B93F9C00A299E6 /* UIKit.framework in Frameworks */,
+ C8FD6F4D15B93F9C00A299E6 /* Foundation.framework in Frameworks */,
+ C8FD6F4F15B93F9C00A299E6 /* CoreGraphics.framework in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+ C8F6537A15B98D2C008535CE /* PubNub */ = {
+ isa = PBXGroup;
+ children = (
+ C8F6537B15B98D2C008535CE /* Base64.h */,
+ C8F6537C15B98D2C008535CE /* Base64.m */,
+ C8F6537D15B98D2C008535CE /* CEPubnub.h */,
+ C8F6537E15B98D2C008535CE /* CEPubnub.m */,
+ C8F6537F15B98D2C008535CE /* Cipher.h */,
+ C8F6538015B98D2C008535CE /* Cipher.m */,
+ C8F6538115B98D2C008535CE /* Common.h */,
+ C8F6538215B98D2C008535CE /* Common.m */,
+ C8F6538315B98D2C008535CE /* JSON.h */,
+ C8F6538415B98D2C008535CE /* JSON.m */,
+ C8F6538515B98D2C008535CE /* JSONKit.h */,
+ C8F6538615B98D2C008535CE /* JSONKit.m */,
+ );
+ path = PubNub;
+ sourceTree = "<group>";
+ };
+ C8FD6F3B15B93F9A00A299E6 = {
+ isa = PBXGroup;
+ children = (
+ C8FD6F5015B93F9C00A299E6 /* PubnubTest */,
+ C8FD6F4915B93F9B00A299E6 /* Frameworks */,
+ C8FD6F4715B93F9B00A299E6 /* Products */,
+ );
+ sourceTree = "<group>";
+ };
+ C8FD6F4715B93F9B00A299E6 /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ C8FD6F4615B93F9B00A299E6 /* PubnubTest.app */,
+ );
+ name = Products;
+ sourceTree = "<group>";
+ };
+ C8FD6F4915B93F9B00A299E6 /* Frameworks */ = {
+ isa = PBXGroup;
+ children = (
+ C8FD6F4A15B93F9B00A299E6 /* UIKit.framework */,
+ C8FD6F4C15B93F9C00A299E6 /* Foundation.framework */,
+ C8FD6F4E15B93F9C00A299E6 /* CoreGraphics.framework */,
+ C8FD6F6815B93F9D00A299E6 /* SenTestingKit.framework */,
+ );
+ name = Frameworks;
+ sourceTree = "<group>";
+ };
+ C8FD6F5015B93F9C00A299E6 /* PubnubTest */ = {
+ isa = PBXGroup;
+ children = (
+ C8F6537A15B98D2C008535CE /* PubNub */,
+ C8FD6F5915B93F9C00A299E6 /* AppDelegate.h */,
+ C8FD6F5A15B93F9C00A299E6 /* AppDelegate.m */,
+ C8FD6F5C15B93F9C00A299E6 /* MainStoryboard.storyboard */,
+ C8FD6F5F15B93F9C00A299E6 /* ViewController.h */,
+ C8FD6F6015B93F9C00A299E6 /* ViewController.m */,
+ C8FD6F5115B93F9C00A299E6 /* Supporting Files */,
+ );
+ path = PubnubTest;
+ sourceTree = "<group>";
+ };
+ C8FD6F5115B93F9C00A299E6 /* Supporting Files */ = {
+ isa = PBXGroup;
+ children = (
+ C8FD6F5215B93F9C00A299E6 /* PubnubTest-Info.plist */,
+ C8FD6F5315B93F9C00A299E6 /* InfoPlist.strings */,
+ C8FD6F5615B93F9C00A299E6 /* main.m */,
+ C8FD6F5815B93F9C00A299E6 /* PubnubTest-Prefix.pch */,
+ );
+ name = "Supporting Files";
+ sourceTree = "<group>";
+ };
+/* End PBXGroup section */
+
+/* Begin PBXNativeTarget section */
+ C8FD6F4515B93F9B00A299E6 /* PubnubTest */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = C8FD6F7915B93F9D00A299E6 /* Build configuration list for PBXNativeTarget "PubnubTest" */;
+ buildPhases = (
+ C8FD6F4215B93F9B00A299E6 /* Sources */,
+ C8FD6F4315B93F9B00A299E6 /* Frameworks */,
+ C8FD6F4415B93F9B00A299E6 /* Resources */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = PubnubTest;
+ productName = PubnubTest;
+ productReference = C8FD6F4615B93F9B00A299E6 /* PubnubTest.app */;
+ productType = "com.apple.product-type.application";
+ };
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+ C8FD6F3D15B93F9A00A299E6 /* Project object */ = {
+ isa = PBXProject;
+ attributes = {
+ LastUpgradeCheck = 0430;
+ };
+ buildConfigurationList = C8FD6F4015B93F9A00A299E6 /* Build configuration list for PBXProject "PubnubTest" */;
+ compatibilityVersion = "Xcode 3.2";
+ developmentRegion = English;
+ hasScannedForEncodings = 0;
+ knownRegions = (
+ en,
+ );
+ mainGroup = C8FD6F3B15B93F9A00A299E6;
+ productRefGroup = C8FD6F4715B93F9B00A299E6 /* Products */;
+ projectDirPath = "";
+ projectRoot = "";
+ targets = (
+ C8FD6F4515B93F9B00A299E6 /* PubnubTest */,
+ );
+ };
+/* End PBXProject section */
+
+/* Begin PBXResourcesBuildPhase section */
+ C8FD6F4415B93F9B00A299E6 /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ C8FD6F5515B93F9C00A299E6 /* InfoPlist.strings in Resources */,
+ C8FD6F5E15B93F9C00A299E6 /* MainStoryboard.storyboard in Resources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXResourcesBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+ C8FD6F4215B93F9B00A299E6 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ C8FD6F5715B93F9C00A299E6 /* main.m in Sources */,
+ C8FD6F5B15B93F9C00A299E6 /* AppDelegate.m in Sources */,
+ C8FD6F6115B93F9C00A299E6 /* ViewController.m in Sources */,
+ C8F6538915B98D2C008535CE /* Base64.m in Sources */,
+ C8F6538A15B98D2C008535CE /* CEPubnub.m in Sources */,
+ C8F6538B15B98D2C008535CE /* Cipher.m in Sources */,
+ C8F6538C15B98D2C008535CE /* Common.m in Sources */,
+ C8F6538D15B98D2C008535CE /* JSON.m in Sources */,
+ C8F6538E15B98D2C008535CE /* JSONKit.m in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXSourcesBuildPhase section */
+
+/* Begin PBXVariantGroup section */
+ C8FD6F5315B93F9C00A299E6 /* InfoPlist.strings */ = {
+ isa = PBXVariantGroup;
+ children = (
+ C8FD6F5415B93F9C00A299E6 /* en */,
+ );
+ name = InfoPlist.strings;
+ sourceTree = "<group>";
+ };
+ C8FD6F5C15B93F9C00A299E6 /* MainStoryboard.storyboard */ = {
+ isa = PBXVariantGroup;
+ children = (
+ C8FD6F5D15B93F9C00A299E6 /* en */,
+ );
+ name = MainStoryboard.storyboard;
+ sourceTree = "<group>";
+ };
+/* End PBXVariantGroup section */
+
+/* Begin XCBuildConfiguration section */
+ C8FD6F7715B93F9D00A299E6 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ ARCHS = "$(ARCHS_STANDARD_32_BIT)";
+ CLANG_ENABLE_OBJC_ARC = YES;
+ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+ COPY_PHASE_STRIP = NO;
+ GCC_C_LANGUAGE_STANDARD = gnu99;
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PREPROCESSOR_DEFINITIONS = (
+ "DEBUG=1",
+ "$(inherited)",
+ );
+ GCC_SYMBOLS_PRIVATE_EXTERN = NO;
+ GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ IPHONEOS_DEPLOYMENT_TARGET = 5.0;
+ SDKROOT = iphoneos;
+ };
+ name = Debug;
+ };
+ C8FD6F7815B93F9D00A299E6 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ ARCHS = "$(ARCHS_STANDARD_32_BIT)";
+ CLANG_ENABLE_OBJC_ARC = YES;
+ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+ COPY_PHASE_STRIP = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu99;
+ GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ IPHONEOS_DEPLOYMENT_TARGET = 5.0;
+ OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1";
+ SDKROOT = iphoneos;
+ VALIDATE_PRODUCT = YES;
+ };
+ name = Release;
+ };
+ C8FD6F7A15B93F9D00A299E6 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ GCC_PRECOMPILE_PREFIX_HEADER = YES;
+ GCC_PREFIX_HEADER = "PubnubTest/PubnubTest-Prefix.pch";
+ INFOPLIST_FILE = "PubnubTest/PubnubTest-Info.plist";
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ WRAPPER_EXTENSION = app;
+ };
+ name = Debug;
+ };
+ C8FD6F7B15B93F9D00A299E6 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ GCC_PRECOMPILE_PREFIX_HEADER = YES;
+ GCC_PREFIX_HEADER = "PubnubTest/PubnubTest-Prefix.pch";
+ INFOPLIST_FILE = "PubnubTest/PubnubTest-Info.plist";
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ WRAPPER_EXTENSION = app;
+ };
+ name = Release;
+ };
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+ C8FD6F4015B93F9A00A299E6 /* Build configuration list for PBXProject "PubnubTest" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ C8FD6F7715B93F9D00A299E6 /* Debug */,
+ C8FD6F7815B93F9D00A299E6 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ C8FD6F7915B93F9D00A299E6 /* Build configuration list for PBXNativeTarget "PubnubTest" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ C8FD6F7A15B93F9D00A299E6 /* Debug */,
+ C8FD6F7B15B93F9D00A299E6 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+/* End XCConfigurationList section */
+ };
+ rootObject = C8FD6F3D15B93F9A00A299E6 /* Project object */;
+}
View
7 objective-c/3.3/PubnubTest/PubnubTest.xcodeproj/project.xcworkspace/contents.xcworkspacedata
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Workspace
+ version = "1.0">
+ <FileRef
+ location = "self:PubnubTest.xcodeproj">
+ </FileRef>
+</Workspace>
View
BIN  ...proj/project.xcworkspace/xcuserdata/dahiwadkar.xcuserdatad/UserInterfaceState.xcuserstate
Binary file not shown
View
5 .../PubnubTest.xcodeproj/xcuserdata/dahiwadkar.xcuserdatad/xcdebugger/Breakpoints.xcbkptlist
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Bucket
+ type = "1"
+ version = "1.0">
+</Bucket>
View
95 ...Test/PubnubTest.xcodeproj/xcuserdata/dahiwadkar.xcuserdatad/xcschemes/PubnubTest.xcscheme
@@ -0,0 +1,95 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Scheme
+ version = "1.3">
+ <BuildAction
+ parallelizeBuildables = "YES"
+ buildImplicitDependencies = "YES">
+ <BuildActionEntries>
+ <BuildActionEntry
+ buildForTesting = "YES"
+ buildForRunning = "YES"
+ buildForProfiling = "YES"
+ buildForArchiving = "YES"
+ buildForAnalyzing = "YES">
+ <BuildableReference
+ BuildableIdentifier = "primary"
+ BlueprintIdentifier = "C8FD6F4515B93F9B00A299E6"
+ BuildableName = "PubnubTest.app"
+ BlueprintName = "PubnubTest"
+ ReferencedContainer = "container:PubnubTest.xcodeproj">
+ </BuildableReference>
+ </BuildActionEntry>
+ </BuildActionEntries>
+ </BuildAction>
+ <TestAction
+ selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
+ selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
+ shouldUseLaunchSchemeArgsEnv = "YES"
+ buildConfiguration = "Debug">
+ <Testables>
+ <TestableReference
+ skipped = "NO">
+ <BuildableReference
+ BuildableIdentifier = "primary"
+ BlueprintIdentifier = "C8FD6F6615B93F9D00A299E6"
+ BuildableName = "PubnubTestTests.octest"
+ BlueprintName = "PubnubTestTests"
+ ReferencedContainer = "container:PubnubTest.xcodeproj">
+ </BuildableReference>
+ </TestableReference>
+ </Testables>
+ <MacroExpansion>
+ <BuildableReference
+ BuildableIdentifier = "primary"
+ BlueprintIdentifier = "C8FD6F4515B93F9B00A299E6"
+ BuildableName = "PubnubTest.app"
+ BlueprintName = "PubnubTest"
+ ReferencedContainer = "container:PubnubTest.xcodeproj">
+ </BuildableReference>
+ </MacroExpansion>
+ </TestAction>
+ <LaunchAction
+ selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
+ selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
+ launchStyle = "0"
+ useCustomWorkingDirectory = "NO"
+ buildConfiguration = "Debug"
+ ignoresPersistentStateOnLaunch = "NO"
+ debugDocumentVersioning = "YES"
+ allowLocationSimulation = "YES">
+ <BuildableProductRunnable>
+ <BuildableReference
+ BuildableIdentifier = "primary"
+ BlueprintIdentifier = "C8FD6F4515B93F9B00A299E6"
+ BuildableName = "PubnubTest.app"
+ BlueprintName = "PubnubTest"
+ ReferencedContainer = "container:PubnubTest.xcodeproj">
+ </BuildableReference>
+ </BuildableProductRunnable>
+ <AdditionalOptions>
+ </AdditionalOptions>
+ </LaunchAction>
+ <ProfileAction
+ shouldUseLaunchSchemeArgsEnv = "YES"
+ savedToolIdentifier = ""
+ useCustomWorkingDirectory = "NO"
+ buildConfiguration = "Release"
+ debugDocumentVersioning = "YES">
+ <BuildableProductRunnable>
+ <BuildableReference
+ BuildableIdentifier = "primary"
+ BlueprintIdentifier = "C8FD6F4515B93F9B00A299E6"
+ BuildableName = "PubnubTest.app"
+ BlueprintName = "PubnubTest"
+ ReferencedContainer = "container:PubnubTest.xcodeproj">
+ </BuildableReference>
+ </BuildableProductRunnable>
+ </ProfileAction>
+ <AnalyzeAction
+ buildConfiguration = "Debug">
+ </AnalyzeAction>
+ <ArchiveAction
+ buildConfiguration = "Release"
+ revealArchiveInOrganizer = "YES">
+ </ArchiveAction>
+</Scheme>
View
27 ...PubnubTest.xcodeproj/xcuserdata/dahiwadkar.xcuserdatad/xcschemes/xcschememanagement.plist
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>SchemeUserState</key>
+ <dict>
+ <key>PubnubTest.xcscheme</key>
+ <dict>
+ <key>orderHint</key>
+ <integer>0</integer>
+ </dict>
+ </dict>
+ <key>SuppressBuildableAutocreation</key>
+ <dict>
+ <key>C8FD6F4515B93F9B00A299E6</key>
+ <dict>
+ <key>primary</key>
+ <true/>
+ </dict>
+ <key>C8FD6F6615B93F9D00A299E6</key>
+ <dict>
+ <key>primary</key>
+ <true/>
+ </dict>
+ </dict>
+</dict>
+</plist>
View
15 objective-c/3.3/PubnubTest/PubnubTest/AppDelegate.h
@@ -0,0 +1,15 @@
+//
+// AppDelegate.h
+//
+//
+// Created by itshastra on 20/07/12.
+// Copyright (c) 2012 __MyCompanyName__. All rights reserved.
+//
+
+#import <UIKit/UIKit.h>
+
+@interface AppDelegate : UIResponder <UIApplicationDelegate>
+
+@property (strong, nonatomic) UIWindow *window;
+
+@end
View
50 objective-c/3.3/PubnubTest/PubnubTest/AppDelegate.m
@@ -0,0 +1,50 @@
+//
+// AppDelegate.m
+//
+//
+// Created by itshastra on 20/07/12.
+// Copyright (c) 2012 __MyCompanyName__. All rights reserved.
+//
+
+#import "AppDelegate.h"
+
+@implementation AppDelegate
+
+@synthesize window = _window;
+
+
+
+- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
+{
+ // Override point for customization after application launch.
+ return YES;
+}
+
+- (void)applicationWillResignActive:(UIApplication *)application
+{
+ // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
+ // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
+}
+
+- (void)applicationDidEnterBackground:(UIApplication *)application
+{
+ // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
+ // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
+}
+
+- (void)applicationWillEnterForeground:(UIApplication *)application
+{
+ // 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
+{
+ // 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
+{
+ // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
+}
+
+@end
View
23 objective-c/3.3/PubnubTest/PubnubTest/PubNub/Base64.h
@@ -0,0 +1,23 @@
+//
+// Base64.h
+// CryptTest
+//
+// Created by Kiichi Takeuchi on 4/20/10.
+// Copyright 2010 ObjectGraph LLC. All rights reserved.
+//
+// Original Source Code is donated by Cyrus
+// Public Domain License
+// http://www.cocoadev.com/index.pl?BaseSixtyFour
+
+#import <Foundation/Foundation.h>
+
+
+@interface Base64 : NSObject {
+
+}
++ (void) initialize;
++ (NSString*) encode:(const uint8_t*) input length:(NSInteger) length;
++ (NSString*) encode:(NSData*) rawBytes;
++ (NSData*) decode:(const char*) string length:(NSInteger) inputLength;
++ (NSData*) decode:(NSString*) string;
+@end
View
97 objective-c/3.3/PubnubTest/PubnubTest/PubNub/Base64.m
@@ -0,0 +1,97 @@
+//
+// Base64.m
+// CryptTest
+//
+// Created by Kiichi Takeuchi on 4/20/10.
+// Copyright 2010 ObjectGraph LLC. All rights reserved.
+//
+
+#import "Base64.h"
+
+
+@implementation Base64
+#define ArrayLength(x) (sizeof(x)/sizeof(*(x)))
+
+static char encodingTable[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+static char decodingTable[128];
+
++ (void) initialize {
+ if (self == [Base64 class]) {
+ memset(decodingTable, 0, ArrayLength(decodingTable));
+ for (NSInteger i = 0; i < ArrayLength(encodingTable); i++) {
+ decodingTable[encodingTable[i]] = i;
+ }
+ }
+}
+
+
++ (NSString*) encode:(const uint8_t*) input length:(NSInteger) length {
+ NSMutableData* data = [NSMutableData dataWithLength:((length + 2) / 3) * 4];
+ uint8_t* output = (uint8_t*)data.mutableBytes;
+
+ for (NSInteger i = 0; i < length; i += 3) {
+ NSInteger value = 0;
+ for (NSInteger j = i; j < (i + 3); j++) {
+ value <<= 8;
+
+ if (j < length) {
+ value |= (0xFF & input[j]);
+ }
+ }
+
+ NSInteger index = (i / 3) * 4;
+ output[index + 0] = encodingTable[(value >> 18) & 0x3F];
+ output[index + 1] = encodingTable[(value >> 12) & 0x3F];
+ output[index + 2] = (i + 1) < length ? encodingTable[(value >> 6) & 0x3F] : '=';
+ output[index + 3] = (i + 2) < length ? encodingTable[(value >> 0) & 0x3F] : '=';
+ }
+
+ return [[NSString alloc] initWithData:data
+ encoding:NSASCIIStringEncoding] ;
+}
+
+
++ (NSString*) encode:(NSData*) rawBytes {
+ return [self encode:(const uint8_t*) rawBytes.bytes length:rawBytes.length];
+}
+
+
++ (NSData*) decode:(const char*) string length:(NSInteger) inputLength {
+ if ((string == NULL) || (inputLength % 4 != 0)) {
+ return nil;
+ }
+
+ while (inputLength > 0 && string[inputLength - 1] == '=') {
+ inputLength--;
+ }
+
+ NSInteger outputLength = inputLength * 3 / 4;
+ NSMutableData* data = [NSMutableData dataWithLength:outputLength];
+ uint8_t* output = data.mutableBytes;
+
+ NSInteger inputPoint = 0;
+ NSInteger outputPoint = 0;
+ while (inputPoint < inputLength) {
+ char i0 = string[inputPoint++];
+ char i1 = string[inputPoint++];
+ char i2 = inputPoint < inputLength ? string[inputPoint++] : 'A'; /* 'A' will decode to \0 */
+ char i3 = inputPoint < inputLength ? string[inputPoint++] : 'A';
+
+ output[outputPoint++] = (decodingTable[i0] << 2) | (decodingTable[i1] >> 4);
+ if (outputPoint < outputLength) {
+ output[outputPoint++] = ((decodingTable[i1] & 0xf) << 4) | (decodingTable[i2] >> 2);
+ }
+ if (outputPoint < outputLength) {
+ output[outputPoint++] = ((decodingTable[i2] & 0x3) << 6) | decodingTable[i3];
+ }
+ }
+
+ return data;
+}
+
+
++ (NSData*) decode:(NSString*) string {
+ return [self decode:[string cStringUsingEncoding:NSASCIIStringEncoding] length:string.length];
+}
+
+@end
View
102 objective-c/3.3/PubnubTest/PubnubTest/PubNub/CEPubnub.h
@@ -0,0 +1,102 @@
+ // Copyright 2011 Cooliris, Inc.
+ //
+ // Licensed under the Apache License, Version 2.0 (the "License");
+ // you may not use this file except in compliance with the License.
+ // You may obtain a copy of the License at
+ //
+ // http://www.apache.org/licenses/LICENSE-2.0
+ //
+ // Unless required by applicable law or agreed to in writing, software
+ // distributed under the License is distributed on an "AS IS" BASIS,
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ // See the License for the specific language governing permissions and
+ // limitations under the License.
+
+#import <Foundation/Foundation.h>
+
+@class CEPubnub;
+
+@protocol CEPubnubDelegate <NSObject>
+@optional
+- (void) pubnub:(CEPubnub*)pubnub didSucceedPublishingMessageToChannel:(NSString*)channel withResponce: (id)responce message:(id)message;
+- (void) pubnub:(CEPubnub*)pubnub didFailPublishingMessageToChannel:(NSString*)channel error:(NSString*)error message:(id)message; // "error" may be nil
+
+ //- (void) pubnub:(PubNub*)pubnub didReceiveMessage:(NSDictionary*)message onChannel:(NSString*)channel;
+
+- (void)pubnub:(CEPubnub *)pubnub subscriptionDidReceiveDictionary:(NSDictionary *)message onChannel:(NSString *)channel;
+- (void)pubnub:(CEPubnub *)pubnub subscriptionDidReceiveArray:(NSArray *)message onChannel:(NSString *)channel;
+- (void)pubnub:(CEPubnub *)pubnub subscriptionDidReceiveString:(NSString *)message onChannel:(NSString *)channel;
+- (void)pubnub:(CEPubnub *)pubnub subscriptionDidFailWithResponse:(NSString *)message onChannel:(NSString *)channel;
+
+- (void) pubnub:(CEPubnub*)pubnub didFetchHistory:(NSArray*)messages forChannel:(NSString*)channel;
+- (void) pubnub:(CEPubnub*)pubnub didFailFetchHistoryOnChannel:(NSString*)channel withError:(id)error;
+
+- (void) pubnub:(CEPubnub*)pubnub didFetchDetailedHistory:(NSArray*)messages forChannel:(NSString*)channel;
+- (void) pubnub:(CEPubnub*)pubnub didFailFetchDetailedHistoryOnChannel:(NSString*)channel withError:(id)error;
+
+- (void) pubnub:(CEPubnub*)pubnub didReceiveTime:(NSTimeInterval)time; // "time" will be NAN on failure
+
+- (void) pubnub:(CEPubnub*)pubnub ConnectToChannel:(NSString*)channel ;
+- (void) pubnub:(CEPubnub*)pubnub DisconnectToChannel:(NSString*)channel ;
+- (void) pubnub:(CEPubnub*)pubnub Re_ConnectToChannel:(NSString*)channel ;
+
+- (void)pubnub:(CEPubnub *)pubnub presence:(NSDictionary *)message onChannel:(NSString *)channel;
+
+- (void)pubnub:(CEPubnub *)pubnub here_now:(NSDictionary *)message onChannel:(NSString *)channel;
+@end
+
+ // All operations happen on the main thread
+ // Messages must be JSON compatible
+@interface CEPubnub : NSObject {
+@private
+ __unsafe_unretained id<CEPubnubDelegate> _delegate;
+ NSString* _publishKey;
+ NSString* _subscribeKey;
+ NSString* _secretKey;
+ NSString* _host;
+ NSString* _cipherKey;
+ NSString* _uuids;
+
+ NSMutableSet* _connections;
+ NSMutableSet * _subscriptions;
+}
+@property(nonatomic, assign) id<CEPubnubDelegate> delegate;
+- (CEPubnub*) initWithSubscribeKey:(NSString*)subscribeKey useSSL:(BOOL)useSSL;
+- (CEPubnub*) initWithPublishKey:(NSString*)publishKey
+ subscribeKey:(NSString*)subscribeKey
+ secretKey:(NSString*)secretKey
+ useSSL:(BOOL)useSSL;
+
+- (CEPubnub*) initWithPublishKey:(NSString*)publishKey // May be nil if -publishMessage:toChannel: is never used
+ subscribeKey:(NSString*)subscribeKey
+ secretKey:(NSString*)secretKey // May be nil if -publishMessage:toChannel: is never used
+ useSSL:(BOOL)useSSL
+ cipherKey:(NSString*)cipherKey
+ origin:(NSString*)origin;
+
+- (CEPubnub*) initWithPublishKey:(NSString*)publishKey
+ subscribeKey:(NSString*)subscribeKey
+ secretKey:(NSString*)secretKey
+ cipherKey:(NSString*)cipherKey
+ useSSL:(BOOL)useSSL;
+
+- (void) publish:(NSDictionary * )arg1;
+- (void) publish:(NSString * )message onChannel:(NSString *) channel;
+- (void) fetchHistory:(NSDictionary * )arg1;
+- (void) detailedHistory:(NSDictionary * )arg1;
+- (void) unsubscribeFromAllChannels;
+- (void) getTime;
++ (NSString*) getUUID;
+- (void) subscribe:(NSString*)channel; // Does nothing if already subscribed
+- (void) unsubscribeFromChannel:(NSString*)channel; // Does nothing if not subscribed
+- (BOOL) isSubscribedToChannel:(NSString*)channel;
+- (void) here_now:(NSString*)channel;
+- (void) presence:(NSString*)channel;
+@end
+
+
+@interface ChannelStatus :NSObject
+@property(nonatomic, retain) NSString* channel;
+@property(nonatomic, nonatomic) BOOL connected;
+@property(nonatomic, nonatomic) BOOL first;
+@end
View
903 objective-c/3.3/PubnubTest/PubnubTest/PubNub/CEPubnub.m
@@ -0,0 +1,903 @@
+ // Copyright 2011 Cooliris, Inc.
+ //
+ // Licensed under the Apache License, Version 2.0 (the "License");
+ // you may not use this file except in compliance with the License.
+ // You may obtain a copy of the License at
+ //
+ // http://www.apache.org/licenses/LICENSE-2.0
+ //
+ // Unless required by applicable law or agreed to in writing, software
+ // distributed under the License is distributed on an "AS IS" BASIS,
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ // See the License for the specific language governing permissions and
+ // limitations under the License.
+
+#import "CEPubnub.h"
+#import "JSON.h"
+#import "Common.h"
+
+#define kDefaultOrigin @"pubsub.pubnub.com"
+#define kMaxHistorySize 100 // From documentation
+#define kConnectionTimeOut 310.0 // From https://github.com/jazzychad/CEPubnub/blob/master/CEPubnub/CEPubnubRequest.m
+#define kMinRetryInterval 5.0
+#define kInitialTimeToken @"0"
+
+typedef enum {
+ kCommand_Undefined = 0,
+ kCommand_SendMessage,
+ kCommand_ReceiveMessage,
+ kCommand_FetchHistory,
+ kCommand_FetchDetailHistory,
+ kCommand_GetTime,
+ kCommand_Here_Now
+} Command;
+
+@interface PubNubConnection : NSURLConnection {
+@private
+ CEPubnub * _pubNub;
+ Command _command;
+ NSString* _channel;
+ id _message;
+
+ NSHTTPURLResponse* _response;
+ NSMutableData* _data;
+}
+@property(nonatomic, readonly) Command command;
+@property(nonatomic, readonly) NSString* channel;
+@property(nonatomic, readonly) NSData* data;
+@property(nonatomic, readonly) id message;
+- (id) initWithPubNub:(CEPubnub*)pubNub url:(NSURL*)url command:(Command)command channel:(NSString*)channel;
+@end
+
+@interface CEPubnub ()
+- (void) connection:(PubNubConnection*)connection didCompleteWithResponse:(id)response;
+@end
+
+@implementation ChannelStatus
+@synthesize connected,channel,first;
+@end
+
+@implementation PubNubConnection
+
+@synthesize command=_command, channel=_channel, data=_data, message=_message;
+
+- (id) initWithPubNub:(CEPubnub*)pubNub url:(NSURL*)url command:(Command)command channel:(NSString*)channel {
+ NSMutableURLRequest* request = [NSMutableURLRequest requestWithURL:url
+ cachePolicy:NSURLRequestReloadIgnoringCacheData
+ timeoutInterval:kConnectionTimeOut];
+ [request setValue:@"V" forHTTPHeaderField:@"3.3"];
+ [request setValue:@"User-Agent" forHTTPHeaderField:@"Obj-C-iOS"];
+ [request setValue:@"Accept" forHTTPHeaderField:@"gzip"];
+
+ // [request setValue:@"close" forHTTPHeaderField:@"Connection"];
+ if ((self = [super initWithRequest:request delegate:self])) {
+ _command = command;
+ _pubNub = pubNub;
+ _channel = [channel copy];
+ }
+ return self;
+}
+
+- (id) initWithPubNub:(CEPubnub*)pubNub url:(NSURL*)url command:(Command)command channel:(NSString*)channel message:(id)message{
+ NSMutableURLRequest* request = [NSMutableURLRequest requestWithURL:url
+ cachePolicy:NSURLRequestReloadIgnoringCacheData
+ timeoutInterval:kConnectionTimeOut];
+ [request setValue:@"V" forHTTPHeaderField:@"3.1"];
+ [request setValue:@"User-Agent" forHTTPHeaderField:@"Obj-C-iOS"];
+ [request setValue:@"Accept" forHTTPHeaderField:@"gzip"];
+
+ // [request setValue:@"close" forHTTPHeaderField:@"Connection"];
+ if ((self = [super initWithRequest:request delegate:self])) {
+ _command = command;
+ _pubNub = pubNub;
+ _channel = [channel copy];
+ _message=[message copy];
+ }
+
+ return self;
+}
+
+- (void) connection:(NSURLConnection*)connection didReceiveResponse:(NSURLResponse*)response {
+ // DCHECK(_response == nil);
+ _response = (NSHTTPURLResponse*)[response copy];
+}
+
+- (void) connection:(NSURLConnection*)connection didReceiveData:(NSData*)data {
+ if (_data == nil) {
+ _data = [[NSMutableData alloc] initWithData:data];
+ } else {
+ [_data appendData:data];
+ }
+}
+
+- (void) connectionDidFinishLoading:(NSURLConnection*)connection {
+ if (_response.statusCode == 200) {
+ // NSString* contente = [[_response allHeaderFields] objectForKey:@"Content-Encoding"];
+ // NSLog(@"PubNub request returned Content-Encoding : %@", contente);
+ NSString* contentType = [[_response allHeaderFields] objectForKey:@"Content-Type"];
+ if ([contentType hasPrefix:@"text/javascript"] && [contentType containsString:@"UTF-8"]) { // Should be [text/javascript; charset="UTF-8"] but is sometimes different on 3G
+ [_pubNub connection:self didCompleteWithResponse:JSONParseData(_data)];
+ // NSLog(@"PubNub request returned unexpected content type: %@", contentType);
+ } else if ([contentType hasPrefix:@"text/javascript"])
+ {
+ if(_command== kCommand_Here_Now)
+ {
+ [_pubNub connection:self didCompleteWithResponse:JSONParseData(_data)];
+ }
+ }else {
+ NSLog(@"PubNub request returned unexpected content type: %@", contentType);
+ switch ([self command]) {
+ case kCommand_SendMessage:
+ [_pubNub connection:self didCompleteWithResponse:[NSArray arrayWithObjects:@"0", [NSString stringWithFormat:@"PubNub request returned unexpected content type: %@", contentType ] ,@"0", nil]];
+ break;
+
+ default:
+ [_pubNub connection:self didCompleteWithResponse:nil];
+ break;
+ }
+
+ }
+ } else {
+ NSLog(@"PubNub request failed with HTTP status code %i", _response.statusCode);
+ switch ([self command]) {
+ case kCommand_SendMessage:
+ [_pubNub connection:self didCompleteWithResponse:[NSArray arrayWithObjects:@"0", [NSString stringWithFormat:@"PubNub request failed with HTTP status code %i", _response.statusCode ] ,@"0", nil]];
+ break;
+
+ default:
+ [_pubNub connection:self didCompleteWithResponse:nil];
+ break;
+ }
+
+ }
+}
+
+- (void) connection:(NSURLConnection*)connection didFailWithError:(NSError*)error {
+ if ([error.domain isEqualToString:NSURLErrorDomain] && (error.code == NSURLErrorNotConnectedToInternet)) {
+ NSLog(@"PubNub request failed due to missing Internet connection");
+ switch ([self command]) {
+ case kCommand_SendMessage:
+ [_pubNub connection:self didCompleteWithResponse:[NSArray arrayWithObjects:@"0",@"PubNub request failed due to missing Internet connection" ,@"0", nil]];
+ break;
+
+ default:
+ [_pubNub connection:self didCompleteWithResponse:nil];
+ break;
+ }
+
+ } else {
+ switch ([self command]) {
+ case kCommand_SendMessage:
+ [_pubNub connection:self didCompleteWithResponse:[NSArray arrayWithObjects:@"0", [NSString stringWithFormat:@"PubNub request failed with error: %@", error ] ,@"0", nil]];
+ break;
+
+ default:
+ [_pubNub connection:self didCompleteWithResponse:nil];
+ break;
+ }
+ NSLog(@"PubNub request failed with error: %@", error);
+ }
+}
+
+@end
+
+@implementation CEPubnub
+
+@synthesize delegate=_delegate;
+
+- (CEPubnub*) initWithSubscribeKey:(NSString*)subscribeKey useSSL:(BOOL)useSSL {
+ return [self initWithPublishKey:nil subscribeKey:subscribeKey secretKey:nil useSSL:useSSL cipherKey:nil origin:kDefaultOrigin];
+}
+
+- (CEPubnub*) initWithPublishKey:(NSString*)publishKey
+ subscribeKey:(NSString*)subscribeKey
+ secretKey:(NSString*)secretKey
+ useSSL:(BOOL)useSSL {
+ return [self initWithPublishKey:publishKey subscribeKey:subscribeKey secretKey:secretKey useSSL:useSSL cipherKey:nil origin:kDefaultOrigin];
+}
+
+- (CEPubnub*) initWithPublishKey:(NSString*)publishKey
+ subscribeKey:(NSString*)subscribeKey
+ secretKey:(NSString*)secretKey
+ useSSL:(BOOL)useSSL
+ cipherKey:(NSString*)cipherKey
+ origin:(NSString*)origin {
+ if ((self = [super init])) {
+ _publishKey = [publishKey copy];
+ _subscribeKey = [subscribeKey copy];
+ _secretKey = [secretKey copy];
+ _host = [[NSString alloc] initWithFormat:@"%@://%@", useSSL ? @"https" : @"http", origin];
+ _cipherKey=[cipherKey copy];
+ _connections = [[NSMutableSet alloc] init];
+ _uuids=[CEPubnub getUUID];
+ }
+ return self;
+}
+
+- (CEPubnub*) initWithPublishKey:(NSString*)publishKey
+ subscribeKey:(NSString*)subscribeKey
+ secretKey:(NSString*)secretKey
+ cipherKey:(NSString*)cipherKey
+ useSSL:(BOOL)useSSL{
+ return [self initWithPublishKey:publishKey subscribeKey:subscribeKey secretKey:secretKey useSSL:useSSL cipherKey:cipherKey origin:kDefaultOrigin];
+}
+
+- (void) dealloc {
+ for (PubNubConnection* connection in _connections) {
+ [connection cancel];
+ }
+
+}
+
+-(NSDictionary*) getEncryptedDictionary:(NSDictionary*)message
+{
+ if(_cipherKey != nil)
+ {
+ NSMutableDictionary* msg = [NSMutableDictionary dictionaryWithCapacity: message.count];
+ NSDictionary* disc = (NSDictionary*) message;
+ for (NSString* key in [disc allKeys]) {
+ NSString* val = (NSString*)[disc objectForKey:key];
+ NSString * dec = [CommonFunction AES128EncryptWithKey: _cipherKey Data:val];
+ [msg setObject: dec forKey:key];
+ }
+
+ return msg;
+ }
+ return [NSMutableDictionary dictionaryWithDictionary: message];
+}
+
+-(NSString*) getEncryptedString:(NSString*)disc
+{
+ NSString * returnval;
+ if(_cipherKey != nil)
+ {
+ returnval= [CommonFunction AES128EncryptWithKey:_cipherKey Data:disc];
+ }
+ else {
+ returnval=disc ;
+ }
+ return returnval;
+}
+
+-(NSArray*) getEncryptedArray:(NSArray*)array
+{
+ NSMutableArray *messages = [NSMutableArray arrayWithCapacity: 10];
+ for (int i=0; i<array.count; i++) {
+ id object= [array objectAtIndex:i];
+ if ([object isKindOfClass:[NSString class]]) {
+ [messages addObject:[self getEncryptedString:(NSString *)object]];
+
+ } else if ([object isKindOfClass:[NSArray class]]) {
+ [messages addObject:[self getEncryptedArray:(NSArray *)object ]];
+ } else if ([object isKindOfClass:[NSDictionary class]]) {
+ [messages addObject:[self getEncryptedDictionary:(NSDictionary *)object]];
+ }
+ }
+ return messages;
+}
+
+- (void) publish:(NSString * )message onChannel:(NSString *) channel{
+ NSDictionary *disc= [NSDictionary dictionaryWithObjectsAndKeys:channel,@"channel",message,@"message", nil];
+ [self publish:disc];
+}
+
+- (void) publish:(NSDictionary * )arg1{
+ NSString * channel = [arg1 objectForKey: @"channel"];
+ id message = [arg1 objectForKey: @"message"];
+ if (!channel) {
+ NSLog(@"ERROR::Channel name not found.");
+ return;
+ }
+
+ if (!message) {
+ NSLog(@"ERROR::Message not found.");
+ return;
+ }
+
+ id msg = nil;
+ if ([message isKindOfClass:[NSString class]]) {
+ msg = [self getEncryptedString:(NSString*) message];
+ } else if ([message isKindOfClass:[NSArray class]]) {
+ msg = [self getEncryptedArray:(NSArray*) message];
+ } else if ([message isKindOfClass:[NSDictionary class]]) {
+ msg = [self getEncryptedDictionary:(NSDictionary*) message];
+ }
+
+ NSString* json = JSONWriteString(msg);
+ NSString* signature;
+ if (_secretKey) {
+ signature =[CommonFunction HMAC_SHA256withKey:[NSString stringWithFormat:@"%@",_secretKey] Input:[NSString stringWithFormat:@"%@/%@/%@/%@/%@", _publishKey, _subscribeKey, _secretKey, channel, json] ];
+ } else {
+ signature = @"0";
+ }
+ NSString* url = [NSString stringWithFormat:@"%@/publish/%@/%@/%@/%@/0/%@", _host, _publishKey, _subscribeKey, signature,
+ [channel urlEscapedString], [json urlEscapedString]];
+
+ PubNubConnection* connection = [[PubNubConnection alloc] initWithPubNub:self
+ url:[NSURL URLWithString:url]
+ command:kCommand_SendMessage
+ channel:channel
+ message:message];
+
+ [_connections addObject:connection];
+}
+
+- (void) _resubscribeToChannel:(NSString*)channel timeToken:(NSString*)timeToken {
+
+ NSString* url = [NSString stringWithFormat:@"%@/subscribe/%@/%@/0/%@/?uuid=%@", _host, _subscribeKey, [channel urlEscapedString], timeToken,_uuids];
+ PubNubConnection* connection = [[PubNubConnection alloc] initWithPubNub:self
+ url:[NSURL URLWithString:url]
+ command:kCommand_ReceiveMessage
+ channel:channel];
+ [_connections addObject:connection];
+
+}
+
+- (void) _resubscribeToChannel:(NSString*)channel {
+ // Ensure Single Connection
+ if (_subscriptions && [_subscriptions count] > 0) {
+
+ BOOL channel_exist = NO;
+ for (ChannelStatus* it in [_subscriptions copy]) {
+ if ([it.channel isEqualToString:channel])
+ {
+ channel_exist = YES;
+ break;
+ }
+ }
+
+ if (!channel_exist) {
+ ChannelStatus *cs = [[ChannelStatus alloc] init] ;
+ cs.channel = channel;
+ cs.connected = YES;
+ [_subscriptions addObject:cs];
+ } else {
+ // error_cb.execute("Already Connected");
+ //return;
+ }
+ } else {
+ // New Channel
+ ChannelStatus *cs = [[ChannelStatus alloc] init] ;
+ cs.channel = channel;
+ cs.connected = YES;
+ _subscriptions = [[NSMutableSet alloc] init];
+ [_subscriptions addObject:cs];
+ }
+
+ [self _resubscribeToChannel:channel timeToken:kInitialTimeToken];
+}
+
+- (void) subscribe:(NSString*)channel {
+ if (![self isSubscribedToChannel:channel]) {
+ [self _resubscribeToChannel:channel];
+ NSLog(@"Did subscribe to PubNub channel \"%@\"", channel);
+ }
+}
+
+- (void) here_now:(NSString*)channel {
+ if(channel == nil || channel ==@"")
+ {
+ NSLog(@"Missing channel");
+ return;
+ }
+
+
+ NSString* url = [NSString stringWithFormat:@"%@/v2/presence/sub_key/%@/channel/%@", _host, _subscribeKey, [channel urlEscapedString]];
+
+ PubNubConnection* connection = [[PubNubConnection alloc] initWithPubNub:self
+ url:[NSURL URLWithString:url]
+ command:kCommand_Here_Now
+ channel:channel];
+ [_connections addObject:connection];
+
+}
+
+- (void) presence:(NSString*)channel
+{
+ if(channel == nil || channel ==@"")
+ {
+ NSLog(@"Missing channel");
+ return;
+ }
+ [self subscribe:[NSString stringWithFormat:@"%@-pnpres", channel]];
+}
+
+- (void) unsubscribeFromChannel:(NSString*)channel {
+ for (PubNubConnection* connection in [_connections copy]) {
+ if ((connection.command == kCommand_ReceiveMessage) && (!channel || [connection.channel isEqualToString:channel])) {
+ NSLog(@"Did unsubscribe from PubNub channel \"%@\"", connection.channel);
+ [connection cancel];
+ [_connections removeObject:connection];
+ for (ChannelStatus* it in [_subscriptions copy]) {
+ if ([it.channel isEqualToString:connection.channel])
+ {
+ it.connected=false;
+ it.first=false;
+ if ([_delegate respondsToSelector:@selector(pubnub:DisconnectToChannel:)]) {
+ [_delegate pubnub:self DisconnectToChannel:connection.channel];
+ }
+ [_subscriptions removeObject:it];
+ break;
+ }
+ }
+ }
+ }
+
+ [NSObject cancelPreviousPerformRequestsWithTarget:self];
+}
+
+- (BOOL) isSubscribedToChannel:(NSString*)channel {
+ for (PubNubConnection* connection in _connections) {
+ if ((connection.command == kCommand_ReceiveMessage) && [connection.channel isEqualToString:channel]) {
+ if ([_delegate respondsToSelector:@selector(pubnub:subscriptionDidFailWithResponse:onChannel:)]) {
+ [_delegate pubnub:self subscriptionDidFailWithResponse:@"Already Connected" onChannel:channel];
+ }
+ return YES;
+ }
+ }
+ for (ChannelStatus* it in [_subscriptions copy]) {
+ if ([it.channel isEqualToString:channel])
+ {
+ it.connected=false;
+ it.first=false;
+ }
+ }
+ return NO;
+}
+
+- (void) unsubscribeFromAllChannels {
+ [self unsubscribeFromChannel:nil];
+}
+
+- (void) fetchHistory:(NSUInteger)limit forChannel:(NSString*)channel {
+ NSNumber * aWrappedInt = [NSNumber numberWithInteger:limit];
+ NSDictionary* disc= [NSDictionary dictionaryWithObjectsAndKeys: aWrappedInt,@"limit", channel,@"channel",nil];
+ [self fetchHistory:disc];
+}
+
+- (void) fetchHistory:(NSDictionary * )arg1 {
+ int limit;
+ NSString* channel;
+ if (![arg1 objectForKey:@"limit"])
+ {
+ NSLog(@"ERROR::limit not found.");
+ return;
+
+ }else
+ {
+ limit=[[arg1 objectForKey:@"limit"] intValue];
+ }
+
+ if (![arg1 objectForKey:@"channel"])
+ {
+ NSLog(@"ERROR::Channel name not found.");
+ return;
+ }else
+ {
+ channel=[arg1 objectForKey:@"channel"];
+ }
+
+ if (limit > kMaxHistorySize) {
+ NSLog(@"PubNub history too large: %i", limit);
+ }
+ NSString* url = [NSString stringWithFormat:@"%@/history/%@/%@/0/%i", _host, _subscribeKey, [channel urlEscapedString], limit];
+ PubNubConnection* connection = [[PubNubConnection alloc] initWithPubNub:self
+ url:[NSURL URLWithString:url]
+ command:kCommand_FetchHistory
+ channel:channel];
+ [_connections addObject:connection];
+}
+
+
+- (void) detailedHistory:(NSDictionary * )arg1 {
+
+ NSString* channel;
+
+
+ if (![arg1 objectForKey:@"channel"])
+ {
+ NSLog(@"ERROR::Channel name not found.");
+ return;
+ }else
+ {
+ channel=[arg1 objectForKey:@"channel"];
+ }
+ NSMutableString *parameters= [[NSMutableString alloc]init];
+
+ if ([arg1 objectForKey:@"count"])
+ {
+ [parameters appendFormat:@"count=%@",[arg1 objectForKey:@"count"]];
+ }
+
+ if ([arg1 objectForKey:@"start"])
+ {
+ if ([parameters length] > 0) {
+ [parameters appendString:@"&"];
+ }
+ [parameters appendFormat:@"start=%@",[arg1 objectForKey:@"start"]];
+ }
+
+ if ([arg1 objectForKey:@"end"])
+ {
+ if ([parameters length] > 0) {
+ [parameters appendString:@"&"];
+ }
+ [parameters appendFormat:@"end=%@",[arg1 objectForKey:@"end"]];
+ }
+
+ if ([arg1 objectForKey:@"reverse"])
+ {
+ if ([parameters length] > 0) {
+ [parameters appendString:@"&"];
+ }
+ BOOL reverse=[[arg1 objectForKey:@"reverse"] boolValue];
+ if(reverse)
+ [parameters appendFormat:@"reverse=%@",@"true"];
+ else
+ [parameters appendFormat:@"reverse=%@",@"false"];
+ }
+
+ if ([parameters length] > 0) {
+ [parameters insertString:@"?" atIndex:0 ];
+ }
+
+ NSString* url = [NSString stringWithFormat:@"%@/v2/history/sub-key/%@/channel/%@%@", _host, _subscribeKey, [channel urlEscapedString],[parameters description]];
+ PubNubConnection* connection = [[PubNubConnection alloc] initWithPubNub:self
+ url:[NSURL URLWithString:url]
+ command:kCommand_FetchDetailHistory
+ channel:channel];
+ [_connections addObject:connection];
+}
+
+
+
+- (void) getTime {
+ NSString* url = [NSString stringWithFormat:@"%@/time/0", _host];
+ PubNubConnection* connection = [[PubNubConnection alloc] initWithPubNub:self
+ url:[NSURL URLWithString:url]
+ command:kCommand_GetTime
+ channel:nil];
+ [_connections addObject:connection];
+}
+
+NSDecimalNumber* time_token = 0;
+
+- (void) getTime1 {
+ NSString* url = [NSString stringWithFormat:@"%@/time/0", _host];
+ NSURLRequest * urlRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:url] cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:1.0];
+
+ [NSURLConnection
+ sendAsynchronousRequest:urlRequest
+ queue:[[NSOperationQueue alloc] init]
+ completionHandler:^(NSURLResponse *response2,
+ NSData *data,
+ NSError *error)
+ {
+
+ if ([data length] >0 && error == nil)
+ {
+ NSArray* resp= (NSArray *)JSONParseData(data);
+ if ([resp isKindOfClass:[NSArray class]] && ([resp count] == 1)) {
+ time_token = [resp objectAtIndex:0];
+ }
+ }
+ else if ([data length] == 0 && error == nil)
+ {
+ time_token=0;
+ }
+ else if (error != nil){
+ time_token=0;
+ }
+ }];
+}
+
++ (NSString *) getUUID
+{
+ return [CommonFunction generateUuidString];
+}
+
+-(NSDictionary*) getDecryptedDictionary:(NSDictionary*)message
+{
+ if(_cipherKey != nil)
+ {
+ NSMutableDictionary *msg = [NSMutableDictionary dictionaryWithCapacity: message.count];
+ for (NSString* key in [message allKeys]) {
+ NSString* val = (NSString*) [message objectForKey: key];
+ NSString* dec = [CommonFunction AES128DecryptWithKey: _cipherKey Data: val];
+ [msg setObject: dec forKey: key];
+ }
+ return msg;
+ }
+
+ return [NSMutableDictionary dictionaryWithDictionary: message];
+}
+
+-(NSString*) getDecryptedString:(NSString*)disc
+{
+ NSString * returnval;
+ if(_cipherKey != nil)
+ {
+ returnval= [CommonFunction AES128DecryptWithKey:_cipherKey Data:disc];
+ }
+ else {
+ returnval=disc ;
+ }
+ return returnval;
+}
+
+-(NSArray*) getDecryptedArray:(NSArray*)array
+{
+ NSMutableArray *messages = [NSMutableArray arrayWithCapacity: array.count];
+ for (int i=0; i < array.count; i++) {
+ id object= [array objectAtIndex:i];
+ if ([object isKindOfClass:[NSString class]]) {
+ [messages addObject:[self getDecryptedString:(NSString *)object ]];
+ } else if ([object isKindOfClass:[NSArray class]]) {
+ [messages addObject:[self getDecryptedArray:(NSArray *)object ]];
+ } else if ([object isKindOfClass:[NSDictionary class]]) {
+ [messages addObject:[self getDecryptedDictionary:(NSDictionary *)object ]];
+ }
+ }
+ return messages;
+}
+
+- (void) connection:(PubNubConnection*)connection didCompleteWithResponse:(id)response {
+ switch (connection.command) {
+ case kCommand_SendMessage: {
+ BOOL success = NO;
+ NSString* error = nil;
+ NSArray *array=nil;
+ if(response)
+ {
+ if ([response isKindOfClass:[NSArray class]])
+ {
+ NSArray *arra= (NSArray*)response;
+ if([arra count] > 2)
+ {
+ success = [[arra objectAtIndex:0] boolValue];
+ if(success == NO)
+ {
+ error = [arra objectAtIndex:1];
+ }
+ }
+ }
+ }
+
+ if (success) {
+
+ if ([_delegate respondsToSelector:@selector(pubnub:didSucceedPublishingMessageToChannel:withResponce:message:)]) {
+ [_delegate pubnub:self didSucceedPublishingMessageToChannel:connection.channel withResponce:response message:connection.message];
+ }
+ } else {
+ if (error) {
+ array= [NSArray arrayWithObjects:@"0", error, nil];
+ }else {
+ error= [NSString stringWithFormat:@"Failed sending message to PubNub channel %@:", connection.channel];
+ array= [NSArray arrayWithObjects:@"0", error, nil];
+ }
+ if ([_delegate respondsToSelector:@selector(pubnub:didFailPublishingMessageToChannel:error:message:)]) {
+ [_delegate pubnub:self didFailPublishingMessageToChannel:connection.channel error:[array description] message:connection.message];
+ }
+ }
+ break;
+ }
+
+ case kCommand_ReceiveMessage: {
+ BOOL isPresence=NO;
+ if ([connection.channel hasSuffix:@"-pnpres"]) {
+ isPresence=YES;
+ }
+ NSString* timeToken = @"0";
+ if(!isPresence)
+ {
+
+ if (response == nil ) {
+ for (ChannelStatus* it in [_subscriptions copy]) {
+ if ([it.channel isEqualToString:connection.channel])
+ {
+
+ if(it.first && it.connected) {
+ it.connected=NO;
+ if ([_delegate respondsToSelector:@selector(pubnub:DisconnectToChannel:)]) {
+ [_delegate pubnub:self DisconnectToChannel:connection.channel];
+ }
+ }
+ }
+ }
+//
+// BOOL is_reconnected = NO;
+ [self getTime1 ];
+ if (time_token == 0) {
+
+ }else
+ {
+ if ([_delegate respondsToSelector:@selector(pubnub:Re_ConnectToChannel:)]) {
+ [_delegate pubnub:self Re_ConnectToChannel:connection.channel];
+ }
+ }
+ }
+ else {
+ for (ChannelStatus* it in [_subscriptions copy]) {
+ if ([it.channel isEqualToString:connection.channel])
+ {
+ // Connect Callback
+ if (it.first == NO) {
+ it.first = YES;
+ if ([_delegate respondsToSelector:@selector(pubnub:ConnectToChannel:)]) {
+ // NSLog(@"_Connected to channel %@",connection.channel);
+ [_delegate pubnub:self ConnectToChannel:connection.channel];
+ }
+ break;
+ }else
+ {
+ if ([_delegate respondsToSelector:@selector(pubnub:Re_ConnectToChannel:)]) {
+
+ [_delegate pubnub:self Re_ConnectToChannel:connection.channel];
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if ([response isKindOfClass:[NSArray class]] && ([response count] == 2)) {
+ if(!isPresence)
+ NSLog(@"Received %i messages from PubNub channel \"%@\"", [[response objectAtIndex:0] count], connection.channel);
+
+ if(!isPresence)
+ {
+ for (id message in [response objectAtIndex:0]) {
+ if ([message isKindOfClass:[NSDictionary class]]) {
+ if ([_delegate respondsToSelector:@selector(pubnub:subscriptionDidReceiveDictionary:onChannel:)]) {
+ NSDictionary * disc=[self getDecryptedDictionary:(NSDictionary *)message];
+ [_delegate pubnub:self subscriptionDidReceiveDictionary:disc onChannel:connection.channel];
+ }
+ }else if ([message isKindOfClass:[NSArray class]]) {
+ if ([_delegate respondsToSelector:@selector(pubnub:subscriptionDidReceiveArray:onChannel:)]) {
+ NSArray * arr=[self getDecryptedArray:(NSArray *)message];
+ [_delegate pubnub:self subscriptionDidReceiveArray:arr onChannel:connection.channel];
+ }
+ }else if ([message isKindOfClass:[NSString class]]) {
+ if ([_delegate respondsToSelector:@selector(pubnub:subscriptionDidReceiveArray:onChannel:)]) {
+ NSString * str=[self getDecryptedString:(NSString *)message];
+ [_delegate pubnub:self subscriptionDidReceiveString:str onChannel:connection.channel];
+ }
+ }else {
+ if ([_delegate respondsToSelector:@selector(pubnub:subscriptionDidFailWithResponse:onChannel:onChannel:)]) {
+ [_delegate pubnub:self subscriptionDidFailWithResponse:message onChannel:connection.channel];
+ }
+ }
+ }
+ }else {
+ for (id message in [response objectAtIndex:0]) {
+ if ([message isKindOfClass:[NSDictionary class]]) {
+ if ([_delegate respondsToSelector:@selector(pubnub:presence:onChannel:)]) {
+ NSString* channel = [connection.channel stringByReplacingOccurrencesOfString:@"-pnpres" withString:@""];
+ [_delegate pubnub:self presence:message onChannel:channel];
+ }
+ }
+ }
+
+ }
+
+ timeToken = [response objectAtIndex:1];
+ } else if (response) {
+ NSLog(@"Unexpected subscribe response from PubNub");
+ }
+ if (response) {
+ if (timeToken) {
+ [self _resubscribeToChannel:connection.channel timeToken:timeToken];
+ } else {
+ [self _resubscribeToChannel:connection.channel];
+ }
+ }
+ else {
+ [self performSelector:@selector(_resubscribeToChannel:) withObject:connection.channel afterDelay:kMinRetryInterval];
+ }
+ break;
+ }
+ case kCommand_FetchDetailHistory:{
+ NSMutableArray *mainArray = [NSMutableArray arrayWithCapacity: 2];
+ NSMutableArray *returnArray = [NSMutableArray arrayWithArray:response];
+ if ([response isKindOfClass:[NSArray class]]) {
+ id msg= [response objectAtIndex:0];
+ for (id message in msg) {
+ if ([message isKindOfClass:[NSDictionary class]]) {
+ NSDictionary * disc=[self getDecryptedDictionary:(NSDictionary *)message];
+ [mainArray addObject:disc];
+ }else if ([message isKindOfClass:[NSArray class]]) {
+ NSArray * arr=[self getDecryptedArray:(NSArray *)message];
+ [mainArray addObject:arr];
+ }else if ([message isKindOfClass:[NSString class]]) {
+ NSString * str=[self getDecryptedString:(NSString *)message];
+ [mainArray addObject:str];
+ }
+ }
+
+ [returnArray replaceObjectAtIndex:0 withObject:mainArray];
+
+ }else if (response) {
+ NSLog(@"Unexpected history response from PubNub");
+ }
+
+ if(response)
+ {
+ if ([_delegate respondsToSelector: @selector(pubnub:didFetchDetailedHistory:forChannel:)]) {
+ [_delegate pubnub:self didFetchDetailedHistory: [NSArray arrayWithArray: returnArray] forChannel: connection.channel];
+ }
+ }else {
+ NSArray* array= [NSArray arrayWithObjects:@"0", @"Fetch History request failed due to missing Internet connection", nil];
+ if ([_delegate respondsToSelector: @selector(pubnub:didFailFetchDetailedHistoryOnChannel:withError:)]) {
+ [_delegate pubnub:self didFailFetchDetailedHistoryOnChannel:connection.channel withError:array];
+
+ }
+ }
+ break;
+ }
+
+ case kCommand_FetchHistory: {
+ NSMutableArray *mainArray = [NSMutableArray arrayWithCapacity: 2];
+
+ if ([response isKindOfClass:[NSArray class]]) {
+ NSLog(@"Fetched %i history messages from PubNub channel \"%@\"", [response count], connection.channel);
+
+ for (id message in response) {
+ if ([message isKindOfClass:[NSDictionary class]]) {
+ NSDictionary * disc=[self getDecryptedDictionary:(NSDictionary *)message];
+ [mainArray addObject:disc];
+ }else if ([message isKindOfClass:[NSArray class]]) {
+ NSArray * arr=[self getDecryptedArray:(NSArray *)message];
+ [mainArray addObject:arr];
+ }else if ([message isKindOfClass:[NSString class]]) {
+ NSString * str=[self getDecryptedString:(NSString *)message];
+ [mainArray addObject:str];
+ }
+ }
+ } else if (response) {
+ NSLog(@"Unexpected history response from PubNub");
+ }
+
+ if(response)
+ {
+ if ([_delegate respondsToSelector: @selector(pubnub:didFetchHistory:forChannel:)]) {
+ [_delegate pubnub:self didFetchHistory: [NSArray arrayWithArray: mainArray] forChannel: connection.channel];
+ }
+ }else {
+ NSArray* array= [NSArray arrayWithObjects:@"0", @"Fetch History request failed due to missing Internet connection", nil];
+ if ([_delegate respondsToSelector: @selector(pubnub:didFailFetchHistoryOnChannel:withError:)]) {
+ [_delegate pubnub:self didFailFetchHistoryOnChannel:connection.channel withError:array];
+
+ }
+ }
+ break;
+ }
+ case kCommand_GetTime: {
+ NSDecimalNumber* number = nil;
+ if ([response isKindOfClass:[NSArray class]] && ([response count] == 1)) {
+ NSLog(@"Retrieved PubNub time '%@'", [response objectAtIndex:0]);
+ number = [response objectAtIndex:0];
+ } else if (response) {
+ NSLog(@"Unexpected time response from PubNub");
+ }
+ if ([_delegate respondsToSelector:@selector(pubnub:didReceiveTime:)]) {
+ [_delegate pubnub:self didReceiveTime:(number ? [number doubleValue] : NAN)];
+ }
+ break;
+ }
+ case kCommand_Here_Now: {
+ if ([response isKindOfClass:[NSDictionary class]] ) {
+ if ([_delegate respondsToSelector:@selector(pubnub:here_now:onChannel:)]) {
+
+ [_delegate pubnub:self here_now:response onChannel:connection.channel];
+ }
+ }
+ break;
+ }
+ default:
+ // NOT_REACHED();
+ NSLog(@"ERROR::didCompleteWithResponse Command Not Set..");
+ break;
+ }
+ [_connections removeObject: connection];
+}
+@end
View
21 objective-c/3.3/PubnubTest/PubnubTest/PubNub/Cipher.h
@@ -0,0 +1,21 @@
+//#import <Cocoa/Cocoa.h>
+
+#import <CommonCrypto/CommonDigest.h>
+#import <CommonCrypto/CommonCryptor.h>
+
+@interface Cipher : NSObject {
+ NSString* cipherKey;
+}
+
+@property (retain) NSString* cipherKey;
+
+- (Cipher *) initWithKey:(NSString *) key;
+
+- (NSData *) encrypt:(NSData *) plainText;
+- (NSData *) decrypt:(NSData *) cipherText;
+
+- (NSData *) transform:(CCOperation) encryptOrDecrypt data:(NSData *) inputData;
+
++ (NSData *) md5:(NSString *) stringToHash;
+
+@end
View
107 objective-c/3.3/PubnubTest/PubnubTest/PubNub/Cipher.m
@@ -0,0 +1,107 @@
+//
+// NSObject+Cipher.m
+// FBEncryptor
+//
+// Created by itshastra on 14/04/12.
+// Copyright (c) 2012 __MyCompanyName__. All rights reserved.
+//
+
+#import "Cipher.h"
+
+@implementation Cipher
+
+@synthesize cipherKey;
+
+- (Cipher *) initWithKey:(NSString *) key {
+ self = [super init];
+ if (self) {
+ [self setCipherKey:key];
+ }
+ return self;
+}
+
+- (NSData *) encrypt:(NSData *) plainText {
+ return [self transform:kCCEncrypt data:plainText];
+}
+
+- (NSData *) decrypt:(NSData *) cipherText {
+ return [self transform:kCCDecrypt data:cipherText];
+}
+
+- (NSData *) transform:(CCOperation) encryptOrDecrypt data:(NSData *) inputData {
+
+ // kCCKeySizeAES128 = 16 bytes
+ // CC_MD5_DIGEST_LENGTH = 16 bytes
+ NSData* secretKey = [Cipher md5:cipherKey];
+
+ CCCryptorRef cryptor = NULL;
+ CCCryptorStatus status = kCCSuccess;
+
+ // uint8_t iv[kCCBlockSizeAES128];
+ // memset((void *) iv, 0x0, (size_t) sizeof(iv));
+
+ NSData* ivp = [@"0123456789012345" dataUsingEncoding:NSUTF8StringEncoding];
+
+
+ // setup iv
+ char cIv[kCCBlockSizeAES128];
+ bzero(cIv, kCCBlockSizeAES128);
+ if (ivp) {
+ [ivp getBytes:cIv length:kCCBlockSizeAES128];
+ }
+
+ status = CCCryptorCreate(encryptOrDecrypt, kCCAlgorithmAES128, kCCOptionPKCS7Padding,
+ [secretKey bytes], kCCKeySizeAES128, cIv, &cryptor);
+
+
+
+ if (status != kCCSuccess) {
+ return nil;
+ }
+
+ size_t bufsize = CCCryptorGetOutputLength(cryptor, (size_t)[inputData length], true);
+
+ void * buf = malloc(bufsize * sizeof(uint8_t));
+ memset(buf, 0x0, bufsize);
+
+ size_t bufused = 0;
+ size_t bytesTotal = 0;
+
+ status = CCCryptorUpdate(cryptor, [inputData bytes], (size_t)[inputData length],
+ buf, bufsize, &bufused);
+
+ if (status != kCCSuccess) {
+ free(buf);
+ CCCryptorRelease(cryptor);
+ return nil;
+ }
+
+ bytesTotal += bufused;
+
+ status = CCCryptorFinal(cryptor, buf + bufused, bufsize - bufused, &bufused);
+
+ if (status != kCCSuccess) {
+ free(buf);
+ CCCryptorRelease(cryptor);
+ return nil;
+ }
+
+ bytesTotal += bufused;
+
+ CCCryptorRelease(cryptor);
+
+ return [NSData dataWithBytesNoCopy:buf length:bytesTotal];
+}
+
++ (NSData *) md5:(NSString *) stringToHash {
+
+ const char *src = [stringToHash UTF8String];
+
+ unsigned char result[CC_MD5_DIGEST_LENGTH];
+
+ CC_MD5(src, strlen(src), result);
+
+ return [NSData dataWithBytes:result length:CC_MD5_DIGEST_LENGTH];
+}
+
+@end
View
26 objective-c/3.3/PubnubTest/PubnubTest/PubNub/Common.h
@@ -0,0 +1,26 @@
+//
+// Common.h
+// PubNub_NewAlt
+//
+// Created by itshastra on 11/04/12.
+// Copyright (c) 2012 __MyCompanyName__. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+#import <CommonCrypto/CommonHMAC.h>
+#import <CommonCrypto/CommonCryptor.h>
+@interface NSString (Extensions)
+
+- (NSString*) urlEscapedString; // Uses UTF-8 encoding and also escapes characters that can confuse the parameter string part of the URL
+- (NSString*) unescapeURLString; // Uses UTF-8 encoding
+- (BOOL) containsString:(NSString*)string;
+@end
+
+@interface CommonFunction :NSObject
++(NSString*) HMAC_SHA256withKey:(NSString*)key Input:(NSString*) input;
++ (NSString *)generateUuidString;
+
++ (NSString *)AES128EncryptWithKey:(NSString *)key Data:(NSString *)data ;
++ (NSString *)AES128DecryptWithKey:(NSString *)key Data:(NSString *)data ;
++ (NSString *)AES128EncryptWithKeyAndData:(NSString *)key Data:(NSData *)val;
+@end
View
110 objective-c/3.3/PubnubTest/PubnubTest/PubNub/Common.m
@@ -0,0 +1,110 @@
+//
+// Common.m
+// PubNub_NewAlt
+//
+// Created by itshastra on 11/04/12.
+// Copyright (c) 2012 __MyCompanyName__. All rights reserved.
+//
+
+#import "Common.h"
+#import "Base64.h"
+#import "Cipher.h"
+
+
+
+@implementation NSString (Extensions)
+
+- (NSString*) urlEscapedString {
+ return (__bridge_transfer id)CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, (__bridge CFStringRef)self, NULL, CFSTR(":@/?&=+"),kCFStringEncodingUTF8) ;
+}
+
+- (NSString*) unescapeURLString {
+ return (__bridge_transfer id)CFURLCreateStringByReplacingPercentEscapesUsingEncoding(kCFAllocatorDefault, (__bridge CFStringRef)self, CFSTR(""),
+ kCFStringEncodingUTF8) ;
+}
+- (BOOL) containsString:(NSString*)string {
+ NSRange range = [self rangeOfString:string];
+ return range.location != NSNotFound;
+}
+
+@end
+
+@implementation CommonFunction
+
++(NSString*) HMAC_SHA256withKey:(NSString*)key Input:(NSString*) input {
+
+ const char *cKey = [key cStringUsingEncoding:NSUTF8StringEncoding];
+ const char *cData = [input cStringUsingEncoding:NSUTF8StringEncoding];
+
+ unsigned char cHMAC[CC_SHA256_DIGEST_LENGTH];
+
+ CCHmac(kCCHmacAlgSHA256, cKey, strlen(cKey), cData, strlen(cData), cHMAC);
+
+ NSData *HMAC = [NSData dataWithBytesNoCopy: cHMAC length: sizeof(cHMAC) freeWhenDone: false];
+
+ NSString *hash = [HMAC description]; //This line doesn´t make sense
+ hash = [hash stringByReplacingOccurrencesOfString:@" " withString:@""];
+ hash = [hash stringByReplacingOccurrencesOfString:@"<" withString:@""];
+ hash = [hash stringByReplacingOccurrencesOfString:@">" withString:@""];
+ return hash;
+}
+
+// return a new autoreleased UUID string
++ (NSString *)generateUuidString
+{
+ // create a new UUID which you own
+ CFUUIDRef uuid = CFUUIDCreate(kCFAllocatorDefault);
+
+ // create a new CFStringRef (toll-free bridged to NSString)
+ // that you own
+ NSString *uuidString = (__bridge_transfer NSString *)CFUUIDCreateString(kCFAllocatorDefault, uuid);
+
+
+ // release the UUID
+ CFRelease(uuid);
+
+ return uuidString;
+}
+
++ (NSString *)AES128EncryptWithKey:(NSString *)key Data:(NSString *)val
+{
+ Cipher *ci = [[Cipher alloc] initWithKey: key];
+ NSData *data =[val dataUsingEncoding: NSUTF8StringEncoding];
+ NSData* enc = [ci encrypt: data];
+
+
+ [Base64 initialize];
+ return [Base64 encode:enc];
+}
+
++ (NSString *)AES128EncryptWithKeyAndData:(NSString *)key Data:(NSData *)val
+{
+ //return [self AES128Operation:kCCEncrypt key:key Data:data iv:iv];
+ Cipher *ci = [[Cipher alloc] initWithKey:key];
+ NSData *data = val ;
+ NSData* enc = [ci encrypt: data];
+
+
+ [Base64 initialize];
+ return [Base64 encode: enc];
+}
+
++ (NSString *)AES128DecryptWithKey:(NSString *)key Data:(NSString *)data
+{
+ Cipher *ci= [[Cipher alloc]initWithKey:key] ;
+ [Base64 initialize];
+
+ NSData * dat= [Base64 decode:data];
+ NSData *decData = [ci decrypt:dat] ;
+ if(decData == nil)
+ {
+ NSLog(@"Error: Failed to decrypt. Please validate symmetric (cipher) key.");
+ }
+ NSString *dec= [[NSString alloc]initWithData:decData encoding:NSUTF8StringEncoding] ;
+ return dec ;
+}
+
+@end
+
+
+
View
32 objective-c/3.3/PubnubTest/PubnubTest/PubNub/JSON.h
@@ -0,0 +1,32 @@
+// Copyright 2011 Cooliris, Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#import <Foundation/Foundation.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ id JSONParseData(NSData* data); // Objects must be NSArray or NSDictionary - Assumes UTF8 encoding
+ NSData* JSONWriteData(id object); // Objects must be NSArray or NSDictionary - Assumes UTF8 encoding
+
+ id JSONParseString(NSString* string); // Objects must be NSArray or NSDictionary
+ NSString* JSONWriteString(id object); // Objects must be NSArray or NSDictionary
+
+ id JSONGetDictionaryValueForKey(NSDictionary* dictionary, NSString* key); // Converts NSNull to nil
+ id JSONGetArrayValueAtIndex(NSArray* array, NSUInteger index); // Allows out of bounds and converts NSNull to nil
+
+#ifdef __cplusplus
+}
+#endif
View
94 objective-c/3.3/PubnubTest/PubnubTest/PubNub/JSON.m
@@ -0,0 +1,94 @@
+// Copyright 2011 Cooliris, Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#import "JSON.h"
+#import "JSONKit.h"
+
+#if 1
+//#import "Logging.h"
+#else
+#define LOG_ERROR(...) NSLog(__VA_ARGS__)
+#define DCHECK(...)
+#endif
+
+id JSONParseData(NSData* data) {
+ NSError* error = nil;
+ id object = [data objectFromJSONDataWithParseOptions:JKParseOptionNone error:&error];
+ if (object == nil) {
+ NSLog(@"JSON deserializing failed: %@", error);
+ }
+ return object;
+}
+
+NSData* JSONWriteData(id object) {
+ NSData* data = nil;
+ NSError* error = nil;
+ if ([object isKindOfClass:[NSString class]]) {
+ data = [(NSString*)object JSONDataWithOptions:JKSerializeOptionNone includeQuotes:YES error:&error];
+ } else if ([object isKindOfClass:[NSArray class]]) {
+ data = [(NSArray*)object JSONDataWithOptions:JKSerializeOptionNone error:&error];
+ } else if ([object isKindOfClass:[NSDictionary class]]) {
+ data = [(NSDictionary*)object JSONDataWithOptions:JKSerializeOptionNone error:&error];
+ } else {
+ // NOT_REACHED();
+ }
+ if (data == nil) {
+ NSLog(@"JSON serializing failed: %@", error);
+ }
+ return data;
+}
+
+id JSONParseString(NSString* string) {
+ NSError* error = nil;
+ id object = [string objectFromJSONStringWithParseOptions:JKParseOptionNone error:&error];
+ if (object == nil) {
+ NSLog(@"JSON deserializing failed: %@", error);
+ }
+ return object;
+}
+
+NSString* JSONWriteString(id object) {
+ NSString* string = nil;
+ NSError* error = nil;
+ if ([object isKindOfClass:[NSString class]]) {
+ string = [(NSString*)object JSONStringWithOptions:JKSerializeOptionNone includeQuotes:YES error:&error];
+ } else if ([object isKindOfClass:[NSArray class]]) {
+ string = [(NSArray*)object JSONStringWithOptions:JKSerializeOptionNone error:&error];
+ } else if ([object isKindOfClass:[NSDictionary class]]) {
+ string = [(NSDictionary*)object JSONStringWithOptions:JKSerializeOptionNone error:&error];
+ } else {
+ // NOT_REACHED();
+ }
+ if (string == nil) {
+ NSLog(@"JSON serializing failed: %@", error);
+ }
+ return string;
+}
+
+id JSONGetDictionaryValueForKey(NSDictionary* dictionary, NSString* key) {
+ // DCHECK(!dictionary || [dictionary isKindOfClass:[NSDictionary class]]);
+ id value = nil;
+ if(!dictionary || [dictionary isKindOfClass:[NSDictionary class]])
+ {
+ value = [dictionary objectForKey:key];
+
+ }
+ return (value == [NSNull null] ? nil : value);
+}
+
+id JSONGetArrayValueAtIndex(NSArray* array, NSUInteger index) {
+ // DCHECK(!array || [array isKindOfClass:[NSArray class]]);
+ id value = index < array.count ? [array objectAtIndex:index] : nil;
+ return (value == [NSNull null] ? nil : value);
+}
View
251 objective-c/3.3/PubnubTest/PubnubTest/PubNub/JSONKit.h
@@ -0,0 +1,251 @@
+//
+// JSONKit.h
+// http://github.com/johnezang/JSONKit
+// Dual licensed under either the terms of the BSD License, or alternatively
+// under the terms of the Apache License, Version 2.0, as specified below.
+//
+
+/*
+ Copyright (c) 2011, John Engelhart
+
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the Zang Industries nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/*
+ Copyright 2011 John Engelhart
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+#include <stddef.h>
+#include <stdint.h>
+#include <limits.h>
+#include <TargetConditionals.h>
+#include <AvailabilityMacros.h>
+
+#ifdef __OBJC__
+#import <Foundation/NSArray.h>
+#import <Foundation/NSData.h>
+#import <Foundation/NSDictionary.h>
+#import <Foundation/NSError.h>
+#import <Foundation/NSObjCRuntime.h>
+#import <Foundation/NSString.h>
+#endif // __OBJC__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+// For Mac OS X < 10.5.
+#ifndef NSINTEGER_DEFINED
+#define NSINTEGER_DEFINED
+#if defined(__LP64__) || defined(NS_BUILD_32_LIKE_64)
+typedef long NSInteger;
+typedef unsigned long NSUInteger;
+#define NSIntegerMin LONG_MIN
+#define NSIntegerMax LONG_MAX
+#define NSUIntegerMax ULONG_MAX
+#else // defined(__LP64__) || defined(NS_BUILD_32_LIKE_64)
+typedef int NSInteger;
+typedef unsigned int NSUInteger;
+#define NSIntegerMin INT_MIN
+#define NSIntegerMax INT_MAX
+#define NSUIntegerMax UINT_MAX
+#endif // defined(__LP64__) || defined(NS_BUILD_32_LIKE_64)
+#endif // NSINTEGER_DEFINED
+
+
+#ifndef _JSONKIT_H_
+#define _JSONKIT_H_
+
+#if defined(__GNUC__) && (__GNUC__ >= 4) && defined(__APPLE_CC__) && (__APPLE_CC__ >= 5465)
+#define JK_DEPRECATED_ATTRIBUTE __attribute__((deprecated))
+#else
+#define JK_DEPRECATED_ATTRIBUTE
+#endif
+
+#define JSONKIT_VERSION_MAJOR 1
+#define JSONKIT_VERSION_MINOR 4
+
+typedef NSUInteger JKFlags;
+
+/*
+ JKParseOptionComments : Allow C style // and /_* ... *_/ (without a _, obviously) comments in JSON.
+ JKParseOptionUnicodeNewlines : Allow Unicode recommended (?:\r\n|[\n\v\f\r\x85\p{Zl}\p{Zp}]) newlines.
+ JKParseOptionLooseUnicode : Normally the decoder will stop with an error at any malformed Unicode.
+ This option allows JSON with malformed Unicode to be parsed without reporting an error.
+ Any malformed Unicode is replaced with \uFFFD, or "REPLACEMENT CHARACTER".
+ */
+
+enum {
+ JKParseOptionNone = 0,
+ JKParseOptionStrict = 0,
+ JKParseOptionComments = (1 << 0),
+ JKParseOptionUnicodeNewlines = (1 << 1),
+ JKParseOptionLooseUnicode = (1 << 2),
+ JKParseOptionPermitTextAfterValidJSON = (1 << 3),
+ JKParseOptionValidFlags = (JKParseOptionComments | JKParseOptionUnicodeNewlines | JKParseOptionLooseUnicode | JKParseOptionPermitTextAfterValidJSON),
+};
+typedef JKFlags JKParseOptionFlags;
+
+enum {
+ JKSerializeOptionNone = 0,
+ JKSerializeOptionPretty = (1 << 0),
+ JKSerializeOptionEscapeUnicode = (1 << 1),
+ JKSerializeOptionEscapeForwardSlashes = (1 << 4),
+ JKSerializeOptionValidFlags = (JKSerializeOptionPretty | JKSerializeOptionEscapeUnicode | JKSerializeOptionEscapeForwardSlashes),
+};
+typedef JKFlags JKSerializeOptionFlags;
+
+#ifdef __OBJC__
+
+typedef struct JKParseState JKParseState; // Opaque internal, private type.
+
+// As a general rule of thumb, if you use a method that doesn't accept a JKParseOptionFlags argument, it defaults to JKParseOptionStrict
+
+@interface JSONDecoder : NSObject {
+ JKParseState *parseState;
+}
++ (id)decoder;
++ (id)decoderWithParseOptions:(JKParseOptionFlags)parseOptionFlags;
+- (id)initWithParseOptions:(JKParseOptionFlags)parseOptionFlags;
+- (void)clearCache;
+
+// The parse... methods were deprecated in v1.4 in favor of the v1.4 objectWith... methods.
+- (id)parseUTF8String:(const unsigned char *)string length:(size_t)length JK_DEPRECATED_ATTRIBUTE; // Deprecated in JSONKit v1.4. Use objectWithUTF8String:length: instead.
+- (id)parseUTF8String:(const unsigned char *)string length:(size_t)length error:(NSError **)error JK_DEPRECATED_ATTRIBUTE; // Deprecated in JSONKit v1.4. Use objectWithUTF8String:length:error: instead.
+// The NSData MUST be UTF8 encoded JSON.
+- (id)parseJSONData:(NSData *)jsonData JK_DEPRECATED_ATTRIBUTE; // Deprecated in JSONKit v1.4. Use objectWithData: instead.
+- (id)parseJSONData:(NSData *)jsonData error:(NSError **)error JK_DEPRECATED_ATTRIBUTE; // Deprecated in JSONKit v1.4. Use objectWithData:error: instead.
+
+// Methods that return immutable collection objects.
+- (id)objectWithUTF8String:(const unsigned char *)string length:(NSUInteger)length;
+- (id)objectWithUTF8String:(const unsigned char *)string length:(NSUInteger)length error:(NSError **)error;
+// The NSData MUST be UTF8 encoded JSON.
+- (id)objectWithData:(NSData *)jsonData;
+- (id)objectWithData:(NSData *)jsonData error:(NSError **)error;
+
+// Methods that return mutable collection objects.
+- (id)mutableObjectWithUTF8String:(const unsigned char *)string length:(NSUInteger)length;
+- (id)mutableObjectWithUTF8String:(const unsigned char *)string length:(NSUInteger)length error:(NSError **)error;
+// The NSData MUST be UTF8 encoded JSON.
+- (id)mutableObjectWithData:(NSData *)jsonData;
+- (id)mutableObjectWithData:(NSData *)jsonData error:(NSError **)error;
+
+@end
+
+////////////
+#pragma mark Deserializing methods
+////////////
+
+@interface NSString (JSONKitDeserializing)
+- (id)objectFromJSONString;
+- (id)objectFromJSONStringWithParseOptions:(JKParseOptionFlags)parseOptionFlags;
+- (id)objectFromJSONStringWithParseOptions:(JKParseOptionFlags)parseOptionFlags error:(NSError **)error;
+- (id)mutableObjectFromJSONString;
+- (id)mutableObjectFromJSONStringWithParseOptions:(JKParseOptionFlags)parseOptionFlags;
+- (id)mutableObjectFromJSONStringWithParseOptions:(JKParseOptionFlags)parseOptionFlags error:(NSError **)error;
+@end
+
+@interface NSData (JSONKitDeserializing)
+// The NSData MUST be UTF8 encoded JSON.
+- (id)objectFromJSONData;
+- (id)objectFromJSONDataWithParseOptions:(JKParseOptionFlags)parseOptionFlags;
+- (id)objectFromJSONDataWithParseOptions:(JKParseOptionFlags)parseOptionFlags error:(NSError **)error;
+- (id)mutableObjectFromJSONData;
+- (id)mutableObjectFromJSONDataWithParseOptions:(JKParseOptionFlags)parseOptionFlags;
+- (id)mutableObjectFromJSONDataWithParseOptions:(JKParseOptionFlags)parseOptionFlags error:(NSError **)error;
+@end
+
+////////////
+#pragma mark Serializing methods
+////////////
+
+@interface NSString (JSONKitSerializing)
+// Convenience methods for those that need to serialize the receiving NSString (i.e., instead of having to serialize a NSArray with a single NSString, you can "serialize to JSON" just the NSString).
+// Normally, a string that is serialized to JSON has quotation marks surrounding it, which you may or may not want when serializing a single string, and can be controlled with includeQuotes:
+// includeQuotes:YES `a "test"...` -> `"a \"test\"..."`
+// includeQuotes:NO `a "test"...` -> `a \"test\"...`
+- (NSData *)JSONData; // Invokes JSONDataWithOptions:JKSerializeOptionNone includeQuotes:YES