appjam 0.1.8.8 → 0.1.8.9

Sign up to get free protection for your applications and to get access to all the features.
Files changed (168) hide show
  1. data/README.md +22 -62
  2. data/lib/appjam/generators/gist.yml +1 -1
  3. data/lib/appjam/generators/templates/blank/EiffelApplication.xcodeproj/project.pbxproj +1166 -482
  4. data/lib/appjam/generators/templates/blank/EiffelApplication.xcodeproj/project.xcworkspace/xcuserdata/eiffel.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
  5. data/lib/appjam/generators/templates/blank/EiffelApplication/EiffelApplication-Prefix.pch.tt +26 -0
  6. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/AwesomeMenu/AwesomeMenu.h +52 -0
  7. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/AwesomeMenu/AwesomeMenu.m +412 -0
  8. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/AwesomeMenu/AwesomeMenuItem.h +44 -0
  9. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/AwesomeMenu/AwesomeMenuItem.m +97 -0
  10. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/AwesomeMenu/Images/bg-addbutton-highlighted.png +0 -0
  11. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/AwesomeMenu/Images/bg-addbutton-highlighted@2x.png +0 -0
  12. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/AwesomeMenu/Images/bg-addbutton.png +0 -0
  13. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/AwesomeMenu/Images/bg-addbutton@2x.png +0 -0
  14. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/AwesomeMenu/Images/bg-menuitem-highlighted.png +0 -0
  15. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/AwesomeMenu/Images/bg-menuitem-highlighted@2x.png +0 -0
  16. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/AwesomeMenu/Images/bg-menuitem.png +0 -0
  17. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/AwesomeMenu/Images/bg-menuitem@2x.png +0 -0
  18. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/AwesomeMenu/Images/icon-plus-highlighted.png +0 -0
  19. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/AwesomeMenu/Images/icon-plus-highlighted@2x.png +0 -0
  20. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/AwesomeMenu/Images/icon-plus.png +0 -0
  21. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/AwesomeMenu/Images/icon-plus@2x.png +0 -0
  22. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/AwesomeMenu/Images/icon-star.png +0 -0
  23. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/AwesomeMenu/Images/icon-star@2x.png +0 -0
  24. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/CMPopTipView/CMPopTipView.h +167 -0
  25. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/CMPopTipView/CMPopTipView.m +639 -0
  26. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/FXLabel/FXLabel.h +97 -0
  27. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/FXLabel/FXLabel.m +1080 -0
  28. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/MBProgressHUD/MBProgressHUD.h +451 -0
  29. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/MBProgressHUD/MBProgressHUD.m +865 -0
  30. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/PaperFold/FacingView.h +42 -0
  31. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/PaperFold/FacingView.m +56 -0
  32. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/PaperFold/FoldView.h +90 -0
  33. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/PaperFold/FoldView.m +316 -0
  34. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/PaperFold/MultiFoldView.h +104 -0
  35. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/PaperFold/MultiFoldView.m +516 -0
  36. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/PaperFold/PaperFoldConstants.h +49 -0
  37. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/PaperFold/PaperFoldNavigationController.h +18 -0
  38. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/PaperFold/PaperFoldNavigationController.m +88 -0
  39. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/PaperFold/PaperFoldResources.bundle/swipe_guide_left.png +0 -0
  40. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/PaperFold/PaperFoldResources.bundle/swipe_guide_left@2x.png +0 -0
  41. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/PaperFold/PaperFoldResources.bundle/swipe_guide_right.png +0 -0
  42. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/PaperFold/PaperFoldResources.bundle/swipe_guide_right@2x.png +0 -0
  43. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/PaperFold/PaperFoldSwipeHintView.h +25 -0
  44. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/PaperFold/PaperFoldSwipeHintView.m +76 -0
  45. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/PaperFold/PaperFoldView.h +131 -0
  46. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/PaperFold/PaperFoldView.m +941 -0
  47. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/PaperFold/Resources/swipe_guide.psd +0 -0
  48. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/PaperFold/Resources/swipe_guide2.psd +0 -0
  49. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/PaperFold/ShadowView.h +46 -0
  50. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/PaperFold/ShadowView.m +82 -0
  51. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/PaperFold/TouchThroughUIView.h +39 -0
  52. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/PaperFold/TouchThroughUIView.m +72 -0
  53. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/PaperFold/UIView+Screenshot.h +42 -0
  54. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/PaperFold/UIView+Screenshot.m +100 -0
  55. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/UIBubbleTableView/NSBubbleData.h +34 -0
  56. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/UIBubbleTableView/NSBubbleData.m +140 -0
  57. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/UIBubbleTableView/UIBubbleHeaderTableViewCell.h +17 -0
  58. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/UIBubbleTableView/UIBubbleHeaderTableViewCell.m +57 -0
  59. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/UIBubbleTableView/UIBubbleTableView.h +30 -0
  60. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/UIBubbleTableView/UIBubbleTableView.m +233 -0
  61. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/UIBubbleTableView/UIBubbleTableViewCell.h +19 -0
  62. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/UIBubbleTableView/UIBubbleTableViewCell.m +122 -0
  63. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/UIBubbleTableView/UIBubbleTableViewDataSource.h +24 -0
  64. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/UIBubbleTableView/UIBubbleTypingTableViewCell.h +20 -0
  65. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/UIBubbleTableView/UIBubbleTypingTableViewCell.m +56 -0
  66. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/UIBubbleTableView/images/bubbleMine.png +0 -0
  67. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/UIBubbleTableView/images/bubbleMine@2x.png +0 -0
  68. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/UIBubbleTableView/images/bubbleSomeone.png +0 -0
  69. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/UIBubbleTableView/images/bubbleSomeone@2x.png +0 -0
  70. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/UIBubbleTableView/images/missingAvatar.png +0 -0
  71. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/UIBubbleTableView/images/missingAvatar@2x.png +0 -0
  72. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/UIBubbleTableView/images/typingMine.png +0 -0
  73. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/UIBubbleTableView/images/typingMine@2x.png +0 -0
  74. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/UIBubbleTableView/images/typingSomeone.png +0 -0
  75. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/UIBubbleTableView/images/typingSomeone@2x.png +0 -0
  76. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/UIGlossyButton/UIGlossyButton.h +124 -0
  77. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/UIGlossyButton/UIGlossyButton.m +545 -0
  78. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/UIGlossyButton/UIView+LayerEffects.h +22 -0
  79. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/UIGlossyButton/UIView+LayerEffects.m +32 -0
  80. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/frameworks/AFIncrementalStore/AFIncrementalStore.h +344 -0
  81. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/frameworks/AFIncrementalStore/AFIncrementalStore.m +848 -0
  82. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/frameworks/AFIncrementalStore/AFRESTClient.h +135 -0
  83. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/frameworks/AFIncrementalStore/AFRESTClient.m +441 -0
  84. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/frameworks/InflectorKit/NSString+InflectorKit.h +40 -0
  85. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/frameworks/InflectorKit/NSString+InflectorKit.m +36 -0
  86. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/frameworks/InflectorKit/TTTStringInflector.h +76 -0
  87. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/frameworks/InflectorKit/TTTStringInflector.m +270 -0
  88. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/frameworks/SDWebImage/MKAnnotationView+WebCache.h +95 -0
  89. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/frameworks/SDWebImage/MKAnnotationView+WebCache.m +78 -0
  90. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/frameworks/SDWebImage/SDImageCache.h +144 -0
  91. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/frameworks/SDWebImage/SDImageCache.m +311 -0
  92. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/frameworks/SDWebImage/SDWebImageCompat.h +40 -0
  93. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/frameworks/SDWebImage/SDWebImageCompat.m +54 -0
  94. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/frameworks/SDWebImage/SDWebImageDecoder.h +18 -0
  95. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/frameworks/SDWebImage/SDWebImageDecoder.m +70 -0
  96. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/frameworks/SDWebImage/SDWebImageDownloader.h +102 -0
  97. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/frameworks/SDWebImage/SDWebImageDownloader.m +226 -0
  98. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/frameworks/SDWebImage/SDWebImageDownloaderOperation.h +25 -0
  99. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/frameworks/SDWebImage/SDWebImageDownloaderOperation.m +339 -0
  100. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/frameworks/SDWebImage/SDWebImageManager.h +167 -0
  101. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/frameworks/SDWebImage/SDWebImageManager.m +244 -0
  102. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/frameworks/SDWebImage/SDWebImageOperation.h +15 -0
  103. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/frameworks/SDWebImage/SDWebImagePrefetcher.h +58 -0
  104. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/frameworks/SDWebImage/SDWebImagePrefetcher.m +127 -0
  105. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/frameworks/SDWebImage/UIButton+WebCache.h +173 -0
  106. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/frameworks/SDWebImage/UIButton+WebCache.m +129 -0
  107. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/frameworks/SDWebImage/UIImageView+WebCache.h +140 -0
  108. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/frameworks/SDWebImage/UIImageView+WebCache.m +84 -0
  109. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CPAnimationSequence/CPAnimationProgram.h +28 -0
  110. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CPAnimationSequence/CPAnimationSequence.h +28 -0
  111. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CPAnimationSequence/CPAnimationStep.h +49 -0
  112. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CPAnimationSequence/private/CPAnimationProgram.m +100 -0
  113. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CPAnimationSequence/private/CPAnimationSequence.m +85 -0
  114. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CPAnimationSequence/private/CPAnimationStep.m +122 -0
  115. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CocoaAsyncSocket/GCDAsyncSocket.h +1074 -0
  116. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CocoaAsyncSocket/GCDAsyncSocket.m +7430 -0
  117. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CocoaHTTPServer/Core/Categories/DDData.h +14 -0
  118. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CocoaHTTPServer/Core/Categories/DDData.m +158 -0
  119. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CocoaHTTPServer/Core/Categories/DDNumber.h +12 -0
  120. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CocoaHTTPServer/Core/Categories/DDNumber.m +88 -0
  121. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CocoaHTTPServer/Core/Categories/DDRange.h +56 -0
  122. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CocoaHTTPServer/Core/Categories/DDRange.m +104 -0
  123. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CocoaHTTPServer/Core/HTTPAuthenticationRequest.h +45 -0
  124. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CocoaHTTPServer/Core/HTTPAuthenticationRequest.m +195 -0
  125. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CocoaHTTPServer/Core/HTTPConnection.h +119 -0
  126. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CocoaHTTPServer/Core/HTTPConnection.m +2708 -0
  127. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CocoaHTTPServer/Core/HTTPLogging.h +136 -0
  128. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CocoaHTTPServer/Core/HTTPMessage.h +48 -0
  129. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CocoaHTTPServer/Core/HTTPMessage.m +113 -0
  130. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CocoaHTTPServer/Core/HTTPResponse.h +149 -0
  131. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CocoaHTTPServer/Core/HTTPServer.h +205 -0
  132. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CocoaHTTPServer/Core/HTTPServer.m +772 -0
  133. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CocoaHTTPServer/Core/Mime/MultipartFormDataParser.h +65 -0
  134. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CocoaHTTPServer/Core/Mime/MultipartFormDataParser.m +529 -0
  135. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CocoaHTTPServer/Core/Mime/MultipartMessageHeader.h +33 -0
  136. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CocoaHTTPServer/Core/Mime/MultipartMessageHeader.m +86 -0
  137. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CocoaHTTPServer/Core/Mime/MultipartMessageHeaderField.h +23 -0
  138. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CocoaHTTPServer/Core/Mime/MultipartMessageHeaderField.m +211 -0
  139. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CocoaHTTPServer/Core/Responses/HTTPAsyncFileResponse.h +75 -0
  140. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CocoaHTTPServer/Core/Responses/HTTPAsyncFileResponse.m +405 -0
  141. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CocoaHTTPServer/Core/Responses/HTTPDataResponse.h +13 -0
  142. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CocoaHTTPServer/Core/Responses/HTTPDataResponse.m +79 -0
  143. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CocoaHTTPServer/Core/Responses/HTTPDynamicFileResponse.h +52 -0
  144. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CocoaHTTPServer/Core/Responses/HTTPDynamicFileResponse.m +292 -0
  145. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CocoaHTTPServer/Core/Responses/HTTPErrorResponse.h +9 -0
  146. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CocoaHTTPServer/Core/Responses/HTTPErrorResponse.m +38 -0
  147. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CocoaHTTPServer/Core/Responses/HTTPFileResponse.h +25 -0
  148. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CocoaHTTPServer/Core/Responses/HTTPFileResponse.m +237 -0
  149. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CocoaHTTPServer/Core/Responses/HTTPRedirectResponse.h +12 -0
  150. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CocoaHTTPServer/Core/Responses/HTTPRedirectResponse.m +73 -0
  151. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CocoaHTTPServer/Core/WebSocket.h +105 -0
  152. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CocoaHTTPServer/Core/WebSocket.m +791 -0
  153. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CocoaHTTPServer/Extensions/WebDAV/DAVConnection.h +7 -0
  154. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CocoaHTTPServer/Extensions/WebDAV/DAVConnection.m +160 -0
  155. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CocoaHTTPServer/Extensions/WebDAV/DAVResponse.h +11 -0
  156. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CocoaHTTPServer/Extensions/WebDAV/DAVResponse.m +372 -0
  157. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CocoaHTTPServer/Extensions/WebDAV/DELETEResponse.h +7 -0
  158. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CocoaHTTPServer/Extensions/WebDAV/DELETEResponse.m +49 -0
  159. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CocoaHTTPServer/Extensions/WebDAV/PUTResponse.h +8 -0
  160. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CocoaHTTPServer/Extensions/WebDAV/PUTResponse.m +69 -0
  161. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/hpple/TFHpple.h +54 -0
  162. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/hpple/TFHpple.m +102 -0
  163. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/hpple/TFHppleElement.h +103 -0
  164. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/hpple/TFHppleElement.m +200 -0
  165. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/hpple/XPathQuery.h +10 -0
  166. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/hpple/XPathQuery.m +197 -0
  167. data/lib/appjam/version.rb +1 -1
  168. metadata +164 -3
@@ -0,0 +1,100 @@
1
+
2
+ // Created by Karsten Litsche on 25.03.12.
3
+ // Copyright (c) 2012 compeople AG. All rights reserved.
4
+
5
+ #import "CPAnimationProgram.h"
6
+
7
+ @interface CPAnimationStep(hidden)
8
+ - (NSArray*) animationStepArray;
9
+ - (CPAnimationStepBlock) animationStep:(BOOL)animated;
10
+ @end
11
+
12
+ @interface CPAnimationProgram()
13
+ @property (nonatomic, strong, readwrite) NSArray* steps;
14
+ @end
15
+
16
+ #pragma mark -
17
+ @implementation CPAnimationProgram
18
+
19
+ #pragma mark - Object lifecycle
20
+
21
+ + (id) programWithSteps:(CPAnimationStep*)first, ... {
22
+ CPAnimationProgram* instance = [[self alloc] init];
23
+ if (instance) {
24
+ NSMutableArray* tempSteps = [[NSMutableArray alloc] initWithCapacity:10];
25
+ va_list args;
26
+ va_start(args, first);
27
+ [tempSteps insertObject:first atIndex:0];
28
+ CPAnimationStep* aStep;
29
+ while ((aStep = va_arg(args, CPAnimationStep*))) {
30
+ [tempSteps insertObject:aStep atIndex:0];
31
+ }
32
+ instance.steps = [NSArray arrayWithArray:tempSteps];
33
+ va_end(args);
34
+ }
35
+ return instance;
36
+ }
37
+
38
+
39
+ #pragma mark - property override
40
+
41
+ - (void) setDelay:(NSTimeInterval)delay {
42
+ NSAssert(NO, @"Setting a delay on a program is undefined and therefore disallowed!");
43
+ }
44
+
45
+ - (void) setDuration:(NSTimeInterval)duration {
46
+ NSAssert(NO, @"Setting a duration on a program is undefined and therefore disallowed!");
47
+ }
48
+
49
+ - (void) setOptions:(UIViewAnimationOptions)options {
50
+ NSAssert(NO, @"Setting options on a program is undefined and therefore disallowed!");
51
+ }
52
+
53
+ #pragma mark - build the sequence
54
+
55
+ - (NSTimeInterval) longestDuration {
56
+ CPAnimationStep* longestStep = nil;
57
+ for (CPAnimationStep* current in self.steps) {
58
+ NSTimeInterval currentDuration = current.delay+current.duration;
59
+ if (currentDuration > longestStep.delay+longestStep.duration) {
60
+ longestStep = current;
61
+ }
62
+ }
63
+ NSAssert(longestStep, @"Program seems to contain no steps.");
64
+ return self.delay + longestStep.delay + longestStep.duration;
65
+ }
66
+
67
+ - (NSArray*) animationStepArray {
68
+ NSMutableArray* array = [NSMutableArray arrayWithCapacity:3];
69
+ // Note: reverse order!
70
+ [array addObject:[CPAnimationStep after:[self longestDuration] animate:^{}]];
71
+ [array addObject:self];
72
+ [array addObject:[CPAnimationStep after:self.delay animate:^{}]];
73
+ return array;
74
+ }
75
+
76
+ - (CPAnimationStepBlock) animationStep:(BOOL)animated {
77
+ CPAnimationStepBlock programStep = ^{
78
+ for (CPAnimationStep* current in self.steps) {
79
+ [current runAnimated:animated];
80
+ }
81
+ };
82
+ return [programStep copy];
83
+ }
84
+
85
+ #pragma mark - pretty-print
86
+
87
+ - (NSString*) description {
88
+ NSMutableString* programBody = [[NSMutableString alloc] initWithCapacity:100*[self.steps count]];
89
+ for (CPAnimationStep* step in self.steps) {
90
+ [programBody appendString:[step description]];
91
+ }
92
+ // indent
93
+ [programBody replaceOccurrencesOfString:@"\n"
94
+ withString:@"\n "
95
+ options:NSCaseInsensitiveSearch
96
+ range:NSMakeRange(0, [programBody length])];
97
+ return [NSString stringWithFormat:@"\n(program:%@\n)", programBody];
98
+ }
99
+
100
+ @end
@@ -0,0 +1,85 @@
1
+
2
+ // Created by Yang Meyer on 26.07.11.
3
+ // Copyright 2011-2012 compeople AG. All rights reserved.
4
+
5
+ #import "CPAnimationSequence.h"
6
+
7
+ @interface CPAnimationStep(hidden)
8
+ - (NSArray*) animationStepArray;
9
+ @end
10
+
11
+ @interface CPAnimationSequence()
12
+ @property (nonatomic, strong, readwrite) NSArray* steps;
13
+ @end
14
+
15
+ #pragma mark -
16
+ @implementation CPAnimationSequence
17
+
18
+ #pragma mark - Object lifecycle
19
+
20
+ + (id) sequenceWithSteps:(CPAnimationStep*)first, ... {
21
+ CPAnimationSequence* instance = [[self alloc] init];
22
+ if (instance) {
23
+ NSMutableArray* tempSteps = [[NSMutableArray alloc] initWithCapacity:10];
24
+ va_list args;
25
+ va_start(args, first);
26
+ [tempSteps insertObject:first atIndex:0];
27
+ CPAnimationStep* aStep;
28
+ while ((aStep = va_arg(args, CPAnimationStep*))) {
29
+ [tempSteps insertObject:aStep atIndex:0];
30
+ }
31
+ instance.steps = [NSArray arrayWithArray:tempSteps];
32
+ va_end(args);
33
+ }
34
+ return instance;
35
+ }
36
+
37
+ #pragma mark - property override
38
+
39
+ - (void) setDelay:(NSTimeInterval)delay {
40
+ NSAssert(NO, @"Setting a delay on a sequence is undefined and therefore disallowed!");
41
+ }
42
+
43
+ - (void) setDuration:(NSTimeInterval)duration {
44
+ NSAssert(NO, @"Setting a duration on a sequence is undefined and therefore disallowed!");
45
+ }
46
+
47
+ - (NSTimeInterval) duration {
48
+ NSTimeInterval fullDuration = 0;
49
+ for (CPAnimationStep* current in self.animationStepArray) {
50
+ fullDuration += current.delay;
51
+ fullDuration += current.duration;
52
+ }
53
+ return fullDuration+self.delay;
54
+ }
55
+
56
+ - (void) setOptions:(UIViewAnimationOptions)options {
57
+ NSAssert(NO, @"Setting options on a sequence is undefined and therefore disallowed!");
58
+ }
59
+
60
+ #pragma mark - build the sequence
61
+
62
+ - (NSArray*) animationStepArray {
63
+ NSMutableArray* array = [NSMutableArray arrayWithCapacity:[self.steps count]];
64
+ for (CPAnimationStep* current in self.steps) {
65
+ [array addObjectsFromArray:[current animationStepArray]];
66
+ }
67
+ return array;
68
+ }
69
+
70
+ #pragma mark - pretty-print
71
+
72
+ - (NSString*) description {
73
+ NSMutableString* sequenceBody = [[NSMutableString alloc] initWithCapacity:100*[self.steps count]];
74
+ for (CPAnimationStep* step in self.steps) {
75
+ [sequenceBody appendString:[step description]];
76
+ }
77
+ // indent
78
+ [sequenceBody replaceOccurrencesOfString:@"\n"
79
+ withString:@"\n "
80
+ options:NSCaseInsensitiveSearch
81
+ range:NSMakeRange(0, [sequenceBody length])];
82
+ return [NSString stringWithFormat:@"\n(sequence:%@\n)", sequenceBody];
83
+ }
84
+
85
+ @end
@@ -0,0 +1,122 @@
1
+
2
+ // Created by Yang Meyer on 26.07.11.
3
+ // Copyright 2011-2012 compeople AG, 2013 Yang Meyer. All rights reserved.
4
+
5
+ #import "CPAnimationStep.h"
6
+
7
+ @interface CPAnimationStep()
8
+ /** A temporary reverse queue of animation steps, i.e. from last to first.
9
+ It is created when the step is run, and is modified during the animation,
10
+ and is destroyed when the animation finishes. */
11
+ @property (nonatomic, strong) NSMutableArray* consumableSteps;
12
+ @end
13
+
14
+ @implementation CPAnimationStep
15
+
16
+ #pragma mark construction
17
+
18
+ + (id) after:(NSTimeInterval)delay animate:(CPAnimationStepBlock)step {
19
+ return [self after:delay for:0.0 options:0 animate:step];
20
+ }
21
+
22
+ + (id) for:(NSTimeInterval)duration animate:(CPAnimationStepBlock)step {
23
+ return [self after:0.0 for:duration options:0 animate:step];
24
+ }
25
+
26
+ + (id) after:(NSTimeInterval)delay for:(NSTimeInterval)duration animate:(CPAnimationStepBlock)step {
27
+ return [self after:delay for:duration options:0 animate:step];
28
+ }
29
+
30
+ + (id) after:(NSTimeInterval)theDelay
31
+ for:(NSTimeInterval)theDuration
32
+ options:(UIViewAnimationOptions)theOptions
33
+ animate:(CPAnimationStepBlock)theStep {
34
+
35
+ CPAnimationStep* instance = [[self alloc] init];
36
+ if (instance) {
37
+ instance.delay = theDelay;
38
+ instance.duration = theDuration;
39
+ instance.options = theOptions;
40
+ instance.step = [theStep copy];
41
+ }
42
+ return instance;
43
+ }
44
+
45
+ #pragma mark action
46
+
47
+ + (void) runBlock:(CPAnimationStepBlock)block afterDelay:(NSTimeInterval)delay {
48
+ dispatch_after(dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC*delay), dispatch_get_main_queue(), block);
49
+ }
50
+
51
+ - (NSArray*) animationStepArray {
52
+ // subclasses must override this!
53
+ return [NSArray arrayWithObject:self];
54
+ }
55
+
56
+ - (CPAnimationStepBlock) animationStep:(BOOL)animated {
57
+ // override it if needed
58
+ return self.step;
59
+ }
60
+
61
+ - (void) runAnimated:(BOOL)animated {
62
+ if (!self.consumableSteps) {
63
+ self.consumableSteps = [[NSMutableArray alloc] initWithArray:[self animationStepArray]];
64
+ }
65
+ if (![self.consumableSteps count]) { // recursion anchor
66
+ self.consumableSteps = nil;
67
+ return; // we're done
68
+ }
69
+ CPAnimationStepBlock completionStep = ^{
70
+ [self.consumableSteps removeLastObject];
71
+ [self runAnimated:animated]; // recurse!
72
+ };
73
+ CPAnimationStep* currentStep = [self.consumableSteps lastObject];
74
+ // Note: do not animate to short steps
75
+ if (animated && currentStep.duration >= 0.02) {
76
+ [UIView animateWithDuration:currentStep.duration
77
+ delay:currentStep.delay
78
+ options:currentStep.options
79
+ animations:[currentStep animationStep:animated]
80
+ completion:^(BOOL finished) {
81
+ if (finished) {
82
+ completionStep();
83
+ }
84
+ }];
85
+ } else {
86
+ void (^execution)(void) = ^{
87
+ [currentStep animationStep:animated]();
88
+ completionStep();
89
+ };
90
+
91
+ if (animated && currentStep.delay) {
92
+ [CPAnimationStep runBlock:execution afterDelay:currentStep.delay];
93
+ } else {
94
+ execution();
95
+ }
96
+ }
97
+ }
98
+
99
+ - (void) run {
100
+ [self runAnimated:YES];
101
+ }
102
+
103
+ #pragma mark - pretty-print
104
+
105
+ - (NSString*) description {
106
+ NSMutableString* result = [[NSMutableString alloc] initWithCapacity:100];
107
+ [result appendString:@"\n["];
108
+ if (self.delay > 0.0) {
109
+ [result appendFormat:@"after:%.1f ", self.delay];
110
+ }
111
+ if (self.duration > 0.0) {
112
+ [result appendFormat:@"for:%.1f ", self.duration];
113
+ }
114
+ if (self.options > 0) {
115
+ [result appendFormat:@"options:%d ", self.options];
116
+ }
117
+ [result appendFormat:@"animate:%@", self.step];
118
+ [result appendString:@"]"];
119
+ return result;
120
+ }
121
+
122
+ @end
@@ -0,0 +1,1074 @@
1
+ //
2
+ // GCDAsyncSocket.h
3
+ //
4
+ // This class is in the public domain.
5
+ // Originally created by Robbie Hanson in Q3 2010.
6
+ // Updated and maintained by Deusty LLC and the Apple development community.
7
+ //
8
+ // https://github.com/robbiehanson/CocoaAsyncSocket
9
+ //
10
+
11
+ #import <Foundation/Foundation.h>
12
+ #import <Security/Security.h>
13
+ #import <Security/SecureTransport.h>
14
+ #import <dispatch/dispatch.h>
15
+
16
+ @class GCDAsyncReadPacket;
17
+ @class GCDAsyncWritePacket;
18
+ @class GCDAsyncSocketPreBuffer;
19
+
20
+ #if TARGET_OS_IPHONE
21
+
22
+ // Compiling for iOS
23
+
24
+ #if __IPHONE_OS_VERSION_MAX_ALLOWED >= 50000 // iOS 5.0 supported
25
+
26
+ #if __IPHONE_OS_VERSION_MIN_REQUIRED >= 50000 // iOS 5.0 supported and required
27
+
28
+ #define IS_SECURE_TRANSPORT_AVAILABLE YES
29
+ #define SECURE_TRANSPORT_MAYBE_AVAILABLE 1
30
+ #define SECURE_TRANSPORT_MAYBE_UNAVAILABLE 0
31
+
32
+ #else // iOS 5.0 supported but not required
33
+
34
+ #ifndef NSFoundationVersionNumber_iPhoneOS_5_0
35
+ #define NSFoundationVersionNumber_iPhoneOS_5_0 881.00
36
+ #endif
37
+
38
+ #define IS_SECURE_TRANSPORT_AVAILABLE (NSFoundationVersionNumber >= NSFoundationVersionNumber_iPhoneOS_5_0)
39
+ #define SECURE_TRANSPORT_MAYBE_AVAILABLE 1
40
+ #define SECURE_TRANSPORT_MAYBE_UNAVAILABLE 1
41
+
42
+ #endif
43
+
44
+ #else // iOS 5.0 not supported
45
+
46
+ #define IS_SECURE_TRANSPORT_AVAILABLE NO
47
+ #define SECURE_TRANSPORT_MAYBE_AVAILABLE 0
48
+ #define SECURE_TRANSPORT_MAYBE_UNAVAILABLE 1
49
+
50
+ #endif
51
+
52
+ #else
53
+
54
+ // Compiling for Mac OS X
55
+
56
+ #define IS_SECURE_TRANSPORT_AVAILABLE YES
57
+ #define SECURE_TRANSPORT_MAYBE_AVAILABLE 1
58
+ #define SECURE_TRANSPORT_MAYBE_UNAVAILABLE 0
59
+
60
+ #endif
61
+
62
+ extern NSString *const GCDAsyncSocketException;
63
+ extern NSString *const GCDAsyncSocketErrorDomain;
64
+
65
+ extern NSString *const GCDAsyncSocketQueueName;
66
+ extern NSString *const GCDAsyncSocketThreadName;
67
+
68
+ #if SECURE_TRANSPORT_MAYBE_AVAILABLE
69
+ extern NSString *const GCDAsyncSocketSSLCipherSuites;
70
+ #if TARGET_OS_IPHONE
71
+ extern NSString *const GCDAsyncSocketSSLProtocolVersionMin;
72
+ extern NSString *const GCDAsyncSocketSSLProtocolVersionMax;
73
+ #else
74
+ extern NSString *const GCDAsyncSocketSSLDiffieHellmanParameters;
75
+ #endif
76
+ #endif
77
+
78
+ enum GCDAsyncSocketError
79
+ {
80
+ GCDAsyncSocketNoError = 0, // Never used
81
+ GCDAsyncSocketBadConfigError, // Invalid configuration
82
+ GCDAsyncSocketBadParamError, // Invalid parameter was passed
83
+ GCDAsyncSocketConnectTimeoutError, // A connect operation timed out
84
+ GCDAsyncSocketReadTimeoutError, // A read operation timed out
85
+ GCDAsyncSocketWriteTimeoutError, // A write operation timed out
86
+ GCDAsyncSocketReadMaxedOutError, // Reached set maxLength without completing
87
+ GCDAsyncSocketClosedError, // The remote peer closed the connection
88
+ GCDAsyncSocketOtherError, // Description provided in userInfo
89
+ };
90
+ typedef enum GCDAsyncSocketError GCDAsyncSocketError;
91
+
92
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
93
+ #pragma mark -
94
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
95
+
96
+ @interface GCDAsyncSocket : NSObject
97
+
98
+ /**
99
+ * GCDAsyncSocket uses the standard delegate paradigm,
100
+ * but executes all delegate callbacks on a given delegate dispatch queue.
101
+ * This allows for maximum concurrency, while at the same time providing easy thread safety.
102
+ *
103
+ * You MUST set a delegate AND delegate dispatch queue before attempting to
104
+ * use the socket, or you will get an error.
105
+ *
106
+ * The socket queue is optional.
107
+ * If you pass NULL, GCDAsyncSocket will automatically create it's own socket queue.
108
+ * If you choose to provide a socket queue, the socket queue must not be a concurrent queue.
109
+ * If you choose to provide a socket queue, and the socket queue has a configured target queue,
110
+ * then please see the discussion for the method markSocketQueueTargetQueue.
111
+ *
112
+ * The delegate queue and socket queue can optionally be the same.
113
+ **/
114
+ - (id)init;
115
+ - (id)initWithSocketQueue:(dispatch_queue_t)sq;
116
+ - (id)initWithDelegate:(id)aDelegate delegateQueue:(dispatch_queue_t)dq;
117
+ - (id)initWithDelegate:(id)aDelegate delegateQueue:(dispatch_queue_t)dq socketQueue:(dispatch_queue_t)sq;
118
+
119
+ #pragma mark Configuration
120
+
121
+ - (id)delegate;
122
+ - (void)setDelegate:(id)delegate;
123
+ - (void)synchronouslySetDelegate:(id)delegate;
124
+
125
+ - (dispatch_queue_t)delegateQueue;
126
+ - (void)setDelegateQueue:(dispatch_queue_t)delegateQueue;
127
+ - (void)synchronouslySetDelegateQueue:(dispatch_queue_t)delegateQueue;
128
+
129
+ - (void)getDelegate:(id *)delegatePtr delegateQueue:(dispatch_queue_t *)delegateQueuePtr;
130
+ - (void)setDelegate:(id)delegate delegateQueue:(dispatch_queue_t)delegateQueue;
131
+ - (void)synchronouslySetDelegate:(id)delegate delegateQueue:(dispatch_queue_t)delegateQueue;
132
+
133
+ /**
134
+ * By default, both IPv4 and IPv6 are enabled.
135
+ *
136
+ * For accepting incoming connections, this means GCDAsyncSocket automatically supports both protocols,
137
+ * and can simulataneously accept incoming connections on either protocol.
138
+ *
139
+ * For outgoing connections, this means GCDAsyncSocket can connect to remote hosts running either protocol.
140
+ * If a DNS lookup returns only IPv4 results, GCDAsyncSocket will automatically use IPv4.
141
+ * If a DNS lookup returns only IPv6 results, GCDAsyncSocket will automatically use IPv6.
142
+ * If a DNS lookup returns both IPv4 and IPv6 results, the preferred protocol will be chosen.
143
+ * By default, the preferred protocol is IPv4, but may be configured as desired.
144
+ **/
145
+ - (BOOL)isIPv4Enabled;
146
+ - (void)setIPv4Enabled:(BOOL)flag;
147
+
148
+ - (BOOL)isIPv6Enabled;
149
+ - (void)setIPv6Enabled:(BOOL)flag;
150
+
151
+ - (BOOL)isIPv4PreferredOverIPv6;
152
+ - (void)setPreferIPv4OverIPv6:(BOOL)flag;
153
+
154
+ /**
155
+ * User data allows you to associate arbitrary information with the socket.
156
+ * This data is not used internally by socket in any way.
157
+ **/
158
+ - (id)userData;
159
+ - (void)setUserData:(id)arbitraryUserData;
160
+
161
+ #pragma mark Accepting
162
+
163
+ /**
164
+ * Tells the socket to begin listening and accepting connections on the given port.
165
+ * When a connection is accepted, a new instance of GCDAsyncSocket will be spawned to handle it,
166
+ * and the socket:didAcceptNewSocket: delegate method will be invoked.
167
+ *
168
+ * The socket will listen on all available interfaces (e.g. wifi, ethernet, etc)
169
+ **/
170
+ - (BOOL)acceptOnPort:(uint16_t)port error:(NSError **)errPtr;
171
+
172
+ /**
173
+ * This method is the same as acceptOnPort:error: with the
174
+ * additional option of specifying which interface to listen on.
175
+ *
176
+ * For example, you could specify that the socket should only accept connections over ethernet,
177
+ * and not other interfaces such as wifi.
178
+ *
179
+ * The interface may be specified by name (e.g. "en1" or "lo0") or by IP address (e.g. "192.168.4.34").
180
+ * You may also use the special strings "localhost" or "loopback" to specify that
181
+ * the socket only accept connections from the local machine.
182
+ *
183
+ * You can see the list of interfaces via the command line utility "ifconfig",
184
+ * or programmatically via the getifaddrs() function.
185
+ *
186
+ * To accept connections on any interface pass nil, or simply use the acceptOnPort:error: method.
187
+ **/
188
+ - (BOOL)acceptOnInterface:(NSString *)interface port:(uint16_t)port error:(NSError **)errPtr;
189
+
190
+ #pragma mark Connecting
191
+
192
+ /**
193
+ * Connects to the given host and port.
194
+ *
195
+ * This method invokes connectToHost:onPort:viaInterface:withTimeout:error:
196
+ * and uses the default interface, and no timeout.
197
+ **/
198
+ - (BOOL)connectToHost:(NSString *)host onPort:(uint16_t)port error:(NSError **)errPtr;
199
+
200
+ /**
201
+ * Connects to the given host and port with an optional timeout.
202
+ *
203
+ * This method invokes connectToHost:onPort:viaInterface:withTimeout:error: and uses the default interface.
204
+ **/
205
+ - (BOOL)connectToHost:(NSString *)host
206
+ onPort:(uint16_t)port
207
+ withTimeout:(NSTimeInterval)timeout
208
+ error:(NSError **)errPtr;
209
+
210
+ /**
211
+ * Connects to the given host & port, via the optional interface, with an optional timeout.
212
+ *
213
+ * The host may be a domain name (e.g. "deusty.com") or an IP address string (e.g. "192.168.0.2").
214
+ * The host may also be the special strings "localhost" or "loopback" to specify connecting
215
+ * to a service on the local machine.
216
+ *
217
+ * The interface may be a name (e.g. "en1" or "lo0") or the corresponding IP address (e.g. "192.168.4.35").
218
+ * The interface may also be used to specify the local port (see below).
219
+ *
220
+ * To not time out use a negative time interval.
221
+ *
222
+ * This method will return NO if an error is detected, and set the error pointer (if one was given).
223
+ * Possible errors would be a nil host, invalid interface, or socket is already connected.
224
+ *
225
+ * If no errors are detected, this method will start a background connect operation and immediately return YES.
226
+ * The delegate callbacks are used to notify you when the socket connects, or if the host was unreachable.
227
+ *
228
+ * Since this class supports queued reads and writes, you can immediately start reading and/or writing.
229
+ * All read/write operations will be queued, and upon socket connection,
230
+ * the operations will be dequeued and processed in order.
231
+ *
232
+ * The interface may optionally contain a port number at the end of the string, separated by a colon.
233
+ * This allows you to specify the local port that should be used for the outgoing connection. (read paragraph to end)
234
+ * To specify both interface and local port: "en1:8082" or "192.168.4.35:2424".
235
+ * To specify only local port: ":8082".
236
+ * Please note this is an advanced feature, and is somewhat hidden on purpose.
237
+ * You should understand that 99.999% of the time you should NOT specify the local port for an outgoing connection.
238
+ * If you think you need to, there is a very good chance you have a fundamental misunderstanding somewhere.
239
+ * Local ports do NOT need to match remote ports. In fact, they almost never do.
240
+ * This feature is here for networking professionals using very advanced techniques.
241
+ **/
242
+ - (BOOL)connectToHost:(NSString *)host
243
+ onPort:(uint16_t)port
244
+ viaInterface:(NSString *)interface
245
+ withTimeout:(NSTimeInterval)timeout
246
+ error:(NSError **)errPtr;
247
+
248
+ /**
249
+ * Connects to the given address, specified as a sockaddr structure wrapped in a NSData object.
250
+ * For example, a NSData object returned from NSNetService's addresses method.
251
+ *
252
+ * If you have an existing struct sockaddr you can convert it to a NSData object like so:
253
+ * struct sockaddr sa -> NSData *dsa = [NSData dataWithBytes:&remoteAddr length:remoteAddr.sa_len];
254
+ * struct sockaddr *sa -> NSData *dsa = [NSData dataWithBytes:remoteAddr length:remoteAddr->sa_len];
255
+ *
256
+ * This method invokes connectToAdd
257
+ **/
258
+ - (BOOL)connectToAddress:(NSData *)remoteAddr error:(NSError **)errPtr;
259
+
260
+ /**
261
+ * This method is the same as connectToAddress:error: with an additional timeout option.
262
+ * To not time out use a negative time interval, or simply use the connectToAddress:error: method.
263
+ **/
264
+ - (BOOL)connectToAddress:(NSData *)remoteAddr withTimeout:(NSTimeInterval)timeout error:(NSError **)errPtr;
265
+
266
+ /**
267
+ * Connects to the given address, using the specified interface and timeout.
268
+ *
269
+ * The address is specified as a sockaddr structure wrapped in a NSData object.
270
+ * For example, a NSData object returned from NSNetService's addresses method.
271
+ *
272
+ * If you have an existing struct sockaddr you can convert it to a NSData object like so:
273
+ * struct sockaddr sa -> NSData *dsa = [NSData dataWithBytes:&remoteAddr length:remoteAddr.sa_len];
274
+ * struct sockaddr *sa -> NSData *dsa = [NSData dataWithBytes:remoteAddr length:remoteAddr->sa_len];
275
+ *
276
+ * The interface may be a name (e.g. "en1" or "lo0") or the corresponding IP address (e.g. "192.168.4.35").
277
+ * The interface may also be used to specify the local port (see below).
278
+ *
279
+ * The timeout is optional. To not time out use a negative time interval.
280
+ *
281
+ * This method will return NO if an error is detected, and set the error pointer (if one was given).
282
+ * Possible errors would be a nil host, invalid interface, or socket is already connected.
283
+ *
284
+ * If no errors are detected, this method will start a background connect operation and immediately return YES.
285
+ * The delegate callbacks are used to notify you when the socket connects, or if the host was unreachable.
286
+ *
287
+ * Since this class supports queued reads and writes, you can immediately start reading and/or writing.
288
+ * All read/write operations will be queued, and upon socket connection,
289
+ * the operations will be dequeued and processed in order.
290
+ *
291
+ * The interface may optionally contain a port number at the end of the string, separated by a colon.
292
+ * This allows you to specify the local port that should be used for the outgoing connection. (read paragraph to end)
293
+ * To specify both interface and local port: "en1:8082" or "192.168.4.35:2424".
294
+ * To specify only local port: ":8082".
295
+ * Please note this is an advanced feature, and is somewhat hidden on purpose.
296
+ * You should understand that 99.999% of the time you should NOT specify the local port for an outgoing connection.
297
+ * If you think you need to, there is a very good chance you have a fundamental misunderstanding somewhere.
298
+ * Local ports do NOT need to match remote ports. In fact, they almost never do.
299
+ * This feature is here for networking professionals using very advanced techniques.
300
+ **/
301
+ - (BOOL)connectToAddress:(NSData *)remoteAddr
302
+ viaInterface:(NSString *)interface
303
+ withTimeout:(NSTimeInterval)timeout
304
+ error:(NSError **)errPtr;
305
+
306
+ #pragma mark Disconnecting
307
+
308
+ /**
309
+ * Disconnects immediately (synchronously). Any pending reads or writes are dropped.
310
+ *
311
+ * If the socket is not already disconnected, an invocation to the socketDidDisconnect:withError: delegate method
312
+ * will be queued onto the delegateQueue asynchronously (behind any previously queued delegate methods).
313
+ * In other words, the disconnected delegate method will be invoked sometime shortly after this method returns.
314
+ *
315
+ * Please note the recommended way of releasing a GCDAsyncSocket instance (e.g. in a dealloc method)
316
+ * [asyncSocket setDelegate:nil];
317
+ * [asyncSocket disconnect];
318
+ * [asyncSocket release];
319
+ *
320
+ * If you plan on disconnecting the socket, and then immediately asking it to connect again,
321
+ * you'll likely want to do so like this:
322
+ * [asyncSocket setDelegate:nil];
323
+ * [asyncSocket disconnect];
324
+ * [asyncSocket setDelegate:self];
325
+ * [asyncSocket connect...];
326
+ **/
327
+ - (void)disconnect;
328
+
329
+ /**
330
+ * Disconnects after all pending reads have completed.
331
+ * After calling this, the read and write methods will do nothing.
332
+ * The socket will disconnect even if there are still pending writes.
333
+ **/
334
+ - (void)disconnectAfterReading;
335
+
336
+ /**
337
+ * Disconnects after all pending writes have completed.
338
+ * After calling this, the read and write methods will do nothing.
339
+ * The socket will disconnect even if there are still pending reads.
340
+ **/
341
+ - (void)disconnectAfterWriting;
342
+
343
+ /**
344
+ * Disconnects after all pending reads and writes have completed.
345
+ * After calling this, the read and write methods will do nothing.
346
+ **/
347
+ - (void)disconnectAfterReadingAndWriting;
348
+
349
+ #pragma mark Diagnostics
350
+
351
+ /**
352
+ * Returns whether the socket is disconnected or connected.
353
+ *
354
+ * A disconnected socket may be recycled.
355
+ * That is, it can used again for connecting or listening.
356
+ *
357
+ * If a socket is in the process of connecting, it may be neither disconnected nor connected.
358
+ **/
359
+ - (BOOL)isDisconnected;
360
+ - (BOOL)isConnected;
361
+
362
+ /**
363
+ * Returns the local or remote host and port to which this socket is connected, or nil and 0 if not connected.
364
+ * The host will be an IP address.
365
+ **/
366
+ - (NSString *)connectedHost;
367
+ - (uint16_t)connectedPort;
368
+
369
+ - (NSString *)localHost;
370
+ - (uint16_t)localPort;
371
+
372
+ /**
373
+ * Returns the local or remote address to which this socket is connected,
374
+ * specified as a sockaddr structure wrapped in a NSData object.
375
+ *
376
+ * See also the connectedHost, connectedPort, localHost and localPort methods.
377
+ **/
378
+ - (NSData *)connectedAddress;
379
+ - (NSData *)localAddress;
380
+
381
+ /**
382
+ * Returns whether the socket is IPv4 or IPv6.
383
+ * An accepting socket may be both.
384
+ **/
385
+ - (BOOL)isIPv4;
386
+ - (BOOL)isIPv6;
387
+
388
+ /**
389
+ * Returns whether or not the socket has been secured via SSL/TLS.
390
+ *
391
+ * See also the startTLS method.
392
+ **/
393
+ - (BOOL)isSecure;
394
+
395
+ #pragma mark Reading
396
+
397
+ // The readData and writeData methods won't block (they are asynchronous).
398
+ //
399
+ // When a read is complete the socket:didReadData:withTag: delegate method is dispatched on the delegateQueue.
400
+ // When a write is complete the socket:didWriteDataWithTag: delegate method is dispatched on the delegateQueue.
401
+ //
402
+ // You may optionally set a timeout for any read/write operation. (To not timeout, use a negative time interval.)
403
+ // If a read/write opertion times out, the corresponding "socket:shouldTimeout..." delegate method
404
+ // is called to optionally allow you to extend the timeout.
405
+ // Upon a timeout, the "socket:didDisconnectWithError:" method is called
406
+ //
407
+ // The tag is for your convenience.
408
+ // You can use it as an array index, step number, state id, pointer, etc.
409
+
410
+ /**
411
+ * Reads the first available bytes that become available on the socket.
412
+ *
413
+ * If the timeout value is negative, the read operation will not use a timeout.
414
+ **/
415
+ - (void)readDataWithTimeout:(NSTimeInterval)timeout tag:(long)tag;
416
+
417
+ /**
418
+ * Reads the first available bytes that become available on the socket.
419
+ * The bytes will be appended to the given byte buffer starting at the given offset.
420
+ * The given buffer will automatically be increased in size if needed.
421
+ *
422
+ * If the timeout value is negative, the read operation will not use a timeout.
423
+ * If the buffer if nil, the socket will create a buffer for you.
424
+ *
425
+ * If the bufferOffset is greater than the length of the given buffer,
426
+ * the method will do nothing, and the delegate will not be called.
427
+ *
428
+ * If you pass a buffer, you must not alter it in any way while the socket is using it.
429
+ * After completion, the data returned in socket:didReadData:withTag: will be a subset of the given buffer.
430
+ * That is, it will reference the bytes that were appended to the given buffer via
431
+ * the method [NSData dataWithBytesNoCopy:length:freeWhenDone:NO].
432
+ **/
433
+ - (void)readDataWithTimeout:(NSTimeInterval)timeout
434
+ buffer:(NSMutableData *)buffer
435
+ bufferOffset:(NSUInteger)offset
436
+ tag:(long)tag;
437
+
438
+ /**
439
+ * Reads the first available bytes that become available on the socket.
440
+ * The bytes will be appended to the given byte buffer starting at the given offset.
441
+ * The given buffer will automatically be increased in size if needed.
442
+ * A maximum of length bytes will be read.
443
+ *
444
+ * If the timeout value is negative, the read operation will not use a timeout.
445
+ * If the buffer if nil, a buffer will automatically be created for you.
446
+ * If maxLength is zero, no length restriction is enforced.
447
+ *
448
+ * If the bufferOffset is greater than the length of the given buffer,
449
+ * the method will do nothing, and the delegate will not be called.
450
+ *
451
+ * If you pass a buffer, you must not alter it in any way while the socket is using it.
452
+ * After completion, the data returned in socket:didReadData:withTag: will be a subset of the given buffer.
453
+ * That is, it will reference the bytes that were appended to the given buffer via
454
+ * the method [NSData dataWithBytesNoCopy:length:freeWhenDone:NO].
455
+ **/
456
+ - (void)readDataWithTimeout:(NSTimeInterval)timeout
457
+ buffer:(NSMutableData *)buffer
458
+ bufferOffset:(NSUInteger)offset
459
+ maxLength:(NSUInteger)length
460
+ tag:(long)tag;
461
+
462
+ /**
463
+ * Reads the given number of bytes.
464
+ *
465
+ * If the timeout value is negative, the read operation will not use a timeout.
466
+ *
467
+ * If the length is 0, this method does nothing and the delegate is not called.
468
+ **/
469
+ - (void)readDataToLength:(NSUInteger)length withTimeout:(NSTimeInterval)timeout tag:(long)tag;
470
+
471
+ /**
472
+ * Reads the given number of bytes.
473
+ * The bytes will be appended to the given byte buffer starting at the given offset.
474
+ * The given buffer will automatically be increased in size if needed.
475
+ *
476
+ * If the timeout value is negative, the read operation will not use a timeout.
477
+ * If the buffer if nil, a buffer will automatically be created for you.
478
+ *
479
+ * If the length is 0, this method does nothing and the delegate is not called.
480
+ * If the bufferOffset is greater than the length of the given buffer,
481
+ * the method will do nothing, and the delegate will not be called.
482
+ *
483
+ * If you pass a buffer, you must not alter it in any way while AsyncSocket is using it.
484
+ * After completion, the data returned in socket:didReadData:withTag: will be a subset of the given buffer.
485
+ * That is, it will reference the bytes that were appended to the given buffer via
486
+ * the method [NSData dataWithBytesNoCopy:length:freeWhenDone:NO].
487
+ **/
488
+ - (void)readDataToLength:(NSUInteger)length
489
+ withTimeout:(NSTimeInterval)timeout
490
+ buffer:(NSMutableData *)buffer
491
+ bufferOffset:(NSUInteger)offset
492
+ tag:(long)tag;
493
+
494
+ /**
495
+ * Reads bytes until (and including) the passed "data" parameter, which acts as a separator.
496
+ *
497
+ * If the timeout value is negative, the read operation will not use a timeout.
498
+ *
499
+ * If you pass nil or zero-length data as the "data" parameter,
500
+ * the method will do nothing (except maybe print a warning), and the delegate will not be called.
501
+ *
502
+ * To read a line from the socket, use the line separator (e.g. CRLF for HTTP, see below) as the "data" parameter.
503
+ * If you're developing your own custom protocol, be sure your separator can not occur naturally as
504
+ * part of the data between separators.
505
+ * For example, imagine you want to send several small documents over a socket.
506
+ * Using CRLF as a separator is likely unwise, as a CRLF could easily exist within the documents.
507
+ * In this particular example, it would be better to use a protocol similar to HTTP with
508
+ * a header that includes the length of the document.
509
+ * Also be careful that your separator cannot occur naturally as part of the encoding for a character.
510
+ *
511
+ * The given data (separator) parameter should be immutable.
512
+ * For performance reasons, the socket will retain it, not copy it.
513
+ * So if it is immutable, don't modify it while the socket is using it.
514
+ **/
515
+ - (void)readDataToData:(NSData *)data withTimeout:(NSTimeInterval)timeout tag:(long)tag;
516
+
517
+ /**
518
+ * Reads bytes until (and including) the passed "data" parameter, which acts as a separator.
519
+ * The bytes will be appended to the given byte buffer starting at the given offset.
520
+ * The given buffer will automatically be increased in size if needed.
521
+ *
522
+ * If the timeout value is negative, the read operation will not use a timeout.
523
+ * If the buffer if nil, a buffer will automatically be created for you.
524
+ *
525
+ * If the bufferOffset is greater than the length of the given buffer,
526
+ * the method will do nothing (except maybe print a warning), and the delegate will not be called.
527
+ *
528
+ * If you pass a buffer, you must not alter it in any way while the socket is using it.
529
+ * After completion, the data returned in socket:didReadData:withTag: will be a subset of the given buffer.
530
+ * That is, it will reference the bytes that were appended to the given buffer via
531
+ * the method [NSData dataWithBytesNoCopy:length:freeWhenDone:NO].
532
+ *
533
+ * To read a line from the socket, use the line separator (e.g. CRLF for HTTP, see below) as the "data" parameter.
534
+ * If you're developing your own custom protocol, be sure your separator can not occur naturally as
535
+ * part of the data between separators.
536
+ * For example, imagine you want to send several small documents over a socket.
537
+ * Using CRLF as a separator is likely unwise, as a CRLF could easily exist within the documents.
538
+ * In this particular example, it would be better to use a protocol similar to HTTP with
539
+ * a header that includes the length of the document.
540
+ * Also be careful that your separator cannot occur naturally as part of the encoding for a character.
541
+ *
542
+ * The given data (separator) parameter should be immutable.
543
+ * For performance reasons, the socket will retain it, not copy it.
544
+ * So if it is immutable, don't modify it while the socket is using it.
545
+ **/
546
+ - (void)readDataToData:(NSData *)data
547
+ withTimeout:(NSTimeInterval)timeout
548
+ buffer:(NSMutableData *)buffer
549
+ bufferOffset:(NSUInteger)offset
550
+ tag:(long)tag;
551
+
552
+ /**
553
+ * Reads bytes until (and including) the passed "data" parameter, which acts as a separator.
554
+ *
555
+ * If the timeout value is negative, the read operation will not use a timeout.
556
+ *
557
+ * If maxLength is zero, no length restriction is enforced.
558
+ * Otherwise if maxLength bytes are read without completing the read,
559
+ * it is treated similarly to a timeout - the socket is closed with a GCDAsyncSocketReadMaxedOutError.
560
+ * The read will complete successfully if exactly maxLength bytes are read and the given data is found at the end.
561
+ *
562
+ * If you pass nil or zero-length data as the "data" parameter,
563
+ * the method will do nothing (except maybe print a warning), and the delegate will not be called.
564
+ * If you pass a maxLength parameter that is less than the length of the data parameter,
565
+ * the method will do nothing (except maybe print a warning), and the delegate will not be called.
566
+ *
567
+ * To read a line from the socket, use the line separator (e.g. CRLF for HTTP, see below) as the "data" parameter.
568
+ * If you're developing your own custom protocol, be sure your separator can not occur naturally as
569
+ * part of the data between separators.
570
+ * For example, imagine you want to send several small documents over a socket.
571
+ * Using CRLF as a separator is likely unwise, as a CRLF could easily exist within the documents.
572
+ * In this particular example, it would be better to use a protocol similar to HTTP with
573
+ * a header that includes the length of the document.
574
+ * Also be careful that your separator cannot occur naturally as part of the encoding for a character.
575
+ *
576
+ * The given data (separator) parameter should be immutable.
577
+ * For performance reasons, the socket will retain it, not copy it.
578
+ * So if it is immutable, don't modify it while the socket is using it.
579
+ **/
580
+ - (void)readDataToData:(NSData *)data withTimeout:(NSTimeInterval)timeout maxLength:(NSUInteger)length tag:(long)tag;
581
+
582
+ /**
583
+ * Reads bytes until (and including) the passed "data" parameter, which acts as a separator.
584
+ * The bytes will be appended to the given byte buffer starting at the given offset.
585
+ * The given buffer will automatically be increased in size if needed.
586
+ *
587
+ * If the timeout value is negative, the read operation will not use a timeout.
588
+ * If the buffer if nil, a buffer will automatically be created for you.
589
+ *
590
+ * If maxLength is zero, no length restriction is enforced.
591
+ * Otherwise if maxLength bytes are read without completing the read,
592
+ * it is treated similarly to a timeout - the socket is closed with a GCDAsyncSocketReadMaxedOutError.
593
+ * The read will complete successfully if exactly maxLength bytes are read and the given data is found at the end.
594
+ *
595
+ * If you pass a maxLength parameter that is less than the length of the data (separator) parameter,
596
+ * the method will do nothing (except maybe print a warning), and the delegate will not be called.
597
+ * If the bufferOffset is greater than the length of the given buffer,
598
+ * the method will do nothing (except maybe print a warning), and the delegate will not be called.
599
+ *
600
+ * If you pass a buffer, you must not alter it in any way while the socket is using it.
601
+ * After completion, the data returned in socket:didReadData:withTag: will be a subset of the given buffer.
602
+ * That is, it will reference the bytes that were appended to the given buffer via
603
+ * the method [NSData dataWithBytesNoCopy:length:freeWhenDone:NO].
604
+ *
605
+ * To read a line from the socket, use the line separator (e.g. CRLF for HTTP, see below) as the "data" parameter.
606
+ * If you're developing your own custom protocol, be sure your separator can not occur naturally as
607
+ * part of the data between separators.
608
+ * For example, imagine you want to send several small documents over a socket.
609
+ * Using CRLF as a separator is likely unwise, as a CRLF could easily exist within the documents.
610
+ * In this particular example, it would be better to use a protocol similar to HTTP with
611
+ * a header that includes the length of the document.
612
+ * Also be careful that your separator cannot occur naturally as part of the encoding for a character.
613
+ *
614
+ * The given data (separator) parameter should be immutable.
615
+ * For performance reasons, the socket will retain it, not copy it.
616
+ * So if it is immutable, don't modify it while the socket is using it.
617
+ **/
618
+ - (void)readDataToData:(NSData *)data
619
+ withTimeout:(NSTimeInterval)timeout
620
+ buffer:(NSMutableData *)buffer
621
+ bufferOffset:(NSUInteger)offset
622
+ maxLength:(NSUInteger)length
623
+ tag:(long)tag;
624
+
625
+ /**
626
+ * Returns progress of the current read, from 0.0 to 1.0, or NaN if no current read (use isnan() to check).
627
+ * The parameters "tag", "done" and "total" will be filled in if they aren't NULL.
628
+ **/
629
+ - (float)progressOfReadReturningTag:(long *)tagPtr bytesDone:(NSUInteger *)donePtr total:(NSUInteger *)totalPtr;
630
+
631
+ #pragma mark Writing
632
+
633
+ /**
634
+ * Writes data to the socket, and calls the delegate when finished.
635
+ *
636
+ * If you pass in nil or zero-length data, this method does nothing and the delegate will not be called.
637
+ * If the timeout value is negative, the write operation will not use a timeout.
638
+ *
639
+ * Thread-Safety Note:
640
+ * If the given data parameter is mutable (NSMutableData) then you MUST NOT alter the data while
641
+ * the socket is writing it. In other words, it's not safe to alter the data until after the delegate method
642
+ * socket:didWriteDataWithTag: is invoked signifying that this particular write operation has completed.
643
+ * This is due to the fact that GCDAsyncSocket does NOT copy the data. It simply retains it.
644
+ * This is for performance reasons. Often times, if NSMutableData is passed, it is because
645
+ * a request/response was built up in memory. Copying this data adds an unwanted/unneeded overhead.
646
+ * If you need to write data from an immutable buffer, and you need to alter the buffer before the socket
647
+ * completes writing the bytes (which is NOT immediately after this method returns, but rather at a later time
648
+ * when the delegate method notifies you), then you should first copy the bytes, and pass the copy to this method.
649
+ **/
650
+ - (void)writeData:(NSData *)data withTimeout:(NSTimeInterval)timeout tag:(long)tag;
651
+
652
+ /**
653
+ * Returns progress of the current write, from 0.0 to 1.0, or NaN if no current write (use isnan() to check).
654
+ * The parameters "tag", "done" and "total" will be filled in if they aren't NULL.
655
+ **/
656
+ - (float)progressOfWriteReturningTag:(long *)tagPtr bytesDone:(NSUInteger *)donePtr total:(NSUInteger *)totalPtr;
657
+
658
+ #pragma mark Security
659
+
660
+ /**
661
+ * Secures the connection using SSL/TLS.
662
+ *
663
+ * This method may be called at any time, and the TLS handshake will occur after all pending reads and writes
664
+ * are finished. This allows one the option of sending a protocol dependent StartTLS message, and queuing
665
+ * the upgrade to TLS at the same time, without having to wait for the write to finish.
666
+ * Any reads or writes scheduled after this method is called will occur over the secured connection.
667
+ *
668
+ * The possible keys and values for the TLS settings are well documented.
669
+ * Standard keys are:
670
+ *
671
+ * - kCFStreamSSLLevel
672
+ * - kCFStreamSSLAllowsExpiredCertificates
673
+ * - kCFStreamSSLAllowsExpiredRoots
674
+ * - kCFStreamSSLAllowsAnyRoot
675
+ * - kCFStreamSSLValidatesCertificateChain
676
+ * - kCFStreamSSLPeerName
677
+ * - kCFStreamSSLCertificates
678
+ * - kCFStreamSSLIsServer
679
+ *
680
+ * If SecureTransport is available on iOS:
681
+ *
682
+ * - GCDAsyncSocketSSLCipherSuites
683
+ * - GCDAsyncSocketSSLProtocolVersionMin
684
+ * - GCDAsyncSocketSSLProtocolVersionMax
685
+ *
686
+ * If SecureTransport is available on Mac OS X:
687
+ *
688
+ * - GCDAsyncSocketSSLCipherSuites
689
+ * - GCDAsyncSocketSSLDiffieHellmanParameters;
690
+ *
691
+ *
692
+ * Please refer to Apple's documentation for associated values, as well as other possible keys.
693
+ *
694
+ * If you pass in nil or an empty dictionary, the default settings will be used.
695
+ *
696
+ * The default settings will check to make sure the remote party's certificate is signed by a
697
+ * trusted 3rd party certificate agency (e.g. verisign) and that the certificate is not expired.
698
+ * However it will not verify the name on the certificate unless you
699
+ * give it a name to verify against via the kCFStreamSSLPeerName key.
700
+ * The security implications of this are important to understand.
701
+ * Imagine you are attempting to create a secure connection to MySecureServer.com,
702
+ * but your socket gets directed to MaliciousServer.com because of a hacked DNS server.
703
+ * If you simply use the default settings, and MaliciousServer.com has a valid certificate,
704
+ * the default settings will not detect any problems since the certificate is valid.
705
+ * To properly secure your connection in this particular scenario you
706
+ * should set the kCFStreamSSLPeerName property to "MySecureServer.com".
707
+ * If you do not know the peer name of the remote host in advance (for example, you're not sure
708
+ * if it will be "domain.com" or "www.domain.com"), then you can use the default settings to validate the
709
+ * certificate, and then use the X509Certificate class to verify the issuer after the socket has been secured.
710
+ * The X509Certificate class is part of the CocoaAsyncSocket open source project.
711
+ **/
712
+ - (void)startTLS:(NSDictionary *)tlsSettings;
713
+
714
+ #pragma mark Advanced
715
+
716
+ /**
717
+ * Traditionally sockets are not closed until the conversation is over.
718
+ * However, it is technically possible for the remote enpoint to close its write stream.
719
+ * Our socket would then be notified that there is no more data to be read,
720
+ * but our socket would still be writeable and the remote endpoint could continue to receive our data.
721
+ *
722
+ * The argument for this confusing functionality stems from the idea that a client could shut down its
723
+ * write stream after sending a request to the server, thus notifying the server there are to be no further requests.
724
+ * In practice, however, this technique did little to help server developers.
725
+ *
726
+ * To make matters worse, from a TCP perspective there is no way to tell the difference from a read stream close
727
+ * and a full socket close. They both result in the TCP stack receiving a FIN packet. The only way to tell
728
+ * is by continuing to write to the socket. If it was only a read stream close, then writes will continue to work.
729
+ * Otherwise an error will be occur shortly (when the remote end sends us a RST packet).
730
+ *
731
+ * In addition to the technical challenges and confusion, many high level socket/stream API's provide
732
+ * no support for dealing with the problem. If the read stream is closed, the API immediately declares the
733
+ * socket to be closed, and shuts down the write stream as well. In fact, this is what Apple's CFStream API does.
734
+ * It might sound like poor design at first, but in fact it simplifies development.
735
+ *
736
+ * The vast majority of the time if the read stream is closed it's because the remote endpoint closed its socket.
737
+ * Thus it actually makes sense to close the socket at this point.
738
+ * And in fact this is what most networking developers want and expect to happen.
739
+ * However, if you are writing a server that interacts with a plethora of clients,
740
+ * you might encounter a client that uses the discouraged technique of shutting down its write stream.
741
+ * If this is the case, you can set this property to NO,
742
+ * and make use of the socketDidCloseReadStream delegate method.
743
+ *
744
+ * The default value is YES.
745
+ **/
746
+ - (BOOL)autoDisconnectOnClosedReadStream;
747
+ - (void)setAutoDisconnectOnClosedReadStream:(BOOL)flag;
748
+
749
+ /**
750
+ * GCDAsyncSocket maintains thread safety by using an internal serial dispatch_queue.
751
+ * In most cases, the instance creates this queue itself.
752
+ * However, to allow for maximum flexibility, the internal queue may be passed in the init method.
753
+ * This allows for some advanced options such as controlling socket priority via target queues.
754
+ * However, when one begins to use target queues like this, they open the door to some specific deadlock issues.
755
+ *
756
+ * For example, imagine there are 2 queues:
757
+ * dispatch_queue_t socketQueue;
758
+ * dispatch_queue_t socketTargetQueue;
759
+ *
760
+ * If you do this (pseudo-code):
761
+ * socketQueue.targetQueue = socketTargetQueue;
762
+ *
763
+ * Then all socketQueue operations will actually get run on the given socketTargetQueue.
764
+ * This is fine and works great in most situations.
765
+ * But if you run code directly from within the socketTargetQueue that accesses the socket,
766
+ * you could potentially get deadlock. Imagine the following code:
767
+ *
768
+ * - (BOOL)socketHasSomething
769
+ * {
770
+ * __block BOOL result = NO;
771
+ * dispatch_block_t block = ^{
772
+ * result = [self someInternalMethodToBeRunOnlyOnSocketQueue];
773
+ * }
774
+ * if (is_executing_on_queue(socketQueue))
775
+ * block();
776
+ * else
777
+ * dispatch_sync(socketQueue, block);
778
+ *
779
+ * return result;
780
+ * }
781
+ *
782
+ * What happens if you call this method from the socketTargetQueue? The result is deadlock.
783
+ * This is because the GCD API offers no mechanism to discover a queue's targetQueue.
784
+ * Thus we have no idea if our socketQueue is configured with a targetQueue.
785
+ * If we had this information, we could easily avoid deadlock.
786
+ * But, since these API's are missing or unfeasible, you'll have to explicitly set it.
787
+ *
788
+ * IF you pass a socketQueue via the init method,
789
+ * AND you've configured the passed socketQueue with a targetQueue,
790
+ * THEN you should pass the end queue in the target hierarchy.
791
+ *
792
+ * For example, consider the following queue hierarchy:
793
+ * socketQueue -> ipQueue -> moduleQueue
794
+ *
795
+ * This example demonstrates priority shaping within some server.
796
+ * All incoming client connections from the same IP address are executed on the same target queue.
797
+ * And all connections for a particular module are executed on the same target queue.
798
+ * Thus, the priority of all networking for the entire module can be changed on the fly.
799
+ * Additionally, networking traffic from a single IP cannot monopolize the module.
800
+ *
801
+ * Here's how you would accomplish something like that:
802
+ * - (dispatch_queue_t)newSocketQueueForConnectionFromAddress:(NSData *)address onSocket:(GCDAsyncSocket *)sock
803
+ * {
804
+ * dispatch_queue_t socketQueue = dispatch_queue_create("", NULL);
805
+ * dispatch_queue_t ipQueue = [self ipQueueForAddress:address];
806
+ *
807
+ * dispatch_set_target_queue(socketQueue, ipQueue);
808
+ * dispatch_set_target_queue(iqQueue, moduleQueue);
809
+ *
810
+ * return socketQueue;
811
+ * }
812
+ * - (void)socket:(GCDAsyncSocket *)sock didAcceptNewSocket:(GCDAsyncSocket *)newSocket
813
+ * {
814
+ * [clientConnections addObject:newSocket];
815
+ * [newSocket markSocketQueueTargetQueue:moduleQueue];
816
+ * }
817
+ *
818
+ * Note: This workaround is ONLY needed if you intend to execute code directly on the ipQueue or moduleQueue.
819
+ * This is often NOT the case, as such queues are used solely for execution shaping.
820
+ **/
821
+ - (void)markSocketQueueTargetQueue:(dispatch_queue_t)socketQueuesPreConfiguredTargetQueue;
822
+ - (void)unmarkSocketQueueTargetQueue:(dispatch_queue_t)socketQueuesPreviouslyConfiguredTargetQueue;
823
+
824
+ /**
825
+ * It's not thread-safe to access certain variables from outside the socket's internal queue.
826
+ *
827
+ * For example, the socket file descriptor.
828
+ * File descriptors are simply integers which reference an index in the per-process file table.
829
+ * However, when one requests a new file descriptor (by opening a file or socket),
830
+ * the file descriptor returned is guaranteed to be the lowest numbered unused descriptor.
831
+ * So if we're not careful, the following could be possible:
832
+ *
833
+ * - Thread A invokes a method which returns the socket's file descriptor.
834
+ * - The socket is closed via the socket's internal queue on thread B.
835
+ * - Thread C opens a file, and subsequently receives the file descriptor that was previously the socket's FD.
836
+ * - Thread A is now accessing/altering the file instead of the socket.
837
+ *
838
+ * In addition to this, other variables are not actually objects,
839
+ * and thus cannot be retained/released or even autoreleased.
840
+ * An example is the sslContext, of type SSLContextRef, which is actually a malloc'd struct.
841
+ *
842
+ * Although there are internal variables that make it difficult to maintain thread-safety,
843
+ * it is important to provide access to these variables
844
+ * to ensure this class can be used in a wide array of environments.
845
+ * This method helps to accomplish this by invoking the current block on the socket's internal queue.
846
+ * The methods below can be invoked from within the block to access
847
+ * those generally thread-unsafe internal variables in a thread-safe manner.
848
+ * The given block will be invoked synchronously on the socket's internal queue.
849
+ *
850
+ * If you save references to any protected variables and use them outside the block, you do so at your own peril.
851
+ **/
852
+ - (void)performBlock:(dispatch_block_t)block;
853
+
854
+ /**
855
+ * These methods are only available from within the context of a performBlock: invocation.
856
+ * See the documentation for the performBlock: method above.
857
+ *
858
+ * Provides access to the socket's file descriptor(s).
859
+ * If the socket is a server socket (is accepting incoming connections),
860
+ * it might actually have multiple internal socket file descriptors - one for IPv4 and one for IPv6.
861
+ **/
862
+ - (int)socketFD;
863
+ - (int)socket4FD;
864
+ - (int)socket6FD;
865
+
866
+ #if TARGET_OS_IPHONE
867
+
868
+ /**
869
+ * These methods are only available from within the context of a performBlock: invocation.
870
+ * See the documentation for the performBlock: method above.
871
+ *
872
+ * Provides access to the socket's internal CFReadStream/CFWriteStream.
873
+ *
874
+ * These streams are only used as workarounds for specific iOS shortcomings:
875
+ *
876
+ * - Apple has decided to keep the SecureTransport framework private is iOS.
877
+ * This means the only supplied way to do SSL/TLS is via CFStream or some other API layered on top of it.
878
+ * Thus, in order to provide SSL/TLS support on iOS we are forced to rely on CFStream,
879
+ * instead of the preferred and faster and more powerful SecureTransport.
880
+ *
881
+ * - If a socket doesn't have backgrounding enabled, and that socket is closed while the app is backgrounded,
882
+ * Apple only bothers to notify us via the CFStream API.
883
+ * The faster and more powerful GCD API isn't notified properly in this case.
884
+ *
885
+ * See also: (BOOL)enableBackgroundingOnSocket
886
+ **/
887
+ - (CFReadStreamRef)readStream;
888
+ - (CFWriteStreamRef)writeStream;
889
+
890
+ /**
891
+ * This method is only available from within the context of a performBlock: invocation.
892
+ * See the documentation for the performBlock: method above.
893
+ *
894
+ * Configures the socket to allow it to operate when the iOS application has been backgrounded.
895
+ * In other words, this method creates a read & write stream, and invokes:
896
+ *
897
+ * CFReadStreamSetProperty(readStream, kCFStreamNetworkServiceType, kCFStreamNetworkServiceTypeVoIP);
898
+ * CFWriteStreamSetProperty(writeStream, kCFStreamNetworkServiceType, kCFStreamNetworkServiceTypeVoIP);
899
+ *
900
+ * Returns YES if successful, NO otherwise.
901
+ *
902
+ * Note: Apple does not officially support backgrounding server sockets.
903
+ * That is, if your socket is accepting incoming connections, Apple does not officially support
904
+ * allowing iOS applications to accept incoming connections while an app is backgrounded.
905
+ *
906
+ * Example usage:
907
+ *
908
+ * - (void)socket:(GCDAsyncSocket *)sock didConnectToHost:(NSString *)host port:(uint16_t)port
909
+ * {
910
+ * [asyncSocket performBlock:^{
911
+ * [asyncSocket enableBackgroundingOnSocket];
912
+ * }];
913
+ * }
914
+ **/
915
+ - (BOOL)enableBackgroundingOnSocket;
916
+
917
+ #endif
918
+
919
+ #if SECURE_TRANSPORT_MAYBE_AVAILABLE
920
+
921
+ /**
922
+ * This method is only available from within the context of a performBlock: invocation.
923
+ * See the documentation for the performBlock: method above.
924
+ *
925
+ * Provides access to the socket's SSLContext, if SSL/TLS has been started on the socket.
926
+ **/
927
+ - (SSLContextRef)sslContext;
928
+
929
+ #endif
930
+
931
+ #pragma mark Utilities
932
+
933
+ /**
934
+ * Extracting host and port information from raw address data.
935
+ **/
936
+ + (NSString *)hostFromAddress:(NSData *)address;
937
+ + (uint16_t)portFromAddress:(NSData *)address;
938
+ + (BOOL)getHost:(NSString **)hostPtr port:(uint16_t *)portPtr fromAddress:(NSData *)address;
939
+
940
+ /**
941
+ * A few common line separators, for use with the readDataToData:... methods.
942
+ **/
943
+ + (NSData *)CRLFData; // 0x0D0A
944
+ + (NSData *)CRData; // 0x0D
945
+ + (NSData *)LFData; // 0x0A
946
+ + (NSData *)ZeroData; // 0x00
947
+
948
+ @end
949
+
950
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
951
+ #pragma mark -
952
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
953
+
954
+ @protocol GCDAsyncSocketDelegate
955
+ @optional
956
+
957
+ /**
958
+ * This method is called immediately prior to socket:didAcceptNewSocket:.
959
+ * It optionally allows a listening socket to specify the socketQueue for a new accepted socket.
960
+ * If this method is not implemented, or returns NULL, the new accepted socket will create its own default queue.
961
+ *
962
+ * Since you cannot autorelease a dispatch_queue,
963
+ * this method uses the "new" prefix in its name to specify that the returned queue has been retained.
964
+ *
965
+ * Thus you could do something like this in the implementation:
966
+ * return dispatch_queue_create("MyQueue", NULL);
967
+ *
968
+ * If you are placing multiple sockets on the same queue,
969
+ * then care should be taken to increment the retain count each time this method is invoked.
970
+ *
971
+ * For example, your implementation might look something like this:
972
+ * dispatch_retain(myExistingQueue);
973
+ * return myExistingQueue;
974
+ **/
975
+ - (dispatch_queue_t)newSocketQueueForConnectionFromAddress:(NSData *)address onSocket:(GCDAsyncSocket *)sock;
976
+
977
+ /**
978
+ * Called when a socket accepts a connection.
979
+ * Another socket is automatically spawned to handle it.
980
+ *
981
+ * You must retain the newSocket if you wish to handle the connection.
982
+ * Otherwise the newSocket instance will be released and the spawned connection will be closed.
983
+ *
984
+ * By default the new socket will have the same delegate and delegateQueue.
985
+ * You may, of course, change this at any time.
986
+ **/
987
+ - (void)socket:(GCDAsyncSocket *)sock didAcceptNewSocket:(GCDAsyncSocket *)newSocket;
988
+
989
+ /**
990
+ * Called when a socket connects and is ready for reading and writing.
991
+ * The host parameter will be an IP address, not a DNS name.
992
+ **/
993
+ - (void)socket:(GCDAsyncSocket *)sock didConnectToHost:(NSString *)host port:(uint16_t)port;
994
+
995
+ /**
996
+ * Called when a socket has completed reading the requested data into memory.
997
+ * Not called if there is an error.
998
+ **/
999
+ - (void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag;
1000
+
1001
+ /**
1002
+ * Called when a socket has read in data, but has not yet completed the read.
1003
+ * This would occur if using readToData: or readToLength: methods.
1004
+ * It may be used to for things such as updating progress bars.
1005
+ **/
1006
+ - (void)socket:(GCDAsyncSocket *)sock didReadPartialDataOfLength:(NSUInteger)partialLength tag:(long)tag;
1007
+
1008
+ /**
1009
+ * Called when a socket has completed writing the requested data. Not called if there is an error.
1010
+ **/
1011
+ - (void)socket:(GCDAsyncSocket *)sock didWriteDataWithTag:(long)tag;
1012
+
1013
+ /**
1014
+ * Called when a socket has written some data, but has not yet completed the entire write.
1015
+ * It may be used to for things such as updating progress bars.
1016
+ **/
1017
+ - (void)socket:(GCDAsyncSocket *)sock didWritePartialDataOfLength:(NSUInteger)partialLength tag:(long)tag;
1018
+
1019
+ /**
1020
+ * Called if a read operation has reached its timeout without completing.
1021
+ * This method allows you to optionally extend the timeout.
1022
+ * If you return a positive time interval (> 0) the read's timeout will be extended by the given amount.
1023
+ * If you don't implement this method, or return a non-positive time interval (<= 0) the read will timeout as usual.
1024
+ *
1025
+ * The elapsed parameter is the sum of the original timeout, plus any additions previously added via this method.
1026
+ * The length parameter is the number of bytes that have been read so far for the read operation.
1027
+ *
1028
+ * Note that this method may be called multiple times for a single read if you return positive numbers.
1029
+ **/
1030
+ - (NSTimeInterval)socket:(GCDAsyncSocket *)sock shouldTimeoutReadWithTag:(long)tag
1031
+ elapsed:(NSTimeInterval)elapsed
1032
+ bytesDone:(NSUInteger)length;
1033
+
1034
+ /**
1035
+ * Called if a write operation has reached its timeout without completing.
1036
+ * This method allows you to optionally extend the timeout.
1037
+ * If you return a positive time interval (> 0) the write's timeout will be extended by the given amount.
1038
+ * If you don't implement this method, or return a non-positive time interval (<= 0) the write will timeout as usual.
1039
+ *
1040
+ * The elapsed parameter is the sum of the original timeout, plus any additions previously added via this method.
1041
+ * The length parameter is the number of bytes that have been written so far for the write operation.
1042
+ *
1043
+ * Note that this method may be called multiple times for a single write if you return positive numbers.
1044
+ **/
1045
+ - (NSTimeInterval)socket:(GCDAsyncSocket *)sock shouldTimeoutWriteWithTag:(long)tag
1046
+ elapsed:(NSTimeInterval)elapsed
1047
+ bytesDone:(NSUInteger)length;
1048
+
1049
+ /**
1050
+ * Conditionally called if the read stream closes, but the write stream may still be writeable.
1051
+ *
1052
+ * This delegate method is only called if autoDisconnectOnClosedReadStream has been set to NO.
1053
+ * See the discussion on the autoDisconnectOnClosedReadStream method for more information.
1054
+ **/
1055
+ - (void)socketDidCloseReadStream:(GCDAsyncSocket *)sock;
1056
+
1057
+ /**
1058
+ * Called when a socket disconnects with or without error.
1059
+ *
1060
+ * If you call the disconnect method, and the socket wasn't already disconnected,
1061
+ * this delegate method will be called before the disconnect method returns.
1062
+ **/
1063
+ - (void)socketDidDisconnect:(GCDAsyncSocket *)sock withError:(NSError *)err;
1064
+
1065
+ /**
1066
+ * Called after the socket has successfully completed SSL/TLS negotiation.
1067
+ * This method is not called unless you use the provided startTLS method.
1068
+ *
1069
+ * If a SSL/TLS negotiation fails (invalid certificate, etc) then the socket will immediately close,
1070
+ * and the socketDidDisconnect:withError: delegate method will be called with the specific SSL error code.
1071
+ **/
1072
+ - (void)socketDidSecure:(GCDAsyncSocket *)sock;
1073
+
1074
+ @end