ViewControllers.m 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374
  1. /*
  2. *
  3. * Copyright 2015 gRPC authors.
  4. *
  5. * Licensed under the Apache License, Version 2.0 (the "License");
  6. * you may not use this file except in compliance with the License.
  7. * You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. *
  17. */
  18. #import <UIKit/UIKit.h>
  19. #if COCOAPODS
  20. #import <RouteGuide/RouteGuide.pbrpc.h>
  21. #else
  22. #import "examples/protos/RouteGuide.pbrpc.h"
  23. #endif
  24. #import <GRPCClient/GRPCTransport.h>
  25. static NSString *const kHostAddress = @"localhost:50051";
  26. /** Category to override RTGPoint's description. */
  27. @interface RTGPoint (Description)
  28. - (NSString *)description;
  29. @end
  30. @implementation RTGPoint (Description)
  31. - (NSString *)description {
  32. NSString *verticalDirection = self.latitude >= 0 ? @"N" : @"S";
  33. NSString *horizontalDirection = self.longitude >= 0 ? @"E" : @"W";
  34. return
  35. [NSString stringWithFormat:@"%.02f%@ %.02f%@", abs(self.latitude) / 1E7f, verticalDirection,
  36. abs(self.longitude) / 1E7f, horizontalDirection];
  37. }
  38. @end
  39. /** Category to give RTGRouteNote a convenience constructor. */
  40. @interface RTGRouteNote (Constructors)
  41. + (instancetype)noteWithMessage:(NSString *)message
  42. latitude:(float)latitude
  43. longitude:(float)longitude;
  44. @end
  45. @implementation RTGRouteNote (Constructors)
  46. + (instancetype)noteWithMessage:(NSString *)message
  47. latitude:(float)latitude
  48. longitude:(float)longitude {
  49. RTGRouteNote *note = [self message];
  50. note.message = message;
  51. note.location.latitude = (int32_t)latitude * 1E7;
  52. note.location.longitude = (int32_t)longitude * 1E7;
  53. return note;
  54. }
  55. @end
  56. #pragma mark Demo: Get Feature
  57. /**
  58. * Run the getFeature demo. Calls getFeature with a point known to have a feature and a point known
  59. * not to have a feature.
  60. */
  61. @interface GetFeatureViewController : UIViewController
  62. @property(weak, nonatomic) IBOutlet UILabel *outputLabel;
  63. @end
  64. @implementation GetFeatureViewController {
  65. RTGRouteGuide *_service;
  66. }
  67. - (void)execRequest {
  68. void (^handler)(RTGFeature *response, NSError *error) = ^(RTGFeature *response, NSError *error) {
  69. // TODO(makdharma): Remove boilerplate by consolidating into one log function.
  70. if (response.name.length) {
  71. NSString *str =
  72. [NSString stringWithFormat:@"%@\nFound feature called %@ at %@.", self.outputLabel.text,
  73. response.location, response.name];
  74. self.outputLabel.text = str;
  75. NSLog(@"Found feature called %@ at %@.", response.name, response.location);
  76. } else if (response) {
  77. NSString *str = [NSString stringWithFormat:@"%@\nFound no features at %@",
  78. self.outputLabel.text, response.location];
  79. self.outputLabel.text = str;
  80. NSLog(@"Found no features at %@", response.location);
  81. } else {
  82. NSString *str =
  83. [NSString stringWithFormat:@"%@\nRPC error: %@", self.outputLabel.text, error];
  84. self.outputLabel.text = str;
  85. NSLog(@"RPC error: %@", error);
  86. }
  87. };
  88. RTGPoint *point = [RTGPoint message];
  89. point.latitude = 409146138;
  90. point.longitude = -746188906;
  91. GRPCUnaryProtoCall *call = [_service
  92. getFeatureWithMessage:point
  93. responseHandler:[[GRPCUnaryResponseHandler alloc] initWithResponseHandler:handler
  94. responseDispatchQueue:nil]
  95. callOptions:nil];
  96. [call start];
  97. call = [_service
  98. getFeatureWithMessage:[RTGPoint message]
  99. responseHandler:[[GRPCUnaryResponseHandler alloc] initWithResponseHandler:handler
  100. responseDispatchQueue:nil]
  101. callOptions:nil];
  102. [call start];
  103. }
  104. - (void)viewDidLoad {
  105. [super viewDidLoad];
  106. GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init];
  107. options.transport = GRPCDefaultTransportImplList.core_insecure;
  108. _service = [[RTGRouteGuide alloc] initWithHost:kHostAddress callOptions:options];
  109. }
  110. - (void)viewDidAppear:(BOOL)animated {
  111. self.outputLabel.text = @"RPC log:";
  112. self.outputLabel.numberOfLines = 0;
  113. self.outputLabel.font = [UIFont fontWithName:@"Helvetica Neue" size:8.0];
  114. [self execRequest];
  115. }
  116. @end
  117. #pragma mark Demo: List Features
  118. /**
  119. * Run the listFeatures demo. Calls listFeatures with a rectangle containing all of the features in
  120. * the pre-generated database. Prints each response as it comes in.
  121. */
  122. @interface ListFeaturesViewController : UIViewController <GRPCProtoResponseHandler>
  123. @property(weak, nonatomic) IBOutlet UILabel *outputLabel;
  124. @end
  125. @implementation ListFeaturesViewController {
  126. RTGRouteGuide *_service;
  127. }
  128. - (dispatch_queue_t)dispatchQueue {
  129. return dispatch_get_main_queue();
  130. }
  131. - (void)execRequest {
  132. RTGRectangle *rectangle = [RTGRectangle message];
  133. rectangle.lo.latitude = 405E6;
  134. rectangle.lo.longitude = -750E6;
  135. rectangle.hi.latitude = 410E6;
  136. rectangle.hi.longitude = -745E6;
  137. NSLog(@"Looking for features between %@ and %@", rectangle.lo, rectangle.hi);
  138. GRPCUnaryProtoCall *call = [_service listFeaturesWithMessage:rectangle
  139. responseHandler:self
  140. callOptions:nil];
  141. [call start];
  142. }
  143. - (void)didReceiveProtoMessage:(GPBMessage *)message {
  144. RTGFeature *response = (RTGFeature *)message;
  145. if (response) {
  146. NSString *str =
  147. [NSString stringWithFormat:@"%@\nFound feature at %@ called %@.", self.outputLabel.text,
  148. response.location, response.name];
  149. self.outputLabel.text = str;
  150. NSLog(@"Found feature at %@ called %@.", response.location, response.name);
  151. }
  152. }
  153. - (void)didCloseWithTrailingMetadata:(NSDictionary *)trailingMetadata error:(NSError *)error {
  154. if (error) {
  155. NSString *str = [NSString stringWithFormat:@"%@\nRPC error: %@", self.outputLabel.text, error];
  156. self.outputLabel.text = str;
  157. NSLog(@"RPC error: %@", error);
  158. }
  159. }
  160. - (void)viewDidLoad {
  161. [super viewDidLoad];
  162. GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init];
  163. options.transport = GRPCDefaultTransportImplList.core_insecure;
  164. _service = [[RTGRouteGuide alloc] initWithHost:kHostAddress callOptions:options];
  165. }
  166. - (void)viewDidAppear:(BOOL)animated {
  167. self.outputLabel.text = @"RPC log:";
  168. self.outputLabel.numberOfLines = 0;
  169. self.outputLabel.font = [UIFont fontWithName:@"Helvetica Neue" size:8.0];
  170. [self execRequest];
  171. }
  172. @end
  173. #pragma mark Demo: Record Route
  174. /**
  175. * Run the recordRoute demo. Sends several randomly chosen points from the pre-generated feature
  176. * database with a variable delay in between. Prints the statistics when they are sent from the
  177. * server.
  178. */
  179. @interface RecordRouteViewController : UIViewController
  180. @property(weak, nonatomic) IBOutlet UILabel *outputLabel;
  181. @end
  182. @implementation RecordRouteViewController {
  183. RTGRouteGuide *_service;
  184. }
  185. - (void)execRequest {
  186. NSString *dataBasePath = [NSBundle.mainBundle pathForResource:@"route_guide_db" ofType:@"json"];
  187. NSData *dataBaseContent = [NSData dataWithContentsOfFile:dataBasePath];
  188. NSError *error;
  189. NSArray *features = [NSJSONSerialization JSONObjectWithData:dataBaseContent
  190. options:0
  191. error:&error];
  192. if (error) {
  193. NSLog(@"Error reading database.");
  194. NSString *str = @"Error reading database.";
  195. self.outputLabel.text = str;
  196. return;
  197. }
  198. void (^handler)(RTGRouteSummary *response, NSError *error) =
  199. ^(RTGRouteSummary *response, NSError *error) {
  200. if (response) {
  201. NSString *str = [NSString
  202. stringWithFormat:@"%@\nFinished trip with %i points\nPassed %i features\n"
  203. "Travelled %i meters\nIt took %i seconds",
  204. self.outputLabel.text, response.pointCount, response.featureCount,
  205. response.distance, response.elapsedTime];
  206. self.outputLabel.text = str;
  207. NSLog(@"Finished trip with %i points", response.pointCount);
  208. NSLog(@"Passed %i features", response.featureCount);
  209. NSLog(@"Travelled %i meters", response.distance);
  210. NSLog(@"It took %i seconds", response.elapsedTime);
  211. } else {
  212. NSString *str =
  213. [NSString stringWithFormat:@"%@\nRPC error: %@", self.outputLabel.text, error];
  214. self.outputLabel.text = str;
  215. NSLog(@"RPC error: %@", error);
  216. }
  217. };
  218. // We can use unary response handler here because, despite the requests being a stream, the
  219. // response of the RPC is unary.
  220. GRPCStreamingProtoCall *call =
  221. [_service recordRouteWithResponseHandler:[[GRPCUnaryResponseHandler alloc]
  222. initWithResponseHandler:handler
  223. responseDispatchQueue:nil]
  224. callOptions:nil];
  225. [call start];
  226. for (id feature in features) {
  227. RTGPoint *location = [RTGPoint message];
  228. location.longitude = [((NSNumber *)feature[@"location"][@"longitude"]) intValue];
  229. location.latitude = [((NSNumber *)feature[@"location"][@"latitude"]) intValue];
  230. NSString *str =
  231. [NSString stringWithFormat:@"%@\nVisiting point %@", self.outputLabel.text, location];
  232. self.outputLabel.text = str;
  233. NSLog(@"Visiting point %@", location);
  234. [call writeMessage:location];
  235. }
  236. [call finish];
  237. }
  238. - (void)viewDidLoad {
  239. [super viewDidLoad];
  240. GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init];
  241. options.transport = GRPCDefaultTransportImplList.core_insecure;
  242. _service = [[RTGRouteGuide alloc] initWithHost:kHostAddress callOptions:options];
  243. }
  244. - (void)viewDidAppear:(BOOL)animated {
  245. self.outputLabel.text = @"RPC log:";
  246. self.outputLabel.numberOfLines = 0;
  247. self.outputLabel.font = [UIFont fontWithName:@"Helvetica Neue" size:8.0];
  248. [self execRequest];
  249. }
  250. @end
  251. #pragma mark Demo: Route Chat
  252. /**
  253. * Run the routeChat demo. Send some chat messages, and print any chat messages that are sent from
  254. * the server.
  255. */
  256. @interface RouteChatViewController : UIViewController <GRPCProtoResponseHandler>
  257. @property(weak, nonatomic) IBOutlet UILabel *outputLabel;
  258. @end
  259. @implementation RouteChatViewController {
  260. RTGRouteGuide *_service;
  261. }
  262. - (dispatch_queue_t)dispatchQueue {
  263. return dispatch_get_main_queue();
  264. }
  265. - (void)execRequest {
  266. NSArray *notes = @[
  267. [RTGRouteNote noteWithMessage:@"First message" latitude:0 longitude:0],
  268. [RTGRouteNote noteWithMessage:@"Second message" latitude:0 longitude:1],
  269. [RTGRouteNote noteWithMessage:@"Third message" latitude:1 longitude:0],
  270. [RTGRouteNote noteWithMessage:@"Fourth message" latitude:0 longitude:0]
  271. ];
  272. GRPCStreamingProtoCall *call = [_service routeChatWithResponseHandler:self callOptions:nil];
  273. [call start];
  274. for (RTGRouteNote *note in notes) {
  275. [call writeMessage:note];
  276. }
  277. [call finish];
  278. }
  279. - (void)didReceiveProtoMessage:(GPBMessage *)message {
  280. RTGRouteNote *note = (RTGRouteNote *)message;
  281. if (note) {
  282. NSString *str = [NSString stringWithFormat:@"%@\nGot message %@ at %@", self.outputLabel.text,
  283. note.message, note.location];
  284. self.outputLabel.text = str;
  285. NSLog(@"Got message %@ at %@", note.message, note.location);
  286. }
  287. }
  288. - (void)didCloseWithTrailingMetadata:(NSDictionary *)trailingMetadata error:(NSError *)error {
  289. if (!error) {
  290. NSLog(@"Chat ended.");
  291. } else {
  292. NSString *str = [NSString stringWithFormat:@"%@\nRPC error: %@", self.outputLabel.text, error];
  293. self.outputLabel.text = str;
  294. NSLog(@"RPC error: %@", error);
  295. }
  296. }
  297. - (void)viewDidLoad {
  298. [super viewDidLoad];
  299. GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init];
  300. options.transport = GRPCDefaultTransportImplList.core_insecure;
  301. _service = [[RTGRouteGuide alloc] initWithHost:kHostAddress callOptions:options];
  302. }
  303. - (void)viewDidAppear:(BOOL)animated {
  304. // TODO(makarandd): Set these properties through UI builder
  305. self.outputLabel.text = @"RPC log:";
  306. self.outputLabel.numberOfLines = 0;
  307. self.outputLabel.font = [UIFont fontWithName:@"Helvetica Neue" size:8.0];
  308. [self execRequest];
  309. }
  310. @end