aboutsummaryrefslogtreecommitdiffhomepage
path: root/examples/objective-c/route_guide
diff options
context:
space:
mode:
authorGravatar Stanley Cheung <stanleycheung@google.com>2015-08-27 14:00:20 -0700
committerGravatar Stanley Cheung <stanleycheung@google.com>2015-08-27 14:00:20 -0700
commit20fa6693f3836bf1418176ec78b26feaf51a369d (patch)
tree5975f66d7c6eb447baeea97fb62cdffa19d5c2e5 /examples/objective-c/route_guide
parentb2bea23365acb0bcc1b5adba2d5b2fa5a22eb872 (diff)
move examples to correct locations
Diffstat (limited to 'examples/objective-c/route_guide')
-rw-r--r--examples/objective-c/route_guide/Misc/AppDelegate.h38
-rw-r--r--examples/objective-c/route_guide/Misc/AppDelegate.m37
-rw-r--r--examples/objective-c/route_guide/Misc/Base.lproj/Main.storyboard193
-rw-r--r--examples/objective-c/route_guide/Misc/Images.xcassets/AppIcon.appiconset/Contents.json68
-rw-r--r--examples/objective-c/route_guide/Misc/Images.xcassets/first.imageset/Contents.json12
-rw-r--r--examples/objective-c/route_guide/Misc/Images.xcassets/first.imageset/first.pdfbin0 -> 2465 bytes
-rw-r--r--examples/objective-c/route_guide/Misc/Images.xcassets/second.imageset/Contents.json12
-rw-r--r--examples/objective-c/route_guide/Misc/Images.xcassets/second.imageset/second.pdfbin0 -> 2423 bytes
-rw-r--r--examples/objective-c/route_guide/Misc/Info.plist57
-rw-r--r--examples/objective-c/route_guide/Misc/main.m41
-rw-r--r--examples/objective-c/route_guide/Podfile7
-rw-r--r--examples/objective-c/route_guide/README.md360
-rw-r--r--examples/objective-c/route_guide/RouteGuide.podspec35
-rw-r--r--examples/objective-c/route_guide/RouteGuideClient.xcodeproj/project.pbxproj366
-rw-r--r--examples/objective-c/route_guide/RouteGuideClient.xcodeproj/project.xcworkspace/contents.xcworkspacedata7
-rw-r--r--examples/objective-c/route_guide/ViewControllers.m228
-rw-r--r--examples/objective-c/route_guide/route_guide_db.json121
17 files changed, 1582 insertions, 0 deletions
diff --git a/examples/objective-c/route_guide/Misc/AppDelegate.h b/examples/objective-c/route_guide/Misc/AppDelegate.h
new file mode 100644
index 0000000000..102e7f3ade
--- /dev/null
+++ b/examples/objective-c/route_guide/Misc/AppDelegate.h
@@ -0,0 +1,38 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#import <UIKit/UIKit.h>
+
+@interface AppDelegate : UIResponder <UIApplicationDelegate>
+@property (strong, nonatomic) UIWindow *window;
+@end
diff --git a/examples/objective-c/route_guide/Misc/AppDelegate.m b/examples/objective-c/route_guide/Misc/AppDelegate.m
new file mode 100644
index 0000000000..a38e36651e
--- /dev/null
+++ b/examples/objective-c/route_guide/Misc/AppDelegate.m
@@ -0,0 +1,37 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#import "AppDelegate.h"
+
+@implementation AppDelegate
+@end
diff --git a/examples/objective-c/route_guide/Misc/Base.lproj/Main.storyboard b/examples/objective-c/route_guide/Misc/Base.lproj/Main.storyboard
new file mode 100644
index 0000000000..9bf9498d62
--- /dev/null
+++ b/examples/objective-c/route_guide/Misc/Base.lproj/Main.storyboard
@@ -0,0 +1,193 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="7702" systemVersion="14D131" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="49e-Tb-3d3">
+ <dependencies>
+ <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="7701"/>
+ </dependencies>
+ <scenes>
+ <!--Get Feature-->
+ <scene sceneID="hNz-n2-bh7">
+ <objects>
+ <viewController id="9pv-A4-QxB" customClass="GetFeatureViewController" sceneMemberID="viewController">
+ <layoutGuides>
+ <viewControllerLayoutGuide type="top" id="Ia1-K6-d13"/>
+ <viewControllerLayoutGuide type="bottom" id="4ug-Mw-9AY"/>
+ </layoutGuides>
+ <view key="view" contentMode="scaleToFill" id="tsR-hK-woN">
+ <rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
+ <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+ <subviews>
+ <label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleToFill" text="Get Feature Demo" textAlignment="center" lineBreakMode="tailTruncation" minimumFontSize="10" translatesAutoresizingMaskIntoConstraints="NO" id="KQZ-1w-vlD">
+ <rect key="frame" x="150" y="279" width="299" height="42"/>
+ <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
+ <fontDescription key="fontDescription" name="Helvetica" family="Helvetica" pointSize="36"/>
+ <color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
+ <nil key="highlightedColor"/>
+ </label>
+ <label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" misplaced="YES" text="See ViewControllers.m and this app's log in XCode" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="A5M-7J-77L">
+ <rect key="frame" x="136" y="329" width="329" height="17"/>
+ <fontDescription key="fontDescription" type="system" pointSize="14"/>
+ <color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
+ <nil key="highlightedColor"/>
+ </label>
+ </subviews>
+ <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
+ <constraints>
+ <constraint firstAttribute="centerX" secondItem="KQZ-1w-vlD" secondAttribute="centerX" id="6BV-lF-sBN"/>
+ <constraint firstItem="A5M-7J-77L" firstAttribute="top" secondItem="KQZ-1w-vlD" secondAttribute="bottom" constant="8" symbolic="YES" id="cfb-er-3JN"/>
+ <constraint firstItem="A5M-7J-77L" firstAttribute="centerX" secondItem="KQZ-1w-vlD" secondAttribute="centerX" id="e1l-AV-tCB"/>
+ <constraint firstAttribute="centerY" secondItem="KQZ-1w-vlD" secondAttribute="centerY" id="exm-UA-ej4"/>
+ </constraints>
+ </view>
+ <tabBarItem key="tabBarItem" title="Get Feature" image="first" id="acW-dT-cKf"/>
+ </viewController>
+ <placeholder placeholderIdentifier="IBFirstResponder" id="W5J-7L-Pyd" sceneMemberID="firstResponder"/>
+ </objects>
+ <point key="canvasLocation" x="718" y="-660"/>
+ </scene>
+ <!--List Features-->
+ <scene sceneID="wg7-f3-ORb">
+ <objects>
+ <viewController id="8rJ-Kc-sve" customClass="ListFeaturesViewController" sceneMemberID="viewController">
+ <layoutGuides>
+ <viewControllerLayoutGuide type="top" id="L7p-HK-0SC"/>
+ <viewControllerLayoutGuide type="bottom" id="Djb-ko-YwX"/>
+ </layoutGuides>
+ <view key="view" contentMode="scaleToFill" id="QS5-Rx-YEW">
+ <rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
+ <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+ <subviews>
+ <label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleToFill" text="List Features Demo" textAlignment="center" lineBreakMode="tailTruncation" minimumFontSize="10" translatesAutoresizingMaskIntoConstraints="NO" id="zEq-FU-wV5">
+ <rect key="frame" x="143" y="279" width="315" height="42"/>
+ <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
+ <fontDescription key="fontDescription" name="Helvetica" family="Helvetica" pointSize="36"/>
+ <color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
+ <nil key="highlightedColor"/>
+ </label>
+ <label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="See ViewControllers.m and this app's log in XCode" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="NDk-cv-Gan">
+ <rect key="frame" x="136" y="329" width="329" height="17"/>
+ <fontDescription key="fontDescription" type="system" pointSize="14"/>
+ <color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
+ <nil key="highlightedColor"/>
+ </label>
+ </subviews>
+ <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
+ <constraints>
+ <constraint firstItem="NDk-cv-Gan" firstAttribute="top" secondItem="zEq-FU-wV5" secondAttribute="bottom" constant="8" symbolic="YES" id="Day-4N-Vmt"/>
+ <constraint firstItem="NDk-cv-Gan" firstAttribute="centerX" secondItem="zEq-FU-wV5" secondAttribute="centerX" id="JgO-Fn-dHn"/>
+ <constraint firstAttribute="centerX" secondItem="zEq-FU-wV5" secondAttribute="centerX" id="qqM-NS-xev"/>
+ <constraint firstAttribute="centerY" secondItem="zEq-FU-wV5" secondAttribute="centerY" id="qzY-Ky-pLD"/>
+ </constraints>
+ </view>
+ <tabBarItem key="tabBarItem" title="List Features" image="second" id="cPa-gy-q4n"/>
+ </viewController>
+ <placeholder placeholderIdentifier="IBFirstResponder" id="4Nw-L8-lE0" sceneMemberID="firstResponder"/>
+ </objects>
+ <point key="canvasLocation" x="1466" y="-386"/>
+ </scene>
+ <!--Tab Bar Controller-->
+ <scene sceneID="yl2-sM-qoP">
+ <objects>
+ <tabBarController id="49e-Tb-3d3" sceneMemberID="viewController">
+ <nil key="simulatedBottomBarMetrics"/>
+ <tabBar key="tabBar" contentMode="scaleToFill" id="W28-zg-YXA">
+ <rect key="frame" x="0.0" y="975" width="768" height="49"/>
+ <autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
+ <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
+ </tabBar>
+ <connections>
+ <segue destination="9pv-A4-QxB" kind="relationship" relationship="viewControllers" id="u7Y-xg-7CH"/>
+ <segue destination="8rJ-Kc-sve" kind="relationship" relationship="viewControllers" id="lzU-1b-eKA"/>
+ <segue destination="YIR-e4-hjB" kind="relationship" relationship="viewControllers" id="L0R-vl-fT4"/>
+ <segue destination="6mc-1d-hJy" kind="relationship" relationship="viewControllers" id="C2G-Se-4Fe"/>
+ </connections>
+ </tabBarController>
+ <placeholder placeholderIdentifier="IBFirstResponder" id="HuB-VB-40B" sceneMemberID="firstResponder"/>
+ </objects>
+ <point key="canvasLocation" x="0.0" y="0.0"/>
+ </scene>
+ <!--Record Route-->
+ <scene sceneID="kS4-Oa-mxG">
+ <objects>
+ <viewController id="YIR-e4-hjB" userLabel="Record Route" customClass="RecordRouteViewController" sceneMemberID="viewController">
+ <layoutGuides>
+ <viewControllerLayoutGuide type="top" id="jR8-0x-GjY"/>
+ <viewControllerLayoutGuide type="bottom" id="4Q5-sW-A9H"/>
+ </layoutGuides>
+ <view key="view" contentMode="scaleToFill" id="Wvj-mg-YnO">
+ <rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
+ <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+ <subviews>
+ <label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleToFill" text="Record Route Demo" textAlignment="center" lineBreakMode="tailTruncation" minimumFontSize="10" translatesAutoresizingMaskIntoConstraints="NO" id="Nqv-Vr-o8P">
+ <rect key="frame" x="136" y="279" width="329" height="42"/>
+ <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
+ <fontDescription key="fontDescription" name="Helvetica" family="Helvetica" pointSize="36"/>
+ <color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
+ <nil key="highlightedColor"/>
+ </label>
+ <label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="See ViewControllers.m and this app's log in XCode" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="xjS-0N-tLe">
+ <rect key="frame" x="136" y="329" width="329" height="17"/>
+ <fontDescription key="fontDescription" type="system" pointSize="14"/>
+ <color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
+ <nil key="highlightedColor"/>
+ </label>
+ </subviews>
+ <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
+ <constraints>
+ <constraint firstAttribute="centerX" secondItem="Nqv-Vr-o8P" secondAttribute="centerX" id="1wf-uc-57y"/>
+ <constraint firstItem="xjS-0N-tLe" firstAttribute="centerX" secondItem="Nqv-Vr-o8P" secondAttribute="centerX" id="Gnh-rN-EQ3"/>
+ <constraint firstItem="xjS-0N-tLe" firstAttribute="top" secondItem="Nqv-Vr-o8P" secondAttribute="bottom" constant="8" symbolic="YES" id="Xhj-u3-th9"/>
+ <constraint firstAttribute="centerY" secondItem="Nqv-Vr-o8P" secondAttribute="centerY" id="xqU-v8-Bb3"/>
+ </constraints>
+ </view>
+ <tabBarItem key="tabBarItem" title="Record Route" image="first" id="PLK-Jm-UyM"/>
+ </viewController>
+ <placeholder placeholderIdentifier="IBFirstResponder" id="9RW-dt-a4q" sceneMemberID="firstResponder"/>
+ </objects>
+ <point key="canvasLocation" x="1466" y="264"/>
+ </scene>
+ <!--Route Chat-->
+ <scene sceneID="M4k-TV-RZJ">
+ <objects>
+ <viewController id="6mc-1d-hJy" userLabel="Route Chat" customClass="RouteChatViewController" sceneMemberID="viewController">
+ <layoutGuides>
+ <viewControllerLayoutGuide type="top" id="Sl7-r2-TON"/>
+ <viewControllerLayoutGuide type="bottom" id="e7m-SC-g06"/>
+ </layoutGuides>
+ <view key="view" contentMode="scaleToFill" id="c9d-af-OMP">
+ <rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
+ <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+ <subviews>
+ <label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleToFill" text="Route Chat Demo" textAlignment="center" lineBreakMode="tailTruncation" minimumFontSize="10" translatesAutoresizingMaskIntoConstraints="NO" id="zUL-Bo-wJt">
+ <rect key="frame" x="156" y="279" width="289" height="42"/>
+ <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
+ <fontDescription key="fontDescription" name="Helvetica" family="Helvetica" pointSize="36"/>
+ <color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
+ <nil key="highlightedColor"/>
+ </label>
+ <label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="See ViewControllers.m and this app's log in XCode" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="CgS-1q-Od9">
+ <rect key="frame" x="136" y="329" width="329" height="17"/>
+ <fontDescription key="fontDescription" type="system" pointSize="14"/>
+ <color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
+ <nil key="highlightedColor"/>
+ </label>
+ </subviews>
+ <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
+ <constraints>
+ <constraint firstAttribute="centerY" secondItem="zUL-Bo-wJt" secondAttribute="centerY" id="5hM-q1-ZjM"/>
+ <constraint firstItem="CgS-1q-Od9" firstAttribute="top" secondItem="zUL-Bo-wJt" secondAttribute="bottom" constant="8" symbolic="YES" id="AqI-Ra-a5O"/>
+ <constraint firstItem="CgS-1q-Od9" firstAttribute="centerX" secondItem="zUL-Bo-wJt" secondAttribute="centerX" id="K8f-KI-bc6"/>
+ <constraint firstAttribute="centerX" secondItem="zUL-Bo-wJt" secondAttribute="centerX" id="n8b-x8-Yze"/>
+ </constraints>
+ </view>
+ <tabBarItem key="tabBarItem" title="Route Chat" image="second" id="p2G-IC-yAR"/>
+ </viewController>
+ <placeholder placeholderIdentifier="IBFirstResponder" id="yUz-se-Cfi" sceneMemberID="firstResponder"/>
+ </objects>
+ <point key="canvasLocation" x="718" y="594"/>
+ </scene>
+ </scenes>
+ <resources>
+ <image name="first" width="30" height="30"/>
+ <image name="second" width="30" height="30"/>
+ </resources>
+</document>
diff --git a/examples/objective-c/route_guide/Misc/Images.xcassets/AppIcon.appiconset/Contents.json b/examples/objective-c/route_guide/Misc/Images.xcassets/AppIcon.appiconset/Contents.json
new file mode 100644
index 0000000000..36d2c80d88
--- /dev/null
+++ b/examples/objective-c/route_guide/Misc/Images.xcassets/AppIcon.appiconset/Contents.json
@@ -0,0 +1,68 @@
+{
+ "images" : [
+ {
+ "idiom" : "iphone",
+ "size" : "29x29",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "iphone",
+ "size" : "29x29",
+ "scale" : "3x"
+ },
+ {
+ "idiom" : "iphone",
+ "size" : "40x40",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "iphone",
+ "size" : "40x40",
+ "scale" : "3x"
+ },
+ {
+ "idiom" : "iphone",
+ "size" : "60x60",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "iphone",
+ "size" : "60x60",
+ "scale" : "3x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "29x29",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "29x29",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "40x40",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "40x40",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "76x76",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "76x76",
+ "scale" : "2x"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+} \ No newline at end of file
diff --git a/examples/objective-c/route_guide/Misc/Images.xcassets/first.imageset/Contents.json b/examples/objective-c/route_guide/Misc/Images.xcassets/first.imageset/Contents.json
new file mode 100644
index 0000000000..33a745102c
--- /dev/null
+++ b/examples/objective-c/route_guide/Misc/Images.xcassets/first.imageset/Contents.json
@@ -0,0 +1,12 @@
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "filename" : "first.pdf"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+} \ No newline at end of file
diff --git a/examples/objective-c/route_guide/Misc/Images.xcassets/first.imageset/first.pdf b/examples/objective-c/route_guide/Misc/Images.xcassets/first.imageset/first.pdf
new file mode 100644
index 0000000000..47d911dea6
--- /dev/null
+++ b/examples/objective-c/route_guide/Misc/Images.xcassets/first.imageset/first.pdf
Binary files differ
diff --git a/examples/objective-c/route_guide/Misc/Images.xcassets/second.imageset/Contents.json b/examples/objective-c/route_guide/Misc/Images.xcassets/second.imageset/Contents.json
new file mode 100644
index 0000000000..03bd9c927f
--- /dev/null
+++ b/examples/objective-c/route_guide/Misc/Images.xcassets/second.imageset/Contents.json
@@ -0,0 +1,12 @@
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "filename" : "second.pdf"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+} \ No newline at end of file
diff --git a/examples/objective-c/route_guide/Misc/Images.xcassets/second.imageset/second.pdf b/examples/objective-c/route_guide/Misc/Images.xcassets/second.imageset/second.pdf
new file mode 100644
index 0000000000..401614e288
--- /dev/null
+++ b/examples/objective-c/route_guide/Misc/Images.xcassets/second.imageset/second.pdf
Binary files differ
diff --git a/examples/objective-c/route_guide/Misc/Info.plist b/examples/objective-c/route_guide/Misc/Info.plist
new file mode 100644
index 0000000000..33ad4800f6
--- /dev/null
+++ b/examples/objective-c/route_guide/Misc/Info.plist
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>CFBundleDevelopmentRegion</key>
+ <string>en</string>
+ <key>CFBundleExecutable</key>
+ <string>$(EXECUTABLE_NAME)</string>
+ <key>CFBundleIdentifier</key>
+ <string>gRPC.$(PRODUCT_NAME:rfc1034identifier)</string>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundleName</key>
+ <string>$(PRODUCT_NAME)</string>
+ <key>CFBundlePackageType</key>
+ <string>APPL</string>
+ <key>CFBundleShortVersionString</key>
+ <string>1.0</string>
+ <key>CFBundleSignature</key>
+ <string>????</string>
+ <key>CFBundleVersion</key>
+ <string>1</string>
+ <key>LSRequiresIPhoneOS</key>
+ <true/>
+ <key>UILaunchStoryboardName</key>
+ <string>Main</string>
+ <key>UIMainStoryboardFile</key>
+ <string>Main</string>
+ <key>UIRequiredDeviceCapabilities</key>
+ <array>
+ <string>armv7</string>
+ </array>
+ <key>UIStatusBarTintParameters</key>
+ <dict>
+ <key>UINavigationBar</key>
+ <dict>
+ <key>Style</key>
+ <string>UIBarStyleDefault</string>
+ <key>Translucent</key>
+ <false/>
+ </dict>
+ </dict>
+ <key>UISupportedInterfaceOrientations</key>
+ <array>
+ <string>UIInterfaceOrientationPortrait</string>
+ <string>UIInterfaceOrientationLandscapeLeft</string>
+ <string>UIInterfaceOrientationLandscapeRight</string>
+ </array>
+ <key>UISupportedInterfaceOrientations~ipad</key>
+ <array>
+ <string>UIInterfaceOrientationPortrait</string>
+ <string>UIInterfaceOrientationPortraitUpsideDown</string>
+ <string>UIInterfaceOrientationLandscapeLeft</string>
+ <string>UIInterfaceOrientationLandscapeRight</string>
+ </array>
+</dict>
+</plist>
diff --git a/examples/objective-c/route_guide/Misc/main.m b/examples/objective-c/route_guide/Misc/main.m
new file mode 100644
index 0000000000..fb701005d1
--- /dev/null
+++ b/examples/objective-c/route_guide/Misc/main.m
@@ -0,0 +1,41 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#import <UIKit/UIKit.h>
+#import "AppDelegate.h"
+
+int main(int argc, char * argv[]) {
+ @autoreleasepool {
+ return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
+ }
+}
diff --git a/examples/objective-c/route_guide/Podfile b/examples/objective-c/route_guide/Podfile
new file mode 100644
index 0000000000..a97f414685
--- /dev/null
+++ b/examples/objective-c/route_guide/Podfile
@@ -0,0 +1,7 @@
+source 'https://github.com/CocoaPods/Specs.git'
+platform :ios, '8.0'
+
+target 'RouteGuideClient' do
+ # Depend on the generated RouteGuide library.
+ pod 'RouteGuide', :path => '.'
+end
diff --git a/examples/objective-c/route_guide/README.md b/examples/objective-c/route_guide/README.md
new file mode 100644
index 0000000000..bbbd9e020d
--- /dev/null
+++ b/examples/objective-c/route_guide/README.md
@@ -0,0 +1,360 @@
+#gRPC Basics: Objective-C
+
+This tutorial provides a basic Objective-C programmer's introduction to working with gRPC. By
+walking through this example you'll learn how to:
+
+- Define a service in a .proto file.
+- Generate client code using the protocol buffer compiler.
+- Use the Objective-C gRPC API to write a simple client for your service.
+
+It assumes a passing familiarity with [protocol buffers](https://developers.google.com/protocol-buffers/docs/overview).
+Note that the example in this tutorial uses the proto3 version of the protocol buffers language,
+which is currently in alpha release: you can find out more in the [proto3 language guide](https://developers.google.com/protocol-buffers/docs/proto3)
+and see the [release notes](https://github.com/google/protobuf/releases) for the new version in the
+protocol buffers Github repository.
+
+This isn't a comprehensive guide to using gRPC in Objective-C: more reference documentation is
+coming soon.
+
+- [Why use gRPC?](#why-grpc)
+- [Example code and setup](#setup)
+- [Try it out!](#try)
+- [Defining the service](#proto)
+- [Generating client code](#protoc)
+- [Creating the client](#client)
+
+<a name="why-grpc"></a>
+## Why use gRPC?
+
+With gRPC you can define your service once in a .proto file and implement clients and servers in any
+of gRPC's supported languages, which in turn can be run in environments ranging from servers inside
+Google to your own tablet - all the complexity of communication between different languages and
+environments is handled for you by gRPC. You also get all the advantages of working with protocol
+buffers, including efficient serialization, a simple IDL, and easy interface updating.
+
+gRPC and proto3 are specially suited for mobile clients: gRPC is implemented on top of HTTP/2, which
+results in network bandwidth savings over using HTTP/1.1. Serialization and parsing of the proto
+binary format is more efficient than the equivalent JSON, resulting in CPU and battery savings. And
+proto3 uses a runtime that has been optimized over the years at Google to keep code size to a
+minimum. The latter is important in Objective-C, because the ability of the compiler to strip unused
+code is limited by the dynamic nature of the language.
+
+
+<a name="setup"></a>
+## Example code and setup
+
+The example code for our tutorial is in [grpc/grpc-common/objective-c/route_guide](https://github.com/grpc/grpc-common/tree/master/objective-c/route_guide).
+To download the example, clone the `grpc-common` repository by running the following command:
+```shell
+$ git clone https://github.com/grpc/grpc-common.git
+```
+
+Then change your current directory to `grpc-common/objective-c/route_guide`:
+```shell
+$ cd grpc-common/objective-c/route_guide
+```
+
+Our example is a simple route mapping application that lets clients get information about features
+on their route, create a summary of their route, and exchange route information such as traffic
+updates with the server and other clients.
+
+You also should have [Cocoapods](https://cocoapods.org/#install) installed, as well as the relevant
+tools to generate the client library code (and a server in another language, for testing). You can
+obtain the latter by following [these setup instructions](https://github.com/grpc/homebrew-grpc).
+
+
+<a name="try"></a>
+## Try it out!
+
+To try the sample app, we need a gRPC server running locally. Let's compile and run, for example,
+the C++ server in this repository:
+
+```shell
+$ pushd ../../cpp/route_guide
+$ make
+$ ./route_guide_server &
+$ popd
+```
+
+Now have Cocoapods generate and install the client library for our .proto files:
+
+```shell
+$ pod install
+```
+
+(This might have to compile OpenSSL, which takes around 15 minutes if Cocoapods doesn't have it yet
+on your computer's cache).
+
+Finally, open the XCode workspace created by Cocoapods, and run the app. You can check the calling
+code in `ViewControllers.m` and see the results in XCode's log console.
+
+The next sections guide you step-by-step through how this proto service is defined, how to generate
+a client library from it, and how to create an app that uses that library.
+
+
+<a name="proto"></a>
+## Defining the service
+
+First let's look at how the service we're using is defined. A gRPC *service* and its method
+*request* and *response* types using [protocol buffers](https://developers.google.com/protocol-buffers/docs/overview).
+You can see the complete .proto file for our example in [`grpc-common/protos/route_guide.proto`](https://github.com/grpc/grpc-common/blob/master/protos/route_guide.proto).
+
+To define a service, you specify a named `service` in your .proto file:
+
+```protobuf
+service RouteGuide {
+ ...
+}
+```
+
+Then you define `rpc` methods inside your service definition, specifying their request and response
+types. Protocol buffers let you define four kinds of service method, all of which are used in the
+`RouteGuide` service:
+
+- A *simple RPC* where the client sends a request to the server and receives a response later, just
+like a normal remote procedure call.
+```protobuf
+ // Obtains the feature at a given position.
+ rpc GetFeature(Point) returns (Feature) {}
+```
+
+- A *response-streaming RPC* where the client sends a request to the server and gets back a stream
+of response messages. You specify a response-streaming method by placing the `stream` keyword before
+the *response* type.
+```protobuf
+ // Obtains the Features available within the given Rectangle. Results are
+ // streamed rather than returned at once (e.g. in a response message with a
+ // repeated field), as the rectangle may cover a large area and contain a
+ // huge number of features.
+ rpc ListFeatures(Rectangle) returns (stream Feature) {}
+```
+
+- A *request-streaming RPC* where the client sends a sequence of messages to the server. Once the
+client has finished writing the messages, it waits for the server to read them all and return its
+response. You specify a request-streaming method by placing the `stream` keyword before the
+*request* type.
+```protobuf
+ // Accepts a stream of Points on a route being traversed, returning a
+ // RouteSummary when traversal is completed.
+ rpc RecordRoute(stream Point) returns (RouteSummary) {}
+```
+
+- A *bidirectional streaming RPC* where both sides send a sequence of messages to the other. The two
+streams operate independently, so clients and servers can read and write in whatever order they
+like: for example, the server could wait to receive all the client messages before writing its
+responses, or it could alternately read a message then write a message, or some other combination of
+reads and writes. The order of messages in each stream is preserved. You specify this type of method
+by placing the `stream` keyword before both the request and the response.
+```protobuf
+ // Accepts a stream of RouteNotes sent while a route is being traversed,
+ // while receiving other RouteNotes (e.g. from other users).
+ rpc RouteChat(stream RouteNote) returns (stream RouteNote) {}
+```
+
+Our .proto file also contains protocol buffer message type definitions for all the request and
+response types used in our service methods - for example, here's the `Point` message type:
+```protobuf
+// Points are represented as latitude-longitude pairs in the E7 representation
+// (degrees multiplied by 10**7 and rounded to the nearest integer).
+// Latitudes should be in the range +/- 90 degrees and longitude should be in
+// the range +/- 180 degrees (inclusive).
+message Point {
+ int32 latitude = 1;
+ int32 longitude = 2;
+}
+```
+
+You can specify a prefix to be used for your generated classes by adding the `objc_class_prefix`
+option at the top of the file. For example:
+```protobuf
+option objc_class_prefix = "RTG";
+```
+
+
+<a name="protoc"></a>
+## Generating client code
+
+Next we need to generate the gRPC client interfaces from our .proto service definition. We do this
+using the protocol buffer compiler (`protoc`) with a special gRPC Objective-C plugin.
+
+For simplicity, we've provided a [Podspec file](https://github.com/grpc/grpc-common/blob/master/objective-c/route_guide/RouteGuide.podspec)
+that runs `protoc` for you with the appropriate plugin, input, and output, and describes how to
+compile the generated files. You just need to run in this directory (`grpc-common/objective-c/route_guide`):
+
+```shell
+$ pod install
+```
+
+which, before installing the generated library in the XCode project of this sample, runs:
+
+```shell
+$ protoc -I ../../protos --objc_out=Pods/RouteGuide --objcgrpc_out=Pods/RouteGuide ../../protos/route_guide.proto
+```
+
+Running this command generates the following files under `Pods/RouteGuide/`:
+- `RouteGuide.pbobjc.h`, the header which declares your generated message classes.
+- `RouteGuide.pbobjc.m`, which contains the implementation of your message classes.
+- `RouteGuide.pbrpc.h`, the header which declares your generated service classes.
+- `RouteGuide.pbrpc.m`, which contains the implementation of your service classes.
+
+These contain:
+- All the protocol buffer code to populate, serialize, and retrieve our request and response message
+types.
+- A class called `RTGRouteGuide` that lets clients call the methods defined in the `RouteGuide`
+service.
+
+You can also use the provided Podspec file to generate client code from any other proto service
+definition; just replace the name (matching the file name), version, and other metadata.
+
+
+<a name="client"></a>
+## Creating the client
+
+In this section, we'll look at creating an Objective-C client for our `RouteGuide` service. You can
+see our complete example client code in [grpc-common/objective-c/route_guide/ViewControllers.m](https://github.com/grpc/grpc-common/blob/master/objective-c/route_guide/ViewControllers.m).
+(Note: In your apps, for maintainability and readability reasons, you shouldn't put all of your view
+controllers in a single file; it's done here only to simplify the learning process).
+
+### Constructing a client object
+
+To call service methods, we first need to create a client object, an instance of the generated
+`RTGRouteGuide` class. The designated initializer of the class expects a `NSString *` with the
+server address and port we want to connect to:
+
+```objective-c
+#import <RouteGuide/RouteGuide.pbrpc.h>
+
+static NSString * const kHostAddress = @"http://localhost:50051";
+
+...
+
+RTGRouteGuide *client = [[RTGRouteGuide alloc] initWithHost:kHostAddress];
+```
+
+Notice that we've specified the HTTP scheme in the host address. This is because the server we will
+be using to test our client doesn't use [TLS](http://en.wikipedia.org/wiki/Transport_Layer_Security).
+This is fine because it will be running locally on our development machine. The most common case,
+though, is connecting with a gRPC server on the internet, running gRPC over TLS. For that case, the
+HTTPS scheme can be specified (or no scheme at all, as HTTPS is the default value). The default
+value of the port is that of the scheme selected: 443 for HTTPS and 80 for HTTP.
+
+
+### Calling service methods
+
+Now let's look at how we call our service methods. As you will see, all these methods are
+asynchronous, so you can call them from the main thread of your app without worrying about freezing
+your UI or the OS killing your app.
+
+#### Simple RPC
+
+Calling the simple RPC `GetFeature` is nearly as straightforward as calling any other asynchronous
+method on Cocoa.
+
+```objective-c
+RTGPoint *point = [RTGPoint message];
+point.latitude = 40E7;
+point.longitude = -74E7;
+
+[client getFeatureWithRequest:point handler:^(RTGFeature *response, NSError *error) {
+ if (response) {
+ // Successful response received
+ } else {
+ // RPC error
+ }
+}];
+```
+
+As you can see, we create and populate a request protocol buffer object (in our case `RTGPoint`).
+Then, we call the method on the client object, passing it the request, and a block to handle the
+response (or any RPC error). If the RPC finishes successfully, the handler block is called with a
+`nil` error argument, and we can read the response information from the server from the response
+argument. If, instead, some RPC error happens, the handler block is called with a `nil` response
+argument, and we can read the details of the problem from the error argument.
+
+```objective-c
+NSLog(@"Found feature called %@ at %@.", response.name, response.location);
+```
+
+#### Streaming RPCs
+
+Now let's look at our streaming methods. Here's where we call the response-streaming method
+`ListFeatures`, which results in our client receiving a stream of geographical `RTGFeature`s:
+
+```objective-c
+[client listFeaturesWithRequest:rectangle
+ eventHandler:^(BOOL done, RTGFeature *response, NSError *error) {
+ if (response) {
+ // Element of the stream of responses received
+ } else if (error) {
+ // RPC error; the stream is over.
+ }
+ if (done) {
+ // The stream is over (all the responses were received, or an error occured). Do any cleanup.
+ }
+}];
+```
+
+Notice how the signature of the `eventHandler` block now includes a `BOOL done` parameter. The
+`eventHandler` block can be called any number of times; only on the last call is the `done` argument
+value set to `YES`. If an error occurs, the RPC finishes and the block is called with the arguments
+`(YES, nil, error)`.
+
+The request-streaming method `RecordRoute` expects a stream of `RTGPoint`s from the cient. This
+stream is passed to the method as an object of class `GRXWriter`. The simplest way to create one is
+to initialize one from a `NSArray` object:
+
+
+```objective-c
+#import <RxLibrary/GRXWriter+Immediate.h>
+
+...
+
+RTGPoint *point1 = [RTGPoint message];
+point.latitude = 40E7;
+point.longitude = -74E7;
+
+RTGPoint *point2 = [RTGPoint message];
+point.latitude = 40E7;
+point.longitude = -74E7;
+
+GRXWriter *locationsWriter = [GRXWriter writerWithContainer:@[point1, point2]];
+
+[client recordRouteWithRequestsWriter:locationsWriter
+ handler:^(RTGRouteSummary *response, NSError *error) {
+ if (response) {
+ NSLog(@"Finished trip with %i points", response.pointCount);
+ NSLog(@"Passed %i features", response.featureCount);
+ NSLog(@"Travelled %i meters", response.distance);
+ NSLog(@"It took %i seconds", response.elapsedTime);
+ } else {
+ NSLog(@"RPC error: %@", error);
+ }
+}];
+
+```
+
+The `GRXWriter` class is generic enough to allow for asynchronous streams, streams of future values,
+or even infinite streams.
+
+Finally, let's look at our bidirectional streaming RPC `RouteChat()`. The way to call a
+bidirectional streaming RPC is just a combination of how to call request-streaming RPCs and
+response-streaming RPCs.
+
+```objective-c
+[client routeChatWithRequestsWriter:notesWriter
+ eventHandler:^(BOOL done, RTGRouteNote *note, NSError *error) {
+ if (note) {
+ NSLog(@"Got message %@ at %@", note.message, note.location);
+ } else if (error) {
+ NSLog(@"RPC error: %@", error);
+ }
+ if (done) {
+ NSLog(@"Chat ended.");
+ }
+}];
+```
+
+The semantics for the handler block and the `GRXWriter` argument here are exactly the same as for
+our request-streaming and response-streaming methods. Although both client and server will always
+get the other's messages in the order they were written, the two streams operate completely
+independently.
diff --git a/examples/objective-c/route_guide/RouteGuide.podspec b/examples/objective-c/route_guide/RouteGuide.podspec
new file mode 100644
index 0000000000..7b99a6c6a7
--- /dev/null
+++ b/examples/objective-c/route_guide/RouteGuide.podspec
@@ -0,0 +1,35 @@
+Pod::Spec.new do |s|
+ s.name = "RouteGuide"
+ s.version = "0.0.1"
+ s.license = "New BSD"
+
+ s.ios.deployment_target = "6.0"
+ s.osx.deployment_target = "10.8"
+
+ # Base directory where the .proto files are.
+ src = "../../protos"
+
+ # Directory where the generated files will be place.
+ dir = "Pods/" + s.name
+
+ # Run protoc with the Objective-C and gRPC plugins to generate protocol messages and gRPC clients.
+ s.prepare_command = <<-CMD
+ mkdir -p #{dir}
+ protoc -I #{src} --objc_out=#{dir} --objcgrpc_out=#{dir} #{src}/route_guide.proto
+ CMD
+
+ s.subspec "Messages" do |ms|
+ ms.source_files = "#{dir}/*.pbobjc.{h,m}", "#{dir}/**/*.pbobjc.{h,m}"
+ ms.header_mappings_dir = dir
+ ms.requires_arc = false
+ ms.dependency "Protobuf", "~> 3.0.0-alpha-3"
+ end
+
+ s.subspec "Services" do |ss|
+ ss.source_files = "#{dir}/*.pbrpc.{h,m}", "#{dir}/**/*.pbrpc.{h,m}"
+ ss.header_mappings_dir = dir
+ ss.requires_arc = true
+ ss.dependency "gRPC", "~> 0.6"
+ ss.dependency "#{s.name}/Messages"
+ end
+end
diff --git a/examples/objective-c/route_guide/RouteGuideClient.xcodeproj/project.pbxproj b/examples/objective-c/route_guide/RouteGuideClient.xcodeproj/project.pbxproj
new file mode 100644
index 0000000000..6ab6b27a1b
--- /dev/null
+++ b/examples/objective-c/route_guide/RouteGuideClient.xcodeproj/project.pbxproj
@@ -0,0 +1,366 @@
+// !$*UTF8*$!
+{
+ archiveVersion = 1;
+ classes = {
+ };
+ objectVersion = 46;
+ objects = {
+
+/* Begin PBXBuildFile section */
+ 124E20A2FC8EAE54460D4ED2 /* libPods-RouteGuideClient.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 71CEE03D66D40FC37264D6E4 /* libPods-RouteGuideClient.a */; };
+ 632527831B1D0396003073D9 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 632527821B1D0396003073D9 /* main.m */; };
+ 632527861B1D0396003073D9 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 632527851B1D0396003073D9 /* AppDelegate.m */; };
+ 6325278F1B1D0396003073D9 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 6325278D1B1D0396003073D9 /* Main.storyboard */; };
+ 632527911B1D0396003073D9 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 632527901B1D0396003073D9 /* Images.xcassets */; };
+ 6367B55B1B223AFA008861F5 /* route_guide_db.json in Resources */ = {isa = PBXBuildFile; fileRef = 6367B55A1B223AFA008861F5 /* route_guide_db.json */; };
+ 63A6015C1B1DAB5000FA5B86 /* ViewControllers.m in Sources */ = {isa = PBXBuildFile; fileRef = 63A6015B1B1DAB5000FA5B86 /* ViewControllers.m */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXFileReference section */
+ 6325277D1B1D0396003073D9 /* RouteGuideClient.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = RouteGuideClient.app; sourceTree = BUILT_PRODUCTS_DIR; };
+ 632527811B1D0396003073D9 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
+ 632527821B1D0396003073D9 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
+ 632527841B1D0396003073D9 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; };
+ 632527851B1D0396003073D9 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; };
+ 6325278E1B1D0396003073D9 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
+ 632527901B1D0396003073D9 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = "<group>"; };
+ 6367B55A1B223AFA008861F5 /* route_guide_db.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = route_guide_db.json; sourceTree = "<group>"; };
+ 63A6015B1B1DAB5000FA5B86 /* ViewControllers.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ViewControllers.m; sourceTree = "<group>"; };
+ 71CEE03D66D40FC37264D6E4 /* libPods-RouteGuideClient.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-RouteGuideClient.a"; sourceTree = BUILT_PRODUCTS_DIR; };
+ ADA4C647BAE906F79AD9A45E /* Pods-RouteGuideClient.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RouteGuideClient.debug.xcconfig"; path = "Pods/Target Support Files/Pods-RouteGuideClient/Pods-RouteGuideClient.debug.xcconfig"; sourceTree = "<group>"; };
+ C83C5A54D1A4EA07569F1AED /* Pods-RouteGuideClient.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RouteGuideClient.release.xcconfig"; path = "Pods/Target Support Files/Pods-RouteGuideClient/Pods-RouteGuideClient.release.xcconfig"; sourceTree = "<group>"; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+ 6325277A1B1D0395003073D9 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 124E20A2FC8EAE54460D4ED2 /* libPods-RouteGuideClient.a in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+ 56849C29DC376BF4B902CD77 /* Pods */ = {
+ isa = PBXGroup;
+ children = (
+ ADA4C647BAE906F79AD9A45E /* Pods-RouteGuideClient.debug.xcconfig */,
+ C83C5A54D1A4EA07569F1AED /* Pods-RouteGuideClient.release.xcconfig */,
+ );
+ name = Pods;
+ sourceTree = "<group>";
+ };
+ 631C63891B1DBC41001295D5 /* Misc */ = {
+ isa = PBXGroup;
+ children = (
+ 632527841B1D0396003073D9 /* AppDelegate.h */,
+ 632527851B1D0396003073D9 /* AppDelegate.m */,
+ 632527901B1D0396003073D9 /* Images.xcassets */,
+ 632527801B1D0396003073D9 /* Supporting Files */,
+ );
+ path = Misc;
+ sourceTree = "<group>";
+ };
+ 632527741B1D0395003073D9 = {
+ isa = PBXGroup;
+ children = (
+ 6325277F1B1D0396003073D9 /* RouteGuideClient */,
+ 6325277E1B1D0396003073D9 /* Products */,
+ 56849C29DC376BF4B902CD77 /* Pods */,
+ 7482B8A18481F7B13ADE4530 /* Frameworks */,
+ );
+ sourceTree = "<group>";
+ };
+ 6325277E1B1D0396003073D9 /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ 6325277D1B1D0396003073D9 /* RouteGuideClient.app */,
+ );
+ name = Products;
+ sourceTree = "<group>";
+ };
+ 6325277F1B1D0396003073D9 /* RouteGuideClient */ = {
+ isa = PBXGroup;
+ children = (
+ 63A6015B1B1DAB5000FA5B86 /* ViewControllers.m */,
+ 6367B55A1B223AFA008861F5 /* route_guide_db.json */,
+ 6325278D1B1D0396003073D9 /* Main.storyboard */,
+ 631C63891B1DBC41001295D5 /* Misc */,
+ );
+ name = RouteGuideClient;
+ sourceTree = SOURCE_ROOT;
+ };
+ 632527801B1D0396003073D9 /* Supporting Files */ = {
+ isa = PBXGroup;
+ children = (
+ 632527811B1D0396003073D9 /* Info.plist */,
+ 632527821B1D0396003073D9 /* main.m */,
+ );
+ name = "Supporting Files";
+ sourceTree = "<group>";
+ };
+ 7482B8A18481F7B13ADE4530 /* Frameworks */ = {
+ isa = PBXGroup;
+ children = (
+ 71CEE03D66D40FC37264D6E4 /* libPods-RouteGuideClient.a */,
+ );
+ name = Frameworks;
+ sourceTree = "<group>";
+ };
+/* End PBXGroup section */
+
+/* Begin PBXNativeTarget section */
+ 6325277C1B1D0395003073D9 /* RouteGuideClient */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 632527A31B1D0396003073D9 /* Build configuration list for PBXNativeTarget "RouteGuideClient" */;
+ buildPhases = (
+ C6FC30AD2376EC04317237C5 /* Check Pods Manifest.lock */,
+ 632527791B1D0395003073D9 /* Sources */,
+ 6325277A1B1D0395003073D9 /* Frameworks */,
+ 6325277B1B1D0395003073D9 /* Resources */,
+ FFE0BCF30339E7A50A989EAB /* Copy Pods Resources */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = RouteGuideClient;
+ productName = RouteGuideClient;
+ productReference = 6325277D1B1D0396003073D9 /* RouteGuideClient.app */;
+ productType = "com.apple.product-type.application";
+ };
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+ 632527751B1D0395003073D9 /* Project object */ = {
+ isa = PBXProject;
+ attributes = {
+ LastUpgradeCheck = 0630;
+ ORGANIZATIONNAME = gRPC;
+ TargetAttributes = {
+ 6325277C1B1D0395003073D9 = {
+ CreatedOnToolsVersion = 6.3.1;
+ };
+ };
+ };
+ buildConfigurationList = 632527781B1D0395003073D9 /* Build configuration list for PBXProject "RouteGuideClient" */;
+ compatibilityVersion = "Xcode 3.2";
+ developmentRegion = English;
+ hasScannedForEncodings = 0;
+ knownRegions = (
+ en,
+ Base,
+ );
+ mainGroup = 632527741B1D0395003073D9;
+ productRefGroup = 6325277E1B1D0396003073D9 /* Products */;
+ projectDirPath = "";
+ projectRoot = "";
+ targets = (
+ 6325277C1B1D0395003073D9 /* RouteGuideClient */,
+ );
+ };
+/* End PBXProject section */
+
+/* Begin PBXResourcesBuildPhase section */
+ 6325277B1B1D0395003073D9 /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 6325278F1B1D0396003073D9 /* Main.storyboard in Resources */,
+ 632527911B1D0396003073D9 /* Images.xcassets in Resources */,
+ 6367B55B1B223AFA008861F5 /* route_guide_db.json in Resources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXResourcesBuildPhase section */
+
+/* Begin PBXShellScriptBuildPhase section */
+ C6FC30AD2376EC04317237C5 /* Check Pods Manifest.lock */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ );
+ name = "Check Pods Manifest.lock";
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [[ $? != 0 ]] ; then\n cat << EOM\nerror: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\nEOM\n exit 1\nfi\n";
+ showEnvVarsInLog = 0;
+ };
+ FFE0BCF30339E7A50A989EAB /* Copy Pods Resources */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ );
+ name = "Copy Pods Resources";
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-RouteGuideClient/Pods-RouteGuideClient-resources.sh\"\n";
+ showEnvVarsInLog = 0;
+ };
+/* End PBXShellScriptBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+ 632527791B1D0395003073D9 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 632527861B1D0396003073D9 /* AppDelegate.m in Sources */,
+ 632527831B1D0396003073D9 /* main.m in Sources */,
+ 63A6015C1B1DAB5000FA5B86 /* ViewControllers.m in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXSourcesBuildPhase section */
+
+/* Begin PBXVariantGroup section */
+ 6325278D1B1D0396003073D9 /* Main.storyboard */ = {
+ isa = PBXVariantGroup;
+ children = (
+ 6325278E1B1D0396003073D9 /* Base */,
+ );
+ name = Main.storyboard;
+ path = Misc;
+ sourceTree = "<group>";
+ };
+/* End PBXVariantGroup section */
+
+/* Begin XCBuildConfiguration section */
+ 632527A11B1D0396003073D9 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+ COPY_PHASE_STRIP = NO;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu99;
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PREPROCESSOR_DEFINITIONS = (
+ "DEBUG=1",
+ "$(inherited)",
+ );
+ GCC_SYMBOLS_PRIVATE_EXTERN = NO;
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ IPHONEOS_DEPLOYMENT_TARGET = 8.3;
+ MTL_ENABLE_DEBUG_INFO = YES;
+ ONLY_ACTIVE_ARCH = YES;
+ SDKROOT = iphoneos;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ };
+ name = Debug;
+ };
+ 632527A21B1D0396003073D9 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+ COPY_PHASE_STRIP = NO;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ ENABLE_NS_ASSERTIONS = NO;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu99;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ IPHONEOS_DEPLOYMENT_TARGET = 8.3;
+ MTL_ENABLE_DEBUG_INFO = NO;
+ SDKROOT = iphoneos;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ VALIDATE_PRODUCT = YES;
+ };
+ name = Release;
+ };
+ 632527A41B1D0396003073D9 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = ADA4C647BAE906F79AD9A45E /* Pods-RouteGuideClient.debug.xcconfig */;
+ buildSettings = {
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ INFOPLIST_FILE = Misc/Info.plist;
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ };
+ name = Debug;
+ };
+ 632527A51B1D0396003073D9 /* Release */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = C83C5A54D1A4EA07569F1AED /* Pods-RouteGuideClient.release.xcconfig */;
+ buildSettings = {
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ INFOPLIST_FILE = Misc/Info.plist;
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ };
+ name = Release;
+ };
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+ 632527781B1D0395003073D9 /* Build configuration list for PBXProject "RouteGuideClient" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 632527A11B1D0396003073D9 /* Debug */,
+ 632527A21B1D0396003073D9 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ 632527A31B1D0396003073D9 /* Build configuration list for PBXNativeTarget "RouteGuideClient" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 632527A41B1D0396003073D9 /* Debug */,
+ 632527A51B1D0396003073D9 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+/* End XCConfigurationList section */
+ };
+ rootObject = 632527751B1D0395003073D9 /* Project object */;
+}
diff --git a/examples/objective-c/route_guide/RouteGuideClient.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/examples/objective-c/route_guide/RouteGuideClient.xcodeproj/project.xcworkspace/contents.xcworkspacedata
new file mode 100644
index 0000000000..f208589e44
--- /dev/null
+++ b/examples/objective-c/route_guide/RouteGuideClient.xcodeproj/project.xcworkspace/contents.xcworkspacedata
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Workspace
+ version = "1.0">
+ <FileRef
+ location = "self:RouteGuideClient.xcodeproj">
+ </FileRef>
+</Workspace>
diff --git a/examples/objective-c/route_guide/ViewControllers.m b/examples/objective-c/route_guide/ViewControllers.m
new file mode 100644
index 0000000000..cfc3338bca
--- /dev/null
+++ b/examples/objective-c/route_guide/ViewControllers.m
@@ -0,0 +1,228 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#import <UIKit/UIKit.h>
+#import <RouteGuide/RouteGuide.pbrpc.h>
+#import <RxLibrary/GRXWriter+Immediate.h>
+#import <RxLibrary/GRXWriter+Transformations.h>
+
+static NSString * const kHostAddress = @"http://localhost:50051";
+
+// Category to override RTGPoint's description.
+@interface RTGPoint (Description)
+- (NSString *)description;
+@end
+
+@implementation RTGPoint (Description)
+- (NSString *)description {
+ NSString *verticalDirection = self.latitude >= 0 ? @"N" : @"S";
+ NSString *horizontalDirection = self.longitude >= 0 ? @"E" : @"W";
+ return [NSString stringWithFormat:@"%.02f%@ %.02f%@",
+ abs(self.latitude) / 1E7f, verticalDirection,
+ abs(self.longitude) / 1E7f, horizontalDirection];
+}
+@end
+
+// Category to give RTGRouteNote a convenience constructor.
+@interface RTGRouteNote (Constructors)
++ (instancetype)noteWithMessage:(NSString *)message
+ latitude:(float)latitude
+ longitude:(float)longitude;
+@end
+
+@implementation RTGRouteNote (Constructors)
++ (instancetype)noteWithMessage:(NSString *)message
+ latitude:(float)latitude
+ longitude:(float)longitude {
+ RTGRouteNote *note = [self message];
+ note.message = message;
+ note.location.latitude = (int32_t) latitude * 1E7;
+ note.location.longitude = (int32_t) longitude * 1E7;
+ return note;
+}
+@end
+
+
+#pragma mark Demo: Get Feature
+
+// Run the getFeature demo. Calls getFeature with a point known to have a feature and a point known
+// not to have a feature.
+
+@interface GetFeatureViewController : UIViewController
+@end
+
+@implementation GetFeatureViewController
+
+- (void)viewDidLoad {
+ [super viewDidLoad];
+
+ RTGRouteGuide *client = [[RTGRouteGuide alloc] initWithHost:kHostAddress];
+
+ void (^handler)(RTGFeature *response, NSError *error) = ^(RTGFeature *response, NSError *error) {
+ if (response.name.length) {
+ NSLog(@"Found feature called %@ at %@.", response.name, response.location);
+ } else if (response) {
+ NSLog(@"Found no features at %@", response.location);
+ } else {
+ NSLog(@"RPC error: %@", error);
+ }
+ };
+
+ RTGPoint *point = [RTGPoint message];
+ point.latitude = 409146138;
+ point.longitude = -746188906;
+
+ [client getFeatureWithRequest:point handler:handler];
+ [client getFeatureWithRequest:[RTGPoint message] handler:handler];
+}
+
+@end
+
+
+#pragma mark Demo: List Features
+
+// Run the listFeatures demo. Calls listFeatures with a rectangle containing all of the features in
+// the pre-generated database. Prints each response as it comes in.
+
+@interface ListFeaturesViewController : UIViewController
+@end
+
+@implementation ListFeaturesViewController
+
+- (void)viewDidLoad {
+ [super viewDidLoad];
+
+ RTGRouteGuide *client = [[RTGRouteGuide alloc] initWithHost:kHostAddress];
+
+ RTGRectangle *rectangle = [RTGRectangle message];
+ rectangle.lo.latitude = 405E6;
+ rectangle.lo.longitude = -750E6;
+ rectangle.hi.latitude = 410E6;
+ rectangle.hi.longitude = -745E6;
+
+ NSLog(@"Looking for features between %@ and %@", rectangle.lo, rectangle.hi);
+ [client listFeaturesWithRequest:rectangle
+ eventHandler:^(BOOL done, RTGFeature *response, NSError *error) {
+ if (response) {
+ NSLog(@"Found feature at %@ called %@.", response.location, response.name);
+ } else if (error) {
+ NSLog(@"RPC error: %@", error);
+ }
+ }];
+}
+
+@end
+
+
+#pragma mark Demo: Record Route
+
+// Run the recordRoute demo. Sends several randomly chosen points from the pre-generated feature
+// database with a variable delay in between. Prints the statistics when they are sent from the
+// server.
+
+@interface RecordRouteViewController : UIViewController
+@end
+
+@implementation RecordRouteViewController
+
+- (void)viewDidLoad {
+ [super viewDidLoad];
+
+ NSString *dataBasePath = [NSBundle.mainBundle pathForResource:@"route_guide_db"
+ ofType:@"json"];
+ NSData *dataBaseContent = [NSData dataWithContentsOfFile:dataBasePath];
+ NSArray *features = [NSJSONSerialization JSONObjectWithData:dataBaseContent options:0 error:NULL];
+
+ GRXWriter *locations = [[GRXWriter writerWithContainer:features] map:^id(id feature) {
+ RTGPoint *location = [RTGPoint message];
+ location.longitude = [((NSNumber *) feature[@"location"][@"longitude"]) intValue];
+ location.latitude = [((NSNumber *) feature[@"location"][@"latitude"]) intValue];
+ NSLog(@"Visiting point %@", location);
+ return location;
+ }];
+
+ RTGRouteGuide *client = [[RTGRouteGuide alloc] initWithHost:kHostAddress];
+
+ [client recordRouteWithRequestsWriter:locations handler:^(RTGRouteSummary *response, NSError *error) {
+ if (response) {
+ NSLog(@"Finished trip with %i points", response.pointCount);
+ NSLog(@"Passed %i features", response.featureCount);
+ NSLog(@"Travelled %i meters", response.distance);
+ NSLog(@"It took %i seconds", response.elapsedTime);
+ } else {
+ NSLog(@"RPC error: %@", error);
+ }
+ }];
+}
+
+@end
+
+
+#pragma mark Demo: Route Chat
+
+// Run the routeChat demo. Send some chat messages, and print any chat messages that are sent from
+// the server.
+
+@interface RouteChatViewController : UIViewController
+@end
+
+@implementation RouteChatViewController
+
+- (void)viewDidLoad {
+ [super viewDidLoad];
+
+ NSArray *notes = @[[RTGRouteNote noteWithMessage:@"First message" latitude:0 longitude:0],
+ [RTGRouteNote noteWithMessage:@"Second message" latitude:0 longitude:1],
+ [RTGRouteNote noteWithMessage:@"Third message" latitude:1 longitude:0],
+ [RTGRouteNote noteWithMessage:@"Fourth message" latitude:0 longitude:0]];
+ GRXWriter *notesWriter = [[GRXWriter writerWithContainer:notes] map:^id(RTGRouteNote *note) {
+ NSLog(@"Sending message %@ at %@", note.message, note.location);
+ return note;
+ }];
+
+ RTGRouteGuide *client = [[RTGRouteGuide alloc] initWithHost:kHostAddress];
+
+ [client routeChatWithRequestsWriter:notesWriter
+ eventHandler:^(BOOL done, RTGRouteNote *note, NSError *error) {
+ if (note) {
+ NSLog(@"Got message %@ at %@", note.message, note.location);
+ } else if (error) {
+ NSLog(@"RPC error: %@", error);
+ }
+ if (done) {
+ NSLog(@"Chat ended.");
+ }
+ }];
+}
+
+@end
diff --git a/examples/objective-c/route_guide/route_guide_db.json b/examples/objective-c/route_guide/route_guide_db.json
new file mode 100644
index 0000000000..9caebaa433
--- /dev/null
+++ b/examples/objective-c/route_guide/route_guide_db.json
@@ -0,0 +1,121 @@
+[{
+ "location": {
+ "latitude": 407838351,
+ "longitude": -746143763
+ },
+ "name": "Patriots Path, Mendham, NJ 07945, USA"
+}, {
+ "location": {
+ "latitude": 408122808,
+ "longitude": -743999179
+ },
+ "name": "101 New Jersey 10, Whippany, NJ 07981, USA"
+}, {
+ "location": {
+ "latitude": 413628156,
+ "longitude": -749015468
+ },
+ "name": "U.S. 6, Shohola, PA 18458, USA"
+}, {
+ "location": {
+ "latitude": 419999544,
+ "longitude": -740371136
+ },
+ "name": "5 Conners Road, Kingston, NY 12401, USA"
+}, {
+ "location": {
+ "latitude": 414008389,
+ "longitude": -743951297
+ },
+ "name": "Mid Hudson Psychiatric Center, New Hampton, NY 10958, USA"
+}, {
+ "location": {
+ "latitude": 419611318,
+ "longitude": -746524769
+ },
+ "name": "287 Flugertown Road, Livingston Manor, NY 12758, USA"
+}, {
+ "location": {
+ "latitude": 406109563,
+ "longitude": -742186778
+ },
+ "name": "4001 Tremley Point Road, Linden, NJ 07036, USA"
+}, {
+ "location": {
+ "latitude": 416802456,
+ "longitude": -742370183
+ },
+ "name": "352 South Mountain Road, Wallkill, NY 12589, USA"
+}, {
+ "location": {
+ "latitude": 412950425,
+ "longitude": -741077389
+ },
+ "name": "Bailey Turn Road, Harriman, NY 10926, USA"
+}, {
+ "location": {
+ "latitude": 412144655,
+ "longitude": -743949739
+ },
+ "name": "193-199 Wawayanda Road, Hewitt, NJ 07421, USA"
+}, {
+ "location": {
+ "latitude": 404306372,
+ "longitude": -741079661
+ },
+ "name": ""
+}, {
+ "location": {
+ "latitude": 403966326,
+ "longitude": -748519297
+ },
+ "name": ""
+}, {
+ "location": {
+ "latitude": 405002031,
+ "longitude": -748407866
+ },
+ "name": ""
+}, {
+ "location": {
+ "latitude": 409532885,
+ "longitude": -742200683
+ },
+ "name": ""
+}, {
+ "location": {
+ "latitude": 416851321,
+ "longitude": -742674555
+ },
+ "name": ""
+}, {
+ "location": {
+ "latitude": 406411633,
+ "longitude": -741722051
+ },
+ "name": "3387 Richmond Terrace, Staten Island, NY 10303, USA"
+}, {
+ "location": {
+ "latitude": 413069058,
+ "longitude": -744597778
+ },
+ "name": "261 Van Sickle Road, Goshen, NY 10924, USA"
+}, {
+ "location": {
+ "latitude": 418465462,
+ "longitude": -746859398
+ },
+ "name": ""
+}, {
+ "location": {
+ "latitude": 411733222,
+ "longitude": -744228360
+ },
+ "name": ""
+}, {
+ "location": {
+ "latitude": 410248224,
+ "longitude": -747127767
+ },
+ "name": "3 Hasta Way, Newton, NJ 07860, USA"
+}]