Adds NearbyConectionsExample xcode project with README how to guide to build example project.
PiperOrigin-RevId: 409963391
diff --git a/cpp/platform/impl/ios/Example/NearbyConnectionsExample/NearbyConnectionsExample.png b/cpp/platform/impl/ios/Example/NearbyConnectionsExample/NearbyConnectionsExample.png
new file mode 100644
index 0000000..c495d68
--- /dev/null
+++ b/cpp/platform/impl/ios/Example/NearbyConnectionsExample/NearbyConnectionsExample.png
Binary files differ
diff --git a/cpp/platform/impl/ios/Example/NearbyConnectionsExample/NearbyConnectionsExample.xcodeproj/project.pbxproj b/cpp/platform/impl/ios/Example/NearbyConnectionsExample/NearbyConnectionsExample.xcodeproj/project.pbxproj
new file mode 100644
index 0000000..5f57eaf
--- /dev/null
+++ b/cpp/platform/impl/ios/Example/NearbyConnectionsExample/NearbyConnectionsExample.xcodeproj/project.pbxproj
@@ -0,0 +1,355 @@
+// !$*UTF8*$!
+{
+ archiveVersion = 1;
+ classes = {
+ };
+ objectVersion = 50;
+ objects = {
+
+/* Begin PBXBuildFile section */
+ 41B7A2C3208F900100EBA53E /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 41B7A2C2208F900100EBA53E /* AppDelegate.m */; };
+ 41B7A2C6208F900100EBA53E /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 41B7A2C5208F900100EBA53E /* ViewController.m */; };
+ 41B7A2C9208F900100EBA53E /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 41B7A2C7208F900100EBA53E /* Main.storyboard */; };
+ 41B7A2CB208F900200EBA53E /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 41B7A2CA208F900200EBA53E /* Assets.xcassets */; };
+ 41B7A2CE208F900200EBA53E /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 41B7A2CC208F900200EBA53E /* LaunchScreen.storyboard */; };
+ 41B7A2D1208F900200EBA53E /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 41B7A2D0208F900200EBA53E /* main.m */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXFileReference section */
+ 41B7A2BE208F900100EBA53E /* NearbyConnectionsExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = NearbyConnectionsExample.app; sourceTree = BUILT_PRODUCTS_DIR; };
+ 41B7A2C1208F900100EBA53E /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; };
+ 41B7A2C2208F900100EBA53E /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; };
+ 41B7A2C4208F900100EBA53E /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = "<group>"; };
+ 41B7A2C5208F900100EBA53E /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = "<group>"; };
+ 41B7A2C8208F900100EBA53E /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
+ 41B7A2CA208F900200EBA53E /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
+ 41B7A2CD208F900200EBA53E /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
+ 41B7A2CF208F900200EBA53E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
+ 41B7A2D0208F900200EBA53E /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+ 41B7A2BB208F900100EBA53E /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+ 41B7A2B5208F900000EBA53E = {
+ isa = PBXGroup;
+ children = (
+ 41B7A2C0208F900100EBA53E /* NearbyConnectionsExample */,
+ 41B7A2BF208F900100EBA53E /* Products */,
+ );
+ sourceTree = "<group>";
+ };
+ 41B7A2BF208F900100EBA53E /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ 41B7A2BE208F900100EBA53E /* NearbyConnectionsExample.app */,
+ );
+ name = Products;
+ sourceTree = "<group>";
+ };
+ 41B7A2C0208F900100EBA53E /* NearbyConnectionsExample */ = {
+ isa = PBXGroup;
+ children = (
+ 41B7A2C1208F900100EBA53E /* AppDelegate.h */,
+ 41B7A2C2208F900100EBA53E /* AppDelegate.m */,
+ 41B7A2C4208F900100EBA53E /* ViewController.h */,
+ 41B7A2C5208F900100EBA53E /* ViewController.m */,
+ 41B7A2C7208F900100EBA53E /* Main.storyboard */,
+ 41B7A2CA208F900200EBA53E /* Assets.xcassets */,
+ 41B7A2CC208F900200EBA53E /* LaunchScreen.storyboard */,
+ 41B7A2CF208F900200EBA53E /* Info.plist */,
+ 41B7A2D0208F900200EBA53E /* main.m */,
+ );
+ path = NearbyConnectionsExample;
+ sourceTree = "<group>";
+ };
+/* End PBXGroup section */
+
+/* Begin PBXNativeTarget section */
+ 41B7A2BD208F900100EBA53E /* NearbyConnectionsExample */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 41B7A2D4208F900200EBA53E /* Build configuration list for PBXNativeTarget "NearbyConnectionsExample" */;
+ buildPhases = (
+ 41B7A2BA208F900100EBA53E /* Sources */,
+ 41B7A2BB208F900100EBA53E /* Frameworks */,
+ 41B7A2BC208F900100EBA53E /* Resources */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = NearbyConnectionsExample;
+ productName = NearbyConnectionsExample;
+ productReference = 41B7A2BE208F900100EBA53E /* NearbyConnectionsExample.app */;
+ productType = "com.apple.product-type.application";
+ };
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+ 41B7A2B6208F900000EBA53E /* Project object */ = {
+ isa = PBXProject;
+ attributes = {
+ LastUpgradeCheck = 0930;
+ ORGANIZATIONNAME = Google;
+ TargetAttributes = {
+ 41B7A2BD208F900100EBA53E = {
+ CreatedOnToolsVersion = 9.3;
+ };
+ };
+ };
+ buildConfigurationList = 41B7A2B9208F900000EBA53E /* Build configuration list for PBXProject "NearbyConnectionsExample" */;
+ compatibilityVersion = "Xcode 9.3";
+ developmentRegion = en;
+ hasScannedForEncodings = 0;
+ knownRegions = (
+ en,
+ Base,
+ );
+ mainGroup = 41B7A2B5208F900000EBA53E;
+ productRefGroup = 41B7A2BF208F900100EBA53E /* Products */;
+ projectDirPath = "";
+ projectRoot = "";
+ targets = (
+ 41B7A2BD208F900100EBA53E /* NearbyConnectionsExample */,
+ );
+ };
+/* End PBXProject section */
+
+/* Begin PBXResourcesBuildPhase section */
+ 41B7A2BC208F900100EBA53E /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 41B7A2CE208F900200EBA53E /* LaunchScreen.storyboard in Resources */,
+ 41B7A2CB208F900200EBA53E /* Assets.xcassets in Resources */,
+ 41B7A2C9208F900100EBA53E /* Main.storyboard in Resources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXResourcesBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+ 41B7A2BA208F900100EBA53E /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 41B7A2C6208F900100EBA53E /* ViewController.m in Sources */,
+ 41B7A2D1208F900200EBA53E /* main.m in Sources */,
+ 41B7A2C3208F900100EBA53E /* AppDelegate.m in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXSourcesBuildPhase section */
+
+/* Begin PBXVariantGroup section */
+ 41B7A2C7208F900100EBA53E /* Main.storyboard */ = {
+ isa = PBXVariantGroup;
+ children = (
+ 41B7A2C8208F900100EBA53E /* Base */,
+ );
+ name = Main.storyboard;
+ sourceTree = "<group>";
+ };
+ 41B7A2CC208F900200EBA53E /* LaunchScreen.storyboard */ = {
+ isa = PBXVariantGroup;
+ children = (
+ 41B7A2CD208F900200EBA53E /* Base */,
+ );
+ name = LaunchScreen.storyboard;
+ sourceTree = "<group>";
+ };
+/* End PBXVariantGroup section */
+
+/* Begin XCBuildConfiguration section */
+ 41B7A2D2208F900200EBA53E /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_ENABLE_OBJC_WEAK = YES;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_COMMA = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ CODE_SIGN_IDENTITY = "iPhone Developer";
+ COPY_PHASE_STRIP = NO;
+ DEBUG_INFORMATION_FORMAT = dwarf;
+ ENABLE_BITCODE = NO;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ ENABLE_TESTABILITY = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu11;
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PREPROCESSOR_DEFINITIONS = (
+ "DEBUG=1",
+ "$(inherited)",
+ );
+ 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 = 9.3;
+ MTL_ENABLE_DEBUG_INFO = YES;
+ ONLY_ACTIVE_ARCH = YES;
+ SDKROOT = iphoneos;
+ };
+ name = Debug;
+ };
+ 41B7A2D3208F900200EBA53E /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_ENABLE_OBJC_WEAK = YES;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_COMMA = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ CODE_SIGN_IDENTITY = "iPhone Developer";
+ COPY_PHASE_STRIP = NO;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ ENABLE_BITCODE = NO;
+ ENABLE_NS_ASSERTIONS = NO;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu11;
+ 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 = 9.3;
+ MTL_ENABLE_DEBUG_INFO = NO;
+ SDKROOT = iphoneos;
+ VALIDATE_PRODUCT = YES;
+ };
+ name = Release;
+ };
+ 41B7A2D5208F900200EBA53E /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ CODE_SIGN_IDENTITY = "iPhone Developer";
+ CODE_SIGN_STYLE = Automatic;
+ DEVELOPMENT_TEAM = "";
+ FRAMEWORK_SEARCH_PATHS = (
+ "$(inherited)",
+ "$(PROJECT_DIR)",
+ );
+ INFOPLIST_FILE = NearbyConnectionsExample/Info.plist;
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "@executable_path/Frameworks",
+ );
+ PRODUCT_BUNDLE_IDENTIFIER = com.google.NearbyConnectionsExample;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ PROVISIONING_PROFILE = "";
+ PROVISIONING_PROFILE_SPECIFIER = "";
+ TARGETED_DEVICE_FAMILY = "1,2";
+ };
+ name = Debug;
+ };
+ 41B7A2D6208F900200EBA53E /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ CODE_SIGN_IDENTITY = "iPhone Developer";
+ CODE_SIGN_STYLE = Automatic;
+ DEVELOPMENT_TEAM = "";
+ FRAMEWORK_SEARCH_PATHS = (
+ "$(inherited)",
+ "$(PROJECT_DIR)",
+ );
+ INFOPLIST_FILE = NearbyConnectionsExample/Info.plist;
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "@executable_path/Frameworks",
+ );
+ PRODUCT_BUNDLE_IDENTIFIER = com.google.NearbyConnectionsExample;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ PROVISIONING_PROFILE_SPECIFIER = "";
+ TARGETED_DEVICE_FAMILY = "1,2";
+ };
+ name = Release;
+ };
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+ 41B7A2B9208F900000EBA53E /* Build configuration list for PBXProject "NearbyConnectionsExample" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 41B7A2D2208F900200EBA53E /* Debug */,
+ 41B7A2D3208F900200EBA53E /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ 41B7A2D4208F900200EBA53E /* Build configuration list for PBXNativeTarget "NearbyConnectionsExample" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 41B7A2D5208F900200EBA53E /* Debug */,
+ 41B7A2D6208F900200EBA53E /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+/* End XCConfigurationList section */
+ };
+ rootObject = 41B7A2B6208F900000EBA53E /* Project object */;
+}
diff --git a/cpp/platform/impl/ios/Example/NearbyConnectionsExample/NearbyConnectionsExample/AppDelegate.h b/cpp/platform/impl/ios/Example/NearbyConnectionsExample/NearbyConnectionsExample/AppDelegate.h
new file mode 100644
index 0000000..c1b1202
--- /dev/null
+++ b/cpp/platform/impl/ios/Example/NearbyConnectionsExample/NearbyConnectionsExample/AppDelegate.h
@@ -0,0 +1,34 @@
+//
+// Copyright (c) 2021 Google Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// AppDelegate.h
+// NearbyConnectionsExample
+//
+
+#import <UIKit/UIKit.h>
+
+/**
+ * A delegate for NSApplication to handle notifications about app launch and
+ * shutdown. Owned by the application object.
+ */
+@interface AppDelegate : UIResponder <UIApplicationDelegate>
+
+/**
+ * Main screen window displayed to the user which contains any active view
+ * hierarchy.
+ */
+@property(nonatomic) UIWindow *window;
+
+@end
diff --git a/cpp/platform/impl/ios/Example/NearbyConnectionsExample/NearbyConnectionsExample/AppDelegate.m b/cpp/platform/impl/ios/Example/NearbyConnectionsExample/NearbyConnectionsExample/AppDelegate.m
new file mode 100644
index 0000000..6902250
--- /dev/null
+++ b/cpp/platform/impl/ios/Example/NearbyConnectionsExample/NearbyConnectionsExample/AppDelegate.m
@@ -0,0 +1,23 @@
+//
+// Copyright (c) 2021 Google Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// AppDelegate.m
+// NearbyConnectionsExample
+//
+
+#import "AppDelegate.h"
+
+@implementation AppDelegate
+@end
diff --git a/cpp/platform/impl/ios/Example/NearbyConnectionsExample/NearbyConnectionsExample/Assets.xcassets/AppIcon.appiconset/Contents.json b/cpp/platform/impl/ios/Example/NearbyConnectionsExample/NearbyConnectionsExample/Assets.xcassets/AppIcon.appiconset/Contents.json
new file mode 100644
index 0000000..d8db8d6
--- /dev/null
+++ b/cpp/platform/impl/ios/Example/NearbyConnectionsExample/NearbyConnectionsExample/Assets.xcassets/AppIcon.appiconset/Contents.json
@@ -0,0 +1,98 @@
+{
+ "images" : [
+ {
+ "idiom" : "iphone",
+ "size" : "20x20",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "iphone",
+ "size" : "20x20",
+ "scale" : "3x"
+ },
+ {
+ "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" : "20x20",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "20x20",
+ "scale" : "2x"
+ },
+ {
+ "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"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "83.5x83.5",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "ios-marketing",
+ "size" : "1024x1024",
+ "scale" : "1x"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
\ No newline at end of file
diff --git a/cpp/platform/impl/ios/Example/NearbyConnectionsExample/NearbyConnectionsExample/Assets.xcassets/Contents.json b/cpp/platform/impl/ios/Example/NearbyConnectionsExample/NearbyConnectionsExample/Assets.xcassets/Contents.json
new file mode 100644
index 0000000..da4a164
--- /dev/null
+++ b/cpp/platform/impl/ios/Example/NearbyConnectionsExample/NearbyConnectionsExample/Assets.xcassets/Contents.json
@@ -0,0 +1,6 @@
+{
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
\ No newline at end of file
diff --git a/cpp/platform/impl/ios/Example/NearbyConnectionsExample/NearbyConnectionsExample/Base.lproj/LaunchScreen.storyboard b/cpp/platform/impl/ios/Example/NearbyConnectionsExample/NearbyConnectionsExample/Base.lproj/LaunchScreen.storyboard
new file mode 100644
index 0000000..f83f6fd
--- /dev/null
+++ b/cpp/platform/impl/ios/Example/NearbyConnectionsExample/NearbyConnectionsExample/Base.lproj/LaunchScreen.storyboard
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="13122.16" systemVersion="17A277" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
+ <dependencies>
+ <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13104.12"/>
+ <capability name="Safe area layout guides" minToolsVersion="9.0"/>
+ <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
+ </dependencies>
+ <scenes>
+ <!--View Controller-->
+ <scene sceneID="EHf-IW-A2E">
+ <objects>
+ <viewController id="01J-lp-oVM" sceneMemberID="viewController">
+ <view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
+ <rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
+ <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+ <color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+ <viewLayoutGuide key="safeArea" id="6Tk-OE-BBY"/>
+ </view>
+ </viewController>
+ <placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
+ </objects>
+ <point key="canvasLocation" x="53" y="375"/>
+ </scene>
+ </scenes>
+</document>
diff --git a/cpp/platform/impl/ios/Example/NearbyConnectionsExample/NearbyConnectionsExample/Base.lproj/Main.storyboard b/cpp/platform/impl/ios/Example/NearbyConnectionsExample/NearbyConnectionsExample/Base.lproj/Main.storyboard
new file mode 100644
index 0000000..b39e95c
--- /dev/null
+++ b/cpp/platform/impl/ios/Example/NearbyConnectionsExample/NearbyConnectionsExample/Base.lproj/Main.storyboard
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="14113" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="fos-Uz-R9B">
+ <device id="retina4_7" orientation="portrait">
+ <adaptation id="fullscreen"/>
+ </device>
+ <dependencies>
+ <deployment identifier="iOS"/>
+ <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14088"/>
+ <capability name="Safe area layout guides" minToolsVersion="9.0"/>
+ <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
+ </dependencies>
+ <scenes>
+ <!--View Controller-->
+ <scene sceneID="BVh-fg-s4x">
+ <objects>
+ <viewController id="Tuj-3T-cB2" customClass="ViewController" sceneMemberID="viewController">
+ <view key="view" contentMode="scaleToFill" id="9NC-2J-1xS">
+ <rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
+ <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+ <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+ <viewLayoutGuide key="safeArea" id="wwJ-gb-kZn"/>
+ </view>
+ <navigationItem key="navigationItem" id="ega-4i-ebx"/>
+ </viewController>
+ <placeholder placeholderIdentifier="IBFirstResponder" id="xJQ-q8-wWg" userLabel="First Responder" sceneMemberID="firstResponder"/>
+ </objects>
+ <point key="canvasLocation" x="433" y="-133"/>
+ </scene>
+ <!--Navigation Controller-->
+ <scene sceneID="Jcj-tp-czJ">
+ <objects>
+ <navigationController id="fos-Uz-R9B" sceneMemberID="viewController">
+ <navigationBar key="navigationBar" contentMode="scaleToFill" insetsLayoutMarginsFromSafeArea="NO" id="x6x-US-muI">
+ <rect key="frame" x="0.0" y="20" width="375" height="44"/>
+ <autoresizingMask key="autoresizingMask"/>
+ </navigationBar>
+ <connections>
+ <segue destination="Tuj-3T-cB2" kind="relationship" relationship="rootViewController" id="Xa2-HD-mUn"/>
+ </connections>
+ </navigationController>
+ <placeholder placeholderIdentifier="IBFirstResponder" id="99I-fh-ObP" userLabel="First Responder" sceneMemberID="firstResponder"/>
+ </objects>
+ <point key="canvasLocation" x="-455" y="-132"/>
+ </scene>
+ </scenes>
+</document>
diff --git a/cpp/platform/impl/ios/Example/NearbyConnectionsExample/NearbyConnectionsExample/Info.plist b/cpp/platform/impl/ios/Example/NearbyConnectionsExample/NearbyConnectionsExample/Info.plist
new file mode 100644
index 0000000..44aa9d7
--- /dev/null
+++ b/cpp/platform/impl/ios/Example/NearbyConnectionsExample/NearbyConnectionsExample/Info.plist
@@ -0,0 +1,51 @@
+<?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>$(DEVELOPMENT_LANGUAGE)</string>
+ <key>CFBundleExecutable</key>
+ <string>$(EXECUTABLE_NAME)</string>
+ <key>CFBundleIdentifier</key>
+ <string>$(PRODUCT_BUNDLE_IDENTIFIER)</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>CFBundleVersion</key>
+ <string>1</string>
+ <key>LSRequiresIPhoneOS</key>
+ <true/>
+ <key>UILaunchStoryboardName</key>
+ <string>LaunchScreen</string>
+ <key>UIMainStoryboardFile</key>
+ <string>Main</string>
+ <key>UIRequiredDeviceCapabilities</key>
+ <array>
+ <string>armv7</string>
+ </array>
+ <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>
+ <key>NSLocalNetworkUsageDescription</key>
+ <string>Exchange data with nearby devices running the NearbyConnectionsExmaple app.</string>
+ <key>NSBonjourServices</key>
+ <array>
+ <string>_54167B379724._tcp</string>
+ </array>
+</dict>
+</plist>
diff --git a/cpp/platform/impl/ios/Example/NearbyConnectionsExample/NearbyConnectionsExample/ViewController.h b/cpp/platform/impl/ios/Example/NearbyConnectionsExample/NearbyConnectionsExample/ViewController.h
new file mode 100644
index 0000000..5996099
--- /dev/null
+++ b/cpp/platform/impl/ios/Example/NearbyConnectionsExample/NearbyConnectionsExample/ViewController.h
@@ -0,0 +1,24 @@
+//
+// Copyright (c) 2021 Google Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// ViewController.h
+// NearbyConnectionsExample
+//
+
+#import <UIKit/UIKit.h>
+
+/** View controller for demo by loading NearbyConnections lib for advertiser and discoverer. */
+@interface ViewController : UIViewController
+@end
diff --git a/cpp/platform/impl/ios/Example/NearbyConnectionsExample/NearbyConnectionsExample/ViewController.m b/cpp/platform/impl/ios/Example/NearbyConnectionsExample/NearbyConnectionsExample/ViewController.m
new file mode 100644
index 0000000..f6c8b82
--- /dev/null
+++ b/cpp/platform/impl/ios/Example/NearbyConnectionsExample/NearbyConnectionsExample/ViewController.m
@@ -0,0 +1,291 @@
+//
+// Copyright (c) 2021 Google Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// ViewController.m
+// NearbyConnectionsExample
+//
+
+#import "ViewController.h"
+
+#import <NearbyConnections/NearbyConnections.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+static NSString *kServiceId = @"com.google.NearbyConnectionsExample";
+static NSString *kCellIdentifier = @"endpointCell";
+
+// Simplified version of dispatch_after.
+void delay(NSTimeInterval delay, dispatch_block_t block) {
+ dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delay * NSEC_PER_SEC)),
+ dispatch_get_main_queue(), block);
+}
+
+// This class contains info about a discovered endpoint.
+@interface EndpointInfo : NSObject
+@property(nonatomic, readonly) id<GNCDiscoveredEndpointInfo> discInfo;
+@property(nonatomic, nullable) id<GNCConnection> connection;
+@end
+
+@implementation EndpointInfo
+- (instancetype)initWithDiscoveredInfo:(id<GNCDiscoveredEndpointInfo>)discInfo {
+ self = [super init];
+ if (self) {
+ _discInfo = discInfo;
+ }
+ return self;
+}
+@end
+
+@interface ViewController () <UITableViewDataSource, UITableViewDelegate>
+@property(nonatomic) GNCAdvertiser *advertiser;
+@property(nonatomic) GNCDiscoverer *discoverer;
+@property(nonatomic) NSMutableDictionary<GNCEndpointId, EndpointInfo *> *endpoints;
+@property(nonatomic, readonly) NSData *ping;
+@property(nonatomic, readonly) NSData *pong;
+@property(nonatomic) UITableView *tableView;
+@property(nonatomic) UITextView *statusView;
+@property(nonatomic) NSMutableDictionary<GNCEndpointId, id<GNCConnection> > *incomingConnections;
+@end
+
+@implementation ViewController
+
+- (void)viewDidLoad {
+ [super viewDidLoad];
+ [self makeViews];
+
+ // Enable "info" log messages in the release build.
+ [[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"GTMVerboseLogging"];
+
+ self.title = [[UIDevice currentDevice] name];
+ NSData *endpointInfo = [self.title dataUsingEncoding:NSUTF8StringEncoding];
+ _endpoints = [NSMutableDictionary dictionary];
+ _ping = [@"ping" dataUsingEncoding:NSUTF8StringEncoding];
+ _pong = [@"pong" dataUsingEncoding:NSUTF8StringEncoding];
+ _incomingConnections = [NSMutableDictionary dictionary];
+
+ // The advertiser.
+ _advertiser = [GNCAdvertiser
+ advertiserWithEndpointInfo:endpointInfo
+ serviceId:kServiceId
+ strategy:GNCStrategyCluster
+ connectionInitiationHandler:^(GNCEndpointId endpointId,
+ id<GNCAdvertiserConnectionInfo> advConnInfo,
+ GNCConnectionResponseHandler responseHandler) {
+ // Show a status that a discoverer has requested a connection.
+ [self logStatus:@"Accepting connection request" final:NO];
+
+ // Accept the connection request.
+ responseHandler(GNCConnectionResponseAccept);
+ return [GNCConnectionResultHandlers
+ successHandler:^(id<GNCConnection> connection) {
+ // Save the connection until the ping-pong sequence is done.
+ self.incomingConnections[endpointId] = connection;
+ __block BOOL receivedPong = NO;
+
+ // Send a ping, expecting the remote endpoint to send a pong.
+ [self logStatus:@"Connection established; sending ping" final:NO];
+ [connection sendBytesPayload:[GNCBytesPayload payloadWithBytes:self.ping]
+ completion:^(GNCPayloadResult result) {
+ if (result == GNCPayloadResultSuccess) {
+ [self logStatus:@"Sent ping; waiting for pong" final:NO];
+
+ // Show an error if the pong isn't received in the expected
+ // timeframe.
+ delay(3.0, ^{
+ if (receivedPong) {
+ [self logStatus:@"Error: Didn't receive pong" final:YES];
+ [self.incomingConnections
+ removeObjectForKey:endpointId]; // close the connection
+ }
+ });
+ } else {
+ [self logStatus:@"Error: Failed to send ping" final:YES];
+ }
+ }];
+
+ // Return handlers for incoming payloads.
+ return [GNCConnectionHandlers handlersWithBuilder:^(GNCConnectionHandlers *handlers) {
+ handlers.bytesPayloadHandler = ^(GNCBytesPayload *payload) {
+ receivedPong = NO;
+ [self.incomingConnections removeObjectForKey:endpointId]; // close the connection
+
+ // Show a status of whether the pong was received.
+ [self logStatus:[payload.bytes isEqual:self.pong] ? @"Received pong"
+ : @"Error: Payload is not pong"
+ final:YES];
+ };
+ }];
+ }
+ failureHandler:^(GNCConnectionFailure result) {
+ [self
+ logStatus:(result == GNCConnectionFailureRejected) ? @"Error: Connection rejected"
+ : @"Error: Connection failed"
+ final:YES];
+ }];
+ }];
+
+ // The discoverer.
+ __weak typeof(self) weakSelf = self;
+ _discoverer = [GNCDiscoverer
+ discovererWithServiceId:kServiceId
+ strategy:GNCStrategyCluster
+ endpointFoundHandler:^(GNCEndpointId endpointId,
+ id<GNCDiscoveredEndpointInfo> endpointInfo) {
+ typeof(self) self = weakSelf;
+
+ // An endpoint was discovered; add it to the endpoint list and UI.
+ self.endpoints[endpointId] = [[EndpointInfo alloc] initWithDiscoveredInfo:endpointInfo];
+ [self.tableView reloadData];
+
+ // Return the lost handler for this endpoint.
+ return ^{
+ typeof(self) self = weakSelf; // shadow
+
+ // Endpoint disappeared; remove it from the endpoint list and UI.
+ [self.endpoints removeObjectForKey:endpointId];
+ [self.tableView reloadData];
+ };
+ }];
+}
+
+#pragma mark - UITableViewDelegate
+
+- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
+ // The user tapped on a cell; request a connection with it.
+ EndpointInfo *info = _endpoints[_endpoints.allKeys[indexPath.row]];
+ if (!info) return;
+
+ void (^deselectRow)(void) = ^{
+ [tableView deselectRowAtIndexPath:indexPath animated:YES];
+ };
+
+ [self logStatus:@"Requesting connection" final:NO];
+ info.discInfo.requestConnection(
+ self.title,
+ ^(id<GNCDiscovererConnectionInfo> discConnInfo,
+ GNCConnectionResponseHandler responseHandler) {
+ // Accept the auth token.
+ [self logStatus:@"Accepting auth token" final:NO];
+ responseHandler(GNCConnectionResponseAccept);
+ return ^(id<GNCConnection> connection) {
+ // Save the connection until the ping-pong sequence is done.
+ info.connection = connection;
+ __block BOOL receivedPing = NO;
+
+ [self logStatus:@"Connection established; waiting for ping" final:NO];
+
+ // Show an error if the ping isn't received in the expected timeframe.
+ delay(3.0, ^{
+ if (!receivedPing) {
+ deselectRow();
+ [self logStatus:@"Error: Didn't receive ping" final:YES];
+ info.connection = nil; // close the connection
+ }
+ });
+
+ // Return handlers for incoming payloads.
+ __weak id<GNCConnection> weakConnection = connection; // avoid a retain cycle
+ return [GNCConnectionHandlers handlersWithBuilder:^(GNCConnectionHandlers *handlers) {
+ handlers.bytesPayloadHandler = ^(GNCBytesPayload *payload) {
+ receivedPing = YES;
+
+ // If a ping was received, send a pong back to the advertiser.
+ if ([payload.bytes isEqual:self.ping]) {
+ [self logStatus:@"Received ping; sending pong" final:NO];
+ [weakConnection sendBytesPayload:[GNCBytesPayload payloadWithBytes:self.pong]
+ completion:^(GNCPayloadResult result) {
+ deselectRow();
+ [self logStatus:(result == GNCPayloadResultSuccess)
+ ? @"Sent pong"
+ : @"Error: Failed to send pong"
+ final:YES];
+
+ // Pong was sent, so close the connection.
+ info.connection = nil;
+ }];
+ } else {
+ deselectRow();
+ [self logStatus:@"Error: Payload is not ping" final:YES];
+ }
+ };
+ }];
+ };
+ },
+ ^(GNCConnectionFailure result) {
+ // Connection failed.
+ deselectRow();
+ [self logStatus:(result == GNCConnectionFailureRejected) ? @"Connection rejected"
+ : @"Connection failed"
+ final:YES];
+ });
+}
+
+- (UITableViewCell *)tableView:(UITableView *)tableView
+ cellForRowAtIndexPath:(NSIndexPath *)indexPath {
+ UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellIdentifier
+ forIndexPath:indexPath];
+ cell.textLabel.text = _endpoints[_endpoints.allKeys[indexPath.row]].discInfo.name;
+ return cell;
+}
+
+#pragma mark - UITableViewDataSource
+
+- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
+ return [_endpoints.allKeys count];
+}
+
+#pragma mark - Private
+
+- (void)makeViews {
+ _tableView = [[UITableView alloc] initWithFrame:self.view.frame style:UITableViewStylePlain];
+ [_tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:kCellIdentifier];
+ _tableView.delegate = self;
+ _tableView.dataSource = self;
+ _tableView.rowHeight = 48;
+ _tableView.scrollEnabled = YES;
+ _tableView.showsVerticalScrollIndicator = YES;
+ _tableView.userInteractionEnabled = YES;
+ _tableView.bounces = YES;
+ _tableView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
+ [self.view addSubview:_tableView];
+
+ // Make the status view.
+ UITextView * (^newTextView)(CGRect) = ^(CGRect frame) {
+ UITextView *textView = [[UITextView alloc] initWithFrame:frame];
+ textView.autoresizingMask =
+ UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleTopMargin;
+ textView.layer.borderColor = [UIColor blackColor].CGColor;
+ textView.layer.borderWidth = 1;
+ textView.editable = NO;
+ textView.textContainerInset = UIEdgeInsetsZero;
+ return textView;
+ };
+ CGRect selfFrame = self.view.frame;
+ static const int kStatusHeight = 144;
+ CGRect statusFrame = (CGRect){{selfFrame.origin.x + 4, selfFrame.size.height - kStatusHeight},
+ {selfFrame.size.width - 8, kStatusHeight - 4}};
+ _statusView = newTextView(statusFrame);
+ [self.view addSubview:_statusView];
+}
+
+- (void)logStatus:(NSString *)status final:(BOOL)final {
+ _statusView.text = [NSString stringWithFormat:@"%@\n%@%@", _statusView.text, status,
+ final ? @"\n–––––––––––––––––––––––––" : @""];
+ [_statusView scrollRangeToVisible:NSMakeRange(_statusView.text.length - 1, 1)];
+}
+
+@end
+
+NS_ASSUME_NONNULL_END
diff --git a/cpp/platform/impl/ios/Example/NearbyConnectionsExample/NearbyConnectionsExample/main.m b/cpp/platform/impl/ios/Example/NearbyConnectionsExample/NearbyConnectionsExample/main.m
new file mode 100644
index 0000000..3111188
--- /dev/null
+++ b/cpp/platform/impl/ios/Example/NearbyConnectionsExample/NearbyConnectionsExample/main.m
@@ -0,0 +1,27 @@
+//
+// Copyright (c) 2021 Google Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// main.m
+// NearbyConnectionsExample
+//
+
+#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/cpp/platform/impl/ios/Example/NearbyConnectionsExample/README.md b/cpp/platform/impl/ios/Example/NearbyConnectionsExample/README.md
new file mode 100755
index 0000000..cb0d038
--- /dev/null
+++ b/cpp/platform/impl/ios/Example/NearbyConnectionsExample/README.md
@@ -0,0 +1,198 @@
+# Nearby Connections Sample App for iOS
+
+This is a sample app for third party developers using the Nearby Connections
+library. On startup, it advertises and discovers. Discovered advertisers are
+added to the list in the UI. When the user taps on an advertiser in the list,
+the discoverer requests a connection with it. When the connection is
+established, the advertiser sends a "ping" payload to the discoverer, which
+sends "pong" payload back to the advertiser. The connection is then closed.
+
+## Setup
+
+1.Get the NearbyConnections_framework.zip from https://github.com/google/nearby/tree/master/releases/new/, unzip it,
+and put your unzipped folder under your project folder. The directory structure
+looks like:
+
+```
+/NearbyConnectionsExample
+ /NearbyConnectionsExample
+ NearbyConnectionsExample.xcodeproj
+ README.md
+ /NearbyConnections.framework
+```
+
+2.Import NearbyConnections.framework
+
+- In Xcode, click the NearbyConnectionsExample in the left pane. And click the one in TARGETS-NearbyConnectionsExample at the left of right pane and the Build Phases at the right.
+- See the **Link Binary With Libraries**, and press **+** to import the file - **libc++.tbd**.
+- In Add **Other…**, import the NearbyConnections.framework folder which was unzipped.
+
+
+
+3.Update info.plist:
+
+- add **NSLocalNetworkUsageDescription** key with a description of your usage of Nearby Connections.
+- add **NSBonjourServices** key.
+ for NSBonjourServices key, add the bonjour type name: `_54167B379724._tcp`
+
+> **54167B379724** is the 6 byte hash of service id **com.google.NearbyConnectionsExample**
+
+```
+// NearbyConnectionsExample/info.plist
+...
+<key>NSLocalNetworkUsageDescription</key>
+<string>Exchange data with nearby devices running the NearbyConnectionsExmaple app.</string>
+<key>NSBonjourServices</key>
+<array>
+ <string>_54167B379724._tcp</string>
+</array>
+...
+```
+
+
+4.Add service id and import `<NearbyConnections/NearbyConnections.h>` in your main view controller.
+
+```
+// NearbyConnectionsExample/ViewController.m
+
+static NSString *kServiceId = @"com.google.NearbyConnectionsExample";
+
+#import <NearbyConnections/NearbyConnections.h>
+```
+
+## Code Snippets
+Note: All of the callbacks in this library use blocks rather than delegates. Be careful to avoid retain cycles in your block implementations. See the [Apple documentation](https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmPractical.html#//apple_ref/doc/uid/TP40004447-SW1) describing how to avoid retain cycles.
+
+Here is the skeleton code for an advertiser:
+
+```objc
+_advertiser = [GNCAdvertiser
+ advertiserWithEndpointInfo:endpointInfo
+ serviceId:myServiceId
+ strategy:GNCStrategyCluster
+ connectionInitiationHandler:^(GNCEndpointId endpointId,
+ id<GNCAdvertiserConnectionInfo> connectionInfo,
+ GNCConnectionResponseHandler responseHandler) {
+ // Decide whether to accept or reject the connection. The following code would normally
+ // exist in the callback for an alert, for instance.
+ if (/* user rejected */) {
+ responseHandler(GNCConnectionResponseReject); // the user rejected the invitation
+ } else {
+ responseHandler(GNCConnectionResponseAccept); // the user accepted the invitation
+
+ // Return connection result handlers, one of which is called depending on
+ // whether a successful connection was made.
+ return [GNCConnectionResultHandlers successHandler:^(id<GNCConnection> connection) {
+ // A successful connection was made. Save the connection somewhere, which can
+ // be used to send payloads to the remote endpoint.
+
+ // Return the incoming payload and disconnect handlers.
+ return [GNCConnectionHandlers handlersWithBuilder:^(GNCConnectionHandlers *handlers) {
+ // Optionally set the Bytes payload handler.
+ handlers.bytesPayloadHandler = ^(GNCBytesPayload *payload) {
+ // Process the payload received from the remote endpoint.
+ };
+
+ // Optionally set the Stream payload handler.
+ handlers.streamPayloadHandler = ^(GNCStreamPayload *payload, NSProgress *progress) {
+ // Receipt of a Stream payload has started. Input can be read from the payload’s
+ // NSInputStream, and progress/cancellation is handled via the NSProgress object.
+ return ^(GNCPayloadResult result) {
+ if (result == GNCPayloadResultSuccess) {
+ // The payload has been successfully received.
+ }
+ };
+ };
+
+ // Optionally set the disconnected handler.
+ handlers.disconnectedHandler = ^(GNCDisconnectedReason reason) {
+ // The connection was severed by either endpoint or lost.
+ };
+ }
+ failureHandler:^(GNCConnectionFailure result) {
+ // Failed to make the connection.
+ }]);
+ }
+}];
+```
+
+Here is the skeleton code for a discoverer:
+
+```objc
+_discoverer =
+ [GNCDiscoverer discovererWithServiceId:myServiceId
+ strategy:GNCStrategyCluster
+ endpointFoundHandler:^(GNCEndpointId endpointId,
+ id<GNCDiscoveredEndpointInfo> discEndpointInfo) {
+ // An endpoint was found. Typically you would add it to a list of nearby endpoints
+ // displayed in a UITableView, for instance.
+
+ // The following code shows how to request a connection with the endpoint. This code
+ // would normally exist in the -didSelectRowAtIndexPath: of UITableViewDelegate.
+ if (/* user wants to request a connection */) {
+ requestHandler(myName,
+ // This block is called once an authentication string is generated between the endpoints.
+ ^(id<GNCDiscovererConnectionInfo> discConnInfo, GNCConnectionResponseHandler responseHandler) {
+ // Ask the user to confirm the authentication string.
+ UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"Accept auth?" ...];
+ [alert addAction:[UIAlertAction actionWithTitle:@"OK"
+ style:UIAlertActionStyleDefault
+ handler:^(UIAlertAction *action) {
+ responseHandler(GNCConnectionResponseAccept);
+ }]];
+ [alert addAction:[UIAlertAction actionWithTitle:@"Cancel"
+ style:UIAlertActionStyleDefault
+ handler:^(UIAlertAction *action) {
+ responseHandler(GNCConnectionResponseReject);
+ }]];
+ [self presentViewController:alert animated:YES completion:^{}];
+
+ // Return a block that's called if the connection was successful.
+ return ^(id<GNCConnection> connection) {
+ // A successful connection was made. Save the connection somewhere, which can
+ // be used to send payloads to the remote endpoint.
+
+ // Return incoming data handlers as in the advertiser example above.
+ return [GNCConnectionHandlers handlersWithBuilder:^(GNCConnectionHandlers *handlers) {
+ // Set up payload and disconnect handlers here as in the advertiser example above.
+ }];
+ };
+ },
+ // This block is called if the connection failed for any reason.
+ ^(GNCConnectionFailure result) {
+ // Typically an alert would be shown here explaining why the connection failed.
+ });
+ }
+
+ // Return the endpoint-lost handler, which is called when the endpoint goes out of range
+ // or stops advertising.
+ return ^{
+ // The endpoint disappeared.
+ };
+}];
+```
+
+Here is an example of how to send a Bytes payload. The returned NSProgress object can be passed to UIProgressView to display a progress bar.
+
+```objc
+NSProgress *progress = [connection
+ sendBytesPayload:[GNCBytesPayload payloadWithBytes:someData]
+ completion:^(GNCPayloadResult result) {
+ // Check status to see if it was successfully sent.
+ }];
+```
+
+## Build and run
+
+
+
+If you meet the following error in the debug panel of Xcode, you likely need to set up the keys listed in step 3 **Update info.plist**, as well as the service type.
+
+```
+1970-01-01 00:00:00.000 NearbyConnectionsExample[1383/0x16d87b000] [lvl=1] -[GNCMBonjourService netService:didNotPublish:] Error publishing: service: <NSNetService 0x283a18920> local _307BEAB11028._tcp. IjFQWEUwe-oAAA 51898, errorDic: {
+ NSNetServicesErrorCode = "-72008";
+ NSNetServicesErrorDomain = 10;
+}
+```
+---
+NOTE: The iOS simulator is unstable when advertising. We recommend using an real iOS device.
diff --git a/cpp/platform/impl/ios/Example/NearbyConnectionsExample/XcodeSetup.png b/cpp/platform/impl/ios/Example/NearbyConnectionsExample/XcodeSetup.png
new file mode 100644
index 0000000..4f353ff
--- /dev/null
+++ b/cpp/platform/impl/ios/Example/NearbyConnectionsExample/XcodeSetup.png
Binary files differ