├── Samples ├── TicTacToe │ ├── Pods │ │ ├── Pods-InterAppCommunication.xcconfig │ │ ├── Headers │ │ │ └── InterAppCommunication │ │ │ │ ├── IACClient.h │ │ │ │ ├── IACManager.h │ │ │ │ ├── IACRequest.h │ │ │ │ ├── IACDelegate.h │ │ │ │ └── NSString+IACExtensions.h │ │ ├── BuildHeaders │ │ │ └── InterAppCommunication │ │ │ │ ├── IACClient.h │ │ │ │ ├── IACManager.h │ │ │ │ ├── IACRequest.h │ │ │ │ ├── IACDelegate.h │ │ │ │ └── NSString+IACExtensions.h │ │ ├── Pods-InterAppCommunication-prefix.pch │ │ ├── Pods-dummy.m │ │ ├── Pods-InterAppCommunication-dummy.m │ │ ├── Manifest.lock │ │ ├── Pods.xcconfig │ │ ├── Pods-InterAppCommunication-Private.xcconfig │ │ ├── InterAppCommunication │ │ │ ├── InterAppCommunication │ │ │ │ ├── NSString+IACExtensions.h │ │ │ │ ├── IACRequest.h │ │ │ │ ├── IACRequest.m │ │ │ │ ├── IACDelegate.h │ │ │ │ ├── IACManager.h │ │ │ │ ├── IACClient.h │ │ │ │ ├── IACClient.m │ │ │ │ ├── NSString+IACExtensions.m │ │ │ │ └── IACManager.m │ │ │ ├── LICENSE.markdown │ │ │ └── README.markdown │ │ ├── Pods-environment.h │ │ ├── Pods-acknowledgements.markdown │ │ ├── Pods-acknowledgements.plist │ │ └── Pods-resources.sh │ ├── Podfile │ ├── TicTacToe │ │ ├── en.lproj │ │ │ └── InfoPlist.strings │ │ ├── Images.xcassets │ │ │ ├── O.imageset │ │ │ │ ├── O@2x.png │ │ │ │ └── Contents.json │ │ │ ├── X.imageset │ │ │ │ ├── X@2x.png │ │ │ │ └── Contents.json │ │ │ ├── board.imageset │ │ │ │ ├── board@2x.png │ │ │ │ └── Contents.json │ │ │ ├── intro.imageset │ │ │ │ ├── intro@2x.png │ │ │ │ └── Contents.json │ │ │ ├── AppIconO.appiconset │ │ │ │ ├── Icon-60@2x.png │ │ │ │ └── Contents.json │ │ │ ├── AppIconX.appiconset │ │ │ │ ├── Icon-60@2x.png │ │ │ │ └── Contents.json │ │ │ ├── apocalypse1.imageset │ │ │ │ ├── apocalypse1@2x.png │ │ │ │ └── Contents.json │ │ │ ├── apocalypse2.imageset │ │ │ │ ├── apocalypse2@2x.png │ │ │ │ └── Contents.json │ │ │ ├── apocalypse3.imageset │ │ │ │ ├── apocalypse3@2x.png │ │ │ │ └── Contents.json │ │ │ ├── apocalypse4.imageset │ │ │ │ ├── apocalypse4@2x.png │ │ │ │ └── Contents.json │ │ │ └── LaunchImage.launchimage │ │ │ │ └── Contents.json │ │ ├── TTTIntroViewController.h │ │ ├── TTTAppDelegate.h │ │ ├── TicTacToe-Prefix.pch │ │ ├── main.m │ │ ├── TTTBoardViewController.h │ │ ├── TTTIACClient.h │ │ ├── DMGridModel.h │ │ ├── TTTIACClient.m │ │ ├── TicTacToe-Info.plist │ │ ├── TTTIntroViewController.m │ │ ├── TTTAppDelegate.m │ │ ├── DMGridModel.m │ │ └── TTTBoardViewController.m │ ├── TicTacToeTests │ │ ├── en.lproj │ │ │ └── InfoPlist.strings │ │ ├── TicTacToeTests-Info.plist │ │ └── TicTacToeTests.m │ ├── Podfile.lock │ ├── TicTacToe copy-Info.plist │ └── tictactoe.js ├── API Example │ ├── SoundsPlayer │ │ └── SoundsPlayer │ │ │ ├── en.lproj │ │ │ ├── InfoPlist.strings │ │ │ └── SPViewController.xib │ │ │ ├── Icon.png │ │ │ ├── Default.png │ │ │ ├── Icon@2x.png │ │ │ ├── Default@2x.png │ │ │ ├── sounds │ │ │ ├── bell.m4a │ │ │ ├── boing.m4a │ │ │ ├── applause.m4a │ │ │ └── car key.m4a │ │ │ ├── Default-568h@2x.png │ │ │ ├── SoundsPlayer-Prefix.pch │ │ │ ├── main.m │ │ │ ├── SPAppDelegate.h │ │ │ ├── SPViewController.h │ │ │ ├── SoundsPlayer-Info.plist │ │ │ ├── SPViewController.m │ │ │ └── SPAppDelegate.m │ └── SoundPlayerRemote │ │ └── SoundPlayerRemote │ │ ├── en.lproj │ │ ├── InfoPlist.strings │ │ └── SRViewController.xib │ │ ├── Icon.png │ │ ├── Default.png │ │ ├── Icon@2x.png │ │ ├── Default@2x.png │ │ ├── Default-568h@2x.png │ │ ├── SoundPlayerRemote-Prefix.pch │ │ ├── main.m │ │ ├── SoundPlayerIACClient.h │ │ ├── SRAppDelegate.h │ │ ├── SRViewController.h │ │ ├── SRAppDelegate.m │ │ ├── SoundPlayerIACClient.m │ │ ├── SoundPlayerRemote-Info.plist │ │ └── SRViewController.m └── Google Chrome Integration │ └── ChromeSample │ ├── en.lproj │ ├── InfoPlist.strings │ └── CSViewController.xib │ ├── Icon.png │ ├── Default.png │ ├── Icon@2x.png │ ├── Default@2x.png │ ├── Default-568h@2x.png │ ├── ChromeSample-Prefix.pch │ ├── main.m │ ├── CSAppDelegate.h │ ├── CSViewController.h │ ├── CSAppDelegate.m │ ├── ChromeSample-Info.plist │ └── CSViewController.m ├── Icon.png ├── Icon@2x.png ├── notes.markdown ├── .gitignore ├── AppClients ├── InstapaperIACClient.h ├── FunboxIACClient.h ├── GoogleChromeIACClient.h ├── InstapaperIACClient.m ├── FunboxIACClient.m └── GoogleChromeIACClient.m ├── InterAppCommunication ├── NSString+IACExtensions.h ├── IACRequest.h ├── IACRequest.m ├── IACDelegate.h ├── IACManager.h ├── IACClient.h ├── IACClient.m ├── NSString+IACExtensions.m └── IACManager.m ├── InterAppCommunication.podspec ├── LICENSE.markdown └── README.markdown /Samples/TicTacToe/Pods/Pods-InterAppCommunication.xcconfig: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tapsandswipes/InterAppCommunication/HEAD/Icon.png -------------------------------------------------------------------------------- /Samples/TicTacToe/Podfile: -------------------------------------------------------------------------------- 1 | platform :ios, "7.0" 2 | 3 | pod "InterAppCommunication" 4 | -------------------------------------------------------------------------------- /Icon@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tapsandswipes/InterAppCommunication/HEAD/Icon@2x.png -------------------------------------------------------------------------------- /Samples/TicTacToe/TicTacToe/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /Samples/TicTacToe/TicTacToeTests/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /Samples/API Example/SoundsPlayer/SoundsPlayer/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /Samples/Google Chrome Integration/ChromeSample/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /Samples/TicTacToe/Pods/Headers/InterAppCommunication/IACClient.h: -------------------------------------------------------------------------------- 1 | ../../InterAppCommunication/InterAppCommunication/IACClient.h -------------------------------------------------------------------------------- /Samples/TicTacToe/Pods/Headers/InterAppCommunication/IACManager.h: -------------------------------------------------------------------------------- 1 | ../../InterAppCommunication/InterAppCommunication/IACManager.h -------------------------------------------------------------------------------- /Samples/TicTacToe/Pods/Headers/InterAppCommunication/IACRequest.h: -------------------------------------------------------------------------------- 1 | ../../InterAppCommunication/InterAppCommunication/IACRequest.h -------------------------------------------------------------------------------- /Samples/TicTacToe/Pods/BuildHeaders/InterAppCommunication/IACClient.h: -------------------------------------------------------------------------------- 1 | ../../InterAppCommunication/InterAppCommunication/IACClient.h -------------------------------------------------------------------------------- /Samples/TicTacToe/Pods/BuildHeaders/InterAppCommunication/IACManager.h: -------------------------------------------------------------------------------- 1 | ../../InterAppCommunication/InterAppCommunication/IACManager.h -------------------------------------------------------------------------------- /Samples/TicTacToe/Pods/BuildHeaders/InterAppCommunication/IACRequest.h: -------------------------------------------------------------------------------- 1 | ../../InterAppCommunication/InterAppCommunication/IACRequest.h -------------------------------------------------------------------------------- /Samples/TicTacToe/Pods/Headers/InterAppCommunication/IACDelegate.h: -------------------------------------------------------------------------------- 1 | ../../InterAppCommunication/InterAppCommunication/IACDelegate.h -------------------------------------------------------------------------------- /Samples/API Example/SoundPlayerRemote/SoundPlayerRemote/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /Samples/TicTacToe/Pods/BuildHeaders/InterAppCommunication/IACDelegate.h: -------------------------------------------------------------------------------- 1 | ../../InterAppCommunication/InterAppCommunication/IACDelegate.h -------------------------------------------------------------------------------- /Samples/TicTacToe/Pods/Headers/InterAppCommunication/NSString+IACExtensions.h: -------------------------------------------------------------------------------- 1 | ../../InterAppCommunication/InterAppCommunication/NSString+IACExtensions.h -------------------------------------------------------------------------------- /Samples/TicTacToe/Pods/BuildHeaders/InterAppCommunication/NSString+IACExtensions.h: -------------------------------------------------------------------------------- 1 | ../../InterAppCommunication/InterAppCommunication/NSString+IACExtensions.h -------------------------------------------------------------------------------- /Samples/TicTacToe/Pods/Pods-InterAppCommunication-prefix.pch: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #endif 4 | 5 | #import "Pods-environment.h" 6 | -------------------------------------------------------------------------------- /Samples/TicTacToe/Pods/Pods-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_Pods : NSObject 3 | @end 4 | @implementation PodsDummy_Pods 5 | @end 6 | -------------------------------------------------------------------------------- /Samples/API Example/SoundsPlayer/SoundsPlayer/Icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tapsandswipes/InterAppCommunication/HEAD/Samples/API Example/SoundsPlayer/SoundsPlayer/Icon.png -------------------------------------------------------------------------------- /Samples/Google Chrome Integration/ChromeSample/Icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tapsandswipes/InterAppCommunication/HEAD/Samples/Google Chrome Integration/ChromeSample/Icon.png -------------------------------------------------------------------------------- /Samples/API Example/SoundsPlayer/SoundsPlayer/Default.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tapsandswipes/InterAppCommunication/HEAD/Samples/API Example/SoundsPlayer/SoundsPlayer/Default.png -------------------------------------------------------------------------------- /Samples/API Example/SoundsPlayer/SoundsPlayer/Icon@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tapsandswipes/InterAppCommunication/HEAD/Samples/API Example/SoundsPlayer/SoundsPlayer/Icon@2x.png -------------------------------------------------------------------------------- /Samples/Google Chrome Integration/ChromeSample/Default.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tapsandswipes/InterAppCommunication/HEAD/Samples/Google Chrome Integration/ChromeSample/Default.png -------------------------------------------------------------------------------- /Samples/Google Chrome Integration/ChromeSample/Icon@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tapsandswipes/InterAppCommunication/HEAD/Samples/Google Chrome Integration/ChromeSample/Icon@2x.png -------------------------------------------------------------------------------- /notes.markdown: -------------------------------------------------------------------------------- 1 | # InterAppCmmunication 2 | 3 | ## New functionalities 4 | 5 | ### API discovering 6 | 7 | Add a method to discover the x-callback-url API an app offers to the public 8 | -------------------------------------------------------------------------------- /Samples/API Example/SoundsPlayer/SoundsPlayer/Default@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tapsandswipes/InterAppCommunication/HEAD/Samples/API Example/SoundsPlayer/SoundsPlayer/Default@2x.png -------------------------------------------------------------------------------- /Samples/API Example/SoundsPlayer/SoundsPlayer/sounds/bell.m4a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tapsandswipes/InterAppCommunication/HEAD/Samples/API Example/SoundsPlayer/SoundsPlayer/sounds/bell.m4a -------------------------------------------------------------------------------- /Samples/Google Chrome Integration/ChromeSample/Default@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tapsandswipes/InterAppCommunication/HEAD/Samples/Google Chrome Integration/ChromeSample/Default@2x.png -------------------------------------------------------------------------------- /Samples/API Example/SoundsPlayer/SoundsPlayer/sounds/boing.m4a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tapsandswipes/InterAppCommunication/HEAD/Samples/API Example/SoundsPlayer/SoundsPlayer/sounds/boing.m4a -------------------------------------------------------------------------------- /Samples/TicTacToe/TicTacToe/Images.xcassets/O.imageset/O@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tapsandswipes/InterAppCommunication/HEAD/Samples/TicTacToe/TicTacToe/Images.xcassets/O.imageset/O@2x.png -------------------------------------------------------------------------------- /Samples/TicTacToe/TicTacToe/Images.xcassets/X.imageset/X@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tapsandswipes/InterAppCommunication/HEAD/Samples/TicTacToe/TicTacToe/Images.xcassets/X.imageset/X@2x.png -------------------------------------------------------------------------------- /Samples/API Example/SoundPlayerRemote/SoundPlayerRemote/Icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tapsandswipes/InterAppCommunication/HEAD/Samples/API Example/SoundPlayerRemote/SoundPlayerRemote/Icon.png -------------------------------------------------------------------------------- /Samples/API Example/SoundsPlayer/SoundsPlayer/Default-568h@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tapsandswipes/InterAppCommunication/HEAD/Samples/API Example/SoundsPlayer/SoundsPlayer/Default-568h@2x.png -------------------------------------------------------------------------------- /Samples/API Example/SoundsPlayer/SoundsPlayer/sounds/applause.m4a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tapsandswipes/InterAppCommunication/HEAD/Samples/API Example/SoundsPlayer/SoundsPlayer/sounds/applause.m4a -------------------------------------------------------------------------------- /Samples/API Example/SoundsPlayer/SoundsPlayer/sounds/car key.m4a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tapsandswipes/InterAppCommunication/HEAD/Samples/API Example/SoundsPlayer/SoundsPlayer/sounds/car key.m4a -------------------------------------------------------------------------------- /Samples/Google Chrome Integration/ChromeSample/Default-568h@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tapsandswipes/InterAppCommunication/HEAD/Samples/Google Chrome Integration/ChromeSample/Default-568h@2x.png -------------------------------------------------------------------------------- /Samples/API Example/SoundPlayerRemote/SoundPlayerRemote/Default.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tapsandswipes/InterAppCommunication/HEAD/Samples/API Example/SoundPlayerRemote/SoundPlayerRemote/Default.png -------------------------------------------------------------------------------- /Samples/API Example/SoundPlayerRemote/SoundPlayerRemote/Icon@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tapsandswipes/InterAppCommunication/HEAD/Samples/API Example/SoundPlayerRemote/SoundPlayerRemote/Icon@2x.png -------------------------------------------------------------------------------- /Samples/API Example/SoundPlayerRemote/SoundPlayerRemote/Default@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tapsandswipes/InterAppCommunication/HEAD/Samples/API Example/SoundPlayerRemote/SoundPlayerRemote/Default@2x.png -------------------------------------------------------------------------------- /Samples/TicTacToe/TicTacToe/Images.xcassets/board.imageset/board@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tapsandswipes/InterAppCommunication/HEAD/Samples/TicTacToe/TicTacToe/Images.xcassets/board.imageset/board@2x.png -------------------------------------------------------------------------------- /Samples/TicTacToe/TicTacToe/Images.xcassets/intro.imageset/intro@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tapsandswipes/InterAppCommunication/HEAD/Samples/TicTacToe/TicTacToe/Images.xcassets/intro.imageset/intro@2x.png -------------------------------------------------------------------------------- /Samples/API Example/SoundPlayerRemote/SoundPlayerRemote/Default-568h@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tapsandswipes/InterAppCommunication/HEAD/Samples/API Example/SoundPlayerRemote/SoundPlayerRemote/Default-568h@2x.png -------------------------------------------------------------------------------- /Samples/TicTacToe/TicTacToe/Images.xcassets/AppIconO.appiconset/Icon-60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tapsandswipes/InterAppCommunication/HEAD/Samples/TicTacToe/TicTacToe/Images.xcassets/AppIconO.appiconset/Icon-60@2x.png -------------------------------------------------------------------------------- /Samples/TicTacToe/TicTacToe/Images.xcassets/AppIconX.appiconset/Icon-60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tapsandswipes/InterAppCommunication/HEAD/Samples/TicTacToe/TicTacToe/Images.xcassets/AppIconX.appiconset/Icon-60@2x.png -------------------------------------------------------------------------------- /Samples/TicTacToe/Pods/Pods-InterAppCommunication-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_Pods_InterAppCommunication : NSObject 3 | @end 4 | @implementation PodsDummy_Pods_InterAppCommunication 5 | @end 6 | -------------------------------------------------------------------------------- /Samples/TicTacToe/TicTacToe/Images.xcassets/apocalypse1.imageset/apocalypse1@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tapsandswipes/InterAppCommunication/HEAD/Samples/TicTacToe/TicTacToe/Images.xcassets/apocalypse1.imageset/apocalypse1@2x.png -------------------------------------------------------------------------------- /Samples/TicTacToe/TicTacToe/Images.xcassets/apocalypse2.imageset/apocalypse2@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tapsandswipes/InterAppCommunication/HEAD/Samples/TicTacToe/TicTacToe/Images.xcassets/apocalypse2.imageset/apocalypse2@2x.png -------------------------------------------------------------------------------- /Samples/TicTacToe/TicTacToe/Images.xcassets/apocalypse3.imageset/apocalypse3@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tapsandswipes/InterAppCommunication/HEAD/Samples/TicTacToe/TicTacToe/Images.xcassets/apocalypse3.imageset/apocalypse3@2x.png -------------------------------------------------------------------------------- /Samples/TicTacToe/TicTacToe/Images.xcassets/apocalypse4.imageset/apocalypse4@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tapsandswipes/InterAppCommunication/HEAD/Samples/TicTacToe/TicTacToe/Images.xcassets/apocalypse4.imageset/apocalypse4@2x.png -------------------------------------------------------------------------------- /Samples/TicTacToe/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - InterAppCommunication (1.0) 3 | 4 | DEPENDENCIES: 5 | - InterAppCommunication 6 | 7 | SPEC CHECKSUMS: 8 | InterAppCommunication: 8b5c768edf16414947f4fae4d15a86cc38ddbf8c 9 | 10 | COCOAPODS: 0.32.1 11 | -------------------------------------------------------------------------------- /Samples/TicTacToe/Pods/Manifest.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - InterAppCommunication (1.0) 3 | 4 | DEPENDENCIES: 5 | - InterAppCommunication 6 | 7 | SPEC CHECKSUMS: 8 | InterAppCommunication: 8b5c768edf16414947f4fae4d15a86cc38ddbf8c 9 | 10 | COCOAPODS: 0.32.1 11 | -------------------------------------------------------------------------------- /Samples/TicTacToe/Pods/Pods.xcconfig: -------------------------------------------------------------------------------- 1 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 2 | HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers" "${PODS_ROOT}/Headers/InterAppCommunication" 3 | OTHER_CFLAGS = $(inherited) -isystem "${PODS_ROOT}/Headers" -isystem "${PODS_ROOT}/Headers/InterAppCommunication" 4 | OTHER_LDFLAGS = -ObjC 5 | PODS_ROOT = ${SRCROOT}/Pods -------------------------------------------------------------------------------- /Samples/TicTacToe/TicTacToe/TTTIntroViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // TTTViewController.h 3 | // TicTacToe 4 | // 5 | // Created by Antonio Cabezuelo Vivo on 14/05/14. 6 | // Copyright (c) 2014 Taps and Swipes. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface TTTIntroViewController : UIViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Samples/TicTacToe/Pods/Pods-InterAppCommunication-Private.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Pods-InterAppCommunication.xcconfig" 2 | GCC_PREPROCESSOR_DEFINITIONS = COCOAPODS=1 3 | HEADER_SEARCH_PATHS = "${PODS_ROOT}/BuildHeaders" "${PODS_ROOT}/BuildHeaders/InterAppCommunication" "${PODS_ROOT}/Headers" "${PODS_ROOT}/Headers/InterAppCommunication" 4 | OTHER_LDFLAGS = -ObjC 5 | PODS_ROOT = ${SRCROOT} -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Ignore patterns 2 | *.pyc 3 | *.swp 4 | 5 | # xcode noise 6 | build 7 | *.pbxuser 8 | *.mode1v3 9 | *.mode2v3 10 | !default.pbxuser 11 | !default.mode1v3 12 | !default.mode2v3 13 | xcuserdata 14 | *.perspective 15 | *.perspectivev3 16 | 17 | *~.nib 18 | *~.xib 19 | 20 | # old skool 21 | .svn 22 | 23 | # osx noise 24 | .DS_Store 25 | profile 26 | 27 | *.xcworkspace -------------------------------------------------------------------------------- /Samples/TicTacToe/TicTacToe/TTTAppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // TTTAppDelegate.h 3 | // TicTacToe 4 | // 5 | // Created by Antonio Cabezuelo Vivo on 14/05/14. 6 | // Copyright (c) 2014 Taps and Swipes. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface TTTAppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /Samples/API Example/SoundsPlayer/SoundsPlayer/SoundsPlayer-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header for all source files of the 'SoundsPlayer' target in the 'SoundsPlayer' project 3 | // 4 | 5 | #import 6 | 7 | #ifndef __IPHONE_4_0 8 | #warning "This project uses features only available in iOS SDK 4.0 and later." 9 | #endif 10 | 11 | #ifdef __OBJC__ 12 | #import 13 | #import 14 | #endif 15 | -------------------------------------------------------------------------------- /Samples/Google Chrome Integration/ChromeSample/ChromeSample-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header for all source files of the 'ChromeSample' target in the 'ChromeSample' project 3 | // 4 | 5 | #import 6 | 7 | #ifndef __IPHONE_4_0 8 | #warning "This project uses features only available in iOS SDK 4.0 and later." 9 | #endif 10 | 11 | #ifdef __OBJC__ 12 | #import 13 | #import 14 | #endif 15 | -------------------------------------------------------------------------------- /Samples/TicTacToe/TicTacToe/Images.xcassets/O.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "O@2x.png" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Samples/TicTacToe/TicTacToe/Images.xcassets/X.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "X@2x.png" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Samples/TicTacToe/TicTacToe/TicTacToe-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header 3 | // 4 | // The contents of this file are implicitly included at the beginning of every source file. 5 | // 6 | 7 | #import 8 | 9 | #ifndef __IPHONE_5_0 10 | #warning "This project uses features only available in iOS SDK 5.0 and later." 11 | #endif 12 | 13 | #ifdef __OBJC__ 14 | #import 15 | #import 16 | #endif 17 | -------------------------------------------------------------------------------- /Samples/TicTacToe/TicTacToe/Images.xcassets/board.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "board@2x.png" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Samples/TicTacToe/TicTacToe/Images.xcassets/intro.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "intro@2x.png" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /AppClients/InstapaperIACClient.h: -------------------------------------------------------------------------------- 1 | // 2 | // InstapaperIACClient.h 3 | // IACSample 4 | // 5 | // Created by Antonio Cabezuelo Vivo on 12/02/13. 6 | // Copyright (c) 2013 Antonio Cabezuelo Vivo. All rights reserved. 7 | // 8 | 9 | #import "IACClient.h" 10 | 11 | @interface InstapaperIACClient : IACClient 12 | 13 | - (void)add:(NSString*)url; 14 | - (void)add:(NSString*)url onSuccess:(void(^)(void))onSuccess onFailure:(void(^)(NSError*))onError; 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /Samples/TicTacToe/TicTacToe/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // TicTacToe 4 | // 5 | // Created by Antonio Cabezuelo Vivo on 14/05/14. 6 | // Copyright (c) 2014 Taps and Swipes. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "TTTAppDelegate.h" 12 | 13 | int main(int argc, char * argv[]) 14 | { 15 | @autoreleasepool { 16 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([TTTAppDelegate class])); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Samples/API Example/SoundPlayerRemote/SoundPlayerRemote/SoundPlayerRemote-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header for all source files of the 'SoundPlayerRemote' target in the 'SoundPlayerRemote' project 3 | // 4 | 5 | #import 6 | 7 | #ifndef __IPHONE_4_0 8 | #warning "This project uses features only available in iOS SDK 4.0 and later." 9 | #endif 10 | 11 | #ifdef __OBJC__ 12 | #import 13 | #import 14 | #endif 15 | -------------------------------------------------------------------------------- /Samples/TicTacToe/TicTacToe/Images.xcassets/apocalypse1.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "apocalypse1@2x.png" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Samples/TicTacToe/TicTacToe/Images.xcassets/apocalypse2.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "apocalypse2@2x.png" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Samples/TicTacToe/TicTacToe/Images.xcassets/apocalypse3.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "apocalypse3@2x.png" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Samples/TicTacToe/TicTacToe/Images.xcassets/apocalypse4.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "apocalypse4@2x.png" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Samples/API Example/SoundsPlayer/SoundsPlayer/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // SoundsPlayer 4 | // 5 | // Created by Antonio Cabezuelo Vivo on 15/02/13. 6 | // Copyright (c) 2013 Antonio Cabezuelo Vivo. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "SPAppDelegate.h" 12 | 13 | int main(int argc, char *argv[]) 14 | { 15 | @autoreleasepool { 16 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([SPAppDelegate class])); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Samples/Google Chrome Integration/ChromeSample/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // ChromeSample 4 | // 5 | // Created by Antonio Cabezuelo Vivo on 13/02/13. 6 | // Copyright (c) 2013 Antonio Cabezuelo Vivo. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "CSAppDelegate.h" 12 | 13 | int main(int argc, char *argv[]) 14 | { 15 | @autoreleasepool { 16 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([CSAppDelegate class])); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /InterAppCommunication/NSString+IACExtensions.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSString+IACExtensions.h 3 | // IACSample 4 | // 5 | // Created by Antonio Cabezuelo Vivo on 10/02/13. 6 | // Copyright (c) 2013 Antonio Cabezuelo Vivo. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface NSString (IACExtensions) 12 | 13 | + (NSString*)stringWithUUID; 14 | 15 | - (NSString*)stringByAppendingURLParams:(NSDictionary*)params; 16 | 17 | - (NSDictionary*)parseURLParams; 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /Samples/API Example/SoundPlayerRemote/SoundPlayerRemote/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // SoundPlayerRemote 4 | // 5 | // Created by Antonio Cabezuelo Vivo on 15/02/13. 6 | // Copyright (c) 2013 Antonio Cabezuelo Vivo. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "SRAppDelegate.h" 12 | 13 | int main(int argc, char *argv[]) 14 | { 15 | @autoreleasepool { 16 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([SRAppDelegate class])); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Samples/API Example/SoundPlayerRemote/SoundPlayerRemote/SoundPlayerIACClient.h: -------------------------------------------------------------------------------- 1 | // 2 | // SoundPlayerIACClient.h 3 | // SoundPlayerRemote 4 | // 5 | // Created by Antonio Cabezuelo Vivo on 15/02/13. 6 | // Copyright (c) 2013 Antonio Cabezuelo Vivo. All rights reserved. 7 | // 8 | 9 | #import "IACClient.h" 10 | 11 | @interface SoundPlayerIACClient : IACClient 12 | 13 | - (void)getSoundNamesWithCallback:(void(^)(NSArray *soundNames, NSError *error))callback; 14 | - (void)playSoundWithName:(NSString*)name; 15 | @end 16 | -------------------------------------------------------------------------------- /Samples/API Example/SoundsPlayer/SoundsPlayer/SPAppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // SPAppDelegate.h 3 | // SoundsPlayer 4 | // 5 | // Created by Antonio Cabezuelo Vivo on 15/02/13. 6 | // Copyright (c) 2013 Antonio Cabezuelo Vivo. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @class SPViewController; 12 | 13 | @interface SPAppDelegate : UIResponder 14 | 15 | @property (strong, nonatomic) UIWindow *window; 16 | 17 | @property (strong, nonatomic) SPViewController *viewController; 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /Samples/Google Chrome Integration/ChromeSample/CSAppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // CSAppDelegate.h 3 | // ChromeSample 4 | // 5 | // Created by Antonio Cabezuelo Vivo on 13/02/13. 6 | // Copyright (c) 2013 Antonio Cabezuelo Vivo. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @class CSViewController; 12 | 13 | @interface CSAppDelegate : UIResponder 14 | 15 | @property (strong, nonatomic) UIWindow *window; 16 | 17 | @property (strong, nonatomic) CSViewController *viewController; 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /Samples/TicTacToe/Pods/InterAppCommunication/InterAppCommunication/NSString+IACExtensions.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSString+IACExtensions.h 3 | // IACSample 4 | // 5 | // Created by Antonio Cabezuelo Vivo on 10/02/13. 6 | // Copyright (c) 2013 Antonio Cabezuelo Vivo. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface NSString (IACExtensions) 12 | 13 | + (NSString*)stringWithUUID; 14 | 15 | - (NSString*)stringByAppendingURLParams:(NSDictionary*)params; 16 | 17 | - (NSDictionary*)parseURLParams; 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /Samples/API Example/SoundPlayerRemote/SoundPlayerRemote/SRAppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // SRAppDelegate.h 3 | // SoundPlayerRemote 4 | // 5 | // Created by Antonio Cabezuelo Vivo on 15/02/13. 6 | // Copyright (c) 2013 Antonio Cabezuelo Vivo. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @class SRViewController; 12 | 13 | @interface SRAppDelegate : UIResponder 14 | 15 | @property (strong, nonatomic) UIWindow *window; 16 | 17 | @property (strong, nonatomic) SRViewController *viewController; 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /Samples/TicTacToe/Pods/Pods-environment.h: -------------------------------------------------------------------------------- 1 | 2 | // To check if a library is compiled with CocoaPods you 3 | // can use the `COCOAPODS` macro definition which is 4 | // defined in the xcconfigs so it is available in 5 | // headers also when they are imported in the client 6 | // project. 7 | 8 | 9 | // InterAppCommunication 10 | #define COCOAPODS_POD_AVAILABLE_InterAppCommunication 11 | #define COCOAPODS_VERSION_MAJOR_InterAppCommunication 1 12 | #define COCOAPODS_VERSION_MINOR_InterAppCommunication 0 13 | #define COCOAPODS_VERSION_PATCH_InterAppCommunication 0 14 | 15 | -------------------------------------------------------------------------------- /Samples/API Example/SoundPlayerRemote/SoundPlayerRemote/SRViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // SRViewController.h 3 | // SoundPlayerRemote 4 | // 5 | // Created by Antonio Cabezuelo Vivo on 15/02/13. 6 | // Copyright (c) 2013 Antonio Cabezuelo Vivo. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface SRViewController : UIViewController 12 | @property (weak, nonatomic) IBOutlet UIButton *getButton; 13 | @property (weak, nonatomic) IBOutlet UITableView *tableView; 14 | 15 | - (IBAction)getSounds:(UIButton *)sender; 16 | @end 17 | -------------------------------------------------------------------------------- /Samples/API Example/SoundsPlayer/SoundsPlayer/SPViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // SPViewController.h 3 | // SoundsPlayer 4 | // 5 | // Created by Antonio Cabezuelo Vivo on 15/02/13. 6 | // Copyright (c) 2013 Antonio Cabezuelo Vivo. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface SPViewController : UIViewController 12 | 13 | @property (strong, readonly, nonatomic) NSArray *soundNames; 14 | 15 | @property (strong, nonatomic) IBOutletCollection(UIButton) NSArray *buttons; 16 | 17 | - (IBAction)play:(UIButton *)sender; 18 | 19 | - (BOOL)playSoundWithName:(NSString*)name; 20 | @end 21 | -------------------------------------------------------------------------------- /Samples/TicTacToe/TicTacToe/Images.xcassets/LaunchImage.launchimage/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "orientation" : "portrait", 5 | "idiom" : "iphone", 6 | "extent" : "full-screen", 7 | "minimum-system-version" : "7.0", 8 | "scale" : "2x" 9 | }, 10 | { 11 | "orientation" : "portrait", 12 | "idiom" : "iphone", 13 | "subtype" : "retina4", 14 | "extent" : "full-screen", 15 | "minimum-system-version" : "7.0", 16 | "scale" : "2x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /AppClients/FunboxIACClient.h: -------------------------------------------------------------------------------- 1 | // 2 | // FunboxIACClient.h 3 | // IACSample 4 | // 5 | // Created by Antonio Cabezuelo Vivo on 10/02/13. 6 | // Copyright (c) 2013 Antonio Cabezuelo Vivo. All rights reserved. 7 | // 8 | 9 | #import "IACClient.h" 10 | 11 | typedef NS_ENUM(NSInteger, FunboxError) { 12 | FunboxSoundNotFoundError = -1 13 | }; 14 | 15 | @interface FunboxIACClient : IACClient 16 | 17 | - (void)playSound:(NSString*)soundName; 18 | - (void)playSound:(NSString*)soundName onSuccess:(void(^)(void))onSuccess onFailure:(void(^)(NSError*))onError; 19 | - (void)downloadSoundFromUrl:(NSString*)url; 20 | 21 | @end 22 | -------------------------------------------------------------------------------- /AppClients/GoogleChromeIACClient.h: -------------------------------------------------------------------------------- 1 | // 2 | // ChromeIACClient.h 3 | // IACSample 4 | // 5 | // Created by Antonio Cabezuelo Vivo on 11/02/13. 6 | // Copyright (c) 2013 Antonio Cabezuelo Vivo. All rights reserved. 7 | // 8 | 9 | #import "IACClient.h" 10 | 11 | @interface GoogleChromeIACClient : IACClient 12 | 13 | - (void)openURL:(NSString*)url; 14 | - (void)openNewTabWithURL:(NSString*)url; 15 | - (void)openURL:(NSString*)url onSuccess:(void(^)(void))onSuccess onFailure:(void(^)(NSError*))onError; 16 | - (void)openNewTabWithURL:(NSString*)url onSuccess:(void(^)(void))onSuccess onFailure:(void(^)(NSError*))onError; 17 | 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /InterAppCommunication.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | s.name = "InterAppCommunication" 3 | s.version = "1.0" 4 | s.summary = "x-callback-url made easy." 5 | s.platform = :ios, '5.0' 6 | s.homepage = "https://github.com/tapsandswipes/InterAppCommunication" 7 | s.author = { "Antonio Cabezuelo Vivo" => "antonio@tapsandswipes.com" } 8 | s.source = { :git => "https://github.com/tapsandswipes/InterAppCommunication.git", :tag => '1.0' } 9 | s.source_files = 'InterAppCommunication/*.{h,m}' 10 | s.requires_arc = true 11 | s.license = { :type => 'MIT', :file => 'LICENSE.markdown' } 12 | end -------------------------------------------------------------------------------- /Samples/TicTacToe/TicTacToe/TTTBoardViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // TTTBoardViewController.h 3 | // TicTacToe 4 | // 5 | // Created by Antonio Cabezuelo Vivo on 14/05/14. 6 | // Copyright (c) 2014 Taps and Swipes. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @class TTTIACClient; 12 | 13 | typedef NS_ENUM(NSUInteger, GameType) { 14 | GameTypeOnePlayer, 15 | GameTypeTwoPlayers, 16 | GameTypeZeroPlayers 17 | }; 18 | 19 | @interface TTTBoardViewController : UIViewController 20 | 21 | @property (nonatomic) GameType gameType; 22 | @property (strong, nonatomic) TTTIACClient *remoteClient; 23 | 24 | @end 25 | -------------------------------------------------------------------------------- /Samples/TicTacToe/TicTacToe/Images.xcassets/AppIconO.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "29x29", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "40x40", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "size" : "60x60", 15 | "idiom" : "iphone", 16 | "filename" : "Icon-60@2x.png", 17 | "scale" : "2x" 18 | }, 19 | { 20 | "idiom" : "iphone", 21 | "size" : "60x60", 22 | "scale" : "3x" 23 | } 24 | ], 25 | "info" : { 26 | "version" : 1, 27 | "author" : "xcode" 28 | } 29 | } -------------------------------------------------------------------------------- /InterAppCommunication/IACRequest.h: -------------------------------------------------------------------------------- 1 | // 2 | // IACRequest.h 3 | // IACSample 4 | // 5 | // Created by Antonio Cabezuelo Vivo on 09/02/13. 6 | // Copyright (c) 2013 Antonio Cabezuelo Vivo. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @class IACClient; 12 | 13 | @interface IACRequest : NSObject 14 | 15 | @property (copy, readonly, nonatomic) NSString *requestID; 16 | @property (strong, nonatomic) IACClient *client; 17 | @property (copy, nonatomic) NSString *action; 18 | @property (strong, nonatomic) NSDictionary *parameters; 19 | @property (copy, nonatomic) void(^successCalback)(NSDictionary*); 20 | @property (copy, nonatomic) void(^errorCalback)(NSError*); 21 | 22 | @end 23 | -------------------------------------------------------------------------------- /Samples/Google Chrome Integration/ChromeSample/CSViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // CSViewController.h 3 | // ChromeSample 4 | // 5 | // Created by Antonio Cabezuelo Vivo on 13/02/13. 6 | // Copyright (c) 2013 Antonio Cabezuelo Vivo. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | @interface CSViewController : UIViewController 13 | 14 | @property (weak, nonatomic) IBOutlet UITextField *urlField; 15 | @property (weak, nonatomic) IBOutlet UIBarButtonItem *openButton; 16 | @property (weak, nonatomic) IBOutlet UIWebView *webView; 17 | 18 | - (IBAction)openInChrome:(id)sender; 19 | @end 20 | -------------------------------------------------------------------------------- /Samples/TicTacToe/Pods/InterAppCommunication/InterAppCommunication/IACRequest.h: -------------------------------------------------------------------------------- 1 | // 2 | // IACRequest.h 3 | // IACSample 4 | // 5 | // Created by Antonio Cabezuelo Vivo on 09/02/13. 6 | // Copyright (c) 2013 Antonio Cabezuelo Vivo. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @class IACClient; 12 | 13 | @interface IACRequest : NSObject 14 | 15 | @property (copy, readonly, nonatomic) NSString *requestID; 16 | @property (strong, nonatomic) IACClient *client; 17 | @property (copy, nonatomic) NSString *action; 18 | @property (strong, nonatomic) NSDictionary *parameters; 19 | @property (copy, nonatomic) void(^successCalback)(NSDictionary*); 20 | @property (copy, nonatomic) void(^errorCalback)(NSError*); 21 | 22 | @end 23 | -------------------------------------------------------------------------------- /Samples/TicTacToe/TicTacToe/TTTIACClient.h: -------------------------------------------------------------------------------- 1 | // 2 | // TTTIACClient.h 3 | // TicTacToe 4 | // 5 | // Created by Antonio Cabezuelo Vivo on 15/05/14. 6 | // Copyright (c) 2014 Taps and Swipes. All rights reserved. 7 | // 8 | 9 | #import "IACClient.h" 10 | 11 | extern NSString * const TTTShowAction; 12 | extern NSString * const TTTInitGameAction; 13 | extern NSString * const TTTSelectSpotAction; 14 | 15 | extern NSString * const kOponentKey; 16 | extern NSString * const kSpotKey; 17 | 18 | @interface TTTIACClient : IACClient 19 | 20 | + (instancetype)clientForOpponent:(NSString *)oponentSchema; 21 | 22 | - (instancetype)initClientA; 23 | - (instancetype)initClientB; 24 | 25 | - (void)show; 26 | - (void)initGame; 27 | - (void)selectSpot:(NSUInteger)spot; 28 | 29 | @end 30 | -------------------------------------------------------------------------------- /Samples/TicTacToe/TicTacToeTests/TicTacToeTests-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | com.tas.${PRODUCT_NAME:rfc1034identifier} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundlePackageType 14 | BNDL 15 | CFBundleShortVersionString 16 | 1.0 17 | CFBundleSignature 18 | ???? 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /Samples/TicTacToe/TicTacToeTests/TicTacToeTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // TicTacToeTests.m 3 | // TicTacToeTests 4 | // 5 | // Created by Antonio Cabezuelo Vivo on 14/05/14. 6 | // Copyright (c) 2014 Taps and Swipes. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface TicTacToeTests : XCTestCase 12 | 13 | @end 14 | 15 | @implementation TicTacToeTests 16 | 17 | - (void)setUp 18 | { 19 | [super setUp]; 20 | // Put setup code here. This method is called before the invocation of each test method in the class. 21 | } 22 | 23 | - (void)tearDown 24 | { 25 | // Put teardown code here. This method is called after the invocation of each test method in the class. 26 | [super tearDown]; 27 | } 28 | 29 | - (void)testExample 30 | { 31 | XCTFail(@"No implementation for \"%s\"", __PRETTY_FUNCTION__); 32 | } 33 | 34 | @end 35 | -------------------------------------------------------------------------------- /Samples/TicTacToe/TicTacToe/Images.xcassets/AppIconX.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "29x29", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "29x29", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "40x40", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "40x40", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "size" : "60x60", 25 | "idiom" : "iphone", 26 | "filename" : "Icon-60@2x.png", 27 | "scale" : "2x" 28 | }, 29 | { 30 | "idiom" : "iphone", 31 | "size" : "60x60", 32 | "scale" : "3x" 33 | } 34 | ], 35 | "info" : { 36 | "version" : 1, 37 | "author" : "xcode" 38 | } 39 | } -------------------------------------------------------------------------------- /InterAppCommunication/IACRequest.m: -------------------------------------------------------------------------------- 1 | // 2 | // IACRequest.m 3 | // IACSample 4 | // 5 | // Created by Antonio Cabezuelo Vivo on 09/02/13. 6 | // Copyright (c) 2013 Antonio Cabezuelo Vivo. All rights reserved. 7 | // 8 | 9 | #import "IACRequest.h" 10 | #import "NSString+IACExtensions.h" 11 | 12 | #if !__has_feature(objc_arc) 13 | #error InterAppComutication must be built with ARC. 14 | // You can turn on ARC for only InterAppComutication files by adding -fobjc-arc to the build phase for each of its files. 15 | #endif 16 | 17 | 18 | @interface IACRequest () 19 | @property (copy, readwrite, nonatomic) NSString *requestID; 20 | @end 21 | 22 | @implementation IACRequest 23 | 24 | - (instancetype)init { 25 | self = [super init]; 26 | if (self) { 27 | self.requestID = [NSString stringWithUUID]; 28 | } 29 | return self; 30 | } 31 | 32 | 33 | @end 34 | -------------------------------------------------------------------------------- /Samples/TicTacToe/Pods/InterAppCommunication/InterAppCommunication/IACRequest.m: -------------------------------------------------------------------------------- 1 | // 2 | // IACRequest.m 3 | // IACSample 4 | // 5 | // Created by Antonio Cabezuelo Vivo on 09/02/13. 6 | // Copyright (c) 2013 Antonio Cabezuelo Vivo. All rights reserved. 7 | // 8 | 9 | #import "IACRequest.h" 10 | #import "NSString+IACExtensions.h" 11 | 12 | #if !__has_feature(objc_arc) 13 | #error InterAppComutication must be built with ARC. 14 | // You can turn on ARC for only InterAppComutication files by adding -fobjc-arc to the build phase for each of its files. 15 | #endif 16 | 17 | 18 | @interface IACRequest () 19 | @property (copy, readwrite, nonatomic) NSString *requestID; 20 | @end 21 | 22 | @implementation IACRequest 23 | 24 | - (instancetype)init { 25 | self = [super init]; 26 | if (self) { 27 | self.requestID = [NSString stringWithUUID]; 28 | } 29 | return self; 30 | } 31 | 32 | 33 | @end 34 | -------------------------------------------------------------------------------- /AppClients/InstapaperIACClient.m: -------------------------------------------------------------------------------- 1 | // 2 | // InstapaperIACClient.m 3 | // IACSample 4 | // 5 | // Created by Antonio Cabezuelo Vivo on 12/02/13. 6 | // Copyright (c) 2013 Antonio Cabezuelo Vivo. All rights reserved. 7 | // 8 | 9 | #import "InstapaperIACClient.h" 10 | 11 | @implementation InstapaperIACClient 12 | 13 | - (instancetype)init { 14 | return [self initWithURLScheme:@"x-callback-instapaper"]; 15 | } 16 | 17 | - (void)add:(NSString*)url { 18 | [self add:url onSuccess:nil onFailure:nil]; 19 | } 20 | 21 | - (void)add:(NSString*)url onSuccess:(void(^)(void))onSuccess onFailure:(void(^)(NSError*))onError { 22 | [self performAction:@"add" 23 | parameters:@{@"url": url} 24 | onSuccess:^(NSDictionary* params) { 25 | if (onSuccess) { 26 | onSuccess(); 27 | } 28 | } 29 | onFailure:onError 30 | ]; 31 | } 32 | 33 | @end 34 | -------------------------------------------------------------------------------- /Samples/TicTacToe/TicTacToe/DMGridModel.h: -------------------------------------------------------------------------------- 1 | // 2 | // DMGridModel.h 3 | // tictactoe 4 | // 5 | // Created by Dennis Wilkins on 5/26/12. 6 | // Copyright (c) 2012 Delicious Morsel LLC. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | typedef NS_ENUM(NSUInteger, DMPlayer) { 12 | PlayerDraw, 13 | PlayerNone, 14 | PlayerA, 15 | PlayerB, 16 | }; 17 | 18 | @interface DMGridModel : NSObject 19 | 20 | @property (nonatomic , retain) NSMutableArray *grid; 21 | @property (nonatomic , retain) NSMutableArray *solves; 22 | @property (nonatomic , assign) NSUInteger size; 23 | 24 | - (id)init; 25 | - (id)initWithSize:(NSUInteger) gridSize; 26 | - (void)resetGrid; 27 | - (BOOL)setPlayer:(DMPlayer)player atGridLocation:(NSUInteger)location; 28 | - (DMPlayer)playerAtGridIndex:(NSUInteger)idx; 29 | - (void)createSolvables; 30 | - (DMPlayer)getWinner; 31 | - (NSInteger)getNextOpenSpot; 32 | 33 | + (NSArray *)getBestMoveForPlayer:(DMPlayer)player inGrid:(DMGridModel *)grid depth:(NSInteger)depth; 34 | 35 | 36 | @end 37 | -------------------------------------------------------------------------------- /InterAppCommunication/IACDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // IACDelegate.h 3 | // IACSample 4 | // 5 | // Created by Antonio Cabezuelo Vivo on 11/02/13. 6 | // Copyright (c) 2013 Antonio Cabezuelo Vivo. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | 12 | // Block templates 13 | typedef void(^IACSuccessBlock)(NSDictionary* returnParams,BOOL cancelled); 14 | typedef void(^IACFailureBlock)(NSError* error); 15 | 16 | 17 | @protocol IACDelegate 18 | 19 | /* Method invoqued to see if an action is handled by the delegate 20 | */ 21 | - (BOOL)supportsIACAction:(NSString*)action; 22 | 23 | /* Method invoqued by the manager to perform an action. 24 | The parameters dictionary does not contain any x-callback-url parameter except 'x-source'. 25 | success and failure are the blocks you must call after you perform the action to support callbacks to the calling app. If the action does not support callbacks you can ignore this blocks. 26 | */ 27 | - (void)performIACAction:(NSString*)action 28 | parameters:(NSDictionary*)parameters 29 | onSuccess:(IACSuccessBlock)success 30 | onFailure:(IACFailureBlock)failure; 31 | 32 | @end 33 | -------------------------------------------------------------------------------- /LICENSE.markdown: -------------------------------------------------------------------------------- 1 | # License 2 | 3 | ## MIT License 4 | 5 | Copyright (c) 2013 Antonio Cabezuelo Vivo (http://tapsandswipes.com) 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a copy 8 | of this software and associated documentation files (the "Software"), to deal 9 | in the Software without restriction, including without limitation the rights 10 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | copies of the Software, and to permit persons to whom the Software is 12 | furnished to do so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in 15 | all copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 | THE SOFTWARE. -------------------------------------------------------------------------------- /Samples/TicTacToe/Pods/InterAppCommunication/InterAppCommunication/IACDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // IACDelegate.h 3 | // IACSample 4 | // 5 | // Created by Antonio Cabezuelo Vivo on 11/02/13. 6 | // Copyright (c) 2013 Antonio Cabezuelo Vivo. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | 12 | // Block templates 13 | typedef void(^IACSuccessBlock)(NSDictionary* returnParams,BOOL cancelled); 14 | typedef void(^IACFailureBlock)(NSError* error); 15 | 16 | 17 | @protocol IACDelegate 18 | 19 | /* Method invoqued to see if an action is handled by the delegate 20 | */ 21 | - (BOOL)supportsIACAction:(NSString*)action; 22 | 23 | /* Method invoqued by the manager to perform an action. 24 | The parameters dictionary does not contain any x-callback-url parameter except 'x-source'. 25 | success and failure are the blocks you must call after you perform the action to support callbacks to the calling app. If the action does not support callbacks you can ignore this blocks. 26 | */ 27 | - (void)performIACAction:(NSString*)action 28 | parameters:(NSDictionary*)parameters 29 | onSuccess:(IACSuccessBlock)success 30 | onFailure:(IACFailureBlock)failure; 31 | 32 | @end 33 | -------------------------------------------------------------------------------- /Samples/TicTacToe/Pods/InterAppCommunication/LICENSE.markdown: -------------------------------------------------------------------------------- 1 | # License 2 | 3 | ## MIT License 4 | 5 | Copyright (c) 2013 Antonio Cabezuelo Vivo (http://tapsandswipes.com) 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a copy 8 | of this software and associated documentation files (the "Software"), to deal 9 | in the Software without restriction, including without limitation the rights 10 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | copies of the Software, and to permit persons to whom the Software is 12 | furnished to do so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in 15 | all copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 | THE SOFTWARE. -------------------------------------------------------------------------------- /Samples/API Example/SoundPlayerRemote/SoundPlayerRemote/SRAppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // SRAppDelegate.m 3 | // SoundPlayerRemote 4 | // 5 | // Created by Antonio Cabezuelo Vivo on 15/02/13. 6 | // Copyright (c) 2013 Antonio Cabezuelo Vivo. All rights reserved. 7 | // 8 | 9 | #import "SRAppDelegate.h" 10 | #import "SRViewController.h" 11 | #import "IACManager.h" 12 | 13 | @implementation SRAppDelegate 14 | 15 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 16 | { 17 | 18 | [IACManager sharedManager].callbackURLScheme = @"iacplayerremote"; 19 | 20 | self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; 21 | // Override point for customization after application launch. 22 | self.viewController = [[SRViewController alloc] initWithNibName:@"SRViewController" bundle:nil]; 23 | self.window.rootViewController = self.viewController; 24 | [self.window makeKeyAndVisible]; 25 | return YES; 26 | } 27 | 28 | - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation 29 | { 30 | return [[IACManager sharedManager] handleOpenURL:url]; 31 | } 32 | 33 | 34 | @end 35 | -------------------------------------------------------------------------------- /Samples/Google Chrome Integration/ChromeSample/CSAppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // CSAppDelegate.m 3 | // ChromeSample 4 | // 5 | // Created by Antonio Cabezuelo Vivo on 13/02/13. 6 | // Copyright (c) 2013 Antonio Cabezuelo Vivo. All rights reserved. 7 | // 8 | 9 | #import "CSAppDelegate.h" 10 | 11 | #import "CSViewController.h" 12 | #import "IACManager.h" 13 | 14 | @implementation CSAppDelegate 15 | 16 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 17 | { 18 | 19 | // We add the url scheme configured in the ChromeSample-Info.plist file under URL types. 20 | [IACManager sharedManager].callbackURLScheme = @"iacchromesample"; 21 | 22 | self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; 23 | self.viewController = [[CSViewController alloc] initWithNibName:@"CSViewController" bundle:nil]; 24 | self.window.rootViewController = self.viewController; 25 | [self.window makeKeyAndVisible]; 26 | return YES; 27 | } 28 | 29 | - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation 30 | { 31 | // Let the manager handle external calls 32 | return [[IACManager sharedManager] handleOpenURL:url]; 33 | } 34 | 35 | 36 | @end 37 | -------------------------------------------------------------------------------- /AppClients/FunboxIACClient.m: -------------------------------------------------------------------------------- 1 | // 2 | // FunboxIACClient.m 3 | // IACSample 4 | // 5 | // Created by Antonio Cabezuelo Vivo on 10/02/13. 6 | // Copyright (c) 2013 Antonio Cabezuelo Vivo. All rights reserved. 7 | // 8 | 9 | #import "FunboxIACClient.h" 10 | 11 | #if !__has_feature(objc_arc) 12 | #error InterAppComutication must be built with ARC. 13 | // You can turn on ARC for only InterAppComutication files by adding -fobjc-arc to the build phase for each of its files. 14 | #endif 15 | 16 | 17 | @implementation FunboxIACClient 18 | 19 | - (instancetype)init { 20 | return [self initWithURLScheme:@"funbox"]; 21 | } 22 | 23 | - (void)playSound:(NSString*)soundName { 24 | [self playSound:soundName onSuccess:nil onFailure:nil]; 25 | } 26 | 27 | - (void)playSound:(NSString*)soundName onSuccess:(void(^)(void))onSuccess onFailure:(void(^)(NSError*))onError { 28 | [self performAction:@"player" 29 | parameters:@{@"sound": soundName} 30 | onSuccess:^(NSDictionary* params) { 31 | if (onSuccess) { 32 | onSuccess(); 33 | } 34 | } 35 | onFailure:onError 36 | ]; 37 | } 38 | 39 | - (void)downloadSoundFromUrl:(NSString*)url { 40 | [self performAction:@"download" 41 | parameters:@{@"url": url} 42 | ]; 43 | } 44 | 45 | 46 | 47 | @end 48 | -------------------------------------------------------------------------------- /Samples/TicTacToe/Pods/Pods-acknowledgements.markdown: -------------------------------------------------------------------------------- 1 | # Acknowledgements 2 | This application makes use of the following third party libraries: 3 | 4 | ## InterAppCommunication 5 | 6 | # License 7 | 8 | ## MIT License 9 | 10 | Copyright (c) 2013 Antonio Cabezuelo Vivo (http://tapsandswipes.com) 11 | 12 | Permission is hereby granted, free of charge, to any person obtaining a copy 13 | of this software and associated documentation files (the "Software"), to deal 14 | in the Software without restriction, including without limitation the rights 15 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 16 | copies of the Software, and to permit persons to whom the Software is 17 | furnished to do so, subject to the following conditions: 18 | 19 | The above copyright notice and this permission notice shall be included in 20 | all copies or substantial portions of the Software. 21 | 22 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 23 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 24 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 25 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 26 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 27 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 28 | THE SOFTWARE. 29 | Generated by CocoaPods - http://cocoapods.org 30 | -------------------------------------------------------------------------------- /Samples/API Example/SoundPlayerRemote/SoundPlayerRemote/SoundPlayerIACClient.m: -------------------------------------------------------------------------------- 1 | // 2 | // SoundPlayerIACClient.m 3 | // SoundPlayerRemote 4 | // 5 | // Created by Antonio Cabezuelo Vivo on 15/02/13. 6 | // Copyright (c) 2013 Antonio Cabezuelo Vivo. All rights reserved. 7 | // 8 | 9 | #import "SoundPlayerIACClient.h" 10 | 11 | @implementation SoundPlayerIACClient 12 | 13 | - (instancetype)init { 14 | return [self initWithURLScheme:@"iacsoundplayer"]; 15 | } 16 | 17 | - (void)getSoundNamesWithCallback:(void(^)(NSArray *soundNames, NSError *error))callback { 18 | if (!callback) return; 19 | 20 | [self performAction:@"getSoundNames" 21 | parameters:nil 22 | onSuccess:^(NSDictionary *result) { 23 | NSString *jsonArray = result[@"names"]; 24 | NSError * __autoreleasing jserr = nil; 25 | NSArray *names = [NSJSONSerialization JSONObjectWithData:[jsonArray dataUsingEncoding:NSUTF8StringEncoding] options:0 error:&jserr]; 26 | 27 | if (!jserr) { 28 | callback(names, nil); 29 | } else { 30 | callback(nil, jserr); 31 | } 32 | } 33 | onFailure:^(NSError *error) { 34 | callback(nil, error); 35 | } 36 | ]; 37 | } 38 | 39 | - (void)playSoundWithName:(NSString*)name { 40 | [self performAction:@"play" parameters:@{@"sound": name}]; 41 | } 42 | 43 | @end 44 | -------------------------------------------------------------------------------- /AppClients/GoogleChromeIACClient.m: -------------------------------------------------------------------------------- 1 | // 2 | // ChromeIACClient.m 3 | // IACSample 4 | // 5 | // Created by Antonio Cabezuelo Vivo on 11/02/13. 6 | // Copyright (c) 2013 Antonio Cabezuelo Vivo. All rights reserved. 7 | // 8 | 9 | #import "GoogleChromeIACClient.h" 10 | 11 | @implementation GoogleChromeIACClient 12 | 13 | - (instancetype)init { 14 | return [self initWithURLScheme:@"googlechrome-x-callback"]; 15 | } 16 | 17 | - (void)openURL:(NSString*)url { 18 | [self openURL:url onSuccess:nil onFailure:nil]; 19 | } 20 | 21 | - (void)openNewTabWithURL:(NSString*)url { 22 | [self openNewTabWithURL:url onSuccess:nil onFailure:nil]; 23 | } 24 | 25 | - (void)openURL:(NSString*)url onSuccess:(void(^)(void))onSuccess onFailure:(void(^)(NSError*))onError { 26 | [self performAction:@"open" 27 | parameters:@{ @"url": url } 28 | onSuccess:^(NSDictionary* params) { 29 | if (onSuccess) { 30 | onSuccess(); 31 | } 32 | } 33 | onFailure:onError 34 | ]; 35 | 36 | } 37 | 38 | - (void)openNewTabWithURL:(NSString*)url onSuccess:(void(^)(void))onSuccess onFailure:(void(^)(NSError*))onError { 39 | [self performAction:@"open" 40 | parameters:@{ @"url": url, @"create-new-tab": @YES } 41 | onSuccess:^(NSDictionary* params) { 42 | if (onSuccess) { 43 | onSuccess(); 44 | } 45 | } 46 | onFailure:onError 47 | ]; 48 | } 49 | 50 | @end 51 | -------------------------------------------------------------------------------- /Samples/TicTacToe/TicTacToe/TTTIACClient.m: -------------------------------------------------------------------------------- 1 | // 2 | // TTTIACClient.m 3 | // TicTacToe 4 | // 5 | // Created by Antonio Cabezuelo Vivo on 15/05/14. 6 | // Copyright (c) 2014 Taps and Swipes. All rights reserved. 7 | // 8 | 9 | #import "TTTIACClient.h" 10 | 11 | NSString * const TTTShowAction = @"show"; 12 | NSString * const TTTInitGameAction = @"initGame"; 13 | NSString * const TTTSelectSpotAction = @"selectSpot"; 14 | 15 | NSString * const kOponentKey = @"oponent"; 16 | NSString * const kSpotKey = @"spot"; 17 | 18 | static NSString * const schemeA = @"iacttta"; 19 | static NSString * const schemeB = @"iactttb"; 20 | 21 | @implementation TTTIACClient 22 | 23 | + (instancetype)clientForOpponent:(NSString *)oponentSchema { 24 | if ([oponentSchema isEqualToString:schemeA]) { 25 | return [[self alloc] initClientA]; 26 | } 27 | 28 | if ([oponentSchema isEqualToString:schemeB]) { 29 | return [[self alloc] initClientB]; 30 | } 31 | 32 | return nil; 33 | } 34 | 35 | - (instancetype)initClientA { 36 | return [self initWithURLScheme:schemeA]; 37 | } 38 | 39 | - (instancetype)initClientB { 40 | return [self initWithURLScheme:schemeB]; 41 | } 42 | 43 | - (void)show { 44 | [self performAction:TTTShowAction]; 45 | } 46 | 47 | - (void)initGame { 48 | [self performAction:TTTInitGameAction parameters:@{kOponentKey:self.URLScheme == schemeA ? schemeB : schemeA}]; 49 | } 50 | 51 | - (void)selectSpot:(NSUInteger)spot { 52 | [self performAction:TTTSelectSpotAction parameters:@{kSpotKey:@(spot)}]; 53 | } 54 | 55 | @end 56 | -------------------------------------------------------------------------------- /Samples/TicTacToe/TicTacToe copy-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | ${PRODUCT_NAME} 9 | CFBundleExecutable 10 | ${EXECUTABLE_NAME} 11 | CFBundleIdentifier 12 | com.tas.${PRODUCT_NAME:rfc1034identifier} 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | ${PRODUCT_NAME} 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleURLTypes 24 | 25 | 26 | CFBundleTypeRole 27 | Editor 28 | CFBundleURLName 29 | com.tas.ttt.B 30 | CFBundleURLSchemes 31 | 32 | iactttb 33 | 34 | 35 | 36 | CFBundleVersion 37 | 1.0 38 | LSRequiresIPhoneOS 39 | 40 | UIMainStoryboardFile 41 | Main 42 | UIRequiredDeviceCapabilities 43 | 44 | armv7 45 | 46 | UIStatusBarHidden 47 | 48 | UISupportedInterfaceOrientations 49 | 50 | UIInterfaceOrientationLandscapeLeft 51 | UIInterfaceOrientationLandscapeRight 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /Samples/TicTacToe/TicTacToe/TicTacToe-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | ${PRODUCT_NAME} 9 | CFBundleExecutable 10 | ${EXECUTABLE_NAME} 11 | CFBundleIdentifier 12 | com.tas.${PRODUCT_NAME:rfc1034identifier} 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | ${PRODUCT_NAME} 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleURLTypes 24 | 25 | 26 | CFBundleTypeRole 27 | Editor 28 | CFBundleURLName 29 | com.tas.ttt.A 30 | CFBundleURLSchemes 31 | 32 | iacttta 33 | 34 | 35 | 36 | CFBundleVersion 37 | 1.0 38 | LSRequiresIPhoneOS 39 | 40 | UIMainStoryboardFile 41 | Main 42 | UIRequiredDeviceCapabilities 43 | 44 | armv7 45 | 46 | UIStatusBarHidden 47 | 48 | UISupportedInterfaceOrientations 49 | 50 | UIInterfaceOrientationLandscapeLeft 51 | UIInterfaceOrientationLandscapeRight 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /InterAppCommunication/IACManager.h: -------------------------------------------------------------------------------- 1 | // 2 | // IACManager.h 3 | // IACSample 4 | // 5 | // Created by Antonio Cabezuelo Vivo on 09/02/13. 6 | // Copyright (c) 2013 Antonio Cabezuelo Vivo. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "IACDelegate.h" 11 | 12 | @protocol IACDelegate; 13 | @class IACRequest; 14 | 15 | // Error domains that this framework will use in error callbacks 16 | extern NSString * const IACErrorDomain; 17 | extern NSString * const IACClientErrorDomain; 18 | 19 | // Predefined error codes 20 | typedef NS_ENUM(NSInteger, IACError) { 21 | IACErrorAppNotInstalled = 1, 22 | IACErrorNotSupportedAction = 2 23 | }; 24 | 25 | // Block template for action handlers 26 | typedef void(^IACActionHandlerBlock)(NSDictionary* inputParameters, IACSuccessBlock success, IACFailureBlock failure); 27 | 28 | 29 | @interface IACManager : NSObject 30 | 31 | // Delegate to be called when an x-callback-url API call is made for this app 32 | @property (weak, nonatomic) id delegate; 33 | 34 | // The URL scheme the app is listening on. It must be defined in Info.plist. If your app is not listening or do not expect callbacks you can leave this empty 35 | @property (copy, nonatomic) NSString *callbackURLScheme; 36 | 37 | 38 | + (IACManager*)sharedManager; 39 | 40 | /* Method to use in app delegate url handler methods. 41 | Handles the URL parsing and invocation of the different handlers and delegate methods. 42 | The IACManager should be initialized with the URL scheme that you want to respond to before make any call that expect callbacks. 43 | */ 44 | - (BOOL)handleOpenURL:(NSURL*)url; 45 | 46 | /* Method to add action handlers for your x-callback-url APIs 47 | */ 48 | - (void)handleAction:(NSString*)action withBlock:(IACActionHandlerBlock)handler; 49 | 50 | /* Method to send request to external apps 51 | */ 52 | - (void)sendIACRequest:(IACRequest*)request; 53 | 54 | @end 55 | -------------------------------------------------------------------------------- /Samples/Google Chrome Integration/ChromeSample/ChromeSample-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | IACChrome 9 | CFBundleExecutable 10 | ${EXECUTABLE_NAME} 11 | CFBundleIcons 12 | 13 | CFBundlePrimaryIcon 14 | 15 | CFBundleIconFiles 16 | 17 | Icon.png 18 | Icon@2x.png 19 | 20 | 21 | 22 | CFBundleIdentifier 23 | com.tapsandswipes.${PRODUCT_NAME:rfc1034identifier} 24 | CFBundleInfoDictionaryVersion 25 | 6.0 26 | CFBundleName 27 | ${PRODUCT_NAME} 28 | CFBundlePackageType 29 | APPL 30 | CFBundleShortVersionString 31 | 1.0 32 | CFBundleSignature 33 | ???? 34 | CFBundleVersion 35 | 1.0 36 | LSRequiresIPhoneOS 37 | 38 | UIRequiredDeviceCapabilities 39 | 40 | armv7 41 | 42 | UISupportedInterfaceOrientations 43 | 44 | UIInterfaceOrientationPortrait 45 | UIInterfaceOrientationLandscapeLeft 46 | UIInterfaceOrientationLandscapeRight 47 | 48 | CFBundleURLTypes 49 | 50 | 51 | CFBundleURLName 52 | com.iacmanager.sample.chrome 53 | CFBundleURLSchemes 54 | 55 | iacchromesample 56 | 57 | 58 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /Samples/API Example/SoundsPlayer/SoundsPlayer/SoundsPlayer-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | IAC Player 9 | CFBundleExecutable 10 | ${EXECUTABLE_NAME} 11 | CFBundleIcons 12 | 13 | CFBundlePrimaryIcon 14 | 15 | CFBundleIconFiles 16 | 17 | Icon.png 18 | Icon@2x.png 19 | 20 | 21 | 22 | CFBundleIdentifier 23 | com.tapsandswipes.${PRODUCT_NAME:rfc1034identifier} 24 | CFBundleInfoDictionaryVersion 25 | 6.0 26 | CFBundleName 27 | ${PRODUCT_NAME} 28 | CFBundlePackageType 29 | APPL 30 | CFBundleShortVersionString 31 | 1.0 32 | CFBundleSignature 33 | ???? 34 | CFBundleURLTypes 35 | 36 | 37 | CFBundleURLName 38 | com.iacmanager.sample.soundplayer 39 | CFBundleURLSchemes 40 | 41 | iacsoundplayer 42 | 43 | 44 | 45 | CFBundleVersion 46 | 1.0 47 | LSRequiresIPhoneOS 48 | 49 | UIRequiredDeviceCapabilities 50 | 51 | armv7 52 | 53 | UISupportedInterfaceOrientations 54 | 55 | UIInterfaceOrientationPortrait 56 | UIInterfaceOrientationLandscapeLeft 57 | UIInterfaceOrientationLandscapeRight 58 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /Samples/API Example/SoundPlayerRemote/SoundPlayerRemote/SoundPlayerRemote-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | IAC Remote 9 | CFBundleExecutable 10 | ${EXECUTABLE_NAME} 11 | CFBundleIcons 12 | 13 | CFBundlePrimaryIcon 14 | 15 | CFBundleIconFiles 16 | 17 | Icon.png 18 | Icon@2x.png 19 | 20 | 21 | 22 | CFBundleIdentifier 23 | com.tapsandswipes.${PRODUCT_NAME:rfc1034identifier} 24 | CFBundleInfoDictionaryVersion 25 | 6.0 26 | CFBundleName 27 | ${PRODUCT_NAME} 28 | CFBundlePackageType 29 | APPL 30 | CFBundleShortVersionString 31 | 1.0 32 | CFBundleSignature 33 | ???? 34 | CFBundleURLTypes 35 | 36 | 37 | CFBundleURLName 38 | com.iacmanager.sample.remote 39 | CFBundleURLSchemes 40 | 41 | iacplayerremote 42 | 43 | 44 | 45 | CFBundleVersion 46 | 1.0 47 | LSRequiresIPhoneOS 48 | 49 | UIRequiredDeviceCapabilities 50 | 51 | armv7 52 | 53 | UISupportedInterfaceOrientations 54 | 55 | UIInterfaceOrientationPortrait 56 | UIInterfaceOrientationLandscapeLeft 57 | UIInterfaceOrientationLandscapeRight 58 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /Samples/TicTacToe/Pods/InterAppCommunication/InterAppCommunication/IACManager.h: -------------------------------------------------------------------------------- 1 | // 2 | // IACManager.h 3 | // IACSample 4 | // 5 | // Created by Antonio Cabezuelo Vivo on 09/02/13. 6 | // Copyright (c) 2013 Antonio Cabezuelo Vivo. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "IACDelegate.h" 11 | 12 | @protocol IACDelegate; 13 | @class IACRequest; 14 | 15 | // Error domains that this framework will use in error callbacks 16 | extern NSString * const IACErrorDomain; 17 | extern NSString * const IACClientErrorDomain; 18 | 19 | // Predefined error codes 20 | typedef NS_ENUM(NSInteger, IACError) { 21 | IACErrorAppNotInstalled = 1, 22 | IACErrorNotSupportedAction = 2 23 | }; 24 | 25 | // Block template for action handlers 26 | typedef void(^IACActionHandlerBlock)(NSDictionary* inputParameters, IACSuccessBlock success, IACFailureBlock failure); 27 | 28 | 29 | @interface IACManager : NSObject 30 | 31 | // Delegate to be called when an x-callback-url API call is made for this app 32 | @property (weak, nonatomic) id delegate; 33 | 34 | // The URL scheme the app is listening on. It must be defined in Info.plist. If your app is not listening or do not expect callbacks you can leave this empty 35 | @property (copy, nonatomic) NSString *callbackURLScheme; 36 | 37 | 38 | + (IACManager*)sharedManager; 39 | 40 | /* Method to use in app delegate url handler methods. 41 | Handles the URL parsing and invocation of the different handlers and delegate methods. 42 | The IACManager should be initialized with the URL scheme that you want to respond to before make any call that expect callbacks. 43 | */ 44 | - (BOOL)handleOpenURL:(NSURL*)url; 45 | 46 | /* Method to add action handlers for your x-callback-url APIs 47 | */ 48 | - (void)handleAction:(NSString*)action withBlock:(IACActionHandlerBlock)handler; 49 | 50 | /* Method to send request to external apps 51 | */ 52 | - (void)sendIACRequest:(IACRequest*)request; 53 | 54 | @end 55 | -------------------------------------------------------------------------------- /Samples/API Example/SoundsPlayer/SoundsPlayer/SPViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // SPViewController.m 3 | // SoundsPlayer 4 | // 5 | // Created by Antonio Cabezuelo Vivo on 15/02/13. 6 | // Copyright (c) 2013 Antonio Cabezuelo Vivo. All rights reserved. 7 | // 8 | #import 9 | #import "SPViewController.h" 10 | 11 | @interface SPViewController () 12 | @property (strong, readwrite, nonatomic) NSArray *soundNames; 13 | @property (strong, nonatomic) AVAudioPlayer *audioPlayer; 14 | @end 15 | 16 | @implementation SPViewController 17 | 18 | - (void)viewDidLoad 19 | { 20 | [super viewDidLoad]; 21 | 22 | self.soundNames = @[ @"applause", @"bell", @"boing", @"car key"]; 23 | 24 | [self.buttons enumerateObjectsUsingBlock:^(UIButton *obj, NSUInteger idx, BOOL *stop) { 25 | if (idx < [self.soundNames count]) { 26 | [obj setTitle:self.soundNames[idx] forState:UIControlStateNormal]; 27 | } 28 | }]; 29 | } 30 | 31 | - (void)didReceiveMemoryWarning 32 | { 33 | [super didReceiveMemoryWarning]; 34 | // Dispose of any resources that can be recreated. 35 | } 36 | 37 | - (IBAction)play:(UIButton *)sender { 38 | NSUInteger idx = [self.buttons indexOfObject:sender]; 39 | 40 | if (idx < [self.soundNames count]) { 41 | [self playSoundWithName:self.soundNames[idx]]; 42 | } 43 | } 44 | 45 | - (BOOL)playSoundWithName:(NSString*)name { 46 | NSURL *url = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:name ofType:@"m4a"]]; 47 | 48 | if (url) { 49 | NSError* __autoreleasing error; 50 | self.audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:&error]; 51 | 52 | if (self.audioPlayer != nil) { 53 | [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:nil]; 54 | [[AVAudioSession sharedInstance] setActive:YES error:nil]; 55 | 56 | [self.audioPlayer prepareToPlay]; 57 | [self.audioPlayer play]; 58 | 59 | return YES; 60 | } 61 | } 62 | 63 | return NO; 64 | } 65 | 66 | @end 67 | -------------------------------------------------------------------------------- /InterAppCommunication/IACClient.h: -------------------------------------------------------------------------------- 1 | // 2 | // IACClient.h 3 | // IACSample 4 | // 5 | // Created by Antonio Cabezuelo Vivo on 09/02/13. 6 | // Copyright (c) 2013 Antonio Cabezuelo Vivo. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "IACManager.h" 11 | 12 | /* This is the class used to make calls to external apps. Use this class as a superclass to create classes for your own apps. Thjis way you can offer a clean API to your app that can meke interact with it easier for other apps. 13 | */ 14 | @interface IACClient : NSObject 15 | 16 | // URL scheme that the external app is listenig to. This is mandatory. 17 | @property (copy, nonatomic) NSString *URLScheme; 18 | 19 | // The manager to use for calls from this client. If not set, IACManager shared instance will be used. 20 | @property (weak, nonatomic) IACManager *manager; 21 | 22 | // Initializers 23 | + (instancetype)client; 24 | + (instancetype)clientWithURLScheme:(NSString*)scheme; 25 | - (instancetype)initWithURLScheme:(NSString*)scheme; 26 | 27 | /* Utility method to test if the app that responds to the URLScheme is installed in the device. 28 | */ 29 | - (BOOL)isAppInstalled; 30 | 31 | 32 | /* Method that transforms from x-callback-url errorCode parameter to a NSInteger to be used in NSError's code. 33 | The default implementation return [code integerValue]. 34 | If you create a subclass for your app and your app return string error codes you must implement this method to transform from your error codes to integer values. 35 | */ 36 | - (NSInteger)NSErrorCodeForXCUErrorCode:(NSString*)code; 37 | 38 | /* Convenient methods to make call to external apps. If you create a subclass for your app, call these methods to launch the external app. 39 | */ 40 | - (void)performAction:(NSString*)action; 41 | 42 | - (void)performAction:(NSString*)action 43 | parameters:(NSDictionary*)params; 44 | 45 | - (void)performAction:(NSString*)action 46 | parameters:(NSDictionary*)params 47 | onSuccess:(void(^)(NSDictionary*result))success 48 | onFailure:(void(^)(NSError*))failure; 49 | 50 | @end 51 | -------------------------------------------------------------------------------- /Samples/TicTacToe/Pods/InterAppCommunication/InterAppCommunication/IACClient.h: -------------------------------------------------------------------------------- 1 | // 2 | // IACClient.h 3 | // IACSample 4 | // 5 | // Created by Antonio Cabezuelo Vivo on 09/02/13. 6 | // Copyright (c) 2013 Antonio Cabezuelo Vivo. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "IACManager.h" 11 | 12 | /* This is the class used to make calls to external apps. Use this class as a superclass to create classes for your own apps. Thjis way you can offer a clean API to your app that can meke interact with it easier for other apps. 13 | */ 14 | @interface IACClient : NSObject 15 | 16 | // URL scheme that the external app is listenig to. This is mandatory. 17 | @property (copy, nonatomic) NSString *URLScheme; 18 | 19 | // The manager to use for calls from this client. If not set, IACManager shared instance will be used. 20 | @property (weak, nonatomic) IACManager *manager; 21 | 22 | // Initializers 23 | + (instancetype)client; 24 | + (instancetype)clientWithURLScheme:(NSString*)scheme; 25 | - (instancetype)initWithURLScheme:(NSString*)scheme; 26 | 27 | /* Utility method to test if the app that responds to the URLScheme is installed in the device. 28 | */ 29 | - (BOOL)isAppInstalled; 30 | 31 | 32 | /* Method that transforms from x-callback-url errorCode parameter to a NSInteger to be used in NSError's code. 33 | The default implementation return [code integerValue]. 34 | If you create a subclass for your app and your app return string error codes you must implement this method to transform from your error codes to integer values. 35 | */ 36 | - (NSInteger)NSErrorCodeForXCUErrorCode:(NSString*)code; 37 | 38 | /* Convenient methods to make call to external apps. If you create a subclass for your app, call these methods to launch the external app. 39 | */ 40 | - (void)performAction:(NSString*)action; 41 | 42 | - (void)performAction:(NSString*)action 43 | parameters:(NSDictionary*)params; 44 | 45 | - (void)performAction:(NSString*)action 46 | parameters:(NSDictionary*)params 47 | onSuccess:(void(^)(NSDictionary*result))success 48 | onFailure:(void(^)(NSError*))failure; 49 | 50 | @end 51 | -------------------------------------------------------------------------------- /InterAppCommunication/IACClient.m: -------------------------------------------------------------------------------- 1 | // 2 | // IACClient.m 3 | // IACSample 4 | // 5 | // Created by Antonio Cabezuelo Vivo on 09/02/13. 6 | // Copyright (c) 2013 Antonio Cabezuelo Vivo. All rights reserved. 7 | // 8 | 9 | #import "IACClient.h" 10 | #import "IACRequest.h" 11 | #import "IACManager.h" 12 | 13 | #if !__has_feature(objc_arc) 14 | #error InterAppComutication must be built with ARC. 15 | // You can turn on ARC for only InterAppComutication files by adding -fobjc-arc to the build phase for each of its files. 16 | #endif 17 | 18 | 19 | @implementation IACClient 20 | 21 | + (instancetype)client { 22 | return [[self alloc] init]; 23 | } 24 | 25 | + (instancetype)clientWithURLScheme:(NSString*)scheme { 26 | return [[self alloc] initWithURLScheme:scheme]; 27 | } 28 | 29 | - (instancetype)initWithURLScheme:(NSString*)scheme { 30 | self = [super init]; 31 | if (self) { 32 | self.URLScheme = scheme; 33 | } 34 | return self; 35 | } 36 | 37 | - (NSInteger)NSErrorCodeForXCUErrorCode:(NSString*)code { 38 | return [code integerValue]; 39 | } 40 | 41 | - (BOOL)isAppInstalled { 42 | return [[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@://Test", self.URLScheme]]]; 43 | } 44 | 45 | - (void)performAction:(NSString*)action { 46 | [self performAction:action parameters:nil]; 47 | } 48 | 49 | - (void)performAction:(NSString*)action parameters:(NSDictionary*)params { 50 | [self performAction:action parameters:params onSuccess:nil onFailure:nil]; 51 | } 52 | 53 | 54 | - (void)performAction:(NSString*)action parameters:(NSDictionary*)params onSuccess:(void(^)(NSDictionary*result))success onFailure:(void(^)(NSError*))failure { 55 | 56 | IACRequest *request = [[IACRequest alloc] init]; 57 | request.client = self; 58 | request.action = action; 59 | request.parameters = params; 60 | request.successCalback = success; 61 | request.errorCalback = failure; 62 | 63 | if (self.manager) { 64 | [self.manager sendIACRequest:request]; 65 | } else { 66 | [[IACManager sharedManager] sendIACRequest:request]; 67 | } 68 | } 69 | 70 | @end 71 | -------------------------------------------------------------------------------- /Samples/TicTacToe/Pods/InterAppCommunication/InterAppCommunication/IACClient.m: -------------------------------------------------------------------------------- 1 | // 2 | // IACClient.m 3 | // IACSample 4 | // 5 | // Created by Antonio Cabezuelo Vivo on 09/02/13. 6 | // Copyright (c) 2013 Antonio Cabezuelo Vivo. All rights reserved. 7 | // 8 | 9 | #import "IACClient.h" 10 | #import "IACRequest.h" 11 | #import "IACManager.h" 12 | 13 | #if !__has_feature(objc_arc) 14 | #error InterAppComutication must be built with ARC. 15 | // You can turn on ARC for only InterAppComutication files by adding -fobjc-arc to the build phase for each of its files. 16 | #endif 17 | 18 | 19 | @implementation IACClient 20 | 21 | + (instancetype)client { 22 | return [[self alloc] init]; 23 | } 24 | 25 | + (instancetype)clientWithURLScheme:(NSString*)scheme { 26 | return [[self alloc] initWithURLScheme:scheme]; 27 | } 28 | 29 | - (instancetype)initWithURLScheme:(NSString*)scheme { 30 | self = [super init]; 31 | if (self) { 32 | self.URLScheme = scheme; 33 | } 34 | return self; 35 | } 36 | 37 | - (NSInteger)NSErrorCodeForXCUErrorCode:(NSString*)code { 38 | return [code integerValue]; 39 | } 40 | 41 | - (BOOL)isAppInstalled { 42 | return [[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@://Test", self.URLScheme]]]; 43 | } 44 | 45 | - (void)performAction:(NSString*)action { 46 | [self performAction:action parameters:nil]; 47 | } 48 | 49 | - (void)performAction:(NSString*)action parameters:(NSDictionary*)params { 50 | [self performAction:action parameters:params onSuccess:nil onFailure:nil]; 51 | } 52 | 53 | 54 | - (void)performAction:(NSString*)action parameters:(NSDictionary*)params onSuccess:(void(^)(NSDictionary*result))success onFailure:(void(^)(NSError*))failure { 55 | 56 | IACRequest *request = [[IACRequest alloc] init]; 57 | request.client = self; 58 | request.action = action; 59 | request.parameters = params; 60 | request.successCalback = success; 61 | request.errorCalback = failure; 62 | 63 | if (self.manager) { 64 | [self.manager sendIACRequest:request]; 65 | } else { 66 | [[IACManager sharedManager] sendIACRequest:request]; 67 | } 68 | } 69 | 70 | @end 71 | -------------------------------------------------------------------------------- /Samples/TicTacToe/TicTacToe/TTTIntroViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // TTTViewController.m 3 | // TicTacToe 4 | // 5 | // Created by Antonio Cabezuelo Vivo on 14/05/14. 6 | // Copyright (c) 2014 Taps and Swipes. All rights reserved. 7 | // 8 | 9 | #import "TTTIntroViewController.h" 10 | #import "TTTBoardViewController.h" 11 | #import 12 | #import "TTTIACClient.h" 13 | 14 | @interface TTTIntroViewController () 15 | 16 | @end 17 | 18 | @implementation TTTIntroViewController 19 | 20 | - (void)viewDidLoad 21 | { 22 | [super viewDidLoad]; 23 | 24 | [[IACManager sharedManager] handleAction:TTTInitGameAction withBlock:^(NSDictionary *inputParameters, IACSuccessBlock success, IACFailureBlock failure) { 25 | TTTBoardViewController *controller = [self.storyboard instantiateViewControllerWithIdentifier:@"TTTBoardViewController"]; 26 | controller.gameType = GameTypeZeroPlayers; 27 | controller.remoteClient = [TTTIACClient clientForOpponent:inputParameters[kOponentKey]]; 28 | controller.modalTransitionStyle = UIModalTransitionStyleCoverVertical; 29 | 30 | if (self.presentedViewController) { 31 | [self dismissViewControllerAnimated:YES completion:^{ 32 | dispatch_async(dispatch_get_main_queue(), ^{ 33 | [self presentViewController:controller animated:YES completion:nil]; 34 | }); 35 | }]; 36 | } else { 37 | [self presentViewController:controller animated:YES completion:nil]; 38 | } 39 | }]; 40 | } 41 | 42 | - (void)didReceiveMemoryWarning 43 | { 44 | [super didReceiveMemoryWarning]; 45 | // Dispose of any resources that can be recreated. 46 | } 47 | 48 | 49 | - (BOOL)prefersStatusBarHidden { 50 | return YES; 51 | } 52 | 53 | 54 | #pragma mark - Navigation 55 | 56 | // In a storyboard-based application, you will often want to do a little preparation before navigation 57 | - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(UIButton *)sender { 58 | TTTBoardViewController *controller = (TTTBoardViewController *)[segue destinationViewController]; 59 | controller.gameType = sender.tag; 60 | } 61 | 62 | @end 63 | -------------------------------------------------------------------------------- /Samples/TicTacToe/Pods/Pods-acknowledgements.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreferenceSpecifiers 6 | 7 | 8 | FooterText 9 | This application makes use of the following third party libraries: 10 | Title 11 | Acknowledgements 12 | Type 13 | PSGroupSpecifier 14 | 15 | 16 | FooterText 17 | # License 18 | 19 | ## MIT License 20 | 21 | Copyright (c) 2013 Antonio Cabezuelo Vivo (http://tapsandswipes.com) 22 | 23 | Permission is hereby granted, free of charge, to any person obtaining a copy 24 | of this software and associated documentation files (the "Software"), to deal 25 | in the Software without restriction, including without limitation the rights 26 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 27 | copies of the Software, and to permit persons to whom the Software is 28 | furnished to do so, subject to the following conditions: 29 | 30 | The above copyright notice and this permission notice shall be included in 31 | all copies or substantial portions of the Software. 32 | 33 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 34 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 35 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 36 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 37 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 38 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 39 | THE SOFTWARE. 40 | Title 41 | InterAppCommunication 42 | Type 43 | PSGroupSpecifier 44 | 45 | 46 | FooterText 47 | Generated by CocoaPods - http://cocoapods.org 48 | Title 49 | 50 | Type 51 | PSGroupSpecifier 52 | 53 | 54 | StringsTable 55 | Acknowledgements 56 | Title 57 | Acknowledgements 58 | 59 | 60 | -------------------------------------------------------------------------------- /Samples/TicTacToe/TicTacToe/TTTAppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // TTTAppDelegate.m 3 | // TicTacToe 4 | // 5 | // Created by Antonio Cabezuelo Vivo on 14/05/14. 6 | // Copyright (c) 2014 Taps and Swipes. All rights reserved. 7 | // 8 | 9 | #import "TTTAppDelegate.h" 10 | #import 11 | 12 | @implementation TTTAppDelegate 13 | 14 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 15 | { 16 | // Override point for customization after application launch. 17 | [IACManager sharedManager].callbackURLScheme = @"iactttb"; 18 | 19 | return YES; 20 | } 21 | 22 | - (void)applicationWillResignActive:(UIApplication *)application 23 | { 24 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 25 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. 26 | } 27 | 28 | - (void)applicationDidEnterBackground:(UIApplication *)application 29 | { 30 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 31 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 32 | } 33 | 34 | - (void)applicationWillEnterForeground:(UIApplication *)application 35 | { 36 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. 37 | } 38 | 39 | - (void)applicationDidBecomeActive:(UIApplication *)application 40 | { 41 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 42 | } 43 | 44 | - (void)applicationWillTerminate:(UIApplication *)application 45 | { 46 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 47 | } 48 | 49 | 50 | - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation { 51 | 52 | return [[IACManager sharedManager] handleOpenURL:url]; 53 | } 54 | @end 55 | -------------------------------------------------------------------------------- /InterAppCommunication/NSString+IACExtensions.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSString+IACExtensions.m 3 | // IACSample 4 | // 5 | // Created by Antonio Cabezuelo Vivo on 10/02/13. 6 | // Copyright (c) 2013 Antonio Cabezuelo Vivo. All rights reserved. 7 | // 8 | 9 | #import "NSString+IACExtensions.h" 10 | 11 | #if !__has_feature(objc_arc) 12 | #error InterAppComutication must be built with ARC. 13 | // You can turn on ARC for only InterAppComutication files by adding -fobjc-arc to the build phase for each of its files. 14 | #endif 15 | 16 | 17 | @implementation NSString (IACExtensions) 18 | 19 | + (NSString*)stringWithUUID { 20 | CFUUIDRef uuid = CFUUIDCreate(kCFAllocatorDefault); 21 | NSString *uuidStr = (__bridge_transfer NSString *)CFUUIDCreateString(kCFAllocatorDefault, uuid); 22 | CFRelease(uuid); 23 | 24 | return uuidStr; 25 | } 26 | 27 | 28 | - (NSDictionary*)parseURLParams { 29 | NSMutableDictionary *result = [[NSMutableDictionary alloc] init]; 30 | 31 | NSArray *pairs = [self componentsSeparatedByString:@"&"]; 32 | 33 | [pairs enumerateObjectsUsingBlock:^(NSString *pair, NSUInteger idx, BOOL *stop) { 34 | NSArray *comps = [pair componentsSeparatedByString:@"="]; 35 | if ([comps count] == 2) { 36 | [result setObject:[comps[1] stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding] forKey:comps[0]]; 37 | } 38 | }]; 39 | 40 | return result; 41 | } 42 | 43 | - (NSString*)stringByAppendingURLParams:(NSDictionary*)params { 44 | NSMutableString *result = [[NSMutableString alloc] init]; 45 | 46 | [result appendString:self]; 47 | 48 | if ([result rangeOfString:@"?"].location != NSNotFound) { 49 | if (![result hasSuffix:@"&"]) 50 | [result appendString:@"&"]; 51 | } else { 52 | [result appendString:@"?"]; 53 | } 54 | 55 | [params enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) { 56 | NSString *escapedObj = obj; 57 | if ([obj isKindOfClass:[NSString class]]) { 58 | escapedObj = (NSString *)CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes( 59 | NULL, 60 | (__bridge CFStringRef) obj, 61 | NULL, 62 | CFSTR("!*'();:@&=+$,/?%#[]"), 63 | kCFStringEncodingUTF8)); 64 | } 65 | [result appendFormat:@"%@=%@&", key, escapedObj]; 66 | }]; 67 | 68 | return result; 69 | } 70 | 71 | @end 72 | -------------------------------------------------------------------------------- /Samples/TicTacToe/Pods/InterAppCommunication/InterAppCommunication/NSString+IACExtensions.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSString+IACExtensions.m 3 | // IACSample 4 | // 5 | // Created by Antonio Cabezuelo Vivo on 10/02/13. 6 | // Copyright (c) 2013 Antonio Cabezuelo Vivo. All rights reserved. 7 | // 8 | 9 | #import "NSString+IACExtensions.h" 10 | 11 | #if !__has_feature(objc_arc) 12 | #error InterAppComutication must be built with ARC. 13 | // You can turn on ARC for only InterAppComutication files by adding -fobjc-arc to the build phase for each of its files. 14 | #endif 15 | 16 | 17 | @implementation NSString (IACExtensions) 18 | 19 | + (NSString*)stringWithUUID { 20 | CFUUIDRef uuid = CFUUIDCreate(kCFAllocatorDefault); 21 | NSString *uuidStr = (__bridge_transfer NSString *)CFUUIDCreateString(kCFAllocatorDefault, uuid); 22 | CFRelease(uuid); 23 | 24 | return uuidStr; 25 | } 26 | 27 | 28 | - (NSDictionary*)parseURLParams { 29 | NSMutableDictionary *result = [[NSMutableDictionary alloc] init]; 30 | 31 | NSArray *pairs = [self componentsSeparatedByString:@"&"]; 32 | 33 | [pairs enumerateObjectsUsingBlock:^(NSString *pair, NSUInteger idx, BOOL *stop) { 34 | NSArray *comps = [pair componentsSeparatedByString:@"="]; 35 | if ([comps count] == 2) { 36 | [result setObject:[comps[1] stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding] forKey:comps[0]]; 37 | } 38 | }]; 39 | 40 | return result; 41 | } 42 | 43 | - (NSString*)stringByAppendingURLParams:(NSDictionary*)params { 44 | NSMutableString *result = [[NSMutableString alloc] init]; 45 | 46 | [result appendString:self]; 47 | 48 | if ([result rangeOfString:@"?"].location != NSNotFound) { 49 | if (![result hasSuffix:@"&"]) 50 | [result appendString:@"&"]; 51 | } else { 52 | [result appendString:@"?"]; 53 | } 54 | 55 | [params enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) { 56 | NSString *escapedObj = obj; 57 | if ([obj isKindOfClass:[NSString class]]) { 58 | escapedObj = (NSString *)CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes( 59 | NULL, 60 | (__bridge CFStringRef) obj, 61 | NULL, 62 | CFSTR("!*'();:@&=+$,/?%#[]"), 63 | kCFStringEncodingUTF8)); 64 | } 65 | [result appendFormat:@"%@=%@&", key, escapedObj]; 66 | }]; 67 | 68 | return result; 69 | } 70 | 71 | @end 72 | -------------------------------------------------------------------------------- /Samples/API Example/SoundsPlayer/SoundsPlayer/SPAppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // SPAppDelegate.m 3 | // SoundsPlayer 4 | // 5 | // Created by Antonio Cabezuelo Vivo on 15/02/13. 6 | // Copyright (c) 2013 Antonio Cabezuelo Vivo. All rights reserved. 7 | // 8 | 9 | #import "SPAppDelegate.h" 10 | #import "SPViewController.h" 11 | #import "IACManager.h" 12 | 13 | @implementation SPAppDelegate 14 | 15 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 16 | { 17 | self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; 18 | // Override point for customization after application launch. 19 | self.viewController = [[SPViewController alloc] initWithNibName:@"SPViewController" bundle:nil]; 20 | self.window.rootViewController = self.viewController; 21 | [self.window makeKeyAndVisible]; 22 | 23 | [IACManager sharedManager].callbackURLScheme = @"iacsoundplayer"; 24 | [self addAPIHandlers]; 25 | 26 | return YES; 27 | } 28 | 29 | - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation { 30 | return [[IACManager sharedManager] handleOpenURL:url]; 31 | } 32 | 33 | - (void)addAPIHandlers { 34 | [[IACManager sharedManager] handleAction:@"getSoundNames" 35 | withBlock:^(NSDictionary *inputParameters, IACSuccessBlock success, IACFailureBlock failure) { 36 | if (success) { 37 | NSError * __autoreleasing jserr = nil; 38 | NSString *json = [[NSString alloc] initWithData:[NSJSONSerialization dataWithJSONObject:self.viewController.soundNames options:0 error:&jserr] encoding:NSUTF8StringEncoding]; 39 | 40 | success(@{@"names": json}, NO); 41 | } 42 | }]; 43 | 44 | [[IACManager sharedManager] handleAction:@"play" 45 | withBlock:^(NSDictionary *inputParameters, IACSuccessBlock success, IACFailureBlock failure) { 46 | BOOL played = [self.viewController playSoundWithName:inputParameters[@"sound"]]; 47 | if (played) { 48 | if (success) { 49 | success(nil, NO); 50 | } 51 | } else { 52 | if (failure) { 53 | NSError *error = [NSError errorWithDomain:@"com.iac.soundplayer.error.domain" code:-1 userInfo:@{NSLocalizedDescriptionKey: @"Sound not found"}]; 54 | failure(error); 55 | } 56 | } 57 | }]; 58 | } 59 | @end 60 | -------------------------------------------------------------------------------- /Samples/API Example/SoundPlayerRemote/SoundPlayerRemote/SRViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // SRViewController.m 3 | // SoundPlayerRemote 4 | // 5 | // Created by Antonio Cabezuelo Vivo on 15/02/13. 6 | // Copyright (c) 2013 Antonio Cabezuelo Vivo. All rights reserved. 7 | // 8 | 9 | #import "SRViewController.h" 10 | #import "SoundPlayerIACClient.h" 11 | 12 | @interface SRViewController () 13 | @property (strong, nonatomic) NSArray *soundNames; 14 | @property (strong, nonatomic) SoundPlayerIACClient *client; 15 | @end 16 | 17 | @implementation SRViewController 18 | 19 | - (void)viewDidLoad 20 | { 21 | [super viewDidLoad]; 22 | // Do any additional setup after loading the view, typically from a nib. 23 | self.client = [SoundPlayerIACClient client]; 24 | 25 | [self.getButton setTitle:@"Install Player please." forState:UIControlStateDisabled]; 26 | self.tableView.hidden = YES; 27 | self.getButton.hidden = NO; 28 | 29 | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(refresh) name:UIApplicationWillEnterForegroundNotification object:nil]; 30 | } 31 | 32 | - (void)didReceiveMemoryWarning 33 | { 34 | [super didReceiveMemoryWarning]; 35 | // Dispose of any resources that can be recreated. 36 | } 37 | 38 | - (void)viewDidUnload { 39 | [[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationWillEnterForegroundNotification object:nil]; 40 | [self setGetButton:nil]; 41 | [self setTableView:nil]; 42 | [super viewDidUnload]; 43 | } 44 | 45 | - (void)viewWillAppear:(BOOL)animated { 46 | [super viewWillAppear:animated]; 47 | 48 | [self refresh]; 49 | } 50 | 51 | - (void)refresh { 52 | self.getButton.enabled = [self.client isAppInstalled]; 53 | } 54 | 55 | - (IBAction)getSounds:(UIButton *)sender { 56 | [self.client getSoundNamesWithCallback:^(NSArray *soundNames, NSError *error) { 57 | if (error) { 58 | UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Player error" message:[error localizedDescription] delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil]; 59 | [alert show]; 60 | } else { 61 | self.tableView.hidden = NO; 62 | self.getButton.hidden = YES; 63 | 64 | self.soundNames = soundNames; 65 | [self.tableView reloadData]; 66 | } 67 | }]; 68 | } 69 | 70 | #pragma mark - UITableView 71 | 72 | - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { 73 | return 1; 74 | } 75 | 76 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 77 | return [self.soundNames count]; 78 | } 79 | 80 | - (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ 81 | static NSString * const cellID = @"Cell"; 82 | 83 | UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellID]; 84 | if (!cell) { 85 | cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellID]; 86 | } 87 | 88 | cell.textLabel.text = self.soundNames[indexPath.row]; 89 | 90 | return cell; 91 | } 92 | 93 | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { 94 | [tableView deselectRowAtIndexPath:indexPath animated:YES]; 95 | [self.client playSoundWithName:self.soundNames[indexPath.row]]; 96 | } 97 | 98 | @end 99 | -------------------------------------------------------------------------------- /Samples/TicTacToe/Pods/Pods-resources.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | RESOURCES_TO_COPY=${PODS_ROOT}/resources-to-copy-${TARGETNAME}.txt 5 | > "$RESOURCES_TO_COPY" 6 | 7 | install_resource() 8 | { 9 | case $1 in 10 | *.storyboard) 11 | echo "ibtool --reference-external-strings-file --errors --warnings --notices --output-format human-readable-text --compile ${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$1\" .storyboard`.storyboardc ${PODS_ROOT}/$1 --sdk ${SDKROOT}" 12 | ibtool --reference-external-strings-file --errors --warnings --notices --output-format human-readable-text --compile "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$1\" .storyboard`.storyboardc" "${PODS_ROOT}/$1" --sdk "${SDKROOT}" 13 | ;; 14 | *.xib) 15 | echo "ibtool --reference-external-strings-file --errors --warnings --notices --output-format human-readable-text --compile ${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$1\" .xib`.nib ${PODS_ROOT}/$1 --sdk ${SDKROOT}" 16 | ibtool --reference-external-strings-file --errors --warnings --notices --output-format human-readable-text --compile "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$1\" .xib`.nib" "${PODS_ROOT}/$1" --sdk "${SDKROOT}" 17 | ;; 18 | *.framework) 19 | echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 20 | mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 21 | echo "rsync -av ${PODS_ROOT}/$1 ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 22 | rsync -av "${PODS_ROOT}/$1" "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 23 | ;; 24 | *.xcdatamodel) 25 | echo "xcrun momc \"${PODS_ROOT}/$1\" \"${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$1"`.mom\"" 26 | xcrun momc "${PODS_ROOT}/$1" "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$1" .xcdatamodel`.mom" 27 | ;; 28 | *.xcdatamodeld) 29 | echo "xcrun momc \"${PODS_ROOT}/$1\" \"${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$1" .xcdatamodeld`.momd\"" 30 | xcrun momc "${PODS_ROOT}/$1" "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$1" .xcdatamodeld`.momd" 31 | ;; 32 | *.xcassets) 33 | ;; 34 | /*) 35 | echo "$1" 36 | echo "$1" >> "$RESOURCES_TO_COPY" 37 | ;; 38 | *) 39 | echo "${PODS_ROOT}/$1" 40 | echo "${PODS_ROOT}/$1" >> "$RESOURCES_TO_COPY" 41 | ;; 42 | esac 43 | } 44 | 45 | rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 46 | if [[ "${ACTION}" == "install" ]]; then 47 | rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 48 | fi 49 | rm -f "$RESOURCES_TO_COPY" 50 | 51 | if [[ -n "${WRAPPER_EXTENSION}" ]] && [ `xcrun --find actool` ] && [ `find . -name '*.xcassets' | wc -l` -ne 0 ] 52 | then 53 | case "${TARGETED_DEVICE_FAMILY}" in 54 | 1,2) 55 | TARGET_DEVICE_ARGS="--target-device ipad --target-device iphone" 56 | ;; 57 | 1) 58 | TARGET_DEVICE_ARGS="--target-device iphone" 59 | ;; 60 | 2) 61 | TARGET_DEVICE_ARGS="--target-device ipad" 62 | ;; 63 | *) 64 | TARGET_DEVICE_ARGS="--target-device mac" 65 | ;; 66 | esac 67 | find "${PWD}" -name "*.xcassets" -print0 | xargs -0 actool --output-format human-readable-text --notices --warnings --platform "${PLATFORM_NAME}" --minimum-deployment-target "${IPHONEOS_DEPLOYMENT_TARGET}" ${TARGET_DEVICE_ARGS} --compress-pngs --compile "${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 68 | fi 69 | -------------------------------------------------------------------------------- /Samples/Google Chrome Integration/ChromeSample/CSViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // CSViewController.m 3 | // ChromeSample 4 | // 5 | // Created by Antonio Cabezuelo Vivo on 13/02/13. 6 | // Copyright (c) 2013 Antonio Cabezuelo Vivo. All rights reserved. 7 | // 8 | 9 | #import "CSViewController.h" 10 | #import "GoogleChromeIACClient.h" 11 | 12 | @interface CSViewController () 13 | 14 | @end 15 | 16 | @implementation CSViewController { 17 | GoogleChromeIACClient *chromeClient; 18 | } 19 | 20 | - (void)viewDidLoad 21 | { 22 | [super viewDidLoad]; 23 | 24 | self.urlField.text = @"http://tapsandswipes.com"; 25 | [self openURLString:self.urlField.text]; 26 | 27 | chromeClient = [GoogleChromeIACClient client]; 28 | } 29 | 30 | - (void)didReceiveMemoryWarning 31 | { 32 | [super didReceiveMemoryWarning]; 33 | } 34 | 35 | - (void)viewWillAppear:(BOOL)animated { 36 | [super viewWillAppear:animated]; 37 | 38 | if (![chromeClient isAppInstalled]) { 39 | self.openButton.title = @"Install chrome"; 40 | } 41 | } 42 | 43 | - (IBAction)openInChrome:(id)sender { 44 | 45 | if ([chromeClient isAppInstalled]) { 46 | [chromeClient openURL:self.urlField.text 47 | onSuccess:^{ 48 | UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Success" 49 | message:@"Back from Chrome" 50 | delegate:nil 51 | cancelButtonTitle:@"OK" 52 | otherButtonTitles:nil]; 53 | [alert show]; 54 | } 55 | onFailure:^(NSError *error) { 56 | UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Error" 57 | message:[error localizedDescription] 58 | delegate:nil 59 | cancelButtonTitle:@"OK" 60 | otherButtonTitles:nil]; 61 | [alert show]; 62 | }]; 63 | } else { 64 | if (NSClassFromString(@"SKStoreProductViewController")) { 65 | self.openButton.enabled = NO; 66 | SKStoreProductViewController *controller = [[SKStoreProductViewController alloc] init]; 67 | controller.delegate = self; 68 | [controller loadProductWithParameters:@{SKStoreProductParameterITunesItemIdentifier: @"535886823"} completionBlock:^(BOOL result, NSError *error){ 69 | if (result) { 70 | [self presentModalViewController:controller animated:YES]; 71 | } else { 72 | self.openButton.enabled = YES; 73 | } 74 | }]; 75 | } else { 76 | [[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"itms-apps://ax.itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=535886823"]]; 77 | } 78 | } 79 | } 80 | 81 | - (void)openURLString:(NSString*)url { 82 | [self.webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:url]]]; 83 | } 84 | 85 | - (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType { 86 | if ([[request.URL scheme] hasPrefix:@"http"]) { 87 | self.urlField.text = [request.URL absoluteString]; 88 | } 89 | return YES; 90 | } 91 | 92 | 93 | - (BOOL)textFieldShouldReturn:(UITextField *)textField { 94 | [self openURLString:self.urlField.text]; 95 | [textField resignFirstResponder]; 96 | return YES; 97 | } 98 | 99 | - (void)productViewControllerDidFinish:(SKStoreProductViewController *)viewController { 100 | [self dismissModalViewControllerAnimated:YES]; 101 | self.openButton.enabled = YES; 102 | } 103 | @end 104 | -------------------------------------------------------------------------------- /Samples/Google Chrome Integration/ChromeSample/en.lproj/CSViewController.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | -------------------------------------------------------------------------------- /Samples/TicTacToe/TicTacToe/DMGridModel.m: -------------------------------------------------------------------------------- 1 | // 2 | // DMGridModel.m 3 | // tictactoe 4 | // 5 | // Created by Dennis Wilkins on 5/26/12. 6 | // Copyright (c) 2012 Delicious Morsel LLC. All rights reserved. 7 | // 8 | 9 | #import "DMGridModel.h" 10 | 11 | @implementation DMGridModel 12 | 13 | - (id)init { 14 | return [self initWithSize:3]; 15 | } 16 | 17 | - (id)initWithSize:(NSUInteger) gridSize { 18 | self = [super init]; 19 | self.size = gridSize; 20 | NSUInteger fullSize = gridSize * gridSize; 21 | self.grid = [NSMutableArray arrayWithCapacity:fullSize]; 22 | for (int i = 0; i < fullSize; i++) { 23 | [self.grid insertObject:@(PlayerNone) atIndex:i]; 24 | } 25 | [self createSolvables]; 26 | 27 | return self; 28 | } 29 | 30 | - (void)resetGrid { 31 | for (int i = 0; i < [self.grid count]; i++) { 32 | [self.grid replaceObjectAtIndex:i withObject:@(PlayerNone)]; 33 | } 34 | } 35 | 36 | - (BOOL)setPlayer:(DMPlayer)player atGridLocation:(NSUInteger)location { 37 | NSNumber *playerInSpace = [self.grid objectAtIndex:location]; 38 | if ([playerInSpace isEqualToNumber:@(PlayerNone)]) { 39 | [self.grid replaceObjectAtIndex:location withObject:@(player)]; 40 | return YES; 41 | } 42 | return NO; 43 | } 44 | 45 | - (DMPlayer)playerAtGridIndex:(NSUInteger)idx { 46 | if (idx >= [self.grid count]) { 47 | return PlayerNone; 48 | } 49 | 50 | return [self.grid[idx] unsignedIntegerValue]; 51 | } 52 | 53 | 54 | - (void)createSolvables { 55 | NSUInteger solveSize = self.size * 2 + 2; 56 | self.solves = [NSMutableArray arrayWithCapacity:solveSize]; 57 | NSUInteger y; 58 | NSUInteger x; 59 | NSMutableArray *innerSolve; // solveable 60 | for(x=0; x < solveSize; x++) { // init them all up 61 | [self.solves addObject: [NSMutableArray arrayWithCapacity:self.size]]; // pre init hte size, cause we know it. 62 | } 63 | for(x = 0; x < self.size; x++) { 64 | for(y = 0; y < self.size; y++) { 65 | 66 | innerSolve = [self.solves objectAtIndex:x];// X axis solves 67 | [innerSolve addObject: @((x * self.size) + y)]; 68 | 69 | innerSolve = [self.solves objectAtIndex: self.size + y];// Y axis solves 70 | [innerSolve addObject: @((x * self.size) + y)]; 71 | 72 | if (x == y) { 73 | innerSolve = [self.solves objectAtIndex: self.size * 2]; // top left going down diagnoally 74 | [innerSolve addObject: @((x * self.size) + y)]; 75 | } 76 | 77 | if ((x + y) == (self.size - 1)) { 78 | innerSolve = [self.solves objectAtIndex: self.size * 2 + 1]; // top right 79 | [innerSolve addObject: @(x * self.size + y)]; 80 | } 81 | } 82 | } 83 | } 84 | 85 | - (DMPlayer)getWinner { 86 | NSUInteger i; 87 | NSUInteger j; 88 | NSMutableArray *solve; 89 | NSNumber *location; 90 | DMPlayer player; 91 | DMPlayer gridPlayer; 92 | NSNumber *gridLocationPlayer; 93 | for(i = 0; i < [self.solves count]; i++) { 94 | solve = [self.solves objectAtIndex:i]; 95 | player = PlayerNone; 96 | for(j = 0; j < [solve count]; j++) { 97 | location = [solve objectAtIndex:j]; 98 | gridLocationPlayer = [self.grid objectAtIndex: [location unsignedIntValue]]; 99 | gridPlayer = [gridLocationPlayer unsignedIntegerValue]; 100 | if (gridPlayer == PlayerNone) { 101 | player = PlayerNone; 102 | break; 103 | } 104 | if (player > PlayerNone && player != gridPlayer) { 105 | player = PlayerNone; 106 | break; 107 | } else { 108 | player = gridPlayer; 109 | } 110 | } 111 | 112 | if (player > PlayerNone) { 113 | return player; 114 | } 115 | } 116 | /// check if its draw, or still in progress 117 | for (i = 0; i < [self.grid count]; i++) { 118 | if ([[self.grid objectAtIndex: i] unsignedIntegerValue] == PlayerNone) { 119 | return PlayerNone; // PlayerNone = in progress 120 | } 121 | } 122 | return PlayerDraw; 123 | } 124 | 125 | - (NSInteger)getNextOpenSpot { 126 | NSUInteger i = 0; 127 | NSUInteger c = [self.grid count]; 128 | for (i = 0; i < c; i++) { 129 | if ([self playerAtGridIndex:i] == PlayerNone) { 130 | return i; 131 | } 132 | } 133 | return -1; 134 | } 135 | 136 | - (void)dealloc { 137 | self.grid = nil; 138 | self.size = 0; 139 | self.solves = nil; 140 | } 141 | 142 | - (BOOL)gridIsEmpty { 143 | BOOL empty = YES; 144 | 145 | for (int i = 0; i < [self.grid count]; i++) { 146 | if ([self playerAtGridIndex:i] != PlayerNone) { 147 | empty = NO; 148 | break; 149 | } 150 | } 151 | 152 | return empty; 153 | } 154 | 155 | - (NSUInteger)randomMove { 156 | sleep(2); 157 | return 2; 158 | 159 | NSUInteger move = arc4random_uniform((u_int32_t)self.grid.count); 160 | 161 | if ([self playerAtGridIndex:move] != PlayerNone) { 162 | move = [self randomMove]; 163 | } 164 | 165 | return move; 166 | } 167 | 168 | + (NSArray *)getBestMoveForPlayer:(DMPlayer)player inGrid:(DMGridModel *)gridModel depth:(NSInteger)depth { 169 | NSUInteger i; 170 | NSUInteger gridCount = [gridModel.grid count]; 171 | NSUInteger gridHuge = gridCount * gridCount; 172 | 173 | NSInteger bestMove = NSNotFound; 174 | NSInteger bestScore = (player == PlayerA ? -gridHuge : gridHuge); 175 | NSUInteger move; 176 | NSInteger score; 177 | DMPlayer winner; 178 | NSArray *results; 179 | DMPlayer playerAtGridLocation; 180 | 181 | if ([gridModel gridIsEmpty]) { 182 | return @[@([gridModel randomMove]), @(bestScore)]; 183 | } 184 | 185 | for (i = 0; i < gridCount; i++) { 186 | playerAtGridLocation = [gridModel.grid[i] unsignedIntegerValue]; 187 | if (playerAtGridLocation == PlayerNone) { // no one in there. 188 | [gridModel.grid replaceObjectAtIndex:i withObject:@(player)]; // replace 189 | winner = [gridModel getWinner]; 190 | if (winner > PlayerNone) { 191 | score = (player == PlayerA ? depth * -1 : depth); 192 | move = i; 193 | } else { 194 | results = [self getBestMoveForPlayer:(player == PlayerA ? PlayerB : PlayerA) 195 | inGrid:gridModel 196 | depth:depth + 1]; 197 | move = [results[0] unsignedIntegerValue]; 198 | score = [results[1] unsignedIntegerValue]; 199 | } 200 | if (player == PlayerA ? score > bestScore : score < bestScore) { 201 | bestScore = score; 202 | bestMove = move; 203 | } 204 | 205 | [gridModel.grid replaceObjectAtIndex:i withObject:@(playerAtGridLocation)]; // replace 206 | } 207 | 208 | } 209 | return @[@(bestMove) , @(bestScore)]; 210 | 211 | } 212 | 213 | @end 214 | -------------------------------------------------------------------------------- /Samples/TicTacToe/TicTacToe/TTTBoardViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // TTTBoardViewController.m 3 | // TicTacToe 4 | // 5 | // Created by Antonio Cabezuelo Vivo on 14/05/14. 6 | // Copyright (c) 2014 Taps and Swipes. All rights reserved. 7 | // 8 | 9 | #import "TTTBoardViewController.h" 10 | #import "DMGridModel.h" 11 | #import "TTTIACClient.h" 12 | #import 13 | 14 | @interface TTTBoardViewController () 15 | 16 | @property (strong, nonatomic) IBOutletCollection(UIButton) NSArray *buttons; 17 | @property (nonatomic) DMPlayer currentPlayer; 18 | @property (strong, nonatomic) DMGridModel *gridModel; 19 | @property (nonatomic, getter = isMaster) BOOL master; 20 | @property (nonatomic) NSUInteger drawsCount; 21 | 22 | @end 23 | 24 | @implementation TTTBoardViewController 25 | 26 | - (void)viewDidLoad { 27 | [super viewDidLoad]; 28 | 29 | self.gridModel = [[DMGridModel alloc] initWithSize:3]; 30 | self.currentPlayer = PlayerA; 31 | 32 | [[IACManager sharedManager] handleAction:TTTSelectSpotAction withBlock:^(NSDictionary *inputParameters, IACSuccessBlock success, IACFailureBlock failure) { 33 | NSInteger spot = [inputParameters[kSpotKey] integerValue]; 34 | [self playerMovedToSpot:spot]; 35 | }]; 36 | } 37 | 38 | - (void)didReceiveMemoryWarning { 39 | [super didReceiveMemoryWarning]; 40 | // Dispose of any resources that can be recreated. 41 | } 42 | 43 | - (BOOL)prefersStatusBarHidden { 44 | return YES; 45 | } 46 | 47 | - (void)viewDidAppear:(BOOL)animated { 48 | if (self.gameType == GameTypeZeroPlayers) { 49 | if (!self.remoteClient) { 50 | [IACManager sharedManager].callbackURLScheme = @"iacttta"; 51 | self.master = YES; 52 | 53 | self.remoteClient = [[TTTIACClient alloc] initClientB]; 54 | [self.remoteClient initGame]; 55 | self.currentPlayer = PlayerB; 56 | [self startComputerTurn]; 57 | } else { 58 | self.master = NO; 59 | [self.remoteClient show]; 60 | } 61 | } 62 | } 63 | 64 | - (IBAction)buttonAction:(UIButton *)sender { 65 | if (self.gameType != GameTypeZeroPlayers) { 66 | if (self.gameType == GameTypeOnePlayer && self.currentPlayer == PlayerB) { 67 | return; 68 | } 69 | 70 | [self playerMovedToSpot:sender.tag]; 71 | } 72 | } 73 | 74 | - (IBAction)resetAction:(UIButton *)sender { 75 | [self resetGame]; 76 | 77 | } 78 | 79 | - (IBAction)backAction:(id)sender { 80 | [self.presentingViewController dismissViewControllerAnimated:YES completion:nil]; 81 | } 82 | 83 | - (void)playerMovedToSpot:(NSUInteger)spot { 84 | [self.gridModel setPlayer:self.currentPlayer atGridLocation:spot]; 85 | [self updateGridView]; 86 | [self endPlayerTurn]; 87 | } 88 | 89 | - (void)updateGridView { 90 | [self.buttons enumerateObjectsUsingBlock:^(UIButton *button, NSUInteger idx, BOOL *stop) { 91 | DMPlayer player = [self.gridModel playerAtGridIndex:idx]; 92 | UIImage *image = nil; 93 | 94 | if (player != PlayerNone) { 95 | if (self.gameType == GameTypeZeroPlayers && !self.isMaster) { 96 | image = (player == PlayerA ? [UIImage imageNamed:@"X"] : [UIImage imageNamed:@"O"]); 97 | } else { 98 | image = (player == PlayerA ? [UIImage imageNamed:@"O"] : [UIImage imageNamed:@"X"]); 99 | } 100 | } 101 | 102 | [button setImage:[image imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal] forState:UIControlStateNormal]; 103 | }]; 104 | } 105 | 106 | - (void)resetGame { 107 | [self.gridModel resetGrid]; 108 | self.currentPlayer = PlayerA; 109 | [self updateGridView]; 110 | 111 | if (self.gameType == GameTypeZeroPlayers) { 112 | if (self.isMaster) { 113 | [self.remoteClient initGame]; 114 | self.currentPlayer = PlayerB; 115 | [self startComputerTurn]; 116 | } 117 | } 118 | } 119 | 120 | - (void)endPlayerTurn { 121 | DMPlayer winner = [self.gridModel getWinner]; 122 | if (winner != PlayerNone) { // game is over 123 | self.currentPlayer = PlayerNone; // no ones turn. 124 | if (winner == PlayerDraw && self.gameType == GameTypeZeroPlayers && self.isMaster) { 125 | self.drawsCount++; 126 | if (self.drawsCount < 2) { 127 | [self performSelector:@selector(resetGame) withObject:nil afterDelay:1]; 128 | } else { 129 | [self apocalypseNow]; 130 | } 131 | } else { 132 | // [self resetGame]; 133 | } 134 | } else { 135 | if (self.gameType == GameTypeZeroPlayers) { 136 | [self performSelector:@selector(nextPlayerTurn) withObject:nil afterDelay:1.0]; 137 | } else { 138 | [self nextPlayerTurn]; 139 | } 140 | } 141 | 142 | } 143 | 144 | - (void)nextPlayerTurn { 145 | if (self.currentPlayer == PlayerA) { 146 | self.currentPlayer = PlayerB; 147 | if (self.gameType != GameTypeTwoPlayers) { 148 | [self startComputerTurn]; 149 | } 150 | } else { 151 | self.currentPlayer = PlayerA; 152 | } 153 | } 154 | 155 | - (void)startComputerTurn { 156 | dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{ 157 | NSArray *result = [DMGridModel getBestMoveForPlayer:PlayerB inGrid:self.gridModel depth:0]; 158 | NSInteger bestMove = [result[0] integerValue]; 159 | if (bestMove == NSNotFound) { 160 | bestMove = [self.gridModel getNextOpenSpot]; 161 | } 162 | dispatch_sync(dispatch_get_main_queue(), ^{ 163 | [self.gridModel setPlayer:PlayerB atGridLocation:bestMove]; 164 | [self updateGridView]; 165 | [self endPlayerTurn]; 166 | if (self.currentPlayer != PlayerNone) { 167 | if (self.gameType == GameTypeZeroPlayers) { 168 | dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ 169 | [self.remoteClient selectSpot:bestMove]; 170 | }); 171 | } 172 | } 173 | }); 174 | }); 175 | } 176 | 177 | - (void)apocalypseNow { 178 | UIImage *apocalypseAnimation = [UIImage animatedImageNamed:@"apocalypse" duration:2]; 179 | UIImageView *apocalypseView = [[UIImageView alloc] initWithImage:apocalypseAnimation]; 180 | apocalypseView.frame = CGRectMake(125.0, 18.0, 311.0, 233.0); 181 | [self.view addSubview:apocalypseView]; 182 | [apocalypseView startAnimating]; 183 | } 184 | 185 | /* 186 | #pragma mark - Navigation 187 | 188 | // In a storyboard-based application, you will often want to do a little preparation before navigation 189 | - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { 190 | // Get the new view controller using [segue destinationViewController]. 191 | // Pass the selected object to the new view controller. 192 | } 193 | */ 194 | 195 | @end 196 | -------------------------------------------------------------------------------- /Samples/TicTacToe/Pods/InterAppCommunication/README.markdown: -------------------------------------------------------------------------------- 1 | # Inter-App Communication 2 | 3 | ## x-callback-url made easy 4 | 5 | Inter-App Communication, **IAC** from now on, is a framework that allows your iOS app to communicate, very easily, with other iOS apps installed in the device that supports the [**x-callback-url**](http://x-callback-url.com/) protocol. With **IAC** you can also add an **x-callback-url** **API** to your app in a very easy and intuitive way. 6 | 7 | **IAC** currently supports the **x-callback-url** [1.0 DRAFT specification](http://x-callback-url.com/specifications/). 8 | 9 | 10 | ## Usage 11 | 12 | ### Call external app 13 | 14 | From anywhere in your app you can call any external app on the device with the following code 15 | 16 | ```objective-c 17 | #import "IACClient.h" 18 | 19 | IACClient *client = [IACClient clientWithURLScheme:@"appscheme"]; 20 | [client performAction@"action" parameters:@{@"param1": value1, @"param2": value2}]; 21 | ``` 22 | 23 | 24 | You can also use, if available, client subclasses for the app you are calling. Within the framework there are clients for Instapaper and Google Chrome and many more will be added in the future. 25 | 26 | For example, to add a url to Instapaper from your app, you can do: 27 | 28 | * Without specific client class: 29 | 30 | ```objective-c 31 | #import "IACClient.h" 32 | 33 | IACClient *client = [IACClient clientWithURLScheme:@"x-callback-instapaper"]; 34 | [client performAction@"add" parameters:@{@"url": @"http://tapsandswipes.com"}]; 35 | ``` 36 | 37 | * With the client class specific for Instapaper: 38 | 39 | ```objective-c 40 | #import "InstapaperIACClient.h" 41 | 42 | [[InstapaperIACClient client] add:@"http://tapsandswipes.com"]; 43 | ``` 44 | 45 | 46 | ### Receive callbacks from the external app 47 | 48 | If you want to be called back from the external app you can specify success and failure handler blocks, for example: 49 | 50 | ```objective-c 51 | IACClient *client = [IACClient clientWithURLScheme:@"appscheme"]; 52 | [client performAction:@"action" 53 | parameters:@{@"param1": value1, @"param2": value2} 54 | onSuccess:^(NSDictionary *resultParams){ 55 | NSLog(@"The app response was: %@", resultParams) 56 | } 57 | onFailure:^(NSError *error){ 58 | NSLog(@"ERROR: %@", [error localizedDescription]); 59 | } 60 | ]; 61 | ``` 62 | 63 | 64 | For the callbacks to work, your app must support the **x-callback-url** protocol. The easiest way is to let **IAC** manage that. 65 | 66 | ### Add x-callback-url support to your app 67 | 68 | Follow these simple steps to add **x-callback-url** support to your app: 69 | 70 | 1. Define the url scheme that your app will respond to in the `Info.plist` of your app. See the section **Implementing Custom URL Schemes** in [this article](http://developer.apple.com/library/ios/#DOCUMENTATION/iPhone/Conceptual/iPhoneOSProgrammingGuide/AdvancedAppTricks/AdvancedAppTricks.html#//apple_ref/doc/uid/TP40007072-CH7-SW50). 71 | 72 | 2. Assign this scheme to the IACManager instance with `[IACManager sharedManager].calbackURLScheme = @"myappscheme";`. I recommend doing this in the delegate method `-application:didFinishLaunchingWithOptions:` 73 | 74 | 3. Call `-handleOpenURL:` from the URL handling method in the app`s delegate. For example: 75 | 76 | ```objective-c 77 | - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url 78 | sourceApplication:(NSString *)sourceApplication annotation:(id)annotation { 79 | 80 | return [[IACManager sharedManager] handleOpenURL:url]; 81 | } 82 | ``` 83 | 84 | With these three steps your app will be available to call other apps and receive callbacks from them. 85 | 86 | ### Add an x-callback-url API to your app 87 | 88 | If you want to add an external **API** to your app through the **x-callback-url** protocol you can use any of these two options or both: 89 | 90 | - Add handler blocks for your actions directly to the `IACManager` instance calling `-handleAction:withBlock:` for each action. 91 | 92 | - Implement the `IACDelegate` protocol in any of your classes and assign the delegate to the `IACManager` instance, preferably in the app delegate `-application:didFinishLaunchingWithOptions:` method. 93 | 94 | Action handlers take precedence over the delegate for the same action. 95 | 96 | Explore the sample code to see all of these in place. 97 | 98 | 99 | 100 | ## Installation 101 | 102 | #### Via CocoaPods 103 | 104 | The easiest way to install **IAC** is via [CocoaPods](http://cocoapods.org). Add this line to your Podfile: 105 | 106 | ```sh 107 | pod 'InterAppCommunication' 108 | ``` 109 | 110 | and run `pod install`. 111 | 112 | #### Manual 113 | 114 | You can also install it manually by copying to your project the contents of the directory `InterAppCommunication`. 115 | 116 | Within the directory `AppClients` you can find clients for some apps, copy the files for the client you want to use to your project. 117 | 118 | 119 | ### Requirements 120 | 121 | * **IAC** uses ARC but it may be used with non-ARC projects by setting the: ` -fobjc-arc ` compiler flag on all ` IAC*.m ` files. You can set this flag under Target -> Build Phases -> Compile Sources 122 | * Requires iOS 5.0+ and Xcode 4.3+. 123 | 124 | 125 | 126 | ## Create an IAC client class for your app 127 | 128 | If you have an app that already have an x-callback-url API, you can help other apps to communicate with your app by creating an `IACClient` subclass and share these classes with them. 129 | 130 | This way you can implement the exposed API as if the app where an internal component within the caller app. You can implement the methods with the required parameters and even make some validation before the call is made. 131 | 132 | Inside the `AppClients` directory you can find all the client subclasses currently implemented. If you have implemented one for your own app, do not hesitate to contact me and I will add it to the repository. 133 | 134 | 135 | 136 | ## Contact 137 | 138 | - [Personal website](http://tapsandswipes.com) 139 | - [GitHub](http://github.com/tapsandswipes) 140 | - [Twitter](http://twitter.com/acvivo) 141 | - [LinkedIn](http://www.linkedin.com/in/acvivo) 142 | - [Email](mailto:antonio@tapsandswipes.com) 143 | 144 | If you use/enjoy Inter-app Communication framework, let me know! 145 | 146 | 147 | 148 | ## License 149 | 150 | ### MIT License 151 | 152 | Copyright (c) 2013 Antonio Cabezuelo Vivo (http://tapsandswipes.com) 153 | 154 | Permission is hereby granted, free of charge, to any person obtaining a copy 155 | of this software and associated documentation files (the "Software"), to deal 156 | in the Software without restriction, including without limitation the rights 157 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 158 | copies of the Software, and to permit persons to whom the Software is 159 | furnished to do so, subject to the following conditions: 160 | 161 | The above copyright notice and this permission notice shall be included in 162 | all copies or substantial portions of the Software. 163 | 164 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 165 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 166 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 167 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 168 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 169 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 170 | THE SOFTWARE. -------------------------------------------------------------------------------- /README.markdown: -------------------------------------------------------------------------------- 1 | # Inter-App Communication (Objective-C) 2 | 3 | ## x-callback-url made easy 4 | 5 | Inter-App Communication, **IAC** from now on, is a framework that allows your iOS app to communicate, very easily, with other iOS apps installed in the device that supports the [**x-callback-url**](http://x-callback-url.com/) protocol. With **IAC** you can also add an **x-callback-url** **API** to your app in a very easy and intuitive way. 6 | 7 | **IAC** currently supports the **x-callback-url** [1.0 DRAFT specification](http://x-callback-url.com/specifications/). 8 | 9 | The swift version is available [here](https://github.com/tapsandswipes/Inter-AppCommunication.git) 10 | 11 | ## Usage 12 | 13 | ### Call external app 14 | 15 | From anywhere in your app you can call any external app on the device with the following code 16 | 17 | ```objective-c 18 | #import "IACClient.h" 19 | 20 | IACClient *client = [IACClient clientWithURLScheme:@"appscheme"]; 21 | [client performAction@"action" parameters:@{@"param1": value1, @"param2": value2}]; 22 | ``` 23 | 24 | 25 | You can also use, if available, client subclasses for the app you are calling. Within the framework there are clients for Instapaper and Google Chrome and many more will be added in the future. 26 | 27 | For example, to add a url to Instapaper from your app, you can do: 28 | 29 | * Without specific client class: 30 | 31 | ```objective-c 32 | #import "IACClient.h" 33 | 34 | IACClient *client = [IACClient clientWithURLScheme:@"x-callback-instapaper"]; 35 | [client performAction@"add" parameters:@{@"url": @"http://tapsandswipes.com"}]; 36 | ``` 37 | 38 | * With the client class specific for Instapaper: 39 | 40 | ```objective-c 41 | #import "InstapaperIACClient.h" 42 | 43 | [[InstapaperIACClient client] add:@"http://tapsandswipes.com"]; 44 | ``` 45 | 46 | 47 | ### Receive callbacks from the external app 48 | 49 | If you want to be called back from the external app you can specify success and failure handler blocks, for example: 50 | 51 | ```objective-c 52 | IACClient *client = [IACClient clientWithURLScheme:@"appscheme"]; 53 | [client performAction:@"action" 54 | parameters:@{@"param1": value1, @"param2": value2} 55 | onSuccess:^(NSDictionary *resultParams){ 56 | NSLog(@"The app response was: %@", resultParams) 57 | } 58 | onFailure:^(NSError *error){ 59 | NSLog(@"ERROR: %@", [error localizedDescription]); 60 | } 61 | ]; 62 | ``` 63 | 64 | 65 | For the callbacks to work, your app must support the **x-callback-url** protocol. The easiest way is to let **IAC** manage that. 66 | 67 | ### Add x-callback-url support to your app 68 | 69 | Follow these simple steps to add **x-callback-url** support to your app: 70 | 71 | 1. Define the url scheme that your app will respond to in the `Info.plist` of your app. See the section **Register Your URL Scheme** in [this article](https://developer.apple.com/documentation/uikit/core_app/allowing_apps_and_websites_to_link_to_your_content/defining_a_custom_url_scheme_for_your_app). 72 | 73 | 2. Assign this scheme to the IACManager instance with `[IACManager sharedManager].callbackURLScheme = @"myappscheme";`. I recommend doing this in the delegate method `-application:didFinishLaunchingWithOptions:` 74 | 75 | 3. Call `-handleOpenURL:` from the URL handling method in the app`s delegate. For example: 76 | 77 | ```objective-c 78 | - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url 79 | sourceApplication:(NSString *)sourceApplication annotation:(id)annotation { 80 | 81 | return [[IACManager sharedManager] handleOpenURL:url]; 82 | } 83 | ``` 84 | 85 | With these three steps your app will be available to call other apps and receive callbacks from them. 86 | 87 | ### Add an x-callback-url API to your app 88 | 89 | If you want to add an external **API** to your app through the **x-callback-url** protocol you can use any of these two options or both: 90 | 91 | - Add handler blocks for your actions directly to the `IACManager` instance calling `-handleAction:withBlock:` for each action. 92 | 93 | - Implement the `IACDelegate` protocol in any of your classes and assign the delegate to the `IACManager` instance, preferably in the app delegate `-application:didFinishLaunchingWithOptions:` method. 94 | 95 | Action handlers take precedence over the delegate for the same action. 96 | 97 | Explore the sample code to see all of these in place. 98 | 99 | 100 | 101 | ## Installation 102 | 103 | #### Via CocoaPods 104 | 105 | The easiest way to install **IAC** is via [CocoaPods](http://cocoapods.org). Add this line to your Podfile: 106 | 107 | ```sh 108 | pod 'InterAppCommunication' 109 | ``` 110 | 111 | and run `pod install`. 112 | 113 | #### Manual 114 | 115 | You can also install it manually by copying to your project the contents of the directory `InterAppCommunication`. 116 | 117 | Within the directory `AppClients` you can find clients for some apps, copy the files for the client you want to use to your project. 118 | 119 | 120 | ### Requirements 121 | 122 | * **IAC** uses ARC but it may be used with non-ARC projects by setting the: ` -fobjc-arc ` compiler flag on all ` IAC*.m ` files. You can set this flag under Target -> Build Phases -> Compile Sources 123 | * Requires iOS 5.0+ and Xcode 4.3+. 124 | 125 | 126 | 127 | ## Create an IAC client class for your app 128 | 129 | If you have an app that already have an x-callback-url API, you can help other apps to communicate with your app by creating an `IACClient` subclass and share these classes with them. 130 | 131 | This way you can implement the exposed API as if the app were an internal component within the caller app. You can implement the methods with the required parameters and even make some validation before the call is made. 132 | 133 | Inside the `AppClients` directory you can find all the client subclasses currently implemented. If you have implemented one for your own app, do not hesitate to contact me and I will add it to the repository. 134 | 135 | 136 | 137 | ## Contact 138 | 139 | - [Personal website](http://tapsandswipes.com) 140 | - [GitHub](http://github.com/tapsandswipes) 141 | - [Twitter](http://twitter.com/acvivo) 142 | - [LinkedIn](http://www.linkedin.com/in/acvivo) 143 | - [Email](mailto:antonio@tapsandswipes.com) 144 | 145 | If you use/enjoy Inter-app Communication framework, let me know! 146 | 147 | 148 | 149 | ## License 150 | 151 | ### MIT License 152 | 153 | Copyright (c) 2013 Antonio Cabezuelo Vivo (http://tapsandswipes.com) 154 | 155 | Permission is hereby granted, free of charge, to any person obtaining a copy 156 | of this software and associated documentation files (the "Software"), to deal 157 | in the Software without restriction, including without limitation the rights 158 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 159 | copies of the Software, and to permit persons to whom the Software is 160 | furnished to do so, subject to the following conditions: 161 | 162 | The above copyright notice and this permission notice shall be included in 163 | all copies or substantial portions of the Software. 164 | 165 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 166 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 167 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 168 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 169 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 170 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 171 | THE SOFTWARE. 172 | -------------------------------------------------------------------------------- /InterAppCommunication/IACManager.m: -------------------------------------------------------------------------------- 1 | // 2 | // IACManager.m 3 | // IACSample 4 | // 5 | // Created by Antonio Cabezuelo Vivo on 09/02/13. 6 | // Copyright (c) 2013 Antonio Cabezuelo Vivo. All rights reserved. 7 | // 8 | 9 | #import "IACManager.h" 10 | #import "IACDelegate.h" 11 | #import "IACClient.h" 12 | #import "IACRequest.h" 13 | #import "NSString+IACExtensions.h" 14 | 15 | 16 | #if !__has_feature(objc_arc) 17 | #error InterAppComutication must be built with ARC. 18 | // You can turn on ARC for only InterAppComutication files by adding -fobjc-arc to the build phase for each of its files. 19 | #endif 20 | 21 | 22 | NSString * const IACErrorDomain = @"com.iac.manager.error"; 23 | NSString * const IACClientErrorDomain = @"com.iac.client.error"; 24 | 25 | // x-callback-url strings 26 | static NSString * const kXCUPrefix = @"x-"; 27 | static NSString * const kXCUHost = @"x-callback-url"; 28 | static NSString * const kXCUSource = @"x-source"; 29 | static NSString * const kXCUSuccess = @"x-success"; 30 | static NSString * const kXCUError = @"x-error"; 31 | static NSString * const kXCUCancel = @"x-cancel"; 32 | static NSString * const kXCUErrorCode = @"error-Code"; 33 | static NSString * const kXCUErrorMessage = @"errorMessage"; 34 | 35 | // IAC strings 36 | static NSString * const kIACPrefix = @"IAC"; 37 | static NSString * const kIACResponse = @"IACRequestResponse"; 38 | static NSString * const kIACRequest = @"IACRequestID"; 39 | static NSString * const kIACResponseType = @"IACResponseType"; 40 | static NSString * const kIACErrorDomain = @"errorDomain"; 41 | 42 | typedef NS_ENUM(NSUInteger, IACResponseType) { 43 | IACResponseTypeSuccess, 44 | IACResponseTypeFailure, 45 | IACResponseTypeCancel 46 | }; 47 | 48 | 49 | @implementation IACManager { 50 | NSMutableDictionary *sessions; 51 | NSMutableDictionary *actions; 52 | } 53 | 54 | + (IACManager*)sharedManager { 55 | static IACManager *sharedManager = nil; 56 | static dispatch_once_t onceToken; 57 | dispatch_once(&onceToken, ^{ 58 | sharedManager = [[self alloc] init]; 59 | }); 60 | 61 | return sharedManager; 62 | } 63 | 64 | - (instancetype)init { 65 | self = [super init]; 66 | if (self) { 67 | sessions = [NSMutableDictionary dictionary]; 68 | actions = [NSMutableDictionary dictionary]; 69 | } 70 | return self; 71 | } 72 | 73 | - (BOOL)handleOpenURL:(NSURL*)url { 74 | // An app can respond to multiple url schemes and the app can use different IACManagers for each one 75 | // so we test if the url is handled by this manager 76 | if (![url.scheme isEqualToString:self.callbackURLScheme]) { 77 | return NO; 78 | } 79 | 80 | // If the url is an x-callback-url compatible url we handle it 81 | if ([url.host isEqualToString:kXCUHost]) { 82 | NSString *action = [[url path] substringFromIndex:1]; 83 | NSDictionary *parameters = [url.query parseURLParams]; 84 | NSDictionary *actionParamters = [self removeProtocolParamsFromDictionary:parameters]; 85 | 86 | 87 | // Lets see if this is a response to a previous call 88 | if ([action isEqualToString:kIACResponse]) { 89 | NSString *requestID = parameters[kIACRequest]; 90 | 91 | IACRequest *request = sessions[requestID]; 92 | if (request) { 93 | IACResponseType responseType = [parameters[kIACResponseType] intValue]; 94 | 95 | switch (responseType) { 96 | case IACResponseTypeSuccess: 97 | if (request.successCalback) { 98 | request.successCalback(actionParamters); 99 | } 100 | break; 101 | 102 | case IACResponseTypeFailure: 103 | if (request.errorCalback) { 104 | NSInteger errorCode = [request.client NSErrorCodeForXCUErrorCode:parameters[kXCUErrorCode]]; 105 | NSString *errorDomain = parameters[kIACErrorDomain] ? parameters[kIACErrorDomain] : IACClientErrorDomain; 106 | NSError *error = [NSError errorWithDomain:errorDomain 107 | code:errorCode 108 | userInfo:@{NSLocalizedDescriptionKey: parameters[kXCUErrorMessage]}]; 109 | 110 | request.errorCalback(error); 111 | } 112 | break; 113 | 114 | case IACResponseTypeCancel: 115 | if (request.successCalback) { 116 | request.successCalback(nil); 117 | } 118 | break; 119 | 120 | default: 121 | [sessions removeObjectForKey:requestID]; 122 | return NO; 123 | break; 124 | } 125 | 126 | [sessions removeObjectForKey:requestID]; 127 | return YES; 128 | } 129 | 130 | return NO; 131 | } 132 | 133 | // Lets see if there is somebody that handles this action 134 | if (actions[action] || [self.delegate supportsIACAction:action]) { 135 | 136 | IACSuccessBlock success = ^(NSDictionary *returnParams, BOOL cancelled) { 137 | if (cancelled) { 138 | if (parameters[kXCUCancel]) { 139 | [[UIApplication sharedApplication] openURL:[NSURL URLWithString:parameters[kXCUCancel]]]; 140 | } 141 | } else if (parameters[kXCUSuccess]) { 142 | [[UIApplication sharedApplication] openURL:[NSURL URLWithString:[parameters[kXCUSuccess] stringByAppendingURLParams:returnParams]]]; 143 | } 144 | }; 145 | 146 | IACFailureBlock failure = ^(NSError *error) { 147 | if (parameters[kXCUError]) { 148 | NSDictionary *errorParams = @{ kXCUErrorCode: @([error code]), 149 | kXCUErrorMessage: [error localizedDescription], 150 | kIACErrorDomain: [error domain] 151 | }; 152 | [[UIApplication sharedApplication] openURL:[NSURL URLWithString:[parameters[kXCUError] stringByAppendingURLParams:errorParams]]]; 153 | } 154 | }; 155 | 156 | // Handlers take precedence over the delegate 157 | if (actions[action]) { 158 | IACActionHandlerBlock actionHandler = actions[action]; 159 | actionHandler(actionParamters, success, failure); 160 | return YES; 161 | 162 | } else if ([self.delegate supportsIACAction:action]) { 163 | [self.delegate performIACAction:action 164 | parameters:actionParamters 165 | onSuccess:success 166 | onFailure:failure]; 167 | 168 | return YES; 169 | } 170 | } else { 171 | if (parameters[kXCUError]) { 172 | NSDictionary *errorParams = @{ kXCUErrorCode: @(IACErrorNotSupportedAction), 173 | kXCUErrorMessage: [NSString stringWithFormat:NSLocalizedString(@"'%@' is not an x-callback-url action supported by %@", nil), action, [self localizedAppName]], 174 | kIACErrorDomain: IACErrorDomain 175 | }; 176 | [[UIApplication sharedApplication] openURL:[NSURL URLWithString:[parameters[kXCUError] stringByAppendingURLParams:errorParams]]]; 177 | return YES; 178 | } 179 | } 180 | } 181 | 182 | 183 | return NO; 184 | } 185 | 186 | - (void)sendIACRequest:(IACRequest*)request { 187 | 188 | if (![request.client isAppInstalled]) { 189 | if (request.errorCalback) { 190 | NSError *error = [NSError errorWithDomain:IACErrorDomain 191 | code:IACErrorAppNotInstalled 192 | userInfo:@{NSLocalizedDescriptionKey:[NSString stringWithFormat:NSLocalizedString(@"App with scheme '%@' is not installed in this device", nil), request.client.URLScheme]}]; 193 | request.errorCalback(error); 194 | } 195 | return; 196 | } 197 | 198 | NSString *final_url = [NSString stringWithFormat:@"%@://%@/%@?", request.client.URLScheme, kXCUHost, request.action]; 199 | final_url = [final_url stringByAppendingURLParams:request.parameters]; 200 | final_url = [final_url stringByAppendingURLParams:@{kXCUSource: [self localizedAppName]}]; 201 | 202 | if (self.callbackURLScheme) { 203 | NSString *xcu = [NSString stringWithFormat:@"%@://%@/%@?", self.callbackURLScheme, kXCUHost, kIACResponse]; 204 | xcu = [xcu stringByAppendingURLParams:@{kIACRequest:request.requestID}]; 205 | 206 | NSMutableDictionary *xcu_params = [NSMutableDictionary dictionary]; 207 | 208 | if (request.successCalback) { 209 | xcu_params[kXCUSuccess] = [xcu stringByAppendingURLParams:@{kIACResponseType:@(IACResponseTypeSuccess)}]; 210 | xcu_params[kXCUCancel] = [xcu stringByAppendingURLParams:@{kIACResponseType:@(IACResponseTypeCancel)}]; 211 | } 212 | 213 | if (request.errorCalback) { 214 | xcu_params[kXCUError] = [xcu stringByAppendingURLParams:@{kIACResponseType:@(IACResponseTypeFailure)}]; 215 | } 216 | 217 | final_url = [final_url stringByAppendingURLParams:xcu_params]; 218 | } else if (request.successCalback || request.errorCalback) { 219 | NSLog(@"WARNING: If you want to support callbacks from the remote app you must define a URL Scheme for this app to listen on"); 220 | } 221 | 222 | sessions[request.requestID] = request; 223 | 224 | [[UIApplication sharedApplication] openURL:[NSURL URLWithString:final_url]]; 225 | } 226 | 227 | 228 | - (void)handleAction:(NSString*)action withBlock:(IACActionHandlerBlock)handler { 229 | actions[action] = [handler copy]; 230 | } 231 | 232 | 233 | - (NSDictionary*)removeProtocolParamsFromDictionary:(NSDictionary*)dictionary { 234 | NSMutableDictionary *result = [NSMutableDictionary dictionary]; 235 | 236 | // Removes all x-callback-url and all IAC parameters 237 | [dictionary enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) { 238 | if (![key hasPrefix:kXCUPrefix] && ![key hasPrefix:kIACPrefix]) { 239 | [result setObject:obj forKey:key]; 240 | } 241 | }]; 242 | 243 | // Adds x-source parameter as this is needed to inform the user 244 | if (dictionary[kXCUSource]) { 245 | result[kXCUSource] = dictionary[kXCUSource]; 246 | } 247 | 248 | return result; 249 | } 250 | 251 | - (NSString*)localizedAppName { 252 | NSString *appname = [[NSBundle mainBundle] localizedInfoDictionary][@"CFBundleDisplayName"]; 253 | if (!appname) { 254 | appname = [[NSBundle mainBundle] infoDictionary][@"CFBundleDisplayName"]; 255 | } 256 | 257 | return appname; 258 | } 259 | 260 | @end 261 | -------------------------------------------------------------------------------- /Samples/TicTacToe/Pods/InterAppCommunication/InterAppCommunication/IACManager.m: -------------------------------------------------------------------------------- 1 | // 2 | // IACManager.m 3 | // IACSample 4 | // 5 | // Created by Antonio Cabezuelo Vivo on 09/02/13. 6 | // Copyright (c) 2013 Antonio Cabezuelo Vivo. All rights reserved. 7 | // 8 | 9 | #import "IACManager.h" 10 | #import "IACDelegate.h" 11 | #import "IACClient.h" 12 | #import "IACRequest.h" 13 | #import "NSString+IACExtensions.h" 14 | 15 | 16 | #if !__has_feature(objc_arc) 17 | #error InterAppComutication must be built with ARC. 18 | // You can turn on ARC for only InterAppComutication files by adding -fobjc-arc to the build phase for each of its files. 19 | #endif 20 | 21 | 22 | NSString * const IACErrorDomain = @"com.iac.manager.error"; 23 | NSString * const IACClientErrorDomain = @"com.iac.client.error"; 24 | 25 | // x-callback-url strings 26 | static NSString * const kXCUPrefix = @"x-"; 27 | static NSString * const kXCUHost = @"x-callback-url"; 28 | static NSString * const kXCUSource = @"x-source"; 29 | static NSString * const kXCUSuccess = @"x-success"; 30 | static NSString * const kXCUError = @"x-error"; 31 | static NSString * const kXCUCancel = @"x-cancel"; 32 | static NSString * const kXCUErrorCode = @"error-Code"; 33 | static NSString * const kXCUErrorMessage = @"errorMessage"; 34 | 35 | // IAC strings 36 | static NSString * const kIACPrefix = @"IAC"; 37 | static NSString * const kIACResponse = @"IACRequestResponse"; 38 | static NSString * const kIACRequest = @"IACRequestID"; 39 | static NSString * const kIACResponseType = @"IACResponseType"; 40 | static NSString * const kIACErrorDomain = @"errorDomain"; 41 | 42 | typedef NS_ENUM(NSUInteger, IACResponseType) { 43 | IACResponseTypeSuccess, 44 | IACResponseTypeFailure, 45 | IACResponseTypeCancel 46 | }; 47 | 48 | 49 | @implementation IACManager { 50 | NSMutableDictionary *sessions; 51 | NSMutableDictionary *actions; 52 | } 53 | 54 | + (IACManager*)sharedManager { 55 | static IACManager *sharedManager = nil; 56 | static dispatch_once_t onceToken; 57 | dispatch_once(&onceToken, ^{ 58 | sharedManager = [[self alloc] init]; 59 | }); 60 | 61 | return sharedManager; 62 | } 63 | 64 | - (instancetype)init { 65 | self = [super init]; 66 | if (self) { 67 | sessions = [NSMutableDictionary dictionary]; 68 | actions = [NSMutableDictionary dictionary]; 69 | } 70 | return self; 71 | } 72 | 73 | - (BOOL)handleOpenURL:(NSURL*)url { 74 | // An app can respond to multiple url schemes and the app can use different IACManagers for each one 75 | // so we test if the url is handled by this manager 76 | if (![url.scheme isEqualToString:self.callbackURLScheme]) { 77 | return NO; 78 | } 79 | 80 | // If the url is an x-callback-url compatible url we handle it 81 | if ([url.host isEqualToString:kXCUHost]) { 82 | NSString *action = [[url path] substringFromIndex:1]; 83 | NSDictionary *parameters = [url.query parseURLParams]; 84 | NSDictionary *actionParamters = [self removeProtocolParamsFromDictionary:parameters]; 85 | 86 | 87 | // Lets see if this is a response to a previous call 88 | if ([action isEqualToString:kIACResponse]) { 89 | NSString *requestID = parameters[kIACRequest]; 90 | 91 | IACRequest *request = sessions[requestID]; 92 | if (request) { 93 | IACResponseType responseType = [parameters[kIACResponseType] intValue]; 94 | 95 | switch (responseType) { 96 | case IACResponseTypeSuccess: 97 | if (request.successCalback) { 98 | request.successCalback(actionParamters); 99 | } 100 | break; 101 | 102 | case IACResponseTypeFailure: 103 | if (request.errorCalback) { 104 | NSInteger errorCode = [request.client NSErrorCodeForXCUErrorCode:parameters[kXCUErrorCode]]; 105 | NSString *errorDomain = parameters[kIACErrorDomain] ? parameters[kIACErrorDomain] : IACClientErrorDomain; 106 | NSError *error = [NSError errorWithDomain:errorDomain 107 | code:errorCode 108 | userInfo:@{NSLocalizedDescriptionKey: parameters[kXCUErrorMessage]}]; 109 | 110 | request.errorCalback(error); 111 | } 112 | break; 113 | 114 | case IACResponseTypeCancel: 115 | if (request.successCalback) { 116 | request.successCalback(nil); 117 | } 118 | break; 119 | 120 | default: 121 | [sessions removeObjectForKey:requestID]; 122 | return NO; 123 | break; 124 | } 125 | 126 | [sessions removeObjectForKey:requestID]; 127 | return YES; 128 | } 129 | 130 | return NO; 131 | } 132 | 133 | // Lets see if there is somebody that handles this action 134 | if (actions[action] || [self.delegate supportsIACAction:action]) { 135 | 136 | IACSuccessBlock success = ^(NSDictionary *returnParams, BOOL cancelled) { 137 | if (cancelled) { 138 | if (parameters[kXCUCancel]) { 139 | [[UIApplication sharedApplication] openURL:[NSURL URLWithString:parameters[kXCUCancel]]]; 140 | } 141 | } else if (parameters[kXCUSuccess]) { 142 | [[UIApplication sharedApplication] openURL:[NSURL URLWithString:[parameters[kXCUSuccess] stringByAppendingURLParams:returnParams]]]; 143 | } 144 | }; 145 | 146 | IACFailureBlock failure = ^(NSError *error) { 147 | if (parameters[kXCUError]) { 148 | NSDictionary *errorParams = @{ kXCUErrorCode: @([error code]), 149 | kXCUErrorMessage: [error localizedDescription], 150 | kIACErrorDomain: [error domain] 151 | }; 152 | [[UIApplication sharedApplication] openURL:[NSURL URLWithString:[parameters[kXCUError] stringByAppendingURLParams:errorParams]]]; 153 | } 154 | }; 155 | 156 | // Handlers take precedence over the delegate 157 | if (actions[action]) { 158 | IACActionHandlerBlock actionHandler = actions[action]; 159 | actionHandler(actionParamters, success, failure); 160 | return YES; 161 | 162 | } else if ([self.delegate supportsIACAction:action]) { 163 | [self.delegate performIACAction:action 164 | parameters:actionParamters 165 | onSuccess:success 166 | onFailure:failure]; 167 | 168 | return YES; 169 | } 170 | } else { 171 | if (parameters[kXCUError]) { 172 | NSDictionary *errorParams = @{ kXCUErrorCode: @(IACErrorNotSupportedAction), 173 | kXCUErrorMessage: [NSString stringWithFormat:NSLocalizedString(@"'%@' is not an x-callback-url action supported by %@", nil), action, [self localizedAppName]], 174 | kIACErrorDomain: IACErrorDomain 175 | }; 176 | [[UIApplication sharedApplication] openURL:[NSURL URLWithString:[parameters[kXCUError] stringByAppendingURLParams:errorParams]]]; 177 | return YES; 178 | } 179 | } 180 | } 181 | 182 | 183 | return NO; 184 | } 185 | 186 | - (void)sendIACRequest:(IACRequest*)request { 187 | 188 | if (![request.client isAppInstalled]) { 189 | if (request.errorCalback) { 190 | NSError *error = [NSError errorWithDomain:IACErrorDomain 191 | code:IACErrorAppNotInstalled 192 | userInfo:@{NSLocalizedDescriptionKey:[NSString stringWithFormat:NSLocalizedString(@"App with scheme '%@' is not installed in this device", nil), request.client.URLScheme]}]; 193 | request.errorCalback(error); 194 | } 195 | return; 196 | } 197 | 198 | NSString *final_url = [NSString stringWithFormat:@"%@://%@/%@?", request.client.URLScheme, kXCUHost, request.action]; 199 | final_url = [final_url stringByAppendingURLParams:request.parameters]; 200 | final_url = [final_url stringByAppendingURLParams:@{kXCUSource: [self localizedAppName]}]; 201 | 202 | if (self.callbackURLScheme) { 203 | NSString *xcu = [NSString stringWithFormat:@"%@://%@/%@?", self.callbackURLScheme, kXCUHost, kIACResponse]; 204 | xcu = [xcu stringByAppendingURLParams:@{kIACRequest:request.requestID}]; 205 | 206 | NSMutableDictionary *xcu_params = [NSMutableDictionary dictionary]; 207 | 208 | if (request.successCalback) { 209 | xcu_params[kXCUSuccess] = [xcu stringByAppendingURLParams:@{kIACResponseType:@(IACResponseTypeSuccess)}]; 210 | xcu_params[kXCUCancel] = [xcu stringByAppendingURLParams:@{kIACResponseType:@(IACResponseTypeCancel)}]; 211 | } 212 | 213 | if (request.errorCalback) { 214 | xcu_params[kXCUError] = [xcu stringByAppendingURLParams:@{kIACResponseType:@(IACResponseTypeFailure)}]; 215 | } 216 | 217 | final_url = [final_url stringByAppendingURLParams:xcu_params]; 218 | } else if (request.successCalback || request.errorCalback) { 219 | NSLog(@"WARNING: If you want to support callbacks from the remote app you must define a URL Scheme for this app to listen on"); 220 | } 221 | 222 | sessions[request.requestID] = request; 223 | 224 | [[UIApplication sharedApplication] openURL:[NSURL URLWithString:final_url]]; 225 | } 226 | 227 | 228 | - (void)handleAction:(NSString*)action withBlock:(IACActionHandlerBlock)handler { 229 | actions[action] = [handler copy]; 230 | } 231 | 232 | 233 | - (NSDictionary*)removeProtocolParamsFromDictionary:(NSDictionary*)dictionary { 234 | NSMutableDictionary *result = [NSMutableDictionary dictionary]; 235 | 236 | // Removes all x-callback-url and all IAC parameters 237 | [dictionary enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) { 238 | if (![key hasPrefix:kXCUPrefix] && ![key hasPrefix:kIACPrefix]) { 239 | [result setObject:obj forKey:key]; 240 | } 241 | }]; 242 | 243 | // Adds x-source parameter as this is needed to inform the user 244 | if (dictionary[kXCUSource]) { 245 | result[kXCUSource] = dictionary[kXCUSource]; 246 | } 247 | 248 | return result; 249 | } 250 | 251 | - (NSString*)localizedAppName { 252 | NSString *appname = [[NSBundle mainBundle] localizedInfoDictionary][@"CFBundleDisplayName"]; 253 | if (!appname) { 254 | appname = [[NSBundle mainBundle] infoDictionary][@"CFBundleDisplayName"]; 255 | } 256 | 257 | return appname; 258 | } 259 | 260 | @end 261 | -------------------------------------------------------------------------------- /Samples/TicTacToe/tictactoe.js: -------------------------------------------------------------------------------- 1 | var turn = -1; 2 | var xWon = 0; 3 | var oWon = 0; 4 | var catsGame = 0; 5 | var cells; 6 | function makeCells(){ 7 | var b = document.board; 8 | cells = new Array(b.c1,b.c2,b.c3,b.c4,b.c5,b.c6,b.c7,b.c8,b.c9) 9 | } 10 | 11 | function loadStats(){ 12 | var cookie = getCookie('tictactoeStats'); 13 | if (cookie != null && cookie.length > 1){ 14 | var stats = cookie.substring(1,cookie.length); 15 | if (stats != null){ 16 | var statsSplit = stats.split(':'); 17 | var temp; 18 | if (statsSplit.length == 3){ 19 | var re = new RegExp("^([0-9]*)$"); 20 | if (re.test(statsSplit[0])) xWon = eval(statsSplit[0]); 21 | if (re.test(statsSplit[1])) oWon = eval(statsSplit[1]); 22 | if (re.test(statsSplit[2])) catsGame = eval(statsSplit[2]); 23 | drawStats(); 24 | } 25 | } 26 | } 27 | } 28 | 29 | function nextTurn(){ 30 | turn = -turn; 31 | if (turn == 1){ 32 | if(document.board.p1.selectedIndex == 1) beginnerMove(); 33 | if(document.board.p1.selectedIndex == 2) intermediateMove(); 34 | if(document.board.p1.selectedIndex == 3) experiencedMove(); 35 | if(document.board.p1.selectedIndex == 4) perfectMove(); 36 | } else { 37 | if(document.board.p2.selectedIndex == 1) beginnerMove(); 38 | if(document.board.p2.selectedIndex == 2) intermediateMove(); 39 | if(document.board.p2.selectedIndex == 3) experiencedMove(); 40 | if(document.board.p2.selectedIndex == 4) perfectMove(); 41 | } 42 | } 43 | 44 | function getLegalMoves(state){ 45 | var moves = 0; 46 | for (var i=0; i<9; i++){ 47 | if ((state & (1<<(i*2+1))) == 0){ 48 | moves |= 1 << i; 49 | } 50 | } 51 | return moves; 52 | } 53 | 54 | function moveRandom(moves){ 55 | var numMoves = 0; 56 | for (var i=0; i<9; i++){ 57 | if ((moves & (1< 0){ 60 | var moveNum = Math.ceil(Math.random()*numMoves); 61 | numMoves = 0; 62 | for (var j=0; j<9; j++){ 63 | if ((moves & (1< hope){ 99 | hope = value; 100 | goodMoves = 0; 101 | } 102 | if (hope == value){ 103 | goodMoves |= (1< hope){ 132 | hope = value; 133 | } 134 | } 135 | } 136 | } 137 | return hope; 138 | } 139 | 140 | function detectWinMove(state, cellNum, nextTurn){ 141 | var value = 0x3; 142 | if (nextTurn == -1) value = 0x2; 143 | var newState = state | (value << cellNum*2); 144 | return detectWin(newState); 145 | } 146 | 147 | function beginnerMove(){ 148 | var state = getState(); 149 | var winner = detectWin(state); 150 | if (winner == 0) moveRandom(getLegalMoves(state)); 151 | } 152 | 153 | function getGoodMove(state){ 154 | var moves = getLegalMoves(state); 155 | for (var i=0; i<9; i++){ 156 | if ((moves & (1< 1){ 336 | if (turn == 1) oWon++; 337 | else xWon++; 338 | drawStats(); 339 | } 340 | drawState(0); 341 | if (document.board.firstMove[0].checked=='1'){ 342 | turn = -1; 343 | } else { 344 | turn = 1; 345 | } 346 | nextTurn(); 347 | } 348 | 349 | function getCookie(name) { 350 | var prefix = name + "="; 351 | var begin = document.cookie.indexOf("; " + prefix); 352 | if (begin == -1) { 353 | begin = document.cookie.indexOf(prefix); 354 | if (begin != 0) return null; 355 | } else 356 | begin += 2; 357 | var end = document.cookie.indexOf(";", begin); 358 | if (end == -1) 359 | end = document.cookie.length; 360 | return unescape(document.cookie.substring(begin + prefix.length, end)); 361 | } 362 | -------------------------------------------------------------------------------- /Samples/API Example/SoundPlayerRemote/SoundPlayerRemote/en.lproj/SRViewController.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 1552 5 | 12C60 6 | 3084 7 | 1187.34 8 | 625.00 9 | 10 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 11 | 2083 12 | 13 | 14 | IBProxyObject 15 | IBUIButton 16 | IBUILabel 17 | IBUITableView 18 | IBUIView 19 | 20 | 21 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 22 | 23 | 24 | PluginDependencyRecalculationVersion 25 | 26 | 27 | 28 | 29 | IBFilesOwner 30 | IBCocoaTouchFramework 31 | 32 | 33 | IBFirstResponder 34 | IBCocoaTouchFramework 35 | 36 | 37 | 38 | 274 39 | 40 | 41 | 42 | 274 43 | {{0, 60}, {320, 488}} 44 | 45 | 46 | 47 | _NS:9 48 | 49 | 3 50 | MQA 51 | 52 | YES 53 | IBCocoaTouchFramework 54 | YES 55 | 1 56 | 0 57 | YES 58 | 44 59 | 22 60 | 22 61 | 62 | 63 | 64 | 292 65 | {{20, 228}, {280, 44}} 66 | 67 | 68 | 69 | _NS:9 70 | NO 71 | IBCocoaTouchFramework 72 | 0 73 | 0 74 | 1 75 | Get sounds from Player app 76 | 77 | 78 | 1 79 | MC4xOTYwNzg0MzQ2IDAuMzA5ODAzOTMyOSAwLjUyMTU2ODY1NgA 80 | 81 | 82 | 3 83 | MC41AA 84 | 85 | 86 | 2 87 | 15 88 | 89 | 90 | Helvetica-Bold 91 | 15 92 | 16 93 | 94 | 95 | 96 | 97 | 290 98 | {{20, 20}, {280, 27}} 99 | 100 | 101 | 102 | _NS:9 103 | NO 104 | YES 105 | 7 106 | NO 107 | IBCocoaTouchFramework 108 | Player Remote 109 | 110 | 1 111 | MCAwIDAAA 112 | darkTextColor 113 | 114 | 115 | 0 116 | 1 117 | 118 | 2 119 | 22 120 | 121 | 122 | Helvetica-Bold 123 | 22 124 | 16 125 | 126 | NO 127 | 128 | 129 | {{0, 20}, {320, 548}} 130 | 131 | 132 | 133 | 134 | 3 135 | MC43NQA 136 | 137 | 2 138 | 139 | 140 | NO 141 | 142 | 143 | IBUIScreenMetrics 144 | 145 | YES 146 | 147 | 148 | 149 | 150 | 151 | {320, 568} 152 | {568, 320} 153 | 154 | 155 | IBCocoaTouchFramework 156 | Retina 4 Full Screen 157 | 2 158 | 159 | IBCocoaTouchFramework 160 | 161 | 162 | 163 | 164 | 165 | 166 | view 167 | 168 | 169 | 170 | 7 171 | 172 | 173 | 174 | getButton 175 | 176 | 177 | 178 | 15 179 | 180 | 181 | 182 | tableView 183 | 184 | 185 | 186 | 17 187 | 188 | 189 | 190 | dataSource 191 | 192 | 193 | 194 | 18 195 | 196 | 197 | 198 | delegate 199 | 200 | 201 | 202 | 19 203 | 204 | 205 | 206 | getSounds: 207 | 208 | 209 | 7 210 | 211 | 16 212 | 213 | 214 | 215 | 216 | 217 | 0 218 | 219 | 220 | 221 | 222 | 223 | -1 224 | 225 | 226 | File's Owner 227 | 228 | 229 | -2 230 | 231 | 232 | 233 | 234 | 6 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 8 245 | 246 | 247 | 248 | 249 | 13 250 | 251 | 252 | 253 | 254 | 14 255 | 256 | 257 | 258 | 259 | 260 | 261 | SRViewController 262 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 263 | UIResponder 264 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 265 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 266 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 267 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 268 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 269 | 270 | 271 | 272 | 273 | 274 | 19 275 | 276 | 277 | 278 | 279 | SRViewController 280 | UIViewController 281 | 282 | getSounds: 283 | UIButton 284 | 285 | 286 | getSounds: 287 | 288 | getSounds: 289 | UIButton 290 | 291 | 292 | 293 | UIButton 294 | UITableView 295 | 296 | 297 | 298 | getButton 299 | UIButton 300 | 301 | 302 | tableView 303 | UITableView 304 | 305 | 306 | 307 | IBProjectSource 308 | ./Classes/SRViewController.h 309 | 310 | 311 | 312 | 313 | 0 314 | IBCocoaTouchFramework 315 | YES 316 | 3 317 | 2083 318 | 319 | 320 | -------------------------------------------------------------------------------- /Samples/API Example/SoundsPlayer/SoundsPlayer/en.lproj/SPViewController.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 1552 5 | 12C60 6 | 3084 7 | 1187.34 8 | 625.00 9 | 10 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 11 | 2083 12 | 13 | 14 | IBProxyObject 15 | IBUIButton 16 | IBUILabel 17 | IBUIView 18 | 19 | 20 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 21 | 22 | 23 | PluginDependencyRecalculationVersion 24 | 25 | 26 | 27 | 28 | IBFilesOwner 29 | IBCocoaTouchFramework 30 | 31 | 32 | IBFirstResponder 33 | IBCocoaTouchFramework 34 | 35 | 36 | 37 | 274 38 | 39 | 40 | 41 | 290 42 | {{20, 20}, {280, 32}} 43 | 44 | 45 | _NS:9 46 | NO 47 | YES 48 | 7 49 | NO 50 | IBCocoaTouchFramework 51 | Sound player 52 | 53 | 1 54 | MCAwIDAAA 55 | darkTextColor 56 | 57 | 58 | 0 59 | 1 60 | 61 | 2 62 | 22 63 | 64 | 65 | Helvetica-Bold 66 | 22 67 | 16 68 | 69 | NO 70 | 71 | 72 | 73 | 292 74 | {{20, 94}, {280, 44}} 75 | 76 | 77 | _NS:9 78 | NO 79 | IBCocoaTouchFramework 80 | 0 81 | 0 82 | 1 83 | Button 84 | 85 | 3 86 | MQA 87 | 88 | 89 | 1 90 | MC4xOTYwNzg0MzQ2IDAuMzA5ODAzOTMyOSAwLjUyMTU2ODY1NgA 91 | 92 | 93 | 3 94 | MC41AA 95 | 96 | 97 | 2 98 | 15 99 | 100 | 101 | Helvetica-Bold 102 | 15 103 | 16 104 | 105 | 106 | 107 | 108 | 292 109 | {{20, 145}, {280, 44}} 110 | 111 | 112 | _NS:9 113 | NO 114 | IBCocoaTouchFramework 115 | 0 116 | 0 117 | 1 118 | Button 119 | 120 | 121 | 1 122 | MC4xOTYwNzg0MzQ2IDAuMzA5ODAzOTMyOSAwLjUyMTU2ODY1NgA 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 292 131 | {{20, 196}, {280, 44}} 132 | 133 | 134 | _NS:9 135 | NO 136 | IBCocoaTouchFramework 137 | 0 138 | 0 139 | 1 140 | Button 141 | 142 | 143 | 1 144 | MC4xOTYwNzg0MzQ2IDAuMzA5ODAzOTMyOSAwLjUyMTU2ODY1NgA 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 292 153 | {{20, 247}, {280, 44}} 154 | 155 | 156 | _NS:9 157 | NO 158 | IBCocoaTouchFramework 159 | 0 160 | 0 161 | 1 162 | Button 163 | 164 | 165 | 1 166 | MC4xOTYwNzg0MzQ2IDAuMzA5ODAzOTMyOSAwLjUyMTU2ODY1NgA 167 | 168 | 169 | 170 | 171 | 172 | 173 | {{0, 20}, {320, 548}} 174 | 175 | 176 | 177 | 3 178 | MC43NQA 179 | 180 | 2 181 | 182 | 183 | NO 184 | 185 | 186 | IBUIScreenMetrics 187 | 188 | YES 189 | 190 | 191 | 192 | 193 | 194 | {320, 568} 195 | {568, 320} 196 | 197 | 198 | IBCocoaTouchFramework 199 | Retina 4 Full Screen 200 | 2 201 | 202 | IBCocoaTouchFramework 203 | 204 | 205 | 206 | 207 | 208 | 209 | view 210 | 211 | 212 | 213 | 7 214 | 215 | 216 | 217 | buttons 218 | 219 | 220 | NSArray 221 | NO 222 | 223 | 15 224 | 225 | 226 | 227 | buttons 228 | 229 | 230 | NSArray 231 | NO 232 | 233 | 16 234 | 235 | 236 | 237 | buttons 238 | 239 | 240 | NSArray 241 | NO 242 | 243 | 17 244 | 245 | 246 | 247 | buttons 248 | 249 | 250 | NSArray 251 | NO 252 | 253 | 18 254 | 255 | 256 | 257 | play: 258 | 259 | 260 | 7 261 | 262 | 19 263 | 264 | 265 | 266 | play: 267 | 268 | 269 | 7 270 | 271 | 20 272 | 273 | 274 | 275 | play: 276 | 277 | 278 | 7 279 | 280 | 21 281 | 282 | 283 | 284 | play: 285 | 286 | 287 | 7 288 | 289 | 22 290 | 291 | 292 | 293 | 294 | 295 | 0 296 | 297 | 298 | 299 | 300 | 301 | -1 302 | 303 | 304 | File's Owner 305 | 306 | 307 | -2 308 | 309 | 310 | 311 | 312 | 6 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 8 325 | 326 | 327 | 328 | 329 | 11 330 | 331 | 332 | 333 | 334 | 12 335 | 336 | 337 | 338 | 339 | 13 340 | 341 | 342 | 343 | 344 | 14 345 | 346 | 347 | 348 | 349 | 350 | 351 | SPViewController 352 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 353 | UIResponder 354 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 355 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 356 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 357 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 358 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 359 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 360 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 361 | 362 | 363 | 364 | 365 | 366 | 22 367 | 368 | 369 | 0 370 | IBCocoaTouchFramework 371 | YES 372 | 3 373 | 2083 374 | 375 | 376 | --------------------------------------------------------------------------------