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 19#import <UIKit/UIKit.h> 20#import <GRPCClient/GRPCCall+Tests.h> 21#import <RouteGuide/RouteGuide.pbrpc.h> 22#import <RxLibrary/GRXWriter+Immediate.h> 23#import <RxLibrary/GRXWriter+Transformations.h> 24 25static NSString * const kHostAddress = @"localhost:50051"; 26 27/** Category to override RTGPoint's description. */ 28@interface RTGPoint (Description) 29- (NSString *)description; 30@end 31 32@implementation RTGPoint (Description) 33- (NSString *)description { 34 NSString *verticalDirection = self.latitude >= 0 ? @"N" : @"S"; 35 NSString *horizontalDirection = self.longitude >= 0 ? @"E" : @"W"; 36 return [NSString stringWithFormat:@"%.02f%@ %.02f%@", 37 abs(self.latitude) / 1E7f, verticalDirection, 38 abs(self.longitude) / 1E7f, horizontalDirection]; 39} 40@end 41 42/** Category to give RTGRouteNote a convenience constructor. */ 43@interface RTGRouteNote (Constructors) 44+ (instancetype)noteWithMessage:(NSString *)message 45 latitude:(float)latitude 46 longitude:(float)longitude; 47@end 48 49@implementation RTGRouteNote (Constructors) 50+ (instancetype)noteWithMessage:(NSString *)message 51 latitude:(float)latitude 52 longitude:(float)longitude { 53 RTGRouteNote *note = [self message]; 54 note.message = message; 55 note.location.latitude = (int32_t) latitude * 1E7; 56 note.location.longitude = (int32_t) longitude * 1E7; 57 return note; 58} 59@end 60 61 62#pragma mark Demo: Get Feature 63 64/** 65 * Run the getFeature demo. Calls getFeature with a point known to have a feature and a point known 66 * not to have a feature. 67 */ 68@interface GetFeatureViewController : UIViewController 69 70@property (weak, nonatomic) IBOutlet UILabel *outputLabel; 71 72@end 73 74@implementation GetFeatureViewController { 75 RTGRouteGuide *_service; 76} 77 78- (void)execRequest { 79 void (^handler)(RTGFeature *response, NSError *error) = ^(RTGFeature *response, NSError *error) { 80 // TODO(makdharma): Remove boilerplate by consolidating into one log function. 81 if (response.name.length) { 82 NSString *str =[NSString stringWithFormat:@"%@\nFound feature called %@ at %@.", self.outputLabel.text, response.location, response.name]; 83 self.outputLabel.text = str; 84 NSLog(@"Found feature called %@ at %@.", response.name, response.location); 85 } else if (response) { 86 NSString *str =[NSString stringWithFormat:@"%@\nFound no features at %@", self.outputLabel.text,response.location]; 87 self.outputLabel.text = str; 88 NSLog(@"Found no features at %@", response.location); 89 } else { 90 NSString *str =[NSString stringWithFormat:@"%@\nRPC error: %@", self.outputLabel.text, error]; 91 self.outputLabel.text = str; 92 NSLog(@"RPC error: %@", error); 93 } 94 }; 95 96 RTGPoint *point = [RTGPoint message]; 97 point.latitude = 409146138; 98 point.longitude = -746188906; 99 100 [_service getFeatureWithRequest:point handler:handler]; 101 [_service getFeatureWithRequest:[RTGPoint message] handler:handler]; 102} 103 104- (void)viewDidLoad { 105 [super viewDidLoad]; 106 107 // This only needs to be done once per host, before creating service objects for that host. 108 [GRPCCall useInsecureConnectionsForHost:kHostAddress]; 109 110 _service = [[RTGRouteGuide alloc] initWithHost:kHostAddress]; 111} 112 113- (void)viewDidAppear:(BOOL)animated { 114 self.outputLabel.text = @"RPC log:"; 115 self.outputLabel.numberOfLines = 0; 116 self.outputLabel.font = [UIFont fontWithName:@"Helvetica Neue" size:8.0]; 117 [self execRequest]; 118} 119 120@end 121 122 123#pragma mark Demo: List Features 124 125/** 126 * Run the listFeatures demo. Calls listFeatures with a rectangle containing all of the features in 127 * the pre-generated database. Prints each response as it comes in. 128 */ 129@interface ListFeaturesViewController : UIViewController 130 131@property (weak, nonatomic) IBOutlet UILabel *outputLabel; 132 133@end 134 135@implementation ListFeaturesViewController { 136 RTGRouteGuide *_service; 137} 138 139- (void)execRequest { 140 RTGRectangle *rectangle = [RTGRectangle message]; 141 rectangle.lo.latitude = 405E6; 142 rectangle.lo.longitude = -750E6; 143 rectangle.hi.latitude = 410E6; 144 rectangle.hi.longitude = -745E6; 145 146 NSLog(@"Looking for features between %@ and %@", rectangle.lo, rectangle.hi); 147 [_service listFeaturesWithRequest:rectangle 148 eventHandler:^(BOOL done, RTGFeature *response, NSError *error) { 149 if (response) { 150 NSString *str =[NSString stringWithFormat:@"%@\nFound feature at %@ called %@.", self.outputLabel.text, response.location, response.name]; 151 self.outputLabel.text = str; 152 NSLog(@"Found feature at %@ called %@.", response.location, response.name); 153 } else if (error) { 154 NSString *str =[NSString stringWithFormat:@"%@\nRPC error: %@", self.outputLabel.text, error]; 155 self.outputLabel.text = str; 156 NSLog(@"RPC error: %@", error); 157 } 158 }]; 159} 160 161- (void)viewDidLoad { 162 [super viewDidLoad]; 163 164 _service = [[RTGRouteGuide alloc] initWithHost:kHostAddress]; 165} 166 167- (void)viewDidAppear:(BOOL)animated { 168 self.outputLabel.text = @"RPC log:"; 169 self.outputLabel.numberOfLines = 0; 170 self.outputLabel.font = [UIFont fontWithName:@"Helvetica Neue" size:8.0]; 171 [self execRequest]; 172} 173 174@end 175 176 177#pragma mark Demo: Record Route 178 179/** 180 * Run the recordRoute demo. Sends several randomly chosen points from the pre-generated feature 181 * database with a variable delay in between. Prints the statistics when they are sent from the 182 * server. 183 */ 184@interface RecordRouteViewController : UIViewController 185 186@property (weak, nonatomic) IBOutlet UILabel *outputLabel; 187 188@end 189 190@implementation RecordRouteViewController { 191 RTGRouteGuide *_service; 192} 193 194- (void)execRequest { 195 NSString *dataBasePath = [NSBundle.mainBundle pathForResource:@"route_guide_db" 196 ofType:@"json"]; 197 NSData *dataBaseContent = [NSData dataWithContentsOfFile:dataBasePath]; 198 NSArray *features = [NSJSONSerialization JSONObjectWithData:dataBaseContent options:0 error:NULL]; 199 200 GRXWriter *locations = [[GRXWriter writerWithContainer:features] map:^id(id feature) { 201 RTGPoint *location = [RTGPoint message]; 202 location.longitude = [((NSNumber *) feature[@"location"][@"longitude"]) intValue]; 203 location.latitude = [((NSNumber *) feature[@"location"][@"latitude"]) intValue]; 204 NSString *str =[NSString stringWithFormat:@"%@\nVisiting point %@", self.outputLabel.text, location]; 205 self.outputLabel.text = str; 206 NSLog(@"Visiting point %@", location); 207 return location; 208 }]; 209 210 [_service recordRouteWithRequestsWriter:locations 211 handler:^(RTGRouteSummary *response, NSError *error) { 212 if (response) { 213 NSString *str =[NSString stringWithFormat: 214 @"%@\nFinished trip with %i points\nPassed %i features\n" 215 "Travelled %i meters\nIt took %i seconds", 216 self.outputLabel.text, response.pointCount, response.featureCount, 217 response.distance, response.elapsedTime]; 218 self.outputLabel.text = str; 219 NSLog(@"Finished trip with %i points", response.pointCount); 220 NSLog(@"Passed %i features", response.featureCount); 221 NSLog(@"Travelled %i meters", response.distance); 222 NSLog(@"It took %i seconds", response.elapsedTime); 223 } else { 224 NSString *str =[NSString stringWithFormat:@"%@\nRPC error: %@", self.outputLabel.text, error]; 225 self.outputLabel.text = str; 226 NSLog(@"RPC error: %@", error); 227 } 228 }]; 229} 230 231- (void)viewDidLoad { 232 [super viewDidLoad]; 233 234 _service = [[RTGRouteGuide alloc] initWithHost:kHostAddress]; 235} 236 237- (void)viewDidAppear:(BOOL)animated { 238 self.outputLabel.text = @"RPC log:"; 239 self.outputLabel.numberOfLines = 0; 240 self.outputLabel.font = [UIFont fontWithName:@"Helvetica Neue" size:8.0]; 241 [self execRequest]; 242} 243 244@end 245 246 247#pragma mark Demo: Route Chat 248 249/** 250 * Run the routeChat demo. Send some chat messages, and print any chat messages that are sent from 251 * the server. 252 */ 253@interface RouteChatViewController : UIViewController 254 255@property (weak, nonatomic) IBOutlet UILabel *outputLabel; 256 257@end 258 259@implementation RouteChatViewController { 260 RTGRouteGuide *_service; 261} 262 263- (void)execRequest { 264 NSArray *notes = @[[RTGRouteNote noteWithMessage:@"First message" latitude:0 longitude:0], 265 [RTGRouteNote noteWithMessage:@"Second message" latitude:0 longitude:1], 266 [RTGRouteNote noteWithMessage:@"Third message" latitude:1 longitude:0], 267 [RTGRouteNote noteWithMessage:@"Fourth message" latitude:0 longitude:0]]; 268 GRXWriter *notesWriter = [[GRXWriter writerWithContainer:notes] map:^id(RTGRouteNote *note) { 269 NSLog(@"Sending message %@ at %@", note.message, note.location); 270 return note; 271 }]; 272 273 [_service routeChatWithRequestsWriter:notesWriter 274 eventHandler:^(BOOL done, RTGRouteNote *note, NSError *error) { 275 if (note) { 276 NSString *str =[NSString stringWithFormat:@"%@\nGot message %@ at %@", 277 self.outputLabel.text, note.message, note.location]; 278 self.outputLabel.text = str; 279 NSLog(@"Got message %@ at %@", note.message, note.location); 280 } else if (error) { 281 NSString *str =[NSString stringWithFormat:@"%@\nRPC error: %@", self.outputLabel.text, error]; 282 self.outputLabel.text = str; 283 NSLog(@"RPC error: %@", error); 284 } 285 if (done) { 286 NSLog(@"Chat ended."); 287 } 288 }]; 289} 290 291- (void)viewDidLoad { 292 [super viewDidLoad]; 293 294 _service = [[RTGRouteGuide alloc] initWithHost:kHostAddress]; 295} 296 297- (void)viewDidAppear:(BOOL)animated { 298 // TODO(makarandd): Set these properties through UI builder 299 self.outputLabel.text = @"RPC log:"; 300 self.outputLabel.numberOfLines = 0; 301 self.outputLabel.font = [UIFont fontWithName:@"Helvetica Neue" size:8.0]; 302 [self execRequest]; 303} 304 305@end 306