├── Pod ├── Assets │ └── .gitkeep └── Classes │ ├── .gitkeep │ ├── Route.h │ ├── Feature.h │ ├── Route.m │ ├── Message.h │ ├── Feature.m │ ├── Message.m │ ├── AeroRouter.h │ ├── AeroRouter.m │ ├── Aerodramus.h │ └── Aerodramus.m ├── Gemfile ├── Example ├── Aerodramus │ ├── en.lproj │ │ └── InfoPlist.strings │ ├── ARViewController.h │ ├── ARAppDelegate.h │ ├── Aerodramus-Prefix.pch │ ├── main.m │ ├── ARViewController.m │ ├── EchoStubbed.json │ ├── Images.xcassets │ │ ├── AppIcon.appiconset │ │ │ └── Contents.json │ │ └── LaunchImage.launchimage │ │ │ └── Contents.json │ ├── Aerodramus-Info.plist │ ├── Main.storyboard │ └── ARAppDelegate.m ├── Aerodramus.xcodeproj │ ├── project.xcworkspace │ │ └── contents.xcworkspacedata │ ├── xcshareddata │ │ └── xcschemes │ │ │ └── Aerodramus-Example.xcscheme │ └── project.pbxproj ├── Podfile ├── Aerodramus.xcworkspace │ └── contents.xcworkspacedata ├── Aerodramus_ExampleTests │ ├── Info.plist │ └── AerodramusSpec.m ├── Podfile.lock └── Echo.json ├── .gitignore ├── Aerodramus.podspec ├── README.md ├── circle.yml ├── LICENSE └── Gemfile.lock /Pod/Assets/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Pod/Classes/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | gem 'cocoapods' 4 | gem 'cocoapods-keys' 5 | -------------------------------------------------------------------------------- /Example/Aerodramus/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /Example/Aerodramus.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Pod/Classes/Route.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | @interface Route : NSObject 4 | 5 | - (instancetype)initWithName:(NSString *)name path:(NSString *)path; 6 | 7 | @property (nonatomic, copy) NSString *name; 8 | @property (nonatomic, copy) NSString *path; 9 | 10 | @end 11 | -------------------------------------------------------------------------------- /Example/Aerodramus/ARViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ARViewController.h 3 | // Aerodramus 4 | // 5 | // Created by Orta Therox on 07/09/2015. 6 | // Copyright (c) 2015 Orta Therox. All rights reserved. 7 | // 8 | 9 | @import UIKit; 10 | 11 | @interface ARViewController : UIViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Example/Podfile: -------------------------------------------------------------------------------- 1 | use_frameworks! 2 | platform :ios, '8.0' 3 | 4 | target 'Aerodramus_Example' do 5 | pod "Aerodramus", :path => "../" 6 | 7 | target 'Aerodramus_ExampleTests' do 8 | inherit! :search_paths 9 | 10 | pod 'Specta' 11 | pod 'Expecta' 12 | pod 'Forgeries' 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /Pod/Classes/Feature.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | @interface Feature : NSObject 4 | 5 | - (instancetype)initWithName:(NSString *)name state:(NSNumber *)state; 6 | 7 | @property (nonatomic, readonly, copy) NSString *name; 8 | @property (nonatomic, readonly, assign) BOOL state; 9 | 10 | @end 11 | -------------------------------------------------------------------------------- /Pod/Classes/Route.m: -------------------------------------------------------------------------------- 1 | #import "Route.h" 2 | 3 | @implementation Route 4 | 5 | - (instancetype)initWithName:(NSString *)name path:(NSString *)path 6 | { 7 | self = [super init]; 8 | if (!self) return nil; 9 | 10 | _name = name; 11 | _path = path; 12 | return self; 13 | } 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /Pod/Classes/Message.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | @interface Message : NSObject 4 | 5 | - (instancetype)initWithName:(NSString *)name content:(NSString *)content; 6 | 7 | @property (nonatomic, readonly, copy) NSString *name; 8 | @property (nonatomic, readonly, copy) NSString *content; 9 | 10 | @end 11 | -------------------------------------------------------------------------------- /Example/Aerodramus.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /Pod/Classes/Feature.m: -------------------------------------------------------------------------------- 1 | #import "Feature.h" 2 | 3 | @implementation Feature 4 | 5 | - (instancetype)initWithName:(NSString *)name state:(NSNumber *)state 6 | { 7 | self = [super init]; 8 | if (!self) return nil; 9 | 10 | _name = name; 11 | _state = state.boolValue; 12 | return self; 13 | } 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /Pod/Classes/Message.m: -------------------------------------------------------------------------------- 1 | #import "Message.h" 2 | 3 | @implementation Message 4 | 5 | - (instancetype)initWithName:(NSString *)name content:(NSString *)content 6 | { 7 | self = [super init]; 8 | if (!self) return nil; 9 | 10 | _name = name; 11 | _content = content; 12 | return self; 13 | } 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /Example/Aerodramus/ARAppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // ARAppDelegate.h 3 | // Aerodramus 4 | // 5 | // Created by Orta Therox on 07/09/2015. 6 | // Copyright (c) 2015 Orta Therox. All rights reserved. 7 | // 8 | 9 | @import UIKit; 10 | 11 | @interface ARAppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | build/ 2 | *.pbxuser 3 | !default.pbxuser 4 | *.mode1v3 5 | !default.mode1v3 6 | *.mode2v3 7 | !default.mode2v3 8 | *.perspectivev3 9 | !default.perspectivev3 10 | xcuserdata 11 | *.xccheckout 12 | profile 13 | *.moved-aside 14 | DerivedData 15 | *.hmap 16 | *.ipa 17 | # Bundler 18 | .bundle 19 | 20 | Example/Pods/ 21 | Example/Aerodramus.xcworkspace/xcshareddata/ 22 | -------------------------------------------------------------------------------- /Example/Aerodramus/Aerodramus-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 UIKit; 15 | @import Foundation; 16 | #endif 17 | -------------------------------------------------------------------------------- /Example/Aerodramus/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // Aerodramus 4 | // 5 | // Created by Orta Therox on 07/09/2015. 6 | // Copyright (c) 2015 Orta Therox. All rights reserved. 7 | // 8 | 9 | @import UIKit; 10 | #import "ARAppDelegate.h" 11 | 12 | int main(int argc, char * argv[]) 13 | { 14 | @autoreleasepool { 15 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([ARAppDelegate class])); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Pod/Classes/AeroRouter.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | /// Offers a way to get NSURLRequests for common tasks 4 | 5 | @interface AeroRouter : NSObject 6 | 7 | /// Inits with an API key and the URL where you are hosting an Echo instance 8 | - (instancetype)initWithBaseURL:(NSURL *)baseURL; 9 | 10 | /// A new reqeust for the HEAD details 11 | - (NSURLRequest *)headLastUpdateRequest; 12 | 13 | /// a new request that GETs the full content 14 | - (NSURLRequest *)getFullContentRequest; 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /Aerodramus.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | s.name = "Aerodramus" 3 | s.version = "2.0.0" 4 | s.summary = "Echo Communication Tools" 5 | s.description = "Allows connection to the Echo API server." 6 | s.homepage = "https://github.com/Artsy/Aerodramus" 7 | s.license = 'MIT' 8 | s.author = { "Orta Therox" => "orta.therox@gmail.com" } 9 | s.source = { :git => "https://github.com/Artsy/Aerodramus.git", :tag => s.version.to_s } 10 | s.platform = :ios, '7.0' 11 | s.requires_arc = true 12 | s.source_files = 'Pod/Classes/**/*' 13 | s.dependency 'ISO8601DateFormatter' 14 | end 15 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Aerodramus 2 | 3 | ### An Objective-C API for interacting with [artsy/echo](https://github.com/artsy/echo) 4 | 5 | ## Usage 6 | 7 | To run the example project, clone the repo, and run `pod install` from the Example directory first. 8 | 9 | ## Requirements 10 | 11 | ## Installation 12 | 13 | Aerodramus is available through [CocoaPods](http://cocoapods.org). To install 14 | it, simply add the following line to your Podfile: 15 | 16 | ```ruby 17 | pod "Aerodramus", :git => "git@github.com:artsy/Aerodramus.git" 18 | ``` 19 | 20 | ## Author 21 | 22 | Orta Therox, orta.therox@gmail.com 23 | 24 | ## License 25 | 26 | Aerodramus is available under the MIT license. See the LICENSE file for more info. -------------------------------------------------------------------------------- /Example/Aerodramus/ARViewController.m: -------------------------------------------------------------------------------- 1 | @import Aerodramus; 2 | 3 | #import "ARViewController.h" 4 | 5 | @interface ARViewController () 6 | 7 | @end 8 | 9 | @implementation ARViewController 10 | 11 | - (void)viewDidLoad 12 | { 13 | [super viewDidLoad]; 14 | 15 | NSURL *uRL = [NSURL URLWithString:@"https://echo.artsy.net"]; 16 | 17 | Aerodramus *aero = [[Aerodramus alloc] initWithServerURL:uRL localFilename:@"Echo"]; 18 | [aero setup]; 19 | [aero checkForUpdates:^(BOOL updatedDataOnServer) { 20 | if (!updatedDataOnServer) return; 21 | 22 | [aero update:^(BOOL updated, NSError *error) { 23 | NSLog(@"Updated"); 24 | }]; 25 | }]; 26 | } 27 | 28 | 29 | @end 30 | -------------------------------------------------------------------------------- /Example/Aerodramus_ExampleTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /Example/Aerodramus/EchoStubbed.json: -------------------------------------------------------------------------------- 1 | {"id":1,"name":"eigen","created_at":"2015-07-10T20:59:23.453Z","updated_at":"2016-01-21T13:50:16.982Z","features":[{"name":"ipad_vir","value":false},{"name":"iphone_vir","value":true}],"messages":[{"name":"intro_text","content":"Artsy has 300,000 artworks"}],"routes":[{"name":"ARArtistRoute","path":"/artist/:id"},{"name":"ARProfileArtistRoute","path":"/:profile_id/artist/:id"},{"name":"ARArtworkRoute","path":"/artwork/:id"},{"name":"ARGeneRoute","path":"/gene/:id"},{"name":"ARShowRoute","path":"/show/:id"},{"name":"ARAuctionRegistrationRoute","path":"/auction-registration/:id"},{"name":"ARAuctionRoute","path":"/auction/:id"},{"name":"ARAuctionBidArtworkRoute","path":"/auction/:id/bid/:artwork_id"},{"name":"ARFairProfileForYouRoute","path":"/:profile_id/for-you"},{"name":"ARFairBrowseArtistRoute","path":"/:profile_id/browse/artist/:id"},{"name":"ARBrowseCategoriesRoute","path":"/categories"}]} -------------------------------------------------------------------------------- /circle.yml: -------------------------------------------------------------------------------- 1 | version: 2.1 2 | 3 | jobs: 4 | test: 5 | macos: 6 | xcode: 11.3.0 7 | steps: 8 | - checkout 9 | - run: 10 | name: bundle install 11 | command: bundle install 12 | - run: 13 | name: set echo key 14 | command: pushd Example; bundle exec pod keys set EchoKey -; popd 15 | - run: 16 | name: pod install 17 | command: pushd Example; bundle e pod install; popd 18 | - run: 19 | name: build test 20 | command: set -o pipefail && xcodebuild test -workspace Example/Aerodramus.xcworkspace -scheme Aerodramus-Example -sdk iphonesimulator ONLY_ACTIVE_ARCH=NO -destination "platform=iOS Simulator,name=iPhone X,OS=12.4" | xcpretty -c 21 | - run: 22 | name: pod lint 23 | command: bundle exec pod lib lint --allow-warnings 24 | 25 | workflows: 26 | version: 2 27 | test: 28 | jobs: 29 | - test 30 | -------------------------------------------------------------------------------- /Example/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - Aerodramus (2.0.0): 3 | - ISO8601DateFormatter 4 | - Expecta (1.0.6) 5 | - Forgeries (1.0.0): 6 | - Forgeries/Core (= 1.0.0) 7 | - Forgeries/Core (1.0.0) 8 | - ISO8601DateFormatter (0.8) 9 | - Specta (1.0.7) 10 | 11 | DEPENDENCIES: 12 | - Aerodramus (from `../`) 13 | - Expecta 14 | - Forgeries 15 | - Specta 16 | 17 | SPEC REPOS: 18 | trunk: 19 | - Expecta 20 | - Forgeries 21 | - ISO8601DateFormatter 22 | - Specta 23 | 24 | EXTERNAL SOURCES: 25 | Aerodramus: 26 | :path: "../" 27 | 28 | SPEC CHECKSUMS: 29 | Aerodramus: 38d9bf0415187247fe0f771904822ebf5c127e31 30 | Expecta: 3b6bd90a64b9a1dcb0b70aa0e10a7f8f631667d5 31 | Forgeries: 64ced144ea8341d89a7eec9d1d7986f0f1366250 32 | ISO8601DateFormatter: 4551b6ce4f83185425f583b0b3feb3c7b59b942c 33 | Specta: 3e1bd89c3517421982dc4d1c992503e48bd5fe66 34 | 35 | PODFILE CHECKSUM: 946a626cd9cdee6d2237156687b8b08d0aaee317 36 | 37 | COCOAPODS: 1.9.3 38 | -------------------------------------------------------------------------------- /Example/Aerodramus/Images.xcassets/AppIcon.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 | "idiom" : "iphone", 15 | "size" : "60x60", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "ipad", 20 | "size" : "29x29", 21 | "scale" : "1x" 22 | }, 23 | { 24 | "idiom" : "ipad", 25 | "size" : "29x29", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "ipad", 30 | "size" : "40x40", 31 | "scale" : "1x" 32 | }, 33 | { 34 | "idiom" : "ipad", 35 | "size" : "40x40", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "idiom" : "ipad", 40 | "size" : "76x76", 41 | "scale" : "1x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "76x76", 46 | "scale" : "2x" 47 | } 48 | ], 49 | "info" : { 50 | "version" : 1, 51 | "author" : "xcode" 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /Pod/Classes/AeroRouter.m: -------------------------------------------------------------------------------- 1 | #import "AeroRouter.h" 2 | 3 | @interface AeroRouter() 4 | @property (nonatomic, readonly, copy) NSURL *baseURL; 5 | @end 6 | 7 | @implementation AeroRouter 8 | 9 | - (instancetype)initWithBaseURL:(NSURL *)baseURL 10 | { 11 | self = [super init]; 12 | if (!self) { return nil; } 13 | 14 | _baseURL = baseURL; 15 | 16 | return self; 17 | } 18 | 19 | - (NSURL *)urlForPath:(NSString *)path 20 | { 21 | return [self.baseURL URLByAppendingPathComponent:path]; 22 | } 23 | 24 | - (NSURLRequest *)headLastUpdateRequest 25 | { 26 | NSURL *url = [self urlForPath:[NSString stringWithFormat:@"Echo.json"]]; 27 | NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; 28 | request.HTTPMethod = @"HEAD"; 29 | NSLog(@"Will request HEAD at %@", request.URL); 30 | return request; 31 | } 32 | 33 | - (NSURLRequest *)getFullContentRequest 34 | { 35 | NSURL *url = [self urlForPath:[NSString stringWithFormat:@"Echo.json"]]; 36 | NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; 37 | request.HTTPMethod = @"GET"; 38 | NSLog(@"Will request GET at %@", request.URL); 39 | return request; 40 | } 41 | 42 | @end 43 | -------------------------------------------------------------------------------- /Example/Aerodramus/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 | "orientation" : "portrait", 20 | "idiom" : "ipad", 21 | "extent" : "full-screen", 22 | "minimum-system-version" : "7.0", 23 | "scale" : "1x" 24 | }, 25 | { 26 | "orientation" : "landscape", 27 | "idiom" : "ipad", 28 | "extent" : "full-screen", 29 | "minimum-system-version" : "7.0", 30 | "scale" : "1x" 31 | }, 32 | { 33 | "orientation" : "portrait", 34 | "idiom" : "ipad", 35 | "extent" : "full-screen", 36 | "minimum-system-version" : "7.0", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "orientation" : "landscape", 41 | "idiom" : "ipad", 42 | "extent" : "full-screen", 43 | "minimum-system-version" : "7.0", 44 | "scale" : "2x" 45 | } 46 | ], 47 | "info" : { 48 | "version" : 1, 49 | "author" : "xcode" 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /Example/Echo.json: -------------------------------------------------------------------------------- 1 | {"id":1,"name":"eigen","created_at":"2015-07-10T20:59:23.453Z","updated_at":"2019-03-11T15:26:24.531Z","features":[{"name":"ipad_vir","value":false},{"name":"iphone_vir","value":true},{"name":"ARDisableReactNativeBidFlow","value":false},{"name":"AREnableBuyNowFlow","value":true},{"name":"AREnableMakeOfferFlow","value":true},{"name":"AREnableLocalDiscovery","value":true}],"messages":[{"name":"LiveAuctionsCurrentWebSocketVersion","content":"3"},{"name":"ARVIRVideo","content":"https://files.artsy.net/videos/artsy-eigen-arvir-iphone.mp4"},{"name":"ExchangeCurrentVersion","content":"1"},{"name":"LocalDiscoveryCurrentVersion","content":"0"}],"routes":[{"name":"ARArtistRoute","path":"/artist/:id"},{"name":"ARProfileArtistRoute","path":"/:profile_id/artist/:id"},{"name":"ARArtworkRoute","path":"/artwork/:id"},{"name":"ARGeneRoute","path":"/gene/:id"},{"name":"ARShowRoute","path":"/show/:id"},{"name":"ARAuctionRegistrationRoute","path":"/auction-registration/:id"},{"name":"ARAuctionRoute","path":"/auction/:id"},{"name":"ARAuctionBidArtworkRoute","path":"/auction/:id/bid/:artwork_id"},{"name":"ARFairProfileForYouRoute","path":"/:profile_id/for-you"},{"name":"ARFairBrowseArtistRoute","path":"/:profile_id/browse/artist/:id"},{"name":"ARBrowseCategoriesRoute","path":"/categories"},{"name":"ARLiveAuctionsURLDomain","path":"live.artsy.net"},{"name":"ARLiveAuctionsStagingURLDomain","path":"live-staging.artsy.net"},{"name":"ARBuyNowRoute","path":"/orders/:id"}]} 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | <<<<<<< HEAD 2 | Copyright (c) 2015 Orta Therox 3 | ======= 4 | The MIT License (MIT) 5 | 6 | Copyright (c) 2015 Artsy 7 | >>>>>>> 4f8616c577b04b6f06395e4a1a90ca4aa400b7aa 8 | 9 | Permission is hereby granted, free of charge, to any person obtaining a copy 10 | of this software and associated documentation files (the "Software"), to deal 11 | in the Software without restriction, including without limitation the rights 12 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | copies of the Software, and to permit persons to whom the Software is 14 | furnished to do so, subject to the following conditions: 15 | 16 | <<<<<<< HEAD 17 | The above copyright notice and this permission notice shall be included in 18 | all copies or substantial portions of the Software. 19 | ======= 20 | The above copyright notice and this permission notice shall be included in all 21 | copies or substantial portions of the Software. 22 | >>>>>>> 4f8616c577b04b6f06395e4a1a90ca4aa400b7aa 23 | 24 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 25 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 26 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 27 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 28 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 29 | <<<<<<< HEAD 30 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 31 | THE SOFTWARE. 32 | ======= 33 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 34 | SOFTWARE. 35 | 36 | >>>>>>> 4f8616c577b04b6f06395e4a1a90ca4aa400b7aa 37 | -------------------------------------------------------------------------------- /Example/Aerodramus/Aerodramus-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | ${PRODUCT_NAME} 9 | CFBundleExecutable 10 | ${EXECUTABLE_NAME} 11 | CFBundleIdentifier 12 | org.cocoapods.demo.${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 | CFBundleVersion 24 | 1.0 25 | LSRequiresIPhoneOS 26 | 27 | UIMainStoryboardFile 28 | Main 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UISupportedInterfaceOrientations 34 | 35 | UIInterfaceOrientationPortrait 36 | UIInterfaceOrientationLandscapeLeft 37 | UIInterfaceOrientationLandscapeRight 38 | 39 | UISupportedInterfaceOrientations~ipad 40 | 41 | UIInterfaceOrientationPortrait 42 | UIInterfaceOrientationPortraitUpsideDown 43 | UIInterfaceOrientationLandscapeLeft 44 | UIInterfaceOrientationLandscapeRight 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /Example/Aerodramus/Main.storyboard: -------------------------------------------------------------------------------- 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 | -------------------------------------------------------------------------------- /Pod/Classes/Aerodramus.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | #if __has_feature(objc_generics) 4 | #define NSArrayOf(x) NSArray 5 | #define NSDictionaryOf(x,y) NSDictionary 6 | #else 7 | #define NSArrayOf(x) NSArray 8 | #define NSDictionaryOf(x,y) NSDictionary 9 | #endif 10 | 11 | #import "Route.h" 12 | #import "Feature.h" 13 | #import "Message.h" 14 | #import "AeroRouter.h" 15 | 16 | NS_ASSUME_NONNULL_BEGIN 17 | 18 | @class Route, Feature, Message; 19 | 20 | /// A class to communicate with the Artsy Echo API 21 | 22 | @interface Aerodramus : NSObject 23 | 24 | /// Creates an instance of Aerodramus hooked up to an echo URL 25 | /// It will look in the user's document dir for [filename].json 26 | /// and then fall back to looking inside the App bundle. 27 | 28 | - (instancetype)initWithServerURL:(NSURL *)url localFilename:(NSString *)filename; 29 | 30 | /// Grabs the local JSON and sets itself up 31 | - (void)setup; 32 | 33 | /// Does a HEAD request against the server comparing the local date with the last changed 34 | - (void)checkForUpdates:(void (^)(BOOL updatedDataOnServer))updateCheckCompleted; 35 | 36 | /// Updates the local instance with data from the server 37 | - (void)update:(void (^)(BOOL updated, NSError * _Nullable error))completed; 38 | 39 | /// The Echo account name for this app 40 | @property (nonatomic, nonnull, copy) NSString *name; 41 | 42 | /// The time when this instance of Aerodramus was last updated 43 | @property (nonatomic, nonnull, strong) NSDate *lastUpdatedDate; 44 | 45 | /// Collection of routes from the echo server 46 | @property (nonatomic, nonnull, copy) NSDictionaryOf(NSString *, Route *) *routes; 47 | 48 | /// Collection of boolean feature switches from the echo server 49 | @property (nonatomic, nonnull, copy) NSDictionaryOf(NSString *, Feature *) *features; 50 | 51 | /// Collection of messages from the echo server 52 | @property (nonatomic, nonnull, copy) NSDictionaryOf(NSString *, Message *) *messages; 53 | 54 | @end 55 | 56 | NS_ASSUME_NONNULL_END 57 | -------------------------------------------------------------------------------- /Example/Aerodramus/ARAppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // ARAppDelegate.m 3 | // Aerodramus 4 | // 5 | // Created by Orta Therox on 07/09/2015. 6 | // Copyright (c) 2015 Orta Therox. All rights reserved. 7 | // 8 | 9 | #import "ARAppDelegate.h" 10 | 11 | @implementation ARAppDelegate 12 | 13 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 14 | { 15 | // Override point for customization after application launch. 16 | return YES; 17 | } 18 | 19 | - (void)applicationWillResignActive:(UIApplication *)application 20 | { 21 | // 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. 22 | // 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. 23 | } 24 | 25 | - (void)applicationDidEnterBackground:(UIApplication *)application 26 | { 27 | // 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. 28 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 29 | } 30 | 31 | - (void)applicationWillEnterForeground:(UIApplication *)application 32 | { 33 | // 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. 34 | } 35 | 36 | - (void)applicationDidBecomeActive:(UIApplication *)application 37 | { 38 | // 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. 39 | } 40 | 41 | - (void)applicationWillTerminate:(UIApplication *)application 42 | { 43 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 44 | } 45 | 46 | @end 47 | -------------------------------------------------------------------------------- /Gemfile.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | remote: https://rubygems.org/ 3 | specs: 4 | CFPropertyList (3.0.2) 5 | RubyInline (3.12.5) 6 | ZenTest (~> 4.3) 7 | ZenTest (4.12.0) 8 | activesupport (4.2.11.3) 9 | i18n (~> 0.7) 10 | minitest (~> 5.1) 11 | thread_safe (~> 0.3, >= 0.3.4) 12 | tzinfo (~> 1.1) 13 | algoliasearch (1.27.4) 14 | httpclient (~> 2.8, >= 2.8.3) 15 | json (>= 1.5.1) 16 | atomos (0.1.3) 17 | claide (1.0.3) 18 | cocoapods (1.9.3) 19 | activesupport (>= 4.0.2, < 5) 20 | claide (>= 1.0.2, < 2.0) 21 | cocoapods-core (= 1.9.3) 22 | cocoapods-deintegrate (>= 1.0.3, < 2.0) 23 | cocoapods-downloader (>= 1.2.2, < 2.0) 24 | cocoapods-plugins (>= 1.0.0, < 2.0) 25 | cocoapods-search (>= 1.0.0, < 2.0) 26 | cocoapods-stats (>= 1.0.0, < 2.0) 27 | cocoapods-trunk (>= 1.4.0, < 2.0) 28 | cocoapods-try (>= 1.1.0, < 2.0) 29 | colored2 (~> 3.1) 30 | escape (~> 0.0.4) 31 | fourflusher (>= 2.3.0, < 3.0) 32 | gh_inspector (~> 1.0) 33 | molinillo (~> 0.6.6) 34 | nap (~> 1.0) 35 | ruby-macho (~> 1.4) 36 | xcodeproj (>= 1.14.0, < 2.0) 37 | cocoapods-core (1.9.3) 38 | activesupport (>= 4.0.2, < 6) 39 | algoliasearch (~> 1.0) 40 | concurrent-ruby (~> 1.1) 41 | fuzzy_match (~> 2.0.4) 42 | nap (~> 1.0) 43 | netrc (~> 0.11) 44 | typhoeus (~> 1.0) 45 | cocoapods-deintegrate (1.0.4) 46 | cocoapods-downloader (1.4.0) 47 | cocoapods-keys (2.2.1) 48 | dotenv 49 | osx_keychain 50 | cocoapods-plugins (1.0.0) 51 | nap 52 | cocoapods-search (1.0.0) 53 | cocoapods-stats (1.1.0) 54 | cocoapods-trunk (1.5.0) 55 | nap (>= 0.8, < 2.0) 56 | netrc (~> 0.11) 57 | cocoapods-try (1.2.0) 58 | colored2 (3.1.2) 59 | concurrent-ruby (1.1.7) 60 | dotenv (2.7.6) 61 | escape (0.0.4) 62 | ethon (0.12.0) 63 | ffi (>= 1.3.0) 64 | ffi (1.13.1) 65 | fourflusher (2.3.1) 66 | fuzzy_match (2.0.4) 67 | gh_inspector (1.1.3) 68 | httpclient (2.8.3) 69 | i18n (0.9.5) 70 | concurrent-ruby (~> 1.0) 71 | json (2.3.1) 72 | minitest (5.14.2) 73 | molinillo (0.6.6) 74 | nanaimo (0.3.0) 75 | nap (1.1.0) 76 | netrc (0.11.0) 77 | osx_keychain (1.0.2) 78 | RubyInline (~> 3) 79 | ruby-macho (1.4.0) 80 | thread_safe (0.3.6) 81 | typhoeus (1.4.0) 82 | ethon (>= 0.9.0) 83 | tzinfo (1.2.7) 84 | thread_safe (~> 0.1) 85 | xcodeproj (1.18.0) 86 | CFPropertyList (>= 2.3.3, < 4.0) 87 | atomos (~> 0.1.3) 88 | claide (>= 1.0.2, < 2.0) 89 | colored2 (~> 3.1) 90 | nanaimo (~> 0.3.0) 91 | 92 | PLATFORMS 93 | ruby 94 | 95 | DEPENDENCIES 96 | cocoapods 97 | cocoapods-keys 98 | 99 | BUNDLED WITH 100 | 2.1.4 101 | -------------------------------------------------------------------------------- /Example/Aerodramus_ExampleTests/AerodramusSpec.m: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | #import 4 | #import 5 | #import 6 | 7 | @interface Aerodramus(PrivateButTests) 8 | @property (nonatomic, copy, readonly) NSString *filename; 9 | @property (nonatomic, strong, readonly) AeroRouter *router; 10 | @property (nonatomic, strong) NSFileManager *fileManager; 11 | @end 12 | 13 | 14 | SpecBegin(AeroTests) 15 | 16 | __block Aerodramus *subject; 17 | 18 | describe(@"getting the default file", ^{ 19 | 20 | before(^{ 21 | NSURL *url = [NSURL URLWithString:@"http://echo.com"]; 22 | subject = [[Aerodramus alloc] initWithServerURL:url localFilename:@"EchoTest"]; 23 | }); 24 | 25 | it(@"prioritises looking in user documents", ^{ 26 | ForgeriesFileManager *fm = [ForgeriesFileManager withFileStringMap:@{ 27 | @"/docs/EchoTest.json" : @{ @"updated_at" : @"2001-01-23" }, 28 | @"/app/EchoTest.json": @{ @"updated_at" : @"1985-01-23" } 29 | }]; 30 | subject.fileManager = fm; 31 | [subject setup]; 32 | 33 | NSDateComponents *components = [[NSCalendar currentCalendar] components:NSCalendarUnitYear fromDate:subject.lastUpdatedDate]; 34 | expect(components.year).to.equal(2001); 35 | }); 36 | 37 | it(@"falls back to the App's JSON", ^{ 38 | ForgeriesFileManager *fm = [ForgeriesFileManager withFileStringMap:@{ 39 | @"/docs/NotEchoTest.json" : @{ @"updated_at" : @"2001-01-23" }, 40 | @"/app/EchoTest.json": @{ @"updated_at" : @"1985-01-23" } 41 | }]; 42 | 43 | subject.fileManager = fm; 44 | [subject setup]; 45 | 46 | NSDateComponents *components = [[NSCalendar currentCalendar] components:NSCalendarUnitYear fromDate:subject.lastUpdatedDate]; 47 | expect(components.year).to.equal(1985); 48 | }); 49 | }); 50 | 51 | describe(@"ORM", ^{ 52 | 53 | before(^{ 54 | NSURL *url = [NSURL URLWithString:@"http://echo.com"]; 55 | subject = [[Aerodramus alloc] initWithServerURL:url localFilename:@"EchoStubbed"]; 56 | }); 57 | 58 | it(@"sets up Aerodramus", ^{ 59 | [subject setup]; 60 | expect(subject.name).to.equal(@"eigen"); 61 | 62 | ISO8601DateFormatter *formatter = [[ISO8601DateFormatter alloc] init]; 63 | NSDate *date = [formatter dateFromString:@"2016-01-21T13:50:16.982Z"]; 64 | expect(subject.lastUpdatedDate).to.equal(date); 65 | }); 66 | 67 | it(@"converts features", ^{ 68 | [subject setup]; 69 | expect([subject features].count).to.equal(2); 70 | 71 | Feature *feature = subject.features[@"ipad_vir"]; 72 | expect(feature.name).to.equal(@"ipad_vir"); 73 | expect(feature.state).to.equal(false); 74 | }); 75 | 76 | it(@"converts messages", ^{ 77 | [subject setup]; 78 | expect([subject messages].count).to.equal(1); 79 | 80 | Message *message = subject.messages.allValues.firstObject; 81 | expect(message.name).to.equal(@"intro_text"); 82 | expect(message.content).to.equal(@"Artsy has 300,000 artworks"); 83 | }); 84 | 85 | it(@"converts routes", ^{ 86 | [subject setup]; 87 | expect([subject routes].count).to.equal(11); 88 | 89 | Route *route = subject.routes[@"ARArtistRoute"]; 90 | expect(route.name).to.equal(@"ARArtistRoute"); 91 | expect(route.path).to.equal(@"/artist/:id"); 92 | }); 93 | }); 94 | 95 | 96 | SpecEnd 97 | 98 | -------------------------------------------------------------------------------- /Example/Aerodramus.xcodeproj/xcshareddata/xcschemes/Aerodramus-Example.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 33 | 39 | 40 | 41 | 43 | 49 | 50 | 51 | 52 | 53 | 59 | 60 | 61 | 62 | 63 | 64 | 74 | 76 | 82 | 83 | 84 | 85 | 86 | 87 | 93 | 95 | 101 | 102 | 103 | 104 | 106 | 107 | 110 | 111 | 112 | -------------------------------------------------------------------------------- /Pod/Classes/Aerodramus.m: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | #import "Aerodramus.h" 4 | #import "AeroRouter.h" 5 | 6 | #import "Feature.h" 7 | #import "Message.h" 8 | #import "Route.h" 9 | 10 | @interface Aerodramus() 11 | @property (nonatomic, copy, readonly) NSString *filename; 12 | @property (nonatomic, strong, readonly) AeroRouter *router; 13 | @property (nonatomic, strong) NSFileManager *fileManager; 14 | @end 15 | 16 | @implementation Aerodramus 17 | 18 | - (instancetype)initWithServerURL:(NSURL *)url localFilename:(NSString *)filename; 19 | { 20 | self = [super init]; 21 | if (!self) return nil; 22 | 23 | _filename = url.copy; 24 | _filename = filename.copy; 25 | _router = [[AeroRouter alloc] initWithBaseURL:url]; 26 | 27 | return self; 28 | } 29 | 30 | - (void)setup 31 | { 32 | NSURL *pathForStoredJSON = [self filePathForFileName:self.filename]; 33 | NSString *errorMessage = [NSString stringWithFormat:@"Could not find a default json for Aerodramus at %@", pathForStoredJSON]; 34 | 35 | NSAssert(pathForStoredJSON, errorMessage); 36 | if (!pathForStoredJSON) return; 37 | 38 | NSData *data = [self.fileManager contentsAtPath:pathForStoredJSON.path]; 39 | [self updateWithJSONData:data]; 40 | } 41 | 42 | - (NSURL *)storedDocumentsFilePathWithName:(NSString *)name 43 | { 44 | NSURL *docsDir = [[self.fileManager URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject]; 45 | return [docsDir URLByAppendingPathComponent:[name stringByAppendingString:@".json"]]; 46 | } 47 | 48 | - (NSURL *)filePathForFileName:(NSString *)name 49 | { 50 | NSURL *fileDocsURL = [self storedDocumentsFilePathWithName:name]; 51 | if ([self.fileManager fileExistsAtPath:fileDocsURL.path]) { return fileDocsURL; } 52 | 53 | NSURL *bundlePath = [NSBundle.mainBundle bundleURL]; 54 | NSURL *fileAppURL = [bundlePath URLByAppendingPathComponent:[name stringByAppendingString:@".json"]]; 55 | if ([self.fileManager fileExistsAtPath:fileAppURL.path]) { return fileAppURL; } 56 | 57 | return nil; 58 | } 59 | 60 | - (void)updateWithJSONData:(NSData *)JSONdata 61 | { 62 | NSError *error = nil; 63 | id JSON = [NSJSONSerialization JSONObjectWithData:JSONdata options:0 error:&error]; 64 | if (error) { 65 | NSLog(@"[Aerodramus] Could not serialize Aerodramus JSON: %@", error.localizedDescription); 66 | return; 67 | } 68 | 69 | ISO8601DateFormatter *formatter = [[ISO8601DateFormatter alloc] init]; 70 | NSString *lastUpdatedDateString = JSON[@"updated_at"]; 71 | 72 | _lastUpdatedDate = [formatter dateFromString:lastUpdatedDateString]; 73 | _name = [JSON[@"name"] copy]; 74 | 75 | _features = [self mapDict:JSON[@"features"] map:^id(NSDictionary *featureDict) { 76 | return [[Feature alloc] initWithName:featureDict[@"name"] state:featureDict[@"value"]]; 77 | }]; 78 | 79 | _messages = [self mapDict:JSON[@"messages"] map:^id(NSDictionary *messageDict) { 80 | return [[Message alloc] initWithName:messageDict[@"name"] content:messageDict[@"content"]]; 81 | }]; 82 | 83 | _routes = [self mapDict:JSON[@"routes"] map:^id(NSDictionary *routeDict) { 84 | return [[Route alloc] initWithName:routeDict[@"name"] path:routeDict[@"path"]]; 85 | }]; 86 | } 87 | 88 | - (void)checkForUpdates:(void (^)(BOOL updatedDataOnServer))updateCheckCompleted 89 | { 90 | NSURLRequest *request = [self.router headLastUpdateRequest]; 91 | [self performRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { 92 | 93 | if (error) { 94 | NSLog(@"[Aerodramus] Check for update failed: %@", error); 95 | updateCheckCompleted(NO); 96 | return; 97 | } 98 | 99 | if ([response isKindOfClass:NSHTTPURLResponse.class]) { 100 | NSHTTPURLResponse *httpResponse = (id)response; 101 | 102 | NSInteger statusCode = httpResponse.statusCode; 103 | if (statusCode < 200 || statusCode > 299) { 104 | NSLog(@"[Aerodramus] Check for update response came back with status code: %ld", (long)statusCode); 105 | updateCheckCompleted(NO); 106 | return; 107 | } 108 | 109 | NSDateFormatter *formatter = [[NSDateFormatter alloc] init]; 110 | [formatter setDateFormat:@"E, dd MMM yyyy HH:mm:ss zzz"]; 111 | 112 | NSString *updatedAtString = httpResponse.allHeaderFields[@"Last-Modified"]; 113 | NSDate *lastUpdatedDate = [formatter dateFromString:updatedAtString]; 114 | 115 | BOOL later; 116 | if (lastUpdatedDate) { 117 | later = ([lastUpdatedDate compare:self.lastUpdatedDate] == NSOrderedDescending); 118 | NSLog(@"[Aerodramus] Check for update (%@). Current settings: %@, new settings: %@", @(later), self.lastUpdatedDate, lastUpdatedDate); 119 | } else { 120 | // Date parsing failed, force an update. 121 | later = YES; 122 | NSLog(@"[Aerodramus] Failed to parse date from Updated-At header: %@", updatedAtString); 123 | } 124 | updateCheckCompleted(later); 125 | return; 126 | } 127 | 128 | updateCheckCompleted(NO); 129 | return; 130 | }]; 131 | } 132 | 133 | - (void)update:(void (^)(BOOL updated, NSError *error))completed; 134 | { 135 | NSURLRequest *request = [self.router getFullContentRequest]; 136 | [self performRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { 137 | 138 | if (error || data == nil) { 139 | NSLog(@"[Aerodramus] Updating Echo data failed: %@, %@", error, data); 140 | completed(NO, error); 141 | return; 142 | } 143 | 144 | if ([response isKindOfClass:NSHTTPURLResponse.class]) { 145 | NSHTTPURLResponse *httpResponse = (id)response; 146 | 147 | NSInteger statusCode = httpResponse.statusCode; 148 | if (statusCode < 200 || statusCode > 299) { 149 | NSLog(@"[Aerodramus] Updating Echo data response came back with status code: %ld", (long)statusCode); 150 | completed(NO, [[NSError alloc] initWithDomain:@"Aerodramus" 151 | code:1 152 | userInfo:@{ 153 | @"statusCode": @(statusCode), 154 | }]); 155 | return; 156 | } 157 | } 158 | 159 | NSLog(@"[Aerodramus] Fetched Echo data."); 160 | [self updateWithJSONData:data]; 161 | BOOL saved = [self saveJSONToDisk:data]; 162 | completed(saved, nil); 163 | 164 | return; 165 | }]; 166 | } 167 | 168 | - (BOOL)saveJSONToDisk:(NSData *)JSONdata 169 | { 170 | NSError *error; 171 | NSURL *url = [self storedDocumentsFilePathWithName:self.filename]; 172 | BOOL success = [JSONdata writeToURL:url options:NSDataWritingAtomic error:&error]; 173 | if (error) { 174 | NSLog(@"[Aerodramus] Error saving Aerodramus json data: %@", error.localizedDescription); 175 | } 176 | return success; 177 | } 178 | 179 | 180 | #pragma mark Helper methods 181 | 182 | - (NSArray *)mapArray:(NSArray *)array map:(id (^)(id object))block { 183 | NSMutableArray *newArray = [NSMutableArray arrayWithCapacity:array.count]; 184 | 185 | for (id object in array) { 186 | id newObject = block(object); 187 | if (newObject) { 188 | [newArray addObject:newObject]; 189 | } 190 | } 191 | 192 | return [NSArray arrayWithArray:newArray]; 193 | } 194 | 195 | - (NSDictionary *)mapDict:(NSArray *)array map:(id (^)(id object))block { 196 | NSMutableDictionary *newDict = [NSMutableDictionary dictionary]; 197 | 198 | for (id object in array) { 199 | id newObject = block(object); 200 | if (newObject) { 201 | NSString *key = object[@"name"]; 202 | newDict[key] = newObject; 203 | } 204 | } 205 | 206 | return [NSDictionary dictionaryWithDictionary:newDict]; 207 | } 208 | 209 | - (void)performRequest:(NSURLRequest *)request completionHandler:(void (^)(NSData *data, NSURLResponse *response, NSError *error))completionHandler; 210 | { 211 | NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration]; 212 | configuration.requestCachePolicy = NSURLRequestReloadIgnoringCacheData; 213 | NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration]; 214 | NSURLSessionDataTask *task = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) { 215 | if (completionHandler) { 216 | dispatch_async(dispatch_get_main_queue(), ^{ 217 | completionHandler(data, response, error); 218 | }); 219 | } 220 | }]; 221 | [task resume]; 222 | } 223 | 224 | #pragma mark - DI 225 | 226 | - (NSFileManager *)fileManager 227 | { 228 | return _fileManager ?: [NSFileManager defaultManager]; 229 | } 230 | 231 | @end 232 | -------------------------------------------------------------------------------- /Example/Aerodramus.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 2BC85AE93146DD5B31446A8A /* Pods_Aerodramus_ExampleTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2C63E8D1C3B592A0D4C05EF0 /* Pods_Aerodramus_ExampleTests.framework */; }; 11 | 6003F58E195388D20070C39A /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6003F58D195388D20070C39A /* Foundation.framework */; }; 12 | 6003F590195388D20070C39A /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6003F58F195388D20070C39A /* CoreGraphics.framework */; }; 13 | 6003F592195388D20070C39A /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6003F591195388D20070C39A /* UIKit.framework */; }; 14 | 6003F598195388D20070C39A /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 6003F596195388D20070C39A /* InfoPlist.strings */; }; 15 | 6003F59A195388D20070C39A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 6003F599195388D20070C39A /* main.m */; }; 16 | 6003F59E195388D20070C39A /* ARAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 6003F59D195388D20070C39A /* ARAppDelegate.m */; }; 17 | 6003F5A7195388D20070C39A /* ARViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 6003F5A6195388D20070C39A /* ARViewController.m */; }; 18 | 6003F5A9195388D20070C39A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 6003F5A8195388D20070C39A /* Images.xcassets */; }; 19 | 60E693961C4938F40058DF5F /* Echo.json in Resources */ = {isa = PBXBuildFile; fileRef = 60E693951C4938F40058DF5F /* Echo.json */; }; 20 | 60E6939E1C494E1D0058DF5F /* AerodramusSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 60E6939D1C494E1D0058DF5F /* AerodramusSpec.m */; }; 21 | 60F63AB21C57A34F00DCFF2A /* EchoStubbed.json in Resources */ = {isa = PBXBuildFile; fileRef = 60F63AB11C57A34F00DCFF2A /* EchoStubbed.json */; }; 22 | 873B8AEB1B1F5CCA007FD442 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 873B8AEA1B1F5CCA007FD442 /* Main.storyboard */; }; 23 | 996114C5227F707BAEF04E19 /* Pods_Aerodramus_Example.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5D80934081D3DA00DEFEC323 /* Pods_Aerodramus_Example.framework */; }; 24 | /* End PBXBuildFile section */ 25 | 26 | /* Begin PBXContainerItemProxy section */ 27 | 60E693A01C494E1D0058DF5F /* PBXContainerItemProxy */ = { 28 | isa = PBXContainerItemProxy; 29 | containerPortal = 6003F582195388D10070C39A /* Project object */; 30 | proxyType = 1; 31 | remoteGlobalIDString = 6003F589195388D20070C39A; 32 | remoteInfo = Aerodramus_Example; 33 | }; 34 | /* End PBXContainerItemProxy section */ 35 | 36 | /* Begin PBXFileReference section */ 37 | 2C63E8D1C3B592A0D4C05EF0 /* Pods_Aerodramus_ExampleTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Aerodramus_ExampleTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 38 | 5D80934081D3DA00DEFEC323 /* Pods_Aerodramus_Example.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Aerodramus_Example.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 39 | 6003F58A195388D20070C39A /* Aerodramus_Example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Aerodramus_Example.app; sourceTree = BUILT_PRODUCTS_DIR; }; 40 | 6003F58D195388D20070C39A /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 41 | 6003F58F195388D20070C39A /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; 42 | 6003F591195388D20070C39A /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; 43 | 6003F595195388D20070C39A /* Aerodramus-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "Aerodramus-Info.plist"; sourceTree = ""; }; 44 | 6003F597195388D20070C39A /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; 45 | 6003F599195388D20070C39A /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 46 | 6003F59B195388D20070C39A /* Aerodramus-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Aerodramus-Prefix.pch"; sourceTree = ""; }; 47 | 6003F59C195388D20070C39A /* ARAppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ARAppDelegate.h; sourceTree = ""; }; 48 | 6003F59D195388D20070C39A /* ARAppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ARAppDelegate.m; sourceTree = ""; }; 49 | 6003F5A5195388D20070C39A /* ARViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ARViewController.h; sourceTree = ""; }; 50 | 6003F5A6195388D20070C39A /* ARViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ARViewController.m; sourceTree = ""; }; 51 | 6003F5A8195388D20070C39A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; 52 | 6003F5AF195388D20070C39A /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; }; 53 | 604419D8ADFAB14E672086FC /* Aerodramus.podspec */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = Aerodramus.podspec; path = ../Aerodramus.podspec; sourceTree = ""; }; 54 | 60E693951C4938F40058DF5F /* Echo.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; name = Echo.json; path = ../Echo.json; sourceTree = ""; }; 55 | 60E6939B1C494E1D0058DF5F /* Aerodramus_ExampleTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = Aerodramus_ExampleTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 56 | 60E6939D1C494E1D0058DF5F /* AerodramusSpec.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AerodramusSpec.m; sourceTree = ""; }; 57 | 60E6939F1C494E1D0058DF5F /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 58 | 60F63AB11C57A34F00DCFF2A /* EchoStubbed.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = EchoStubbed.json; sourceTree = ""; }; 59 | 70D2F65BFEA469BB4D195590 /* Pods-Aerodramus_ExampleTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Aerodramus_ExampleTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Aerodramus_ExampleTests/Pods-Aerodramus_ExampleTests.debug.xcconfig"; sourceTree = ""; }; 60 | 873B8AEA1B1F5CCA007FD442 /* Main.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = Main.storyboard; sourceTree = ""; }; 61 | 94F09FC2DA4FC295F6E96103 /* README.md */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = net.daringfireball.markdown; name = README.md; path = ../README.md; sourceTree = ""; }; 62 | A4311DBE40B0575719644722 /* Pods-Aerodramus_ExampleTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Aerodramus_ExampleTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-Aerodramus_ExampleTests/Pods-Aerodramus_ExampleTests.release.xcconfig"; sourceTree = ""; }; 63 | A83FA455873789DD5C2B0C4A /* LICENSE */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = LICENSE; path = ../LICENSE; sourceTree = ""; }; 64 | ED245C48EB1380A39955E7A4 /* Pods-Aerodramus_Example.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Aerodramus_Example.release.xcconfig"; path = "Pods/Target Support Files/Pods-Aerodramus_Example/Pods-Aerodramus_Example.release.xcconfig"; sourceTree = ""; }; 65 | FAB3B2E07D2AAE0D1E10EE4E /* Pods-Aerodramus_Example.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Aerodramus_Example.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Aerodramus_Example/Pods-Aerodramus_Example.debug.xcconfig"; sourceTree = ""; }; 66 | /* End PBXFileReference section */ 67 | 68 | /* Begin PBXFrameworksBuildPhase section */ 69 | 6003F587195388D20070C39A /* Frameworks */ = { 70 | isa = PBXFrameworksBuildPhase; 71 | buildActionMask = 2147483647; 72 | files = ( 73 | 6003F590195388D20070C39A /* CoreGraphics.framework in Frameworks */, 74 | 6003F592195388D20070C39A /* UIKit.framework in Frameworks */, 75 | 6003F58E195388D20070C39A /* Foundation.framework in Frameworks */, 76 | 996114C5227F707BAEF04E19 /* Pods_Aerodramus_Example.framework in Frameworks */, 77 | ); 78 | runOnlyForDeploymentPostprocessing = 0; 79 | }; 80 | 60E693981C494E1D0058DF5F /* Frameworks */ = { 81 | isa = PBXFrameworksBuildPhase; 82 | buildActionMask = 2147483647; 83 | files = ( 84 | 2BC85AE93146DD5B31446A8A /* Pods_Aerodramus_ExampleTests.framework in Frameworks */, 85 | ); 86 | runOnlyForDeploymentPostprocessing = 0; 87 | }; 88 | /* End PBXFrameworksBuildPhase section */ 89 | 90 | /* Begin PBXGroup section */ 91 | 6003F581195388D10070C39A = { 92 | isa = PBXGroup; 93 | children = ( 94 | 60FF7A9C1954A5C5007DD14C /* Podspec Metadata */, 95 | 6003F593195388D20070C39A /* Example for Aerodramus */, 96 | 60E6939C1C494E1D0058DF5F /* Aerodramus_ExampleTests */, 97 | 6003F58C195388D20070C39A /* Frameworks */, 98 | 6003F58B195388D20070C39A /* Products */, 99 | C879B9FBE0026E279391DFB9 /* Pods */, 100 | ); 101 | sourceTree = ""; 102 | }; 103 | 6003F58B195388D20070C39A /* Products */ = { 104 | isa = PBXGroup; 105 | children = ( 106 | 6003F58A195388D20070C39A /* Aerodramus_Example.app */, 107 | 60E6939B1C494E1D0058DF5F /* Aerodramus_ExampleTests.xctest */, 108 | ); 109 | name = Products; 110 | sourceTree = ""; 111 | }; 112 | 6003F58C195388D20070C39A /* Frameworks */ = { 113 | isa = PBXGroup; 114 | children = ( 115 | 6003F58D195388D20070C39A /* Foundation.framework */, 116 | 6003F58F195388D20070C39A /* CoreGraphics.framework */, 117 | 6003F591195388D20070C39A /* UIKit.framework */, 118 | 6003F5AF195388D20070C39A /* XCTest.framework */, 119 | 5D80934081D3DA00DEFEC323 /* Pods_Aerodramus_Example.framework */, 120 | 2C63E8D1C3B592A0D4C05EF0 /* Pods_Aerodramus_ExampleTests.framework */, 121 | ); 122 | name = Frameworks; 123 | sourceTree = ""; 124 | }; 125 | 6003F593195388D20070C39A /* Example for Aerodramus */ = { 126 | isa = PBXGroup; 127 | children = ( 128 | 60E693951C4938F40058DF5F /* Echo.json */, 129 | 60F63AB11C57A34F00DCFF2A /* EchoStubbed.json */, 130 | 6003F59C195388D20070C39A /* ARAppDelegate.h */, 131 | 6003F59D195388D20070C39A /* ARAppDelegate.m */, 132 | 873B8AEA1B1F5CCA007FD442 /* Main.storyboard */, 133 | 6003F5A5195388D20070C39A /* ARViewController.h */, 134 | 6003F5A6195388D20070C39A /* ARViewController.m */, 135 | 6003F5A8195388D20070C39A /* Images.xcassets */, 136 | 6003F594195388D20070C39A /* Supporting Files */, 137 | ); 138 | name = "Example for Aerodramus"; 139 | path = Aerodramus; 140 | sourceTree = ""; 141 | }; 142 | 6003F594195388D20070C39A /* Supporting Files */ = { 143 | isa = PBXGroup; 144 | children = ( 145 | 6003F595195388D20070C39A /* Aerodramus-Info.plist */, 146 | 6003F596195388D20070C39A /* InfoPlist.strings */, 147 | 6003F599195388D20070C39A /* main.m */, 148 | 6003F59B195388D20070C39A /* Aerodramus-Prefix.pch */, 149 | ); 150 | name = "Supporting Files"; 151 | sourceTree = ""; 152 | }; 153 | 60E6939C1C494E1D0058DF5F /* Aerodramus_ExampleTests */ = { 154 | isa = PBXGroup; 155 | children = ( 156 | 60E6939D1C494E1D0058DF5F /* AerodramusSpec.m */, 157 | 60E6939F1C494E1D0058DF5F /* Info.plist */, 158 | ); 159 | path = Aerodramus_ExampleTests; 160 | sourceTree = ""; 161 | }; 162 | 60FF7A9C1954A5C5007DD14C /* Podspec Metadata */ = { 163 | isa = PBXGroup; 164 | children = ( 165 | 604419D8ADFAB14E672086FC /* Aerodramus.podspec */, 166 | 94F09FC2DA4FC295F6E96103 /* README.md */, 167 | A83FA455873789DD5C2B0C4A /* LICENSE */, 168 | ); 169 | name = "Podspec Metadata"; 170 | sourceTree = ""; 171 | }; 172 | C879B9FBE0026E279391DFB9 /* Pods */ = { 173 | isa = PBXGroup; 174 | children = ( 175 | FAB3B2E07D2AAE0D1E10EE4E /* Pods-Aerodramus_Example.debug.xcconfig */, 176 | ED245C48EB1380A39955E7A4 /* Pods-Aerodramus_Example.release.xcconfig */, 177 | 70D2F65BFEA469BB4D195590 /* Pods-Aerodramus_ExampleTests.debug.xcconfig */, 178 | A4311DBE40B0575719644722 /* Pods-Aerodramus_ExampleTests.release.xcconfig */, 179 | ); 180 | name = Pods; 181 | sourceTree = ""; 182 | }; 183 | /* End PBXGroup section */ 184 | 185 | /* Begin PBXNativeTarget section */ 186 | 6003F589195388D20070C39A /* Aerodramus_Example */ = { 187 | isa = PBXNativeTarget; 188 | buildConfigurationList = 6003F5BF195388D20070C39A /* Build configuration list for PBXNativeTarget "Aerodramus_Example" */; 189 | buildPhases = ( 190 | A91EF9025193E36DEBA77683 /* [CP] Check Pods Manifest.lock */, 191 | 6003F586195388D20070C39A /* Sources */, 192 | 6003F587195388D20070C39A /* Frameworks */, 193 | 6003F588195388D20070C39A /* Resources */, 194 | 5D81D1C7699DEC71AB140D26 /* [CP] Embed Pods Frameworks */, 195 | ); 196 | buildRules = ( 197 | ); 198 | dependencies = ( 199 | ); 200 | name = Aerodramus_Example; 201 | productName = Aerodramus; 202 | productReference = 6003F58A195388D20070C39A /* Aerodramus_Example.app */; 203 | productType = "com.apple.product-type.application"; 204 | }; 205 | 60E6939A1C494E1D0058DF5F /* Aerodramus_ExampleTests */ = { 206 | isa = PBXNativeTarget; 207 | buildConfigurationList = 60E693A21C494E1D0058DF5F /* Build configuration list for PBXNativeTarget "Aerodramus_ExampleTests" */; 208 | buildPhases = ( 209 | 3949D37437D260F438D1666A /* [CP] Check Pods Manifest.lock */, 210 | 60E693971C494E1D0058DF5F /* Sources */, 211 | 60E693981C494E1D0058DF5F /* Frameworks */, 212 | 60E693991C494E1D0058DF5F /* Resources */, 213 | 6B9467EDB966891DF7167AD3 /* [CP] Embed Pods Frameworks */, 214 | ); 215 | buildRules = ( 216 | ); 217 | dependencies = ( 218 | 60E693A11C494E1D0058DF5F /* PBXTargetDependency */, 219 | ); 220 | name = Aerodramus_ExampleTests; 221 | productName = Aerodramus_ExampleTests; 222 | productReference = 60E6939B1C494E1D0058DF5F /* Aerodramus_ExampleTests.xctest */; 223 | productType = "com.apple.product-type.bundle.unit-test"; 224 | }; 225 | /* End PBXNativeTarget section */ 226 | 227 | /* Begin PBXProject section */ 228 | 6003F582195388D10070C39A /* Project object */ = { 229 | isa = PBXProject; 230 | attributes = { 231 | CLASSPREFIX = AR; 232 | LastUpgradeCheck = 0510; 233 | ORGANIZATIONNAME = "Orta Therox"; 234 | TargetAttributes = { 235 | 60E6939A1C494E1D0058DF5F = { 236 | CreatedOnToolsVersion = 7.2; 237 | TestTargetID = 6003F589195388D20070C39A; 238 | }; 239 | }; 240 | }; 241 | buildConfigurationList = 6003F585195388D10070C39A /* Build configuration list for PBXProject "Aerodramus" */; 242 | compatibilityVersion = "Xcode 3.2"; 243 | developmentRegion = English; 244 | hasScannedForEncodings = 0; 245 | knownRegions = ( 246 | en, 247 | Base, 248 | ); 249 | mainGroup = 6003F581195388D10070C39A; 250 | productRefGroup = 6003F58B195388D20070C39A /* Products */; 251 | projectDirPath = ""; 252 | projectRoot = ""; 253 | targets = ( 254 | 6003F589195388D20070C39A /* Aerodramus_Example */, 255 | 60E6939A1C494E1D0058DF5F /* Aerodramus_ExampleTests */, 256 | ); 257 | }; 258 | /* End PBXProject section */ 259 | 260 | /* Begin PBXResourcesBuildPhase section */ 261 | 6003F588195388D20070C39A /* Resources */ = { 262 | isa = PBXResourcesBuildPhase; 263 | buildActionMask = 2147483647; 264 | files = ( 265 | 60E693961C4938F40058DF5F /* Echo.json in Resources */, 266 | 873B8AEB1B1F5CCA007FD442 /* Main.storyboard in Resources */, 267 | 6003F5A9195388D20070C39A /* Images.xcassets in Resources */, 268 | 6003F598195388D20070C39A /* InfoPlist.strings in Resources */, 269 | 60F63AB21C57A34F00DCFF2A /* EchoStubbed.json in Resources */, 270 | ); 271 | runOnlyForDeploymentPostprocessing = 0; 272 | }; 273 | 60E693991C494E1D0058DF5F /* Resources */ = { 274 | isa = PBXResourcesBuildPhase; 275 | buildActionMask = 2147483647; 276 | files = ( 277 | ); 278 | runOnlyForDeploymentPostprocessing = 0; 279 | }; 280 | /* End PBXResourcesBuildPhase section */ 281 | 282 | /* Begin PBXShellScriptBuildPhase section */ 283 | 3949D37437D260F438D1666A /* [CP] Check Pods Manifest.lock */ = { 284 | isa = PBXShellScriptBuildPhase; 285 | buildActionMask = 2147483647; 286 | files = ( 287 | ); 288 | inputPaths = ( 289 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock", 290 | "${PODS_ROOT}/Manifest.lock", 291 | ); 292 | name = "[CP] Check Pods Manifest.lock"; 293 | outputPaths = ( 294 | "$(DERIVED_FILE_DIR)/Pods-Aerodramus_ExampleTests-checkManifestLockResult.txt", 295 | ); 296 | runOnlyForDeploymentPostprocessing = 0; 297 | shellPath = /bin/sh; 298 | shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; 299 | showEnvVarsInLog = 0; 300 | }; 301 | 5D81D1C7699DEC71AB140D26 /* [CP] Embed Pods Frameworks */ = { 302 | isa = PBXShellScriptBuildPhase; 303 | buildActionMask = 2147483647; 304 | files = ( 305 | ); 306 | inputPaths = ( 307 | "${PODS_ROOT}/Target Support Files/Pods-Aerodramus_Example/Pods-Aerodramus_Example-frameworks.sh", 308 | "${BUILT_PRODUCTS_DIR}/Aerodramus/Aerodramus.framework", 309 | "${BUILT_PRODUCTS_DIR}/ISO8601DateFormatter/ISO8601DateFormatter.framework", 310 | ); 311 | name = "[CP] Embed Pods Frameworks"; 312 | outputPaths = ( 313 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Aerodramus.framework", 314 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/ISO8601DateFormatter.framework", 315 | ); 316 | runOnlyForDeploymentPostprocessing = 0; 317 | shellPath = /bin/sh; 318 | shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Aerodramus_Example/Pods-Aerodramus_Example-frameworks.sh\"\n"; 319 | showEnvVarsInLog = 0; 320 | }; 321 | 6B9467EDB966891DF7167AD3 /* [CP] Embed Pods Frameworks */ = { 322 | isa = PBXShellScriptBuildPhase; 323 | buildActionMask = 2147483647; 324 | files = ( 325 | ); 326 | inputPaths = ( 327 | "${PODS_ROOT}/Target Support Files/Pods-Aerodramus_ExampleTests/Pods-Aerodramus_ExampleTests-frameworks.sh", 328 | "${BUILT_PRODUCTS_DIR}/Expecta/Expecta.framework", 329 | "${BUILT_PRODUCTS_DIR}/Forgeries/Forgeries.framework", 330 | "${BUILT_PRODUCTS_DIR}/Specta/Specta.framework", 331 | ); 332 | name = "[CP] Embed Pods Frameworks"; 333 | outputPaths = ( 334 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Expecta.framework", 335 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Forgeries.framework", 336 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Specta.framework", 337 | ); 338 | runOnlyForDeploymentPostprocessing = 0; 339 | shellPath = /bin/sh; 340 | shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Aerodramus_ExampleTests/Pods-Aerodramus_ExampleTests-frameworks.sh\"\n"; 341 | showEnvVarsInLog = 0; 342 | }; 343 | A91EF9025193E36DEBA77683 /* [CP] Check Pods Manifest.lock */ = { 344 | isa = PBXShellScriptBuildPhase; 345 | buildActionMask = 2147483647; 346 | files = ( 347 | ); 348 | inputPaths = ( 349 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock", 350 | "${PODS_ROOT}/Manifest.lock", 351 | ); 352 | name = "[CP] Check Pods Manifest.lock"; 353 | outputPaths = ( 354 | "$(DERIVED_FILE_DIR)/Pods-Aerodramus_Example-checkManifestLockResult.txt", 355 | ); 356 | runOnlyForDeploymentPostprocessing = 0; 357 | shellPath = /bin/sh; 358 | shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; 359 | showEnvVarsInLog = 0; 360 | }; 361 | /* End PBXShellScriptBuildPhase section */ 362 | 363 | /* Begin PBXSourcesBuildPhase section */ 364 | 6003F586195388D20070C39A /* Sources */ = { 365 | isa = PBXSourcesBuildPhase; 366 | buildActionMask = 2147483647; 367 | files = ( 368 | 6003F59E195388D20070C39A /* ARAppDelegate.m in Sources */, 369 | 6003F5A7195388D20070C39A /* ARViewController.m in Sources */, 370 | 6003F59A195388D20070C39A /* main.m in Sources */, 371 | ); 372 | runOnlyForDeploymentPostprocessing = 0; 373 | }; 374 | 60E693971C494E1D0058DF5F /* Sources */ = { 375 | isa = PBXSourcesBuildPhase; 376 | buildActionMask = 2147483647; 377 | files = ( 378 | 60E6939E1C494E1D0058DF5F /* AerodramusSpec.m in Sources */, 379 | ); 380 | runOnlyForDeploymentPostprocessing = 0; 381 | }; 382 | /* End PBXSourcesBuildPhase section */ 383 | 384 | /* Begin PBXTargetDependency section */ 385 | 60E693A11C494E1D0058DF5F /* PBXTargetDependency */ = { 386 | isa = PBXTargetDependency; 387 | target = 6003F589195388D20070C39A /* Aerodramus_Example */; 388 | targetProxy = 60E693A01C494E1D0058DF5F /* PBXContainerItemProxy */; 389 | }; 390 | /* End PBXTargetDependency section */ 391 | 392 | /* Begin PBXVariantGroup section */ 393 | 6003F596195388D20070C39A /* InfoPlist.strings */ = { 394 | isa = PBXVariantGroup; 395 | children = ( 396 | 6003F597195388D20070C39A /* en */, 397 | ); 398 | name = InfoPlist.strings; 399 | sourceTree = ""; 400 | }; 401 | /* End PBXVariantGroup section */ 402 | 403 | /* Begin XCBuildConfiguration section */ 404 | 6003F5BD195388D20070C39A /* Debug */ = { 405 | isa = XCBuildConfiguration; 406 | buildSettings = { 407 | ALWAYS_SEARCH_USER_PATHS = NO; 408 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 409 | CLANG_CXX_LIBRARY = "libc++"; 410 | CLANG_ENABLE_MODULES = YES; 411 | CLANG_ENABLE_OBJC_ARC = YES; 412 | CLANG_WARN_BOOL_CONVERSION = YES; 413 | CLANG_WARN_CONSTANT_CONVERSION = YES; 414 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 415 | CLANG_WARN_EMPTY_BODY = YES; 416 | CLANG_WARN_ENUM_CONVERSION = YES; 417 | CLANG_WARN_INT_CONVERSION = YES; 418 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 419 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 420 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 421 | COPY_PHASE_STRIP = NO; 422 | GCC_C_LANGUAGE_STANDARD = gnu99; 423 | GCC_DYNAMIC_NO_PIC = NO; 424 | GCC_OPTIMIZATION_LEVEL = 0; 425 | GCC_PREPROCESSOR_DEFINITIONS = ( 426 | "DEBUG=1", 427 | "$(inherited)", 428 | ); 429 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 430 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 431 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 432 | GCC_WARN_UNDECLARED_SELECTOR = YES; 433 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 434 | GCC_WARN_UNUSED_FUNCTION = YES; 435 | GCC_WARN_UNUSED_VARIABLE = YES; 436 | IPHONEOS_DEPLOYMENT_TARGET = 7.1; 437 | ONLY_ACTIVE_ARCH = YES; 438 | SDKROOT = iphoneos; 439 | TARGETED_DEVICE_FAMILY = "1,2"; 440 | }; 441 | name = Debug; 442 | }; 443 | 6003F5BE195388D20070C39A /* Release */ = { 444 | isa = XCBuildConfiguration; 445 | buildSettings = { 446 | ALWAYS_SEARCH_USER_PATHS = NO; 447 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 448 | CLANG_CXX_LIBRARY = "libc++"; 449 | CLANG_ENABLE_MODULES = YES; 450 | CLANG_ENABLE_OBJC_ARC = YES; 451 | CLANG_WARN_BOOL_CONVERSION = YES; 452 | CLANG_WARN_CONSTANT_CONVERSION = YES; 453 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 454 | CLANG_WARN_EMPTY_BODY = YES; 455 | CLANG_WARN_ENUM_CONVERSION = YES; 456 | CLANG_WARN_INT_CONVERSION = YES; 457 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 458 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 459 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 460 | COPY_PHASE_STRIP = YES; 461 | ENABLE_NS_ASSERTIONS = NO; 462 | GCC_C_LANGUAGE_STANDARD = gnu99; 463 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 464 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 465 | GCC_WARN_UNDECLARED_SELECTOR = YES; 466 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 467 | GCC_WARN_UNUSED_FUNCTION = YES; 468 | GCC_WARN_UNUSED_VARIABLE = YES; 469 | IPHONEOS_DEPLOYMENT_TARGET = 7.1; 470 | SDKROOT = iphoneos; 471 | TARGETED_DEVICE_FAMILY = "1,2"; 472 | VALIDATE_PRODUCT = YES; 473 | }; 474 | name = Release; 475 | }; 476 | 6003F5C0195388D20070C39A /* Debug */ = { 477 | isa = XCBuildConfiguration; 478 | baseConfigurationReference = FAB3B2E07D2AAE0D1E10EE4E /* Pods-Aerodramus_Example.debug.xcconfig */; 479 | buildSettings = { 480 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 481 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; 482 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 483 | GCC_PREFIX_HEADER = "Aerodramus/Aerodramus-Prefix.pch"; 484 | INFOPLIST_FILE = "Aerodramus/Aerodramus-Info.plist"; 485 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 486 | MODULE_NAME = ExampleApp; 487 | PRODUCT_NAME = "$(TARGET_NAME)"; 488 | WRAPPER_EXTENSION = app; 489 | }; 490 | name = Debug; 491 | }; 492 | 6003F5C1195388D20070C39A /* Release */ = { 493 | isa = XCBuildConfiguration; 494 | baseConfigurationReference = ED245C48EB1380A39955E7A4 /* Pods-Aerodramus_Example.release.xcconfig */; 495 | buildSettings = { 496 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 497 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; 498 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 499 | GCC_PREFIX_HEADER = "Aerodramus/Aerodramus-Prefix.pch"; 500 | INFOPLIST_FILE = "Aerodramus/Aerodramus-Info.plist"; 501 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 502 | MODULE_NAME = ExampleApp; 503 | PRODUCT_NAME = "$(TARGET_NAME)"; 504 | WRAPPER_EXTENSION = app; 505 | }; 506 | name = Release; 507 | }; 508 | 60E693A31C494E1D0058DF5F /* Debug */ = { 509 | isa = XCBuildConfiguration; 510 | baseConfigurationReference = 70D2F65BFEA469BB4D195590 /* Pods-Aerodramus_ExampleTests.debug.xcconfig */; 511 | buildSettings = { 512 | BUNDLE_LOADER = "$(TEST_HOST)"; 513 | CLANG_WARN_UNREACHABLE_CODE = YES; 514 | DEBUG_INFORMATION_FORMAT = dwarf; 515 | ENABLE_STRICT_OBJC_MSGSEND = YES; 516 | ENABLE_TESTABILITY = YES; 517 | GCC_NO_COMMON_BLOCKS = YES; 518 | INFOPLIST_FILE = Aerodramus_ExampleTests/Info.plist; 519 | IPHONEOS_DEPLOYMENT_TARGET = 9.2; 520 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 521 | MTL_ENABLE_DEBUG_INFO = YES; 522 | PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.Aerodramus-ExampleTests"; 523 | PRODUCT_NAME = "$(TARGET_NAME)"; 524 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Aerodramus_Example.app/Aerodramus_Example"; 525 | }; 526 | name = Debug; 527 | }; 528 | 60E693A41C494E1D0058DF5F /* Release */ = { 529 | isa = XCBuildConfiguration; 530 | baseConfigurationReference = A4311DBE40B0575719644722 /* Pods-Aerodramus_ExampleTests.release.xcconfig */; 531 | buildSettings = { 532 | BUNDLE_LOADER = "$(TEST_HOST)"; 533 | CLANG_WARN_UNREACHABLE_CODE = YES; 534 | COPY_PHASE_STRIP = NO; 535 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 536 | ENABLE_STRICT_OBJC_MSGSEND = YES; 537 | GCC_NO_COMMON_BLOCKS = YES; 538 | INFOPLIST_FILE = Aerodramus_ExampleTests/Info.plist; 539 | IPHONEOS_DEPLOYMENT_TARGET = 9.2; 540 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 541 | MTL_ENABLE_DEBUG_INFO = NO; 542 | PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.Aerodramus-ExampleTests"; 543 | PRODUCT_NAME = "$(TARGET_NAME)"; 544 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Aerodramus_Example.app/Aerodramus_Example"; 545 | }; 546 | name = Release; 547 | }; 548 | /* End XCBuildConfiguration section */ 549 | 550 | /* Begin XCConfigurationList section */ 551 | 6003F585195388D10070C39A /* Build configuration list for PBXProject "Aerodramus" */ = { 552 | isa = XCConfigurationList; 553 | buildConfigurations = ( 554 | 6003F5BD195388D20070C39A /* Debug */, 555 | 6003F5BE195388D20070C39A /* Release */, 556 | ); 557 | defaultConfigurationIsVisible = 0; 558 | defaultConfigurationName = Release; 559 | }; 560 | 6003F5BF195388D20070C39A /* Build configuration list for PBXNativeTarget "Aerodramus_Example" */ = { 561 | isa = XCConfigurationList; 562 | buildConfigurations = ( 563 | 6003F5C0195388D20070C39A /* Debug */, 564 | 6003F5C1195388D20070C39A /* Release */, 565 | ); 566 | defaultConfigurationIsVisible = 0; 567 | defaultConfigurationName = Release; 568 | }; 569 | 60E693A21C494E1D0058DF5F /* Build configuration list for PBXNativeTarget "Aerodramus_ExampleTests" */ = { 570 | isa = XCConfigurationList; 571 | buildConfigurations = ( 572 | 60E693A31C494E1D0058DF5F /* Debug */, 573 | 60E693A41C494E1D0058DF5F /* Release */, 574 | ); 575 | defaultConfigurationIsVisible = 0; 576 | defaultConfigurationName = Release; 577 | }; 578 | /* End XCConfigurationList section */ 579 | }; 580 | rootObject = 6003F582195388D10070C39A /* Project object */; 581 | } 582 | --------------------------------------------------------------------------------