├── Example ├── Clarifai │ ├── geth.jpg │ ├── Images.xcassets │ │ └── AppIcon.appiconset │ │ │ ├── logo_60x60_2x.png │ │ │ ├── logo_60x60_3x.png │ │ │ └── Contents.json │ ├── RecognitionViewController.h │ ├── AppDelegate.h │ ├── main.m │ ├── CAIFuture.h │ ├── CAIFuture.m │ ├── Info.plist │ ├── AppDelegate.m │ ├── Base.lproj │ │ ├── LaunchScreen.xib │ │ └── Main.storyboard │ └── RecognitionViewController.m ├── Podfile ├── ClarifaiTests │ └── Info.plist └── Clarifai.xcodeproj │ └── project.pbxproj ├── SwiftExample ├── Podfile ├── ClarifaiSwiftDemo │ ├── Assets.xcassets │ │ └── AppIcon.appiconset │ │ │ └── Contents.json │ ├── Info.plist │ ├── Base.lproj │ │ ├── LaunchScreen.storyboard │ │ └── Main.storyboard │ ├── AppDelegate.swift │ └── ViewController.swift └── ClarifaiSwiftDemo.xcodeproj │ └── project.pbxproj ├── Clarifai └── Classes │ ├── ResponseSerializer.h │ ├── NSDictionary+Clarifai.h │ ├── ClarifaiOutputFace.m │ ├── ClarifaiSearchResult.m │ ├── ClarifaiCrop.m │ ├── ClarifaiOutputFace.h │ ├── ClarifaiSearchResult.h │ ├── ClarifaiLocation.m │ ├── ClarifaiOutputFocus.h │ ├── ClarifaiOutputFocus.m │ ├── ClarifaiLocation.h │ ├── ResponseSerializer.m │ ├── ClarifaiModelVersion.m │ ├── ClarifaiModelVersion.h │ ├── ClarifaiGeo.h │ ├── ClarifaiImage.h │ ├── NSDictionary+Clarifai.m │ ├── ClarifaiCrop.h │ ├── ClarifaiConcept.m │ ├── ClarifaiOutputRegion.h │ ├── ClarifaiConcept.h │ ├── ClarifaiOutput.h │ ├── ClarifaiInput.h │ ├── NSArray+Clarifai.h │ ├── ClarifaiInput.m │ ├── ClarifaiOutput.m │ ├── ClarifaiGeo.m │ ├── ClarifaiImage.m │ ├── ClarifaiOutputRegion.m │ ├── ClarifaiConstants.h │ ├── NSArray+Clarifai.m │ ├── ClarifaiSearchTerm.h │ ├── ClarifaiModel.h │ ├── ClarifaiSearchTerm.m │ ├── ClarifaiModel.m │ └── ClarifaiApp.h ├── .travis.yml ├── LICENSE ├── Clarifai.podspec ├── .gitignore └── README.md /Example/Clarifai/geth.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Clarifai/clarifai-ios/HEAD/Example/Clarifai/geth.jpg -------------------------------------------------------------------------------- /Example/Clarifai/Images.xcassets/AppIcon.appiconset/logo_60x60_2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Clarifai/clarifai-ios/HEAD/Example/Clarifai/Images.xcassets/AppIcon.appiconset/logo_60x60_2x.png -------------------------------------------------------------------------------- /Example/Clarifai/Images.xcassets/AppIcon.appiconset/logo_60x60_3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Clarifai/clarifai-ios/HEAD/Example/Clarifai/Images.xcassets/AppIcon.appiconset/logo_60x60_3x.png -------------------------------------------------------------------------------- /SwiftExample/Podfile: -------------------------------------------------------------------------------- 1 | source 'https://github.com/CocoaPods/Specs.git' 2 | 3 | platform :ios, '8.0' 4 | use_frameworks! 5 | 6 | target 'ClarifaiSwiftDemo' do 7 | pod 'Clarifai', :path => '../' 8 | end 9 | -------------------------------------------------------------------------------- /Example/Clarifai/RecognitionViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // RecognitionViewController.h 3 | // ClarifaiApiDemo 4 | // 5 | 6 | @import UIKit; 7 | 8 | @interface RecognitionViewController : UIViewController 9 | @end -------------------------------------------------------------------------------- /Example/Clarifai/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // ClarifaiApiDemo 4 | // 5 | 6 | @import UIKit; 7 | 8 | @interface AppDelegate : UIResponder 9 | @property (strong, nonatomic) UIWindow *window; 10 | @end 11 | 12 | -------------------------------------------------------------------------------- /Example/Podfile: -------------------------------------------------------------------------------- 1 | 2 | source 'https://github.com/CocoaPods/Specs.git' 3 | 4 | platform :ios, '8.0' 5 | 6 | target 'Clarifai' do 7 | pod 'Clarifai', :path => '../' 8 | end 9 | 10 | target 'ClarifaiTests' do 11 | pod 'AFNetworking’, ‘~> 3.1’ 12 | pod 'Clarifai', :path => '../' 13 | end 14 | -------------------------------------------------------------------------------- /Clarifai/Classes/ResponseSerializer.h: -------------------------------------------------------------------------------- 1 | // 2 | // ResponseSerializer.h 3 | // 4 | // Thanks to @sebastianludwig https://github.com/AFNetworking/AFNetworking/issues/2410 5 | // 6 | // 7 | 8 | #import 9 | 10 | @interface ResponseSerializer : AFJSONResponseSerializer 11 | 12 | @end 13 | -------------------------------------------------------------------------------- /Example/Clarifai/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // ClarifaiApiDemo 4 | // 5 | 6 | #import 7 | #import "AppDelegate.h" 8 | 9 | int main(int argc, char * argv[]) { 10 | @autoreleasepool { 11 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: objective-c 2 | osx_image: xcode7 3 | install: 4 | - gem install xcpretty cocoapods --no-rdoc --no-ri --no-document --quiet 5 | script: 6 | - pod install 7 | - set -o pipefail ; xcodebuild test -workspace ClarifaiApiDemo.xcworkspace -scheme ClarifaiApiDemo -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone 5,OS=9.0' | xcpretty -c 8 | -------------------------------------------------------------------------------- /Clarifai/Classes/NSDictionary+Clarifai.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSDictionary+Clarifai.h 3 | // Pods 4 | // 5 | // Created by John Sloan on 4/28/17. 6 | // 7 | // 8 | 9 | @import Foundation; 10 | 11 | @interface NSDictionary (Clarifai) 12 | 13 | - (id)findObjectForKey:(NSString *)key; 14 | 15 | @end 16 | 17 | 18 | @interface NSMutableDictionary (Clarifai) 19 | 20 | - (id)findObjectForKey:(NSString *)key; 21 | 22 | @end 23 | -------------------------------------------------------------------------------- /Clarifai/Classes/ClarifaiOutputFace.m: -------------------------------------------------------------------------------- 1 | // 2 | // ClarifaiOutputFace.m 3 | // Pods 4 | // 5 | // Created by John Sloan on 3/17/17. 6 | // 7 | // 8 | 9 | #import "ClarifaiOutputFace.h" 10 | 11 | @implementation ClarifaiOutputFace 12 | 13 | - (instancetype)initWithDictionary:(NSDictionary *)dict { 14 | self = [super initWithDictionary:dict]; 15 | if (self) { 16 | 17 | } 18 | return self; 19 | } 20 | 21 | @end 22 | -------------------------------------------------------------------------------- /Clarifai/Classes/ClarifaiSearchResult.m: -------------------------------------------------------------------------------- 1 | // 2 | // ClarifaiSearchResult.m 3 | // ClarifaiApiDemo 4 | // 5 | // Created by Jack Rogers on 9/15/16. 6 | // Copyright © 2016 Clarifai, Inc. All rights reserved. 7 | // 8 | 9 | #import "ClarifaiSearchResult.h" 10 | 11 | @implementation ClarifaiSearchResult 12 | 13 | - (instancetype)initWithDictionary:(NSDictionary *)dict { 14 | self = [super initWithDictionary:dict[@"input"]]; 15 | if (self) { 16 | _score = dict[@"score"]; 17 | } 18 | return self; 19 | } 20 | 21 | 22 | @end 23 | -------------------------------------------------------------------------------- /Clarifai/Classes/ClarifaiCrop.m: -------------------------------------------------------------------------------- 1 | // 2 | // ClarifaiCrop.m 3 | // Pods 4 | // 5 | // Created by John Sloan on 10/13/16. 6 | // 7 | // 8 | 9 | #import "ClarifaiCrop.h" 10 | 11 | @implementation ClarifaiCrop 12 | 13 | - (instancetype)initWithTop:(CGFloat)top left:(CGFloat)left bottom:(CGFloat)bottom right:(CGFloat)right { 14 | self = [super init]; 15 | if (self) { 16 | self.top = top; 17 | self.left = left; 18 | self.bottom = bottom; 19 | self.right = right; 20 | } 21 | return self; 22 | } 23 | 24 | @end 25 | -------------------------------------------------------------------------------- /Clarifai/Classes/ClarifaiOutputFace.h: -------------------------------------------------------------------------------- 1 | // 2 | // ClarifaiConcept.h 3 | // Clarifai API Client 4 | // 5 | // Created by John Sloan on 3/20/17. 6 | // Copyright © 2017 Clarifai, Inc. All rights reserved. 7 | // 8 | 9 | #import "ClarifaiOutput.h" 10 | #import "ClarifaiOutputRegion.h" 11 | 12 | @interface ClarifaiOutputFace : ClarifaiOutput 13 | 14 | /** The bounding boxes of all faces detected. */ 15 | @property (strong,nonatomic) NSArray *faces; 16 | 17 | - (instancetype)initWithDictionary:(NSDictionary *)dict; 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /Clarifai/Classes/ClarifaiSearchResult.h: -------------------------------------------------------------------------------- 1 | // 2 | // ClarifaiSearchResult.h 3 | // ClarifaiApiDemo 4 | // 5 | // Created by Jack Rogers on 9/15/16. 6 | // Copyright © 2016 Clarifai, Inc. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "ClarifaiInput.h" 11 | 12 | /** 13 | * ClarifaiSearchResults are returned when searching across inputs in your application. 14 | */ 15 | @interface ClarifaiSearchResult : ClarifaiInput 16 | 17 | /** The score of the input */ 18 | @property (strong, nonatomic) NSNumber *score; 19 | 20 | @end 21 | -------------------------------------------------------------------------------- /Clarifai/Classes/ClarifaiLocation.m: -------------------------------------------------------------------------------- 1 | // 2 | // ClarifaiLocation.m 3 | // Pods 4 | // 5 | // Created by John Sloan on 2/3/17. 6 | // 7 | // 8 | 9 | #import "ClarifaiLocation.h" 10 | 11 | @implementation ClarifaiLocation 12 | 13 | - (instancetype)initWithLatitude:(double)latitude longitude:(double)longitude { 14 | self = [super init]; 15 | if (self) { 16 | _latitude = latitude; 17 | _longitude = longitude; 18 | } 19 | return self; 20 | } 21 | 22 | - (CLLocation *)clLocation { 23 | return [[CLLocation alloc] initWithLatitude:_latitude longitude:_longitude]; 24 | } 25 | 26 | @end 27 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2016 Clarifai, Inc. 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. 5 | You may obtain a copy of the License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software 10 | distributed under the License is distributed on an "AS IS" BASIS, 11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | See the License for the specific language governing permissions and 13 | limitations under the License. 14 | -------------------------------------------------------------------------------- /Clarifai/Classes/ClarifaiOutputFocus.h: -------------------------------------------------------------------------------- 1 | // 2 | // ClarifaiOutputFocus.h 3 | // Pods 4 | // 5 | // Created by John Sloan on 3/17/17. 6 | // 7 | // 8 | 9 | #import "ClarifaiOutput.h" 10 | #import "ClarifaiOutputRegion.h" 11 | 12 | @interface ClarifaiOutputFocus : ClarifaiOutput 13 | 14 | /** The greatest focus density detected. */ 15 | @property (nonatomic) double focusDensity; 16 | 17 | /** The bounding boxes of all focus regions detected. */ 18 | @property (strong,nonatomic) NSArray *focusRegions; 19 | 20 | - (instancetype)initWithDictionary:(NSDictionary *)dict; 21 | 22 | @end 23 | -------------------------------------------------------------------------------- /Clarifai.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | s.name = 'Clarifai' 3 | s.version = '2.3.2' 4 | s.summary = 'Clarifai API client for Objective-C.' 5 | 6 | s.homepage = 'https://github.com/Clarifai' 7 | s.license = { :type => 'Apache', :file => 'LICENSE' } 8 | s.author = { 'John Sloan' => 'johnsloan@clarifai.com', 'Jack Rogers' => 'jack@clarifai.com' } 9 | 10 | s.platform = :ios, '8.0' 11 | s.source = {:git => 'https://github.com/Clarifai/clarifai-ios.git', :tag => s.version.to_s} 12 | s.source_files = 'Clarifai/Classes/*' 13 | 14 | s.dependency 'AFNetworking', '~> 3.1' 15 | end 16 | -------------------------------------------------------------------------------- /Clarifai/Classes/ClarifaiOutputFocus.m: -------------------------------------------------------------------------------- 1 | // 2 | // ClarifaiOutputFocus.m 3 | // Pods 4 | // 5 | // Created by John Sloan on 3/17/17. 6 | // 7 | // 8 | 9 | #import "ClarifaiOutputFocus.h" 10 | 11 | @implementation ClarifaiOutputFocus 12 | 13 | - (instancetype)initWithDictionary:(NSDictionary *)dict { 14 | self = [super initWithDictionary:dict]; 15 | if (self) { 16 | // add focus value to output, if present. 17 | NSDictionary *focus = [dict findObjectForKey:@"focus"]; 18 | if (![focus isKindOfClass: [NSNull class]]) { 19 | _focusDensity = [[focus findObjectForKey:@"value"] doubleValue]; 20 | } 21 | } 22 | return self; 23 | } 24 | 25 | @end 26 | -------------------------------------------------------------------------------- /Clarifai/Classes/ClarifaiLocation.h: -------------------------------------------------------------------------------- 1 | // 2 | // ClarifaiLocation.h 3 | // Pods 4 | // 5 | // Created by John Sloan on 2/3/17. 6 | // 7 | // 8 | 9 | #import 10 | #import 11 | 12 | @interface ClarifaiLocation : NSObject 13 | 14 | /** The latitude of the location, in degrees. */ 15 | @property (nonatomic) double latitude; 16 | 17 | /** The longitude of the location, in degrees. */ 18 | @property (nonatomic) double longitude; 19 | 20 | /** Initialize a new location with latidude and longitude, in degrees. */ 21 | - (instancetype)initWithLatitude:(double)latitude longitude:(double)longitude; 22 | 23 | /** Returns a CLLocation object from the location's latitude and longitude. */ 24 | - (CLLocation *)clLocation; 25 | 26 | @end 27 | -------------------------------------------------------------------------------- /Clarifai/Classes/ResponseSerializer.m: -------------------------------------------------------------------------------- 1 | // 2 | // ResponseSerializer.m 3 | // 4 | // 5 | 6 | #import "ResponseSerializer.h" 7 | 8 | @implementation ResponseSerializer 9 | 10 | - (id)responseObjectForResponse:(NSURLResponse *)response 11 | data:(NSData *)data 12 | error:(NSError *__autoreleasing *)errorPointer 13 | { 14 | id responseObject = [super responseObjectForResponse:response data:data error:errorPointer]; 15 | if (*errorPointer) { 16 | NSError *error = *errorPointer; 17 | NSMutableDictionary *userInfo = [error.userInfo mutableCopy]; 18 | userInfo[@"responseObject"] = responseObject; 19 | *errorPointer = [NSError errorWithDomain:error.domain code:error.code userInfo:[userInfo copy]]; 20 | } 21 | return responseObject; 22 | } 23 | 24 | @end 25 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | build/ 4 | *.pbxuser 5 | !default.pbxuser 6 | *.mode1v3 7 | !default.mode1v3 8 | *.mode2v3 9 | !default.mode2v3 10 | *.perspectivev3 11 | !default.perspectivev3 12 | xcuserdata 13 | *.xccheckout 14 | *.moved-aside 15 | DerivedData 16 | *.hmap 17 | *.ipa 18 | *.xcuserstate 19 | *.log 20 | 21 | # CocoaPods 22 | # 23 | # CocoaPods recommends against adding the Pods directory to your .gitignore. However, 24 | # checking in your dependencies seems unnecessary and leads to lots of churn as you add 25 | # and remove dependencies, so we will add it here. See also: 26 | # http://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control 27 | # 28 | Pods/ 29 | *.xcworkspace/ 30 | Podfile.lock 31 | 32 | # OS X 33 | .DS_Store 34 | Icon? 35 | 36 | # Thumbnails 37 | ._* 38 | -------------------------------------------------------------------------------- /Clarifai/Classes/ClarifaiModelVersion.m: -------------------------------------------------------------------------------- 1 | // 2 | // ClarifaiModelVersion.m 3 | // ClarifaiApiDemo 4 | // 5 | // Created by John Sloan on 9/15/16. 6 | // Copyright © 2016 Clarifai, Inc. All rights reserved. 7 | // 8 | 9 | #import "ClarifaiModelVersion.h" 10 | 11 | @implementation ClarifaiModelVersion 12 | 13 | - (instancetype)initWithDictionary:(NSDictionary *)dict { 14 | NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; 15 | dateFormatter.dateFormat = @"yyyy-MM-dd'T'HH:mm:ss'Z'"; 16 | self = [super init]; 17 | if (self) { 18 | _versionID = dict[@"id"]; 19 | _createdAt = [dateFormatter dateFromString:dict[@"created_at"]]; 20 | _statusCode = dict[@"status"][@"code"]; 21 | _statusDescription = dict[@"status"][@"description"]; 22 | } 23 | return self; 24 | } 25 | 26 | @end 27 | -------------------------------------------------------------------------------- /Example/ClarifaiTests/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 | -------------------------------------------------------------------------------- /Clarifai/Classes/ClarifaiModelVersion.h: -------------------------------------------------------------------------------- 1 | // 2 | // ClarifaiModelVersion.h 3 | // ClarifaiApiDemo 4 | // 5 | // Created by John Sloan on 9/15/16. 6 | // Copyright © 2016 Clarifai, Inc. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | /** 12 | * ClarifaiModelVersion contains version info for models. 13 | */ 14 | @interface ClarifaiModelVersion : NSObject 15 | 16 | /** The version id of the model. */ 17 | @property (strong, nonatomic) NSString *versionID; 18 | 19 | /** The data the version was created. */ 20 | @property (strong, nonatomic) NSDate *createdAt; 21 | 22 | /** The status code of this version of the model. */ 23 | @property (strong, nonatomic) NSNumber *statusCode; 24 | 25 | /** A description of the status of this version of the model (i.e "Model not yet trained"). */ 26 | @property (strong, nonatomic) NSString *statusDescription; 27 | 28 | - (instancetype)initWithDictionary:(NSDictionary *)dict; 29 | 30 | @end 31 | -------------------------------------------------------------------------------- /Example/Clarifai/CAIFuture.h: -------------------------------------------------------------------------------- 1 | // 2 | // CAIFuture.h 3 | // 4 | 5 | @import Foundation; 6 | 7 | /** 8 | * Represents the result of an asynchronous computation. Methods are provided to set the result of 9 | * the computation and block until the computation is complete. 10 | */ 11 | @interface CAIFuture : NSObject 12 | @property (strong, nonatomic) NSError *error; 13 | 14 | /** Initializes with a nil default value. */ 15 | - (instancetype)init; 16 | 17 | /** Initializes with a given default result. */ 18 | - (instancetype)initWithDefault:(id)defaultResult; 19 | 20 | /** Blocks until the task is done, then returns the value. */ 21 | - (id)getResult; 22 | 23 | /** Blocks until the task is done or timeout expires, then returns the value. */ 24 | - (id)getResultWithTimeout:(NSTimeInterval)timeout; 25 | 26 | /** Sets the result and unblocks anyone waiting. */ 27 | - (void)setResult:(id)value; 28 | 29 | /** Sets the result and error and unblocks anyone waiting. Either can be nil. */ 30 | - (void)setResult:(id)result error:(NSError *)error; 31 | 32 | @end 33 | -------------------------------------------------------------------------------- /Example/Clarifai/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "20x20", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "20x20", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "29x29", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "29x29", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "40x40", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "40x40", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "size" : "60x60", 35 | "idiom" : "iphone", 36 | "filename" : "logo_60x60_2x.png", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "size" : "60x60", 41 | "idiom" : "iphone", 42 | "filename" : "logo_60x60_3x.png", 43 | "scale" : "3x" 44 | } 45 | ], 46 | "info" : { 47 | "version" : 1, 48 | "author" : "xcode" 49 | } 50 | } -------------------------------------------------------------------------------- /Example/Clarifai/CAIFuture.m: -------------------------------------------------------------------------------- 1 | // 2 | // CAIFuture.m 3 | // 4 | 5 | #import "CAIFuture.h" 6 | 7 | @interface CAIFuture () 8 | @property (strong, nonatomic) id result; 9 | @property (strong, nonatomic) dispatch_semaphore_t semaphore; 10 | @end 11 | 12 | @implementation CAIFuture 13 | 14 | - (instancetype)init { 15 | return [self initWithDefault:nil]; 16 | } 17 | 18 | - (instancetype)initWithDefault:(id)defaultResult { 19 | if (self = [super init]) { 20 | _result = defaultResult; 21 | _semaphore = dispatch_semaphore_create(0); 22 | } 23 | return self; 24 | } 25 | 26 | - (id)getResult { 27 | dispatch_semaphore_wait(_semaphore, DISPATCH_TIME_FOREVER); 28 | return _result; 29 | } 30 | 31 | - (id)getResultWithTimeout:(NSTimeInterval)timeout { 32 | dispatch_semaphore_wait(_semaphore, 33 | dispatch_time(DISPATCH_TIME_NOW, (int64_t)(timeout * NSEC_PER_SEC))); 34 | return _result; 35 | } 36 | 37 | - (void)setResult:(id)result { 38 | _result = result; 39 | dispatch_semaphore_signal(_semaphore); 40 | } 41 | 42 | - (void)setResult:(id)result error:(NSError *)error { 43 | _result = result; 44 | _error = error; 45 | dispatch_semaphore_signal(_semaphore); 46 | } 47 | 48 | @end 49 | -------------------------------------------------------------------------------- /Clarifai/Classes/ClarifaiGeo.h: -------------------------------------------------------------------------------- 1 | // 2 | // ClarifaiGeo.h 3 | // Pods 4 | // 5 | // Created by John Sloan on 2/15/17. 6 | // 7 | // 8 | 9 | #import 10 | #import "ClarifaiLocation.h" 11 | 12 | typedef NS_ENUM(NSInteger, ClarifaiRadiusUnit) { 13 | ClarifaiRadiusUnitMiles, 14 | ClarifaiRadiusUnitKilometers, 15 | ClarifaiRadiusUnitDegrees, 16 | ClarifaiRadiusUnitRadians 17 | }; 18 | 19 | @interface ClarifaiGeoBox : NSObject 20 | 21 | @property (strong, nonatomic) ClarifaiLocation *startLoc; 22 | @property (strong, nonatomic) ClarifaiLocation *endLoc; 23 | 24 | @end 25 | 26 | @interface ClarifaiGeo : NSObject 27 | 28 | @property (strong, nonatomic) ClarifaiGeoBox *geoBox; 29 | @property (strong, nonatomic) ClarifaiLocation *geoPoint; 30 | @property (strong, nonatomic) NSNumber *radius; 31 | @property (strong, nonatomic) NSString *unitType; 32 | 33 | - (instancetype)initWithLocation:(ClarifaiLocation *)location andRadius:(double)radius; 34 | - (instancetype)initWithLocation:(ClarifaiLocation *)location radius:(double)radius andRadiusUnit:(ClarifaiRadiusUnit)unit; 35 | - (instancetype)initWithGeoBoxFromStartLocation:(ClarifaiLocation *)startLocation toEndLocation:(ClarifaiLocation *)endLocation; 36 | - (void)setRadiusUnit:(ClarifaiRadiusUnit)unit; 37 | - (NSDictionary *) geoFilterAsDictionary; 38 | 39 | @end 40 | -------------------------------------------------------------------------------- /Example/Clarifai/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | ClarifaiAPI 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 2.0.1 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1 25 | LSRequiresIPhoneOS 26 | 27 | NSPhotoLibraryUsageDescription 28 | Uses photos as a demo 29 | UILaunchStoryboardName 30 | LaunchScreen 31 | UIMainStoryboardFile 32 | Main 33 | UIRequiredDeviceCapabilities 34 | 35 | armv7 36 | 37 | UISupportedInterfaceOrientations 38 | 39 | UIInterfaceOrientationPortrait 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /SwiftExample/ClarifaiSwiftDemo/Assets.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" : "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 | "idiom" : "iphone", 25 | "size" : "60x60", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "60x60", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "ipad", 35 | "size" : "29x29", 36 | "scale" : "1x" 37 | }, 38 | { 39 | "idiom" : "ipad", 40 | "size" : "29x29", 41 | "scale" : "2x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "40x40", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "size" : "40x40", 51 | "scale" : "2x" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "size" : "76x76", 56 | "scale" : "1x" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "size" : "76x76", 61 | "scale" : "2x" 62 | } 63 | ], 64 | "info" : { 65 | "version" : 1, 66 | "author" : "xcode" 67 | } 68 | } -------------------------------------------------------------------------------- /Clarifai/Classes/ClarifaiImage.h: -------------------------------------------------------------------------------- 1 | // 2 | // ClarifaiImage.h 3 | // ClarifaiApiDemo 4 | // 5 | // Created by John Sloan on 9/1/16. 6 | // Copyright © 2016 Clarifai, Inc. All rights reserved. 7 | // 8 | 9 | #import "ClarifaiInput.h" 10 | #import 11 | #import 12 | #import "ClarifaiCrop.h" 13 | 14 | /** 15 | * ClarifaiImage is a subclass of ClarifaiInput used specifically for images. 16 | */ 17 | @interface ClarifaiImage : ClarifaiInput 18 | 19 | /** A crop for media can be specified when adding. Nil otherwise. */ 20 | @property ClarifaiCrop *crop; 21 | 22 | /** Optionally, you can set a UIImage instead of a ClarifaiInput's mediaURL. Set this using an initializer so that the mediaData parameter is also properly set. */ 23 | @property (strong, nonatomic) UIImage *image; 24 | 25 | - (instancetype)initWithImage:(UIImage *)image; 26 | 27 | - (instancetype)initWithImage:(UIImage *)image andCrop:(ClarifaiCrop *)crop; 28 | 29 | /* The concepts array can take ClarifaiConcepts or NSStrings. If it finds strings, it will automatically create concepts named with the given strings. */ 30 | - (instancetype)initWithImage:(UIImage *)image andConcepts:(NSArray *)concepts; 31 | 32 | - (instancetype)initWithImage:(UIImage *)image crop:(ClarifaiCrop *)crop andConcepts:(NSArray *)concepts; 33 | 34 | - (instancetype)initWithURL:(NSString *)url andCrop:(ClarifaiCrop *)crop; 35 | 36 | - (instancetype)initWithURL:(NSString *)url crop:(ClarifaiCrop *)crop andConcepts:(NSArray *)concepts; 37 | @end 38 | -------------------------------------------------------------------------------- /Clarifai/Classes/NSDictionary+Clarifai.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSDictionary+Clarifai.m 3 | // Pods 4 | // 5 | // Created by John Sloan on 4/28/17. 6 | // 7 | // 8 | 9 | #import "NSDictionary+Clarifai.h" 10 | 11 | @implementation NSDictionary (Clarifai) 12 | 13 | - (id)findObjectForKey:(NSString *)key { 14 | return [self findObjectForKey:key inDictionary:self]; 15 | } 16 | 17 | - (id)findObjectForKey:(NSString *)key inDictionary:(NSDictionary *)dict { 18 | if (dict == nil) { 19 | return nil; 20 | } 21 | if ([dict objectForKey:key]) { 22 | return [dict objectForKey:key]; 23 | } else { 24 | id object = nil; 25 | for (NSString *newKey in [dict allKeys]) { 26 | if ([dict[newKey] isKindOfClass:[NSDictionary class]]) { 27 | object = [self findObjectForKey:key inDictionary:dict[newKey]]; 28 | if (object) break; 29 | } 30 | } 31 | return object; 32 | } 33 | } 34 | 35 | @end 36 | 37 | @implementation NSMutableDictionary (Clarifai) 38 | 39 | - (id)findObjectForKey:(NSString *)key { 40 | return [self findObjectForKey:key inDictionary:self]; 41 | } 42 | 43 | - (id)findObjectForKey:(NSString *)key inDictionary:(NSDictionary *)dict { 44 | if (dict == nil) { 45 | return nil; 46 | } 47 | if ([dict objectForKey:key]) { 48 | return [dict objectForKey:key]; 49 | } else { 50 | id object = nil; 51 | for (NSString *newKey in [dict allKeys]) { 52 | if ([dict[newKey] isKindOfClass:[NSDictionary class]]) { 53 | object = [self findObjectForKey:key inDictionary:dict[newKey]]; 54 | if (object) break; 55 | } 56 | } 57 | return object; 58 | } 59 | } 60 | 61 | @end 62 | -------------------------------------------------------------------------------- /Clarifai/Classes/ClarifaiCrop.h: -------------------------------------------------------------------------------- 1 | // 2 | // ClarifaiCrop.h 3 | // Pods 4 | // 5 | // Created by John Sloan on 10/13/16. 6 | // 7 | // 8 | 9 | #import 10 | 11 | /** 12 | * When adding an input, you can specify crop points. The API will 13 | * crop the image and use the resulting image. Crop points are given 14 | * as percentages from the top left point in the order of top, left, bottom and right. 15 | */ 16 | @interface ClarifaiCrop : NSObject 17 | 18 | /** 19 | * Specifies the top edge as a percentage of the original image (a float from 0-1). 20 | * With a value of 0.2 the cropped image will have a top edge that starts 20% down from the original top edge. 21 | */ 22 | @property (nonatomic) CGFloat top; 23 | 24 | /** 25 | * Specifies the left edge as a percentage of the original image (a float from 0-1). 26 | * With a value of 0.4 the cropped image will have a left edge that starts 40% from the original left edge. 27 | */ 28 | @property (nonatomic) CGFloat left; 29 | 30 | /** 31 | * Specifies the bottom edge as a percentage of the original image (a float from 0-1). 32 | * With a value of 0.3 the cropped image will have a bottom edge that starts 30% from the original top edge. 33 | */ 34 | @property (nonatomic) CGFloat bottom; 35 | 36 | /** 37 | * Specifies the right edge as a percentage of the original image (a float from 0-1). 38 | * With a value of 0.6 the cropped image will have a right edge that starts 60% from the original left edge. 39 | */ 40 | @property (nonatomic) CGFloat right; 41 | 42 | - (instancetype)initWithTop:(CGFloat)top left:(CGFloat)left bottom:(CGFloat)bottom right:(CGFloat)right; 43 | 44 | @end 45 | -------------------------------------------------------------------------------- /SwiftExample/ClarifaiSwiftDemo/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 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | NSPhotoLibraryUsageDescription 24 | Allows user to select image to predict tags on. 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UISupportedInterfaceOrientations 34 | 35 | UIInterfaceOrientationPortrait 36 | 37 | UISupportedInterfaceOrientations~ipad 38 | 39 | UIInterfaceOrientationPortrait 40 | UIInterfaceOrientationPortraitUpsideDown 41 | UIInterfaceOrientationLandscapeLeft 42 | UIInterfaceOrientationLandscapeRight 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /Clarifai/Classes/ClarifaiConcept.m: -------------------------------------------------------------------------------- 1 | // 2 | // ClarifaiConcept.m 3 | // ClarifaiApiDemo 4 | // 5 | // Created by John Sloan on 9/1/16. 6 | // Copyright © 2016 Clarifai, Inc. All rights reserved. 7 | // 8 | 9 | #import "ClarifaiConcept.h" 10 | 11 | @implementation ClarifaiConcept 12 | 13 | - (instancetype)initWithDictionary:(NSDictionary *)dict { 14 | self = [super init]; 15 | if (self) { 16 | _conceptID = dict[@"id"]; 17 | _conceptName = dict[@"name"]; 18 | _appID = dict[@"app_id"]; 19 | 20 | if (dict[@"language"] != nil) { 21 | _language = dict[@"language"]; 22 | } 23 | 24 | if (dict[@"value"] != nil && dict[@"value"] != [NSNull null]) { 25 | _score = [dict[@"value"] floatValue]; 26 | } 27 | } 28 | return self; 29 | } 30 | 31 | - (instancetype)initWithConceptName:(NSString *)conceptName { 32 | self = [super init]; 33 | if (self) { 34 | _conceptName = conceptName; 35 | _conceptID = conceptName; 36 | 37 | //default to one(true) when adding with an input. 38 | //This means the concept is positively associated with the input. 39 | _score = 1; 40 | } 41 | return self; 42 | } 43 | 44 | - (instancetype)initWithConceptID:(NSString *)conceptID { 45 | self = [super init]; 46 | if (self) { 47 | _conceptID = conceptID; 48 | _conceptName = conceptID; 49 | _score = 1; 50 | } 51 | return self; 52 | } 53 | 54 | - (instancetype)initWithConceptName:(NSString *)conceptName conceptID:(NSString *)conceptID { 55 | self = [super init]; 56 | if (self) { 57 | _conceptName = conceptName; 58 | _conceptID = conceptID; 59 | _score = 1; 60 | } 61 | return self; 62 | } 63 | 64 | 65 | @end 66 | -------------------------------------------------------------------------------- /Clarifai/Classes/ClarifaiOutputRegion.h: -------------------------------------------------------------------------------- 1 | // 2 | // ClarifaiOutputRegion.h 3 | // Pods 4 | // 5 | // Created by John Sloan on 3/20/17. 6 | // 7 | // 8 | 9 | #import 10 | #import "ClarifaiConcept.h" 11 | 12 | @interface ClarifaiOutputRegion : NSObject 13 | 14 | /** Defines the boudning box of the region. */ 15 | @property double top; 16 | @property double left; 17 | @property double bottom; 18 | @property double right; 19 | 20 | /** Predictions for the current region of the image. This is only populated in some models, like Clarifai's Logo model. */ 21 | @property (strong, nonatomic) NSArray *concepts; 22 | 23 | /** If predicting with Clarifai's Blur model, this represents the density of the current focus region. */ 24 | @property (nonatomic) double focusDensity; 25 | 26 | /** If predicting with Clarifai's Demographics model, this represents a detected face's age appearance. */ 27 | @property (strong, nonatomic) NSArray *ageAppearance; 28 | 29 | /** If predicting with Clarifai's Demographics model, this represents a detected face's gender appearance. */ 30 | @property (strong, nonatomic) NSArray *genderAppearance; 31 | 32 | /** If predicting with Clarifai's Demographics model, this represents a detected face's multicultural appearance. */ 33 | @property (strong, nonatomic) NSArray *multiculturalAppearance; 34 | 35 | /** If predicting with Clarifai's Celebrity model or similar, this represents a detected face's predicted identity. */ 36 | @property (strong, nonatomic) NSArray *identity; 37 | 38 | /** Initializes an output region from the api response dictionary. */ 39 | - (instancetype)initWithDictionary:(NSDictionary *)dict; 40 | 41 | @end 42 | -------------------------------------------------------------------------------- /Clarifai/Classes/ClarifaiConcept.h: -------------------------------------------------------------------------------- 1 | // 2 | // ClarifaiConcept.h 3 | // ClarifaiApiDemo 4 | // 5 | // Created by John Sloan on 9/1/16. 6 | // Copyright © 2016 Clarifai, Inc. All rights reserved. 7 | // 8 | 9 | #import 10 | @class ClarifaiModel; 11 | 12 | /** 13 | * A ClarifaiConcept represents a tag that will be predicted from an image (or any input). You can also use this class to create your own tags when adding to inputs or creating custom models. 14 | */ 15 | @interface ClarifaiConcept : NSObject 16 | 17 | /** The model that this concept is associated with. */ 18 | @property (strong, nonatomic) ClarifaiModel *model; 19 | 20 | /** The id of the concept. */ 21 | @property (strong, nonatomic) NSString *conceptID; 22 | 23 | /** The name of the concept. */ 24 | @property (strong, nonatomic) NSString *conceptName; 25 | 26 | /** The id of the app that this concept is associated with. */ 27 | @property (strong, nonatomic) NSString *appID; 28 | 29 | /** The language of the concept name, or the default language of the ClarifaiApp. */ 30 | @property (nonatomic) NSString *language; 31 | 32 | /** The score of the concept. This is set to true(1) or false(0) when using the concept as a training input. And it is set as a prediction probability, between 0-1, when returned with an output. */ 33 | @property (nonatomic) float score; 34 | 35 | /** If no ID is specified, conceptID will match conceptName. */ 36 | - (instancetype)initWithConceptName:(NSString *)conceptName; 37 | 38 | /** If no Name is specified, conceptID will match conceptName. */ 39 | - (instancetype)initWithConceptID:(NSString *)conceptID; 40 | 41 | /** Initializes concept with given name and ID */ 42 | - (instancetype)initWithConceptName:(NSString *)conceptName conceptID:(NSString *)conceptID; 43 | 44 | - (instancetype)initWithDictionary:(NSDictionary *)dict; 45 | @end 46 | -------------------------------------------------------------------------------- /SwiftExample/ClarifaiSwiftDemo/Base.lproj/LaunchScreen.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 | -------------------------------------------------------------------------------- /Clarifai/Classes/ClarifaiOutput.h: -------------------------------------------------------------------------------- 1 | // 2 | // ClarifaiOutput.h 3 | // ClarifaiApiDemo 4 | // 5 | // Created by John Sloan on 9/1/16. 6 | // Copyright © 2016 Clarifai, Inc. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | #import "ClarifaiModel.h" 12 | #import "ClarifaiConcept.h" 13 | #import "ClarifaiInput.h" 14 | #import "ClarifaiOutputRegion.h" 15 | #import "NSDictionary+Clarifai.h" 16 | 17 | /** 18 | * A ClarifaiOutput is the result of a model's predictions on an input. It contains a list of the predicted concepts with corresponding scores (probabilities from 0-1) for each. It will also contain a reference to the original input that was predicted on. 19 | */ 20 | @interface ClarifaiOutput : NSObject 21 | 22 | /** Predictions for the piece of media. */ 23 | @property (strong, nonatomic) NSArray *concepts; 24 | 25 | /** Colors in the piece of media. This will only be populated when using the Clarifai Color Model. */ 26 | @property (strong, nonatomic) NSArray *colors; 27 | 28 | /** Embedding for the piece of media. This will only be populated when using an model with embed modelType. */ 29 | @property (strong, nonatomic) NSArray *embedding; 30 | 31 | /** Cluster ID. */ 32 | @property (strong, nonatomic) NSString *clusterID; 33 | 34 | /** The input that was predicted on. */ 35 | @property (strong, nonatomic) ClarifaiInput *input; 36 | 37 | /** An array of detected output regions. Some models detect specific regions with bounding boxes or localized predictions. */ 38 | @property (strong, nonatomic) NSArray *regions; 39 | 40 | /** The entire 'data' dictionary returned from the API for a model prediction. If a model type is not currently supported, this dictionary can be used for customized use cases. */ 41 | @property (strong, nonatomic) NSDictionary *responseDict; 42 | 43 | - (instancetype)initWithDictionary:(NSDictionary *)dict; 44 | 45 | @end 46 | -------------------------------------------------------------------------------- /Clarifai/Classes/ClarifaiInput.h: -------------------------------------------------------------------------------- 1 | // 2 | // ClarifaiInput.h 3 | // ClarifaiApiDemo 4 | // 5 | // Created by John Sloan on 9/1/16. 6 | // Copyright © 2016 Clarifai, Inc. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "ClarifaiConcept.h" 11 | #import "ClarifaiLocation.h" 12 | 13 | /** 14 | * ClarifaiInputs are used to represent the inputs of an application. For example, an input can contain an image and a list of concepts (or tags) associated with this image. These can then be added to an app, used as training data for models, or searched across. 15 | */ 16 | @interface ClarifaiInput : NSObject 17 | 18 | /** ID of the piece of media in your Clarifai app. */ 19 | @property (strong, nonatomic) NSString *inputID; 20 | 21 | /** URL of the piece of media in your Clarifai app. */ 22 | @property (strong, nonatomic) NSString *mediaURL; 23 | 24 | 25 | /** Data for media to be added to app. 26 | (only to be used when adding media to your app, nil otherwise) */ 27 | @property (strong, nonatomic) NSData *mediaData; 28 | 29 | /** Time when the piece of media was added to your Clarifai app. */ 30 | @property (strong, nonatomic) NSDate *creationDate; 31 | 32 | /** Concepts associated with this input. */ 33 | @property (strong, nonatomic) NSArray *concepts; 34 | 35 | /** If set to true, this input can use a duplicate url of one already added to the app. Defaults to false. (only to be used when adding media to your app) */ 36 | @property BOOL allowDuplicateURLs; 37 | 38 | /** Optionally you can set metadata for each input, which can be searched on within your app. This can be any valid json object.*/ 39 | @property (strong, nonatomic) NSDictionary *metadata; 40 | 41 | @property (strong, nonatomic) ClarifaiLocation *location; 42 | 43 | - (instancetype)initWithURL:(NSString *)url; 44 | - (instancetype)initWithURL:(NSString *)URL andConcepts:(NSArray *)concepts; 45 | 46 | - (instancetype)initWithDictionary:(NSDictionary *)dict; 47 | 48 | @end 49 | -------------------------------------------------------------------------------- /Example/Clarifai/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // ClarifaiApiDemo 4 | // 5 | 6 | #import "AppDelegate.h" 7 | 8 | @interface AppDelegate () 9 | @end 10 | 11 | @implementation AppDelegate 12 | 13 | 14 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 15 | // Override point for customization after application launch. 16 | return YES; 17 | } 18 | 19 | - (void)applicationWillResignActive:(UIApplication *)application { 20 | // 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. 21 | // 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. 22 | } 23 | 24 | - (void)applicationDidEnterBackground:(UIApplication *)application { 25 | // 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. 26 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 27 | } 28 | 29 | - (void)applicationWillEnterForeground:(UIApplication *)application { 30 | // 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. 31 | } 32 | 33 | - (void)applicationDidBecomeActive:(UIApplication *)application { 34 | // 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. 35 | } 36 | 37 | - (void)applicationWillTerminate:(UIApplication *)application { 38 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 39 | } 40 | 41 | @end 42 | -------------------------------------------------------------------------------- /SwiftExample/ClarifaiSwiftDemo/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // ClarifaiSwiftDemo 4 | // 5 | // Created by John Sloan on 3/31/17. 6 | // Copyright © 2017 Clarifai. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | @UIApplicationMain 12 | class AppDelegate: UIResponder, UIApplicationDelegate { 13 | 14 | var window: UIWindow? 15 | 16 | 17 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { 18 | // Override point for customization after application launch. 19 | return true 20 | } 21 | 22 | func applicationWillResignActive(_ application: UIApplication) { 23 | // 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. 24 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. 25 | } 26 | 27 | func applicationDidEnterBackground(_ application: UIApplication) { 28 | // 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. 29 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 30 | } 31 | 32 | func applicationWillEnterForeground(_ application: UIApplication) { 33 | // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. 34 | } 35 | 36 | func applicationDidBecomeActive(_ application: UIApplication) { 37 | // 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. 38 | } 39 | 40 | func applicationWillTerminate(_ application: UIApplication) { 41 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 42 | } 43 | 44 | 45 | } 46 | 47 | -------------------------------------------------------------------------------- /Clarifai/Classes/NSArray+Clarifai.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSArray+Clarifai.h 3 | // ClarifaiPhotos 4 | // 5 | // Created by Keith Ito on 4/1/15. 6 | // Copyright (c) 2015 Clarifai, Inc. All rights reserved. 7 | // 8 | 9 | @import Foundation; 10 | 11 | typedef id (^CAIMapFunction)(id input); 12 | typedef BOOL (^CAIFilterFunction)(id input); 13 | typedef NSComparisonResult (^CAICompareFunction)(id thing1, id thing2); 14 | 15 | 16 | @interface NSArray (Clarifai) 17 | 18 | /** Creates a new NSArray with the results of calling mapFn on every element. */ 19 | - (NSArray *)map:(CAIMapFunction)mapFn; 20 | 21 | /** Creates a new NSArray with all elements for which filterFn returns YES. */ 22 | - (NSArray *)filter:(CAIFilterFunction)filterFn; 23 | 24 | /** Produces the same result as calling filter, then calling map on the result. */ 25 | - (NSArray *)filter:(CAIFilterFunction)filterFn map:(CAIMapFunction)mapFn; 26 | 27 | /** Builds a dictionary with the key as the result of calling keyFn. */ 28 | - (NSDictionary *)asDictionaryUsingKey:(CAIMapFunction)keyFn; 29 | 30 | /** Returns an array sorted by the named key, in ascending or descending order. */ 31 | - (NSArray *)sortedByKey:(NSString *)key ascending:(BOOL)ascending; 32 | 33 | /** 34 | * Returns an NSArray of NSArrays, each of which are approximately batchSize elements. The size 35 | * of each batch will be no larger than batchSize, but may be smaller. 36 | */ 37 | - (NSArray *)asBatchesOfSize:(NSInteger)batchSize; 38 | 39 | /** Returns a subarray of this NSArray, using the same rules as python slicing. */ 40 | - (NSArray *)slicedFrom:(NSInteger)from to:(NSInteger)to; 41 | 42 | /** Returns a copy of this array with elements in the same order and duplicates removed. */ 43 | - (NSArray *)duplicatesRemoved; 44 | 45 | /** Returns a new array with the elements of this array in random order. */ 46 | - (NSArray *)shuffled; 47 | 48 | /** Returns a random element from the array, or nil if it is empty. */ 49 | - (id)randomElement; 50 | 51 | /** Performs a binary search on the array with the given compare function. The array must be sorted. */ 52 | - (NSInteger)binarySearch:(id)searchItem compareFN:(CAICompareFunction)compareFN; 53 | 54 | @end 55 | 56 | 57 | @interface NSMutableArray (Clarifai) 58 | 59 | /** Sorts in place by the named key, in ascending or descending order. */ 60 | - (void)sortByKey:(NSString *)key ascending:(BOOL)ascending; 61 | 62 | @end 63 | -------------------------------------------------------------------------------- /Clarifai/Classes/ClarifaiInput.m: -------------------------------------------------------------------------------- 1 | // 2 | // ClarifaiInput.m 3 | // ClarifaiApiDemo 4 | // 5 | // Created by John Sloan on 9/1/16. 6 | // Copyright © 2016 Clarifai, Inc. All rights reserved. 7 | // 8 | 9 | #import "ClarifaiInput.h" 10 | #import "NSArray+Clarifai.h" 11 | 12 | @implementation ClarifaiInput 13 | 14 | - (instancetype)initWithDictionary:(NSDictionary *)dict { 15 | 16 | NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; 17 | dateFormatter.dateFormat = @"yyyy-MM-dd'T'HH:mm:ss'Z'"; 18 | 19 | self = [super init]; 20 | if (self) { 21 | _inputID = dict[@"id"]; 22 | _creationDate = [dateFormatter dateFromString:dict[@"created_at"]]; 23 | NSDictionary *data = dict[@"data"]; 24 | NSDictionary *image = data[@"image"]; 25 | if (image) { 26 | _mediaURL = image[@"url"]; 27 | } 28 | 29 | NSArray *conceptsArray = data[@"concepts"]; 30 | NSMutableArray *concepts = [[NSMutableArray alloc] init]; 31 | if (conceptsArray) { 32 | for (NSDictionary *conceptDict in conceptsArray) { 33 | ClarifaiConcept *concept = [[ClarifaiConcept alloc] initWithDictionary:conceptDict]; 34 | [concepts addObject:concept]; 35 | } 36 | _concepts = concepts; 37 | } 38 | 39 | if (data[@"geo"] != nil) { 40 | NSDictionary *geoDict = data[@"geo"]; 41 | if (geoDict[@"geo_point"] != nil) { 42 | double latitude = [(NSNumber *)geoDict[@"geo_point"][@"latitude"] doubleValue]; 43 | double longitude = [(NSNumber *)geoDict[@"geo_point"][@"longitude"] doubleValue]; 44 | _location = [[ClarifaiLocation alloc] initWithLatitude:latitude 45 | longitude:longitude]; 46 | } 47 | } 48 | 49 | _metadata = data[@"metadata"]; 50 | } 51 | return self; 52 | } 53 | 54 | - (instancetype)initWithURL:(NSString *)url { 55 | self = [super init]; 56 | if (self) { 57 | self.mediaURL = url; 58 | } 59 | return self; 60 | } 61 | 62 | - (instancetype)initWithURL:(NSString *)URL andConcepts:(NSArray *)concepts { 63 | self = [super init]; 64 | if (self) { 65 | self.mediaURL = URL; 66 | self.concepts = [concepts map:^(id concept) { 67 | if ([concept isKindOfClass:[NSString class]]) { 68 | return [[ClarifaiConcept alloc] initWithConceptName:concept]; 69 | } else { 70 | return (ClarifaiConcept *)concept; 71 | } 72 | }]; 73 | } 74 | return self; 75 | } 76 | 77 | 78 | @end 79 | -------------------------------------------------------------------------------- /Clarifai/Classes/ClarifaiOutput.m: -------------------------------------------------------------------------------- 1 | // 2 | // ClarifaiOutput.m 3 | // ClarifaiApiDemo 4 | // 5 | // Created by John Sloan on 9/1/16. 6 | // Copyright © 2016 Clarifai, Inc. All rights reserved. 7 | // 8 | 9 | #import "ClarifaiOutput.h" 10 | 11 | @implementation ClarifaiOutput 12 | 13 | - (instancetype)initWithDictionary:(NSDictionary *)dict { 14 | self = [super init]; 15 | if (self) { 16 | 17 | // let user have access to complete dictionary for customized use. 18 | _responseDict = dict; 19 | 20 | // add reference to original input. (contains media like images). 21 | NSDictionary *inputDict = [dict findObjectForKey:@"input"]; 22 | if (inputDict != nil) { 23 | ClarifaiInput *input = [[ClarifaiInput alloc] initWithDictionary:inputDict]; 24 | self.input = input; 25 | } 26 | 27 | // add concepts to output, if any. 28 | NSDictionary *modelDict = [dict findObjectForKey:@"model"]; 29 | NSArray *conceptsArray = [dict findObjectForKey:@"concepts"]; 30 | ClarifaiModel *model = [[ClarifaiModel alloc] initWithDictionary:modelDict]; 31 | NSMutableArray *concepts = [NSMutableArray array]; 32 | for (NSDictionary *conceptData in conceptsArray) { 33 | ClarifaiConcept *concept = [[ClarifaiConcept alloc] initWithDictionary:conceptData]; 34 | concept.model = model; 35 | [concepts addObject:concept]; 36 | } 37 | self.concepts = concepts; 38 | 39 | // add colors to output, if any. 40 | NSArray *colorsArray = [dict findObjectForKey:@"colors"]; 41 | NSMutableArray *colors = [NSMutableArray array]; 42 | for (NSDictionary *colorData in colorsArray) { 43 | ClarifaiConcept *color = [[ClarifaiConcept alloc] init]; 44 | color.model = model; 45 | color.conceptID = [colorData findObjectForKey:@"raw_hex"]; 46 | color.conceptName = [colorData findObjectForKey:@"name"]; 47 | color.score = [[colorData findObjectForKey:@"value"] floatValue]; 48 | [colors addObject:color]; 49 | } 50 | self.colors = colors; 51 | 52 | // add clusterID if in the dictionary. 53 | NSArray *clusterArray = [dict findObjectForKey:@"clusters"]; 54 | for (NSDictionary *clusterData in clusterArray) { 55 | self.clusterID = clusterData[@"id"]; 56 | } 57 | 58 | // add embeddings if any. 59 | NSArray *embeddingsArray = [dict findObjectForKey:@"embeddings"]; 60 | if (embeddingsArray != nil && [embeddingsArray count] > 0) { 61 | self.embedding = embeddingsArray[0][@"vector"]; 62 | } 63 | 64 | // initialize regions array. 65 | self.regions = [NSArray array]; 66 | } 67 | return self; 68 | } 69 | 70 | @end 71 | -------------------------------------------------------------------------------- /Example/Clarifai/Base.lproj/LaunchScreen.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # DEPRECATION NOTICE 2 | 3 | This library is being deprecated in favor of the [Clarifai Apple SDK](https://github.com/Clarifai/clarifai-apple-sdk). 4 | 5 | # Clarifai Objective-C Client 6 | A client for iOS apps using the Clarifai V2 API. 7 | 8 | * Sign up for a free developer account at: https://developer.clarifai.com/signup/ 9 | * Read the developer guide at: https://developer.clarifai.com/guide/ 10 | * Read the full Objective-C docs at: http://cocoadocs.org/docsets/Clarifai/ 11 | 12 | ## Installation 13 | ### CocoaPods 14 | The Clarifai API client can be easily installed with CocoaPods. For more details on setting up CocoaPods, go [here](https://cocoapods.org). To integrate Clarifai into your project, simply add the following to your Podfile: 15 | 16 | ``` 17 | pod 'Clarifai' 18 | ``` 19 | 20 | ## Getting Started 21 | 22 | 1. Create a new XCode project, or use a current one. 23 | 24 | 2. Add Clarifai to your Podfile and generate workspace. 25 | ``` 26 | pod 'Clarifai' 27 | ``` 28 | ``` 29 | pod install 30 | ``` 31 | 32 | 3. Import ClarifaiApp.h and any other classes you need. 33 | ``` 34 | #import ClarifaiApp.h 35 | ``` 36 | 37 | 4. Go to [developer.clarifai.com/applications](https://developer.clarifai.com/applications), click 38 | on your application, then copy your app's API Key (if you don't already 39 | have an account or application, you'll need to sign up first). 40 | 41 | 5. Create your Clarifai application in your project. 42 | ``` 43 | ClarifaiApp *app = [[ClarifaiApp alloc] initWithApiKey:@""]; 44 | ``` 45 | 6. That's it! Explore the [API docs and guide](https://developer.clarifai.com). 46 | 47 | NOTE- to use Clarifai in Swift, make sure to add use_frameworks! to your podfile and import into any swift file using: 48 | ``` 49 | import Clarifai 50 | ``` 51 | 52 | ## Documentation 53 | 54 | The most recent docs can be found [here](http://cocoadocs.org/docsets/Clarifai/) on Cocoadocs. 55 | 56 | ## Example Project 57 | 58 | There is a simple demo included in the repo to help you get started. To build this project, you need [Xcode 8](https://developer.apple.com/xcode/download/) and [CocoaPods](http://cocoapods.org/). To build and run: 59 | 60 | 1. Install dependencies and generate workspace from inside the Example folder. 61 | ``` 62 | pod install 63 | ``` 64 | 65 | 2. Open the workspace in Xcode 66 | ``` 67 | open Clarifai.xcworkspace 68 | ``` 69 | 70 | 3. Go to [developer.clarifai.com/applications](https://developer.clarifai.com/applications), click 71 | on your application, then copy your app's API Key (if you don't already 72 | have an account or application, you'll need to [sign up first](https://developer.clarifai.com/signup/)). 73 | 74 | Add your API Key to the `recognizeImage` method in RecognitionViewController.m. 75 | 76 | 4. Press the "Play" button in the toolbar to build, install, and run the app. 77 | -------------------------------------------------------------------------------- /SwiftExample/ClarifaiSwiftDemo/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // ClarifaiSwiftDemo 4 | // 5 | // Created by John Sloan on 3/31/17. 6 | // Copyright © 2017 Clarifai. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import Clarifai 11 | 12 | class ViewController: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate { 13 | 14 | @IBOutlet weak var imageView: UIImageView! 15 | @IBOutlet weak var textView: UITextView! 16 | @IBOutlet weak var button: UIButton! 17 | 18 | var app:ClarifaiApp? 19 | let picker = UIImagePickerController() 20 | 21 | override func viewDidLoad() { 22 | super.viewDidLoad() 23 | 24 | app = ClarifaiApp(apiKey: "Your key goes here.") 25 | 26 | // Depracated, for older Clarifai Applications. 27 | // app = ClarifaiApp(appID: "", appSecret: "") 28 | 29 | } 30 | 31 | @IBAction func buttonPressed(_ sender: UIButton) { 32 | // Show a UIImagePickerController to let the user pick an image from their library. 33 | picker.allowsEditing = false; 34 | picker.sourceType = UIImagePickerControllerSourceType.photoLibrary 35 | picker.delegate = self; 36 | present(picker, animated: true, completion: nil) 37 | } 38 | 39 | func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) { 40 | // The user picked an image. Send it to Clarifai for recognition. 41 | dismiss(animated: true, completion: nil) 42 | if let image = info[UIImagePickerControllerOriginalImage] as? UIImage { 43 | imageView.image = image 44 | recognizeImage(image: image) 45 | textView.text = "Recognizing..." 46 | button.isEnabled = false 47 | } 48 | } 49 | 50 | func recognizeImage(image: UIImage) { 51 | 52 | // Check that the application was initialized correctly. 53 | if let app = app { 54 | 55 | // Fetch Clarifai's general model. 56 | app.getModelByName("general-v1.3", completion: { (model, error) in 57 | 58 | // Create a Clarifai image from a uiimage. 59 | let caiImage = ClarifaiImage(image: image)! 60 | 61 | // Use Clarifai's general model to pedict tags for the given image. 62 | model?.predict(on: [caiImage], completion: { (outputs, error) in 63 | print("%@", error ?? "no error") 64 | guard 65 | let caiOuputs = outputs 66 | else { 67 | print("Predict failed") 68 | return 69 | } 70 | 71 | if let caiOutput = caiOuputs.first { 72 | // Loop through predicted concepts (tags), and display them on the screen. 73 | let tags = NSMutableArray() 74 | for concept in caiOutput.concepts { 75 | tags.add(concept.conceptName) 76 | } 77 | 78 | DispatchQueue.main.async { 79 | // Update the new tags in the UI. 80 | self.textView.text = String(format: "Tags:\n%@", tags.componentsJoined(by: ", ")) 81 | } 82 | } 83 | 84 | DispatchQueue.main.async { 85 | // Reset select photo button for multiple selections. 86 | self.button.isEnabled = true; 87 | } 88 | }) 89 | }) 90 | } 91 | } 92 | } 93 | 94 | -------------------------------------------------------------------------------- /Example/Clarifai/RecognitionViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // RecognitionViewController.m 3 | // ClarifaiApiDemo 4 | // 5 | 6 | #import "RecognitionViewController.h" 7 | #import "ClarifaiApp.h" 8 | 9 | /** 10 | * This view controller performs recognition using the Clarifai API. 11 | * See the README for instructions on running the demo. 12 | */ 13 | @interface RecognitionViewController () 15 | @property (weak, nonatomic) IBOutlet UIImageView *imageView; 16 | @property (weak, nonatomic) IBOutlet UITextView *textView; 17 | @property (weak, nonatomic) IBOutlet UIButton *button; 18 | @property (strong, nonatomic) ClarifaiApp *app; 19 | @end 20 | 21 | 22 | @implementation RecognitionViewController 23 | 24 | 25 | - (IBAction)buttonPressed:(id)sender { 26 | // Show a UIImagePickerController to let the user pick an image from their library. 27 | UIImagePickerController *picker = [[UIImagePickerController alloc] init]; 28 | picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary; 29 | picker.allowsEditing = NO; 30 | picker.delegate = self; 31 | [self presentViewController:picker animated:YES completion:nil]; 32 | } 33 | 34 | - (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker { 35 | [self dismissViewControllerAnimated:YES completion:nil]; 36 | } 37 | 38 | - (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info { 39 | [self dismissViewControllerAnimated:YES completion:nil]; 40 | UIImage *image = info[UIImagePickerControllerOriginalImage]; 41 | if (image) { 42 | // The user picked an image. Send it to Clarifai for recognition. 43 | self.imageView.image = image; 44 | self.textView.text = @"Recognizing..."; 45 | self.button.enabled = NO; 46 | [self recognizeImage:image]; 47 | } 48 | } 49 | 50 | - (void)recognizeImage:(UIImage *)image { 51 | 52 | // Initialize the Clarifai app with your app's API Key. 53 | ClarifaiApp *app = [[ClarifaiApp alloc] initWithApiKey:@""]; 54 | 55 | // Fetch Clarifai's general model. 56 | [app getModelByName:@"general-v1.3" completion:^(ClarifaiModel *model, NSError *error) { 57 | // Create a Clarifai image from a uiimage. 58 | ClarifaiImage *clarifaiImage = [[ClarifaiImage alloc] initWithImage:image]; 59 | 60 | // Use Clarifai's general model to pedict tags for the given image. 61 | [model predictOnImages:@[clarifaiImage] completion:^(NSArray *outputs, NSError *error) { 62 | if (!error) { 63 | ClarifaiOutput *output = outputs[0]; 64 | 65 | // Loop through predicted concepts (tags), and display them on the screen. 66 | NSMutableArray *tags = [NSMutableArray array]; 67 | for (ClarifaiConcept *concept in output.concepts) { 68 | [tags addObject:concept.conceptName]; 69 | } 70 | dispatch_async(dispatch_get_main_queue(), ^{ 71 | self.textView.text = [NSString stringWithFormat:@"Tags:\n%@", [tags componentsJoinedByString:@", "]]; 72 | }); 73 | } else { 74 | NSLog(@"Error: %@", error.description); 75 | } 76 | 77 | dispatch_async(dispatch_get_main_queue(), ^{ 78 | self.button.enabled = YES; 79 | }); 80 | 81 | }]; 82 | }]; 83 | } 84 | 85 | @end 86 | -------------------------------------------------------------------------------- /Clarifai/Classes/ClarifaiGeo.m: -------------------------------------------------------------------------------- 1 | // 2 | // ClarifaiGeo.m 3 | // Pods 4 | // 5 | // Created by John Sloan on 2/15/17. 6 | // 7 | // 8 | 9 | #import "ClarifaiGeo.h" 10 | 11 | @implementation ClarifaiGeoBox 12 | // Initialize a geo box defined as a rectangular area between two locations as opposing corners. 13 | - (instancetype)initWithStartLocation:(ClarifaiLocation *)startLocation endLocation:(ClarifaiLocation *)endLocation { 14 | self = [super init]; 15 | if (self) { 16 | _startLoc = startLocation; 17 | _endLoc = endLocation; 18 | } 19 | return self; 20 | } 21 | @end 22 | 23 | 24 | @implementation ClarifaiGeo 25 | 26 | - (instancetype)initWithLocation:(ClarifaiLocation *)location andRadius:(double)radius { 27 | self = [super init]; 28 | if (self) { 29 | _geoPoint = location; 30 | _radius = [NSNumber numberWithDouble:radius]; 31 | _unitType = @"withinMiles"; 32 | } 33 | return self; 34 | } 35 | 36 | - (instancetype)initWithLocation:(ClarifaiLocation *)location radius:(double)radius andRadiusUnit:(ClarifaiRadiusUnit)unit { 37 | self = [super init]; 38 | if (self) { 39 | _geoPoint = location; 40 | _radius = [NSNumber numberWithDouble:radius]; 41 | [self setRadiusUnit:unit]; 42 | } 43 | return self; 44 | } 45 | 46 | - (instancetype)initWithGeoBoxFromStartLocation:(ClarifaiLocation *)startLocation toEndLocation:(ClarifaiLocation *)endLocation { 47 | self = [super init]; 48 | if (self) { 49 | _geoBox = [[ClarifaiGeoBox alloc] initWithStartLocation:startLocation endLocation:endLocation]; 50 | _unitType = @"withinMiles"; 51 | } 52 | return self; 53 | } 54 | 55 | - (void)setRadiusUnit:(ClarifaiRadiusUnit)unit { 56 | switch (unit) { 57 | case ClarifaiRadiusUnitMiles: 58 | _unitType = @"withinMiles"; 59 | break; 60 | 61 | case ClarifaiRadiusUnitKilometers: 62 | _unitType = @"withinKilometers"; 63 | break; 64 | 65 | case ClarifaiRadiusUnitDegrees: 66 | _unitType = @"withinDegrees"; 67 | break; 68 | 69 | case ClarifaiRadiusUnitRadians: 70 | _unitType = @"withinRadians"; 71 | break; 72 | 73 | default: 74 | _unitType = @"withinMiles"; 75 | break; 76 | } 77 | } 78 | 79 | - (NSDictionary *) geoFilterAsDictionary { 80 | NSMutableDictionary *geoDict = [NSMutableDictionary dictionary]; 81 | if (_geoBox) { 82 | geoDict[@"geo_box"] = @[@{@"geo_point": 83 | @{@"latitude":[NSNumber numberWithDouble:_geoBox.startLoc.latitude], 84 | @"longitude":[NSNumber numberWithDouble:_geoBox.startLoc.longitude]} 85 | }, 86 | @{@"geo_point": 87 | @{@"latitude":[NSNumber numberWithDouble:_geoBox.endLoc.latitude], 88 | @"longitude":[NSNumber numberWithDouble:_geoBox.endLoc.longitude]} 89 | } 90 | ]; 91 | } else if (_geoPoint && _radius && _unitType) { 92 | geoDict[@"geo_point"] = @{@"latitude":[NSNumber numberWithDouble:_geoPoint.latitude], 93 | @"longitude":[NSNumber numberWithDouble:_geoPoint.longitude]}; 94 | 95 | geoDict[@"geo_limit"] = @{@"type":_unitType, 96 | @"value":_radius 97 | }; 98 | } 99 | 100 | return geoDict; 101 | } 102 | 103 | @end 104 | -------------------------------------------------------------------------------- /Clarifai/Classes/ClarifaiImage.m: -------------------------------------------------------------------------------- 1 | // 2 | // ClarifaiImage.m 3 | // ClarifaiApiDemo 4 | // 5 | // Created by John Sloan on 9/1/16. 6 | // Copyright © 2016 Clarifai, Inc. All rights reserved. 7 | // 8 | 9 | #import "ClarifaiImage.h" 10 | #import "NSArray+Clarifai.h" 11 | 12 | @implementation ClarifaiImage 13 | 14 | - (instancetype)initWithScoredImageDictionary:(NSDictionary *)dict { 15 | 16 | NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; 17 | dateFormatter.dateFormat = @"yyyy-MM-dd'T'HH:mm:ss'Z'"; 18 | 19 | self = [super init]; 20 | if (self) { 21 | NSDictionary *image = dict[@"image"]; 22 | self.inputID = image[@"id"]; 23 | self.mediaURL = dict[@"url"]; 24 | self.creationDate = [dateFormatter dateFromString:dict[@"created_at"]]; 25 | } 26 | return self; 27 | } 28 | 29 | - (instancetype)initWithImage:(UIImage *)image { 30 | self = [super init]; 31 | if (self) { 32 | self.image = image; 33 | self.mediaData = UIImageJPEGRepresentation(image, 1.0); 34 | } 35 | return self; 36 | } 37 | 38 | - (instancetype)initWithImage:(UIImage *)image andCrop:(ClarifaiCrop *)crop { 39 | self = [super init]; 40 | if (self) { 41 | self.image = image; 42 | self.mediaData = UIImageJPEGRepresentation(image, 1.0); 43 | self.crop = crop; 44 | } 45 | return self; 46 | } 47 | 48 | - (instancetype)initWithImage:(UIImage *)image andConcepts:(NSArray *)concepts { 49 | self = [super init]; 50 | if (self) { 51 | self.image = image; 52 | self.mediaData = UIImageJPEGRepresentation(image, 1.0); 53 | self.concepts = [concepts map:^(id concept) { 54 | if ([concept isKindOfClass:[NSString class]]) { 55 | return [[ClarifaiConcept alloc] initWithConceptName:concept]; 56 | } else { 57 | return (ClarifaiConcept *)concept; 58 | } 59 | }]; 60 | } 61 | return self; 62 | } 63 | 64 | - (instancetype)initWithImage:(UIImage *)image crop:(ClarifaiCrop *)crop andConcepts:(NSArray *)concepts { 65 | self = [super init]; 66 | if (self) { 67 | self.image = image; 68 | self.crop = crop; 69 | self.mediaData = UIImageJPEGRepresentation(image, 1.0); 70 | self.concepts = [concepts map:^(id concept) { 71 | if ([concept isKindOfClass:[NSString class]]) { 72 | return [[ClarifaiConcept alloc] initWithConceptName:concept]; 73 | } else { 74 | return (ClarifaiConcept *)concept; 75 | } 76 | }]; 77 | } 78 | return self; 79 | } 80 | 81 | - (instancetype)initWithURL:(NSString *)url andCrop:(ClarifaiCrop *)crop { 82 | self = [super init]; 83 | if (self) { 84 | self.mediaURL = url; 85 | self.crop = crop; 86 | } 87 | return self; 88 | } 89 | 90 | - (instancetype)initWithURL:(NSString *)url crop:(ClarifaiCrop *)crop andConcepts:(NSArray *)concepts { 91 | self = [super init]; 92 | if (self) { 93 | self.mediaURL = url; 94 | self.crop = crop; 95 | self.concepts = [concepts map:^(id concept) { 96 | if ([concept isKindOfClass:[NSString class]]) { 97 | return [[ClarifaiConcept alloc] initWithConceptName:concept]; 98 | } else { 99 | return (ClarifaiConcept *)concept; 100 | } 101 | }]; 102 | } 103 | return self; 104 | } 105 | 106 | @end 107 | -------------------------------------------------------------------------------- /Clarifai/Classes/ClarifaiOutputRegion.m: -------------------------------------------------------------------------------- 1 | // 2 | // ClarifaiOutputRegion.m 3 | // Pods 4 | // 5 | // Created by John Sloan on 3/20/17. 6 | // 7 | // 8 | 9 | #import "ClarifaiOutputRegion.h" 10 | #import "NSDictionary+Clarifai.h" 11 | 12 | @implementation ClarifaiOutputRegion 13 | 14 | - (instancetype)initWithDictionary:(NSDictionary *)dict { 15 | self = [super init]; 16 | if (self) { 17 | // Add bounding box if present for current region. 18 | _top = [[dict findObjectForKey:@"top_row"] doubleValue]; 19 | _left = [[dict findObjectForKey:@"left_col"] doubleValue]; 20 | _bottom = [[dict findObjectForKey:@"bottom_row"] doubleValue]; 21 | _right = [[dict findObjectForKey:@"right_col"] doubleValue]; 22 | 23 | // Add focus value, if present for current region. 24 | _focusDensity =[[dict findObjectForKey:@"density"] doubleValue]; 25 | 26 | // Add face identity if present. 27 | NSMutableArray *identityConcepts = [NSMutableArray array]; 28 | NSDictionary *identity = [dict findObjectForKey:@"identity"]; 29 | NSArray *identityConceptsArray = [identity findObjectForKey:@"concepts"]; 30 | for (NSDictionary *conceptDict in identityConceptsArray) { 31 | ClarifaiConcept *concept = [[ClarifaiConcept alloc] initWithDictionary:conceptDict]; 32 | [identityConcepts addObject:concept]; 33 | } 34 | _identity = identityConcepts; 35 | 36 | // Add age demographics if present. 37 | NSMutableArray *ageConcepts = [NSMutableArray array]; 38 | NSDictionary *ageAppearance = [dict findObjectForKey:@"age_appearance"]; 39 | NSArray *ageConceptsArray = [ageAppearance findObjectForKey:@"concepts"]; 40 | for (NSDictionary *conceptDict in ageConceptsArray) { 41 | ClarifaiConcept *concept = [[ClarifaiConcept alloc] initWithDictionary:conceptDict]; 42 | [ageConcepts addObject:concept]; 43 | } 44 | _ageAppearance = ageConcepts; 45 | 46 | // Add gender demographics if present. 47 | NSMutableArray *genderConcepts = [NSMutableArray array]; 48 | NSDictionary *genderAppearance = [dict findObjectForKey:@"gender_appearance"]; 49 | NSArray *genderConceptsArray = [genderAppearance findObjectForKey:@"concepts"]; 50 | for (NSDictionary *conceptDict in genderConceptsArray) { 51 | ClarifaiConcept *concept = [[ClarifaiConcept alloc] initWithDictionary:conceptDict]; 52 | [genderConcepts addObject:concept]; 53 | } 54 | _genderAppearance = genderConcepts; 55 | 56 | // Add multicultural demographics if present. 57 | NSMutableArray *multiculturalConcepts = [NSMutableArray array]; 58 | NSDictionary *multiculturalAppearance = [dict findObjectForKey:@"multicultural_appearance"]; 59 | NSArray *multiculturalConceptsArray = [multiculturalAppearance findObjectForKey:@"concepts"]; 60 | for (NSDictionary *conceptDict in multiculturalConceptsArray) { 61 | ClarifaiConcept *concept = [[ClarifaiConcept alloc] initWithDictionary:conceptDict]; 62 | [multiculturalConcepts addObject:concept]; 63 | } 64 | _multiculturalAppearance = multiculturalConcepts; 65 | 66 | if ([dict objectForKey:@"data"] != nil) { 67 | NSDictionary *regionData = dict[@"data"]; 68 | 69 | // Add concepts, if present for current region. 70 | NSMutableArray *concepts = [NSMutableArray array]; 71 | NSArray *conceptsArray = regionData[@"concepts"]; 72 | for (NSDictionary *conceptDict in conceptsArray) { 73 | ClarifaiConcept *concept = [[ClarifaiConcept alloc] initWithDictionary:conceptDict]; 74 | [concepts addObject:concept]; 75 | } 76 | _concepts = concepts; 77 | } 78 | } 79 | return self; 80 | } 81 | 82 | @end 83 | -------------------------------------------------------------------------------- /Clarifai/Classes/ClarifaiConstants.h: -------------------------------------------------------------------------------- 1 | // 2 | // ClarifaiCompletionBlocks.h 3 | // ClarifaiApiDemo 4 | // 5 | // Created by John Sloan on 9/7/16. 6 | // Copyright © 2016 Clarifai, Inc. All rights reserved. 7 | // 8 | 9 | #import "ClarifaiSearchResult.h" 10 | 11 | @class ClarifaiModel; 12 | @class ClarifaiConcept; 13 | @class ClarifaiInput; 14 | @class ClarifaiImage; 15 | @class ClarifaiOutput; 16 | @class ClarifaiModelVersion; 17 | 18 | #define SafeRunBlock(block, ...) block ? block(__VA_ARGS__) : nil 19 | 20 | static NSString * const kApiBaseUrl = @"https://api.clarifai.com/v2"; 21 | static NSString * const kErrorDomain = @"com.clarifai.ClarifaiClient"; 22 | static NSString * const kKeyAccessToken = @"com.clarifai.ClarifaiClient.AccessToken"; 23 | static NSString * const kKeyAppID = @"com.clarifai.ClarifaiClient.AppID"; 24 | static NSString * const kKeyAccessTokenExpiration = @"com.clarifai.ClarifaiClient.AccessTokenExpiration"; 25 | static NSString * const kKeyApiKey = @"com.clarifai.ClarifaiClient.ApiKey"; 26 | static NSTimeInterval const kMinTokenLifetime = 60.0; 27 | static NSString * const ClientVersion = @"2.3.2"; 28 | 29 | /** 30 | * @param error Error code or nil if no error occured. */ 31 | typedef void (^ClarifaiRequestCompletion)(NSError *error); 32 | 33 | /** 34 | * @param inputs An array containing ClarifaiInputs returned from the api. 35 | * @param error Error code or nil if no error occured. */ 36 | typedef void (^ClarifaiInputsCompletion)(NSArray *inputs, NSError *error); 37 | 38 | /** 39 | * @param results An array containing ClarifaiSearchResults returned from the api. 40 | * @param error Error code or nil if no error occured. */ 41 | typedef void (^ClarifaiSearchCompletion)(NSArray *results, NSError *error); 42 | 43 | /** 44 | * @param outputs An array containing ClarifaiOutputs returned from the api. 45 | * @param error Error code or nil if no error occured. */ 46 | typedef void (^ClarifaiPredictionsCompletion)(NSArray *outputs, NSError *error); 47 | 48 | /** 49 | * @param concepts An array containing ClarifaiConcepts returned from the api. 50 | * @param error Error code or nil if no error occured. */ 51 | typedef void (^ClarifaiConceptsCompletion)(NSArray *concepts, NSError *error); 52 | 53 | /** 54 | * @param input A ClarifaiInput returned from the api. 55 | * @param error Error code or nil if no error occured. */ 56 | typedef void (^ClarifaiStoreInputCompletion)(ClarifaiInput *input, NSError *error); 57 | 58 | /** 59 | * @param concept A ClarifaiConcept returned from the api. 60 | * @param error Error code or nil if no error occured. */ 61 | typedef void (^ClarifaiStoreConceptCompletion)(ClarifaiConcept *concept, NSError *error); 62 | 63 | /** 64 | * @param numProcessed Number of inputs processed so far in your application. 65 | * @param numToProcess Number of inputs queued for processing in your application. 66 | * @param errors Number of errors so far while processing inputs. 67 | * @param error Error code or nil if no error occured. */ 68 | typedef void (^ClarifaiInputsStatusCompletion)(int numProcessed, int numToProcess, int errors, NSError *error); 69 | 70 | /** 71 | * @param models An array containing ClarifaiModels returned from the api. 72 | * @param error Error code or nil if no error occured. */ 73 | typedef void (^ClarifaiModelsCompletion)(NSArray *models, NSError *error); 74 | 75 | /** 76 | * @param model A ClarifaiModel returned from the api. 77 | * @param error Error code or nil if no error occured. */ 78 | typedef void (^ClarifaiModelCompletion)(ClarifaiModel *model, NSError *error); 79 | 80 | /** 81 | * @param versions An array of ClarifaiModelVersions returned from the api. 82 | * @param error Error code or nil if no error occured. */ 83 | typedef void (^ClarifaiModelVersionsCompletion)(NSArray *versions, NSError *error); 84 | 85 | /** 86 | * @param version A ClarifaiModelVersion returned from the api. 87 | * @param error Error code or nil if no error occured. */ 88 | typedef void (^ClarifaiModelVersionCompletion)(ClarifaiModelVersion *version, NSError *error); 89 | 90 | /** 91 | * @param concepts An array containing ClarifaiConcepts returned from the api. 92 | * @param error Error code or nil if no error occured. */ 93 | typedef void (^ClarifaiSearchConceptCompletion)(NSArray *concepts, NSError *error); 94 | -------------------------------------------------------------------------------- /Clarifai/Classes/NSArray+Clarifai.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSArray+Clarifai.m 3 | // ClarifaiPhotos 4 | // 5 | // Created by Keith Ito on 4/1/15. 6 | // Copyright (c) 2015 Clarifai, Inc. All rights reserved. 7 | // 8 | 9 | #import "NSArray+Clarifai.h" 10 | 11 | @implementation NSArray (Clarifai) 12 | 13 | - (NSArray *)map:(CAIMapFunction)mapFn { 14 | NSMutableArray *result = [[NSMutableArray alloc] initWithCapacity:self.count]; 15 | for (id item in self) { 16 | id mapped = mapFn(item); 17 | if (mapped != nil) { 18 | [result addObject:mapped]; 19 | } 20 | } 21 | return result; 22 | } 23 | 24 | - (NSArray *)filter:(CAIFilterFunction)filterFn { 25 | return [self filter:filterFn map:^(id item) { return item; }]; 26 | } 27 | 28 | - (NSArray *)filter:(CAIFilterFunction)filterFn map:(CAIMapFunction)mapFn { 29 | NSMutableArray *result = [[NSMutableArray alloc] init]; 30 | for (id item in self) { 31 | if (filterFn(item)) { 32 | id mapped = mapFn(item); 33 | if (mapped != nil) { 34 | [result addObject:mapped]; 35 | } 36 | } 37 | } 38 | return result; 39 | } 40 | 41 | - (NSDictionary *)asDictionaryUsingKey:(CAIMapFunction)keyFn { 42 | NSMutableDictionary *dict = [[NSMutableDictionary alloc] initWithCapacity:self.count]; 43 | for (id item in self) { 44 | id key = keyFn(item); 45 | if (key != nil) { 46 | dict[key] = item; 47 | } 48 | } 49 | return dict; 50 | } 51 | 52 | - (NSArray *)asBatchesOfSize:(NSInteger)batchSize { 53 | if (batchSize <= 0) { 54 | return nil; 55 | } 56 | NSInteger numBatches = (self.count + batchSize - 1) / batchSize; 57 | if (numBatches == 0) { 58 | return @[]; 59 | } 60 | NSInteger actualBatchSize = (self.count + numBatches - 1) / numBatches; 61 | NSMutableArray *result = [[NSMutableArray alloc] initWithCapacity:numBatches]; 62 | for (NSInteger i = 0; i < self.count; i += actualBatchSize) { 63 | [result addObject:[self slicedFrom:i to:i + actualBatchSize]]; 64 | } 65 | return result; 66 | } 67 | 68 | - (NSArray *)sortedByKey:(NSString *)key ascending:(BOOL)ascending { 69 | NSSortDescriptor *descriptor = [[NSSortDescriptor alloc] initWithKey:key ascending:ascending]; 70 | return [self sortedArrayUsingDescriptors:@[descriptor]]; 71 | } 72 | 73 | - (NSArray *)slicedFrom:(NSInteger)from to:(NSInteger)to { 74 | // Translate negative values into offsets from the end (a la Python) 75 | if (from < 0) { 76 | from += self.count; 77 | } 78 | if (to < 0) { 79 | to += self.count; 80 | } 81 | 82 | // Clamp: 83 | from = MAX(0, MIN((NSInteger)self.count, from)); 84 | to = MAX(0, MIN((NSInteger)self.count, to)); 85 | if (from == 0 && to == self.count) { 86 | return self; 87 | } else { 88 | return [self subarrayWithRange:NSMakeRange(from, MAX(0, to - from))]; 89 | } 90 | } 91 | 92 | - (NSArray *)duplicatesRemoved { 93 | return [[NSOrderedSet orderedSetWithArray:self] array]; 94 | } 95 | 96 | - (NSArray *)shuffled { 97 | NSMutableArray *shuffled = [[NSMutableArray alloc] initWithArray:self]; 98 | NSInteger n = shuffled.count; 99 | for (NSInteger i = n - 1; i > 0; i--) { 100 | [shuffled exchangeObjectAtIndex:i withObjectAtIndex:arc4random_uniform((int)i + 1)]; 101 | } 102 | return shuffled; 103 | } 104 | 105 | - (id)randomElement { 106 | if (self.count == 0) { 107 | return nil; 108 | } else { 109 | NSUInteger randomIndex = arc4random_uniform((int)self.count); 110 | return [self objectAtIndex:randomIndex]; 111 | } 112 | } 113 | 114 | - (NSInteger)binarySearch:(id)searchItem compareFN:(CAICompareFunction)compareFN { 115 | if (searchItem == nil) 116 | return NSNotFound; 117 | return [self binarySearch:searchItem minIndex:0 maxIndex:[self count] - 1 compareFN:compareFN]; 118 | } 119 | 120 | - (NSInteger)binarySearch:(id)searchItem minIndex:(NSInteger)minIndex maxIndex:(NSInteger)maxIndex compareFN:(CAICompareFunction)compareFN { 121 | if (maxIndex < minIndex) 122 | return NSNotFound; 123 | 124 | NSInteger midIndex = (minIndex + maxIndex) / 2; 125 | id itemAtMidIndex = [self objectAtIndex:midIndex]; 126 | 127 | NSComparisonResult comparison = compareFN(searchItem, itemAtMidIndex); 128 | if (comparison == NSOrderedSame) 129 | return midIndex; 130 | else if (comparison == NSOrderedDescending) 131 | return [self binarySearch:searchItem minIndex:minIndex maxIndex:midIndex - 1 compareFN:compareFN]; 132 | else 133 | return [self binarySearch:searchItem minIndex:midIndex + 1 maxIndex:maxIndex compareFN:compareFN]; 134 | } 135 | 136 | @end 137 | 138 | 139 | @implementation NSMutableArray (Clarifai) 140 | 141 | - (void)sortByKey:(NSString *)key ascending:(BOOL)ascending { 142 | NSSortDescriptor *descriptor = [[NSSortDescriptor alloc] initWithKey:key ascending:ascending]; 143 | [self sortUsingDescriptors:@[descriptor]]; 144 | } 145 | 146 | @end 147 | -------------------------------------------------------------------------------- /SwiftExample/ClarifaiSwiftDemo/Base.lproj/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 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 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 | -------------------------------------------------------------------------------- /Example/Clarifai/Base.lproj/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 | 29 | 30 | 31 | 32 | 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 | 73 | 74 | 75 | -------------------------------------------------------------------------------- /Clarifai/Classes/ClarifaiSearchTerm.h: -------------------------------------------------------------------------------- 1 | // 2 | // ClarifaiSearchTerm.h 3 | // Pods 4 | // 5 | // Created by John Sloan on 3/7/17. 6 | // 7 | // 8 | 9 | #import 10 | #import "ClarifaiConcept.h" 11 | #import "ClarifaiGeo.h" 12 | #import "ClarifaiCrop.h" 13 | 14 | @interface ClarifaiSearchTerm : NSObject 15 | 16 | #pragma mark Search outputs 17 | 18 | /** 19 | * Creates a search term from an imageURL. This will visually search the inputs 20 | * of your application for all inputs that look similar to the given imageURL. 21 | * 22 | * @param imageURL The url of an image to be visually searched. 23 | */ 24 | + (ClarifaiSearchTerm *) searchVisuallyWithImageURL:(NSString *)imageURL; 25 | 26 | /** 27 | * Creates a search term from an imageURL and crop. This will first crop the image 28 | * located at the given URL and then visually search the inputs of your application 29 | * for all inputs that look similar to the cropped image. 30 | * 31 | * @param imageURL The url of an image to be visually searched. 32 | * @param imageCrop Specifies a crop for the image, prior to searching. 33 | */ 34 | + (ClarifaiSearchTerm *) searchVisuallyWithImageURL:(NSString *)imageURL andCrop:(ClarifaiCrop *)imageCrop; 35 | 36 | /** 37 | * Creates a search term from an inputID. This will visually search the inputs 38 | * of your application for all inputs that look similar to the image of the given inputID. 39 | * 40 | * @param inputID The inputID of the input to be visually searched. 41 | */ 42 | + (ClarifaiSearchTerm *) searchVisuallyWithInputID:(NSString *)inputID; 43 | 44 | /** 45 | * Creates a search term from image data. This will visually search the inputs 46 | * of your application for all inputs that look similar to the image of the given data. 47 | * 48 | * @param imageData The NSData of an image to be visually searched. 49 | */ 50 | + (ClarifaiSearchTerm *) searchVisuallyWithImageData:(NSData *)imageData; 51 | 52 | /** 53 | * Creates a search term from a UIImage. This will visually search the inputs 54 | * of your application for all inputs that look similar to the given UIImage. 55 | * 56 | * @param image A UIImage to be visually searched. 57 | */ 58 | + (ClarifaiSearchTerm *) searchVisuallyWithUIImage:(UIImage *)image; 59 | 60 | /** 61 | * Creates a search term from a ClarifaiConcept. This will search the inputs of your 62 | * application by predicting which inputs are associated with the given concept. 63 | * 64 | * @warning Concepts can only be searched if they are either in Clarifai's 65 | * general model, or part of a TRAINED custom model. To find out 66 | * which tags are available to use in a search term (or for autocomplete 67 | * purposes), you can use [app searchForConceptsByName:andLanguage:completion:]. 68 | * See ClarifaiApp for more details on this. 69 | * 70 | * @param concept The NSData of an image to be visually searched. 71 | */ 72 | + (ClarifaiSearchTerm *) searchByPredictedConcept:(ClarifaiConcept *)concept; 73 | 74 | /** 75 | * Adds an image crop to the current visual search term. 76 | * 77 | * @warning A crop can only be added to images for visual search. This method 78 | * will do nothing if the search term is created for other types of searches. 79 | * 80 | * 81 | * @param imageCrop An image crop that will crop the input image before searching. 82 | */ 83 | - (ClarifaiSearchTerm *)addImageCrop:(ClarifaiCrop *)imageCrop; 84 | 85 | #pragma mark Search inputs 86 | 87 | /** 88 | * Creates a search term from an imageURL. This will search the inputs of your 89 | * application for all inputs that contain the exact given URL. 90 | * 91 | * @param imageURL The url to be searched. 92 | */ 93 | + (ClarifaiSearchTerm *)searchInputsWithImageURL:(NSString *)imageURL; 94 | 95 | /** 96 | * Creates a search term from an inputID. This will search the inputs of your 97 | * application for the input with a matching inputID. 98 | * 99 | * @param inputID The inputID to be searched. 100 | */ 101 | + (ClarifaiSearchTerm *)searchInputsWithInputID:(NSString *)inputID; 102 | 103 | /** 104 | * Creates a search term from a geo filter. This will search the inputs of your 105 | * application for all inputs with tagged locations within the range of the geo 106 | * filter. See ClarifaiGeo for more details on creating a geo filter. 107 | * 108 | * @param geo A geo filter to search inputs. 109 | */ 110 | + (ClarifaiSearchTerm *)searchInputsWithGeoFilter:(ClarifaiGeo *)geo; 111 | 112 | /** 113 | * Creates a search term from a metadata dictionary. This will search the inputs 114 | * of your application for all inputs with matching metadata. 115 | * 116 | * @param metadata An NSDictionary of metadata to be searched. 117 | */ 118 | + (ClarifaiSearchTerm *)searchInputsWithMetadata:(NSDictionary *)metadata; 119 | 120 | /** 121 | * Creates a search term from a ClarifaiConcept. This will search the inputs 122 | * of your application for all inputs explicitly tagged with the given concept. 123 | * 124 | * @warning This method does not search using predicted concepts, this means 125 | * it will only search for inputs that were added explicitly with the 126 | * given custom concept. Use searchByPredictedConcept in order to search 127 | * for inputs by predicting which inputs are associated with the given 128 | * concept. Ex: searchByPredictedConcept is used for searching with 129 | * predicted concepts from Clarifai's general model or trained custom models. 130 | * 131 | * @param concept A ClarifaiConcept to be searched. 132 | */ 133 | + (ClarifaiSearchTerm *)searchInputsByConcept:(ClarifaiConcept *)concept; 134 | 135 | /** 136 | * (Depracated) Create a search term from a search item. This can be a 137 | * ClarifiaInput or ClarifaiConcept. Marking isInput:YES will search the 138 | * inputs of your application, whereas isInput:NO will search predicted 139 | * outputs of your application (like visual searching, and searching by 140 | * predicted tags). 141 | * 142 | * @param searchItem The item being searched. This can be an input or concept. 143 | * @param isInput A boolean value indicating wether the search term should be accross inputs or outputs. 144 | */ 145 | - (instancetype)initWithSearchItem:(id)searchItem isInput:(BOOL)isInput __attribute__((deprecated)); 146 | 147 | /** 148 | * Outputs the current search term as a dictionary formatted for sending to the Clarifai API as JSON. 149 | */ 150 | - (NSDictionary *)searchTermAsDictionary; 151 | 152 | @end 153 | -------------------------------------------------------------------------------- /Clarifai/Classes/ClarifaiModel.h: -------------------------------------------------------------------------------- 1 | // 2 | // ClarifaiModel.h 3 | // ClarifaiApiDemo 4 | // 5 | // Created by John Sloan on 9/1/16. 6 | // Copyright © 2016 Clarifai, Inc. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "ClarifaiImage.h" 11 | #import "ClarifaiConstants.h" 12 | #import "ClarifaiModelVersion.h" 13 | @class ClarifaiApp; 14 | 15 | typedef NS_ENUM(NSInteger, ClarifaiModelType) { 16 | ClarifaiModelTypeConcept, 17 | ClarifaiModelTypeEmbed, 18 | ClarifaiModelTypeFaceDetect, 19 | ClarifaiModelTypeDetection, 20 | ClarifaiModelTypeCluster, 21 | ClarifaiModelTypeColor, 22 | ClarifaiModelTypeBlur, 23 | ClarifaiModelTypeUnsupported 24 | }; 25 | 26 | /** 27 | * A ClarifaiModel will represent a single model from your application. You can get any model saved in your app using the ClarifaiApp class. You can then use each instance to train the model, predict on inputs, or inspect model version info and training data. 28 | */ 29 | @interface ClarifaiModel : NSObject 30 | 31 | /** The name of the model. */ 32 | @property (strong, nonatomic) NSString *name; 33 | 34 | /** The id of the model. */ 35 | @property (strong, nonatomic) NSString *modelID; 36 | 37 | /** The date the model was created. */ 38 | @property (strong, nonatomic) NSDate *createdAt; 39 | 40 | /** The id of the app that the model is contained in. */ 41 | @property (strong, nonatomic) NSString *appID; 42 | 43 | /** The type of the model. */ 44 | @property (nonatomic) ClarifaiModelType modelType; 45 | 46 | /** The concepts associated with the model. */ 47 | @property (strong, nonatomic) NSArray *concepts; 48 | 49 | /** Do you expect to see more than one of the concepts in this model in the SAME image? If Yes, then conceptsMutuallyExclusive: false (default), if No, then conceptsMutuallyExclusive: true. */ 50 | @property BOOL conceptsMututallyExclusive; 51 | 52 | /** Do you expect to run the trained model on images that do not contain ANY of the concepts in the model? If yes, closedEnvironment: false (default), if no closedEnvironment: true. */ 53 | @property BOOL closedEnvironment; 54 | 55 | /** The version of the model. */ 56 | @property (strong, nonatomic) ClarifaiModelVersion *version; 57 | 58 | /** A reference to the ClarifaiApp object. */ 59 | @property (strong, nonatomic) ClarifaiApp *app; 60 | 61 | - (instancetype)initWithDictionary:(NSDictionary *)dict; 62 | 63 | /** 64 | * Train the model. 65 | * 66 | * @warning This method is async on the server, meaning that it completes the request immediately, before the model may have finished training. To check for completion, this method polls for the training status code of the model. It will return the model version, containing a status code, to the completion handler when training has completed unless an error occured with training or the user loses internet connection. In the event that a user's internet connection is lost during polling, an error is returned, but the model may still have trained successfully on the server. Make sure to handle this case appropriately and you can always just retrain. You should also double check that the returned model version has a status code of 21100 (model trained successfully). 67 | * 68 | * @param completion Invoked when the request completes. 69 | */ 70 | - (void)train:(ClarifaiModelVersionCompletion)completion; 71 | 72 | /** 73 | * Predict on a set of images. 74 | * 75 | * @param images The images to predict on. 76 | * @param completion Invoked when the request completes. 77 | */ 78 | - (void)predictOnImages:(NSArray *)images 79 | completion:(ClarifaiPredictionsCompletion)completion; 80 | 81 | /** 82 | * Predict on a set of images using a specified language for the returned tags. 83 | * 84 | * @warning This will not translate returned concepts into other languages, except when using 85 | * Clarifai's general model. The general model can be obtained using getModels, getModelByID, 86 | * or getModelByName. For custom models, concepts are saved using the default language 87 | * specified in your Clarifai application on devhub, and will error if attempting to 88 | * predict concepts in another language. 89 | * 90 | * @param images The images to predict on. 91 | * @param completion Invoked when the request completes. 92 | */ 93 | - (void)predictOnImages:(NSArray *)images 94 | withLanguage:(NSString *)language 95 | completion:(ClarifaiPredictionsCompletion)completion; 96 | 97 | /** 98 | * List versions of the model. 99 | * 100 | * @param page Results page to load. 101 | * @param resultsPerPage Number of results to return per page. 102 | * @param completion Invoked when the request completes. 103 | */ 104 | - (void)listVersions:(int)page 105 | resultsPerPage:(int)resultsPerPage 106 | completion:(ClarifaiModelVersionsCompletion)completion; 107 | 108 | /** 109 | * Get specific version of the model. 110 | * 111 | * @param versionID ID of the version info you want to retrieve. 112 | * @param completion Invoked when the request completes. 113 | */ 114 | - (void)getVersion:(NSString *)versionID 115 | completion:(ClarifaiModelVersionCompletion)completion; 116 | 117 | /** 118 | * Delete specific version of the model. 119 | * 120 | * @param versionID ID of the version info you want to retrieve. 121 | * @param completion Invoked when the request completes. 122 | */ 123 | - (void)deleteVersion:(NSString *)versionID 124 | completion:(ClarifaiRequestCompletion)completion; 125 | 126 | /** 127 | * Get training inputs associated with the model. 128 | * 129 | * @param page Results page to load. 130 | * @param resultsPerPage Number of results to return per page. 131 | * @param completion Invoked when the request completes. 132 | */ 133 | - (void)listTrainingInputs:(int)page 134 | resultsPerPage:(int)resultsPerPage 135 | completion:(ClarifaiInputsCompletion)completion; 136 | 137 | /** 138 | * Get training inputs associated with a given version of the model. 139 | * 140 | * @param versionID ID of the version you want to retrieve. 141 | * @param page Results page to load. 142 | * @param resultsPerPage Number of results to return per page. 143 | * @param completion Invoked when the request completes. 144 | */ 145 | - (void)listTrainingInputsForVersion:(NSString *)versionID 146 | page:(int)page 147 | resultsPerPage:(int)resultsPerPage 148 | completion:(ClarifaiInputsCompletion)completion; 149 | @end 150 | -------------------------------------------------------------------------------- /Clarifai/Classes/ClarifaiSearchTerm.m: -------------------------------------------------------------------------------- 1 | // 2 | // ClarifaiSearchTerm.m 3 | // Pods 4 | // 5 | // Created by John Sloan on 3/7/17. 6 | // 7 | // 8 | 9 | #import "ClarifaiSearchTerm.h" 10 | #import "ClarifaiInput.h" 11 | #import "ClarifaiConcept.h" 12 | #import "ClarifaiImage.h" 13 | 14 | @interface ClarifaiSearchTerm() 15 | 16 | @property BOOL isInputsTerm; 17 | 18 | // Properties for Inputs Term 19 | @property (strong, nonatomic) NSString *imageURL; 20 | @property (strong, nonatomic) NSString *inputID; 21 | @property (strong, nonatomic) ClarifaiGeo *geo; 22 | @property (strong, nonatomic) NSDictionary *metadata; 23 | @property (strong, nonatomic) ClarifaiConcept *concept; 24 | 25 | // Properties for Outputs Term 26 | @property (strong,nonatomic) NSString *visualSearchImageURL; 27 | @property (strong,nonatomic) NSString *visualSearchInputID; 28 | @property (strong,nonatomic) NSData *visualSearchImageData; 29 | @property (strong,nonatomic) ClarifaiCrop *imageCrop; 30 | @property (strong,nonatomic) ClarifaiConcept *predictedConcept; 31 | 32 | @end 33 | 34 | 35 | @implementation ClarifaiSearchTerm 36 | 37 | #pragma mark Search outputs 38 | 39 | + (ClarifaiSearchTerm *) searchVisuallyWithImageURL:(NSString *)imageURL { 40 | ClarifaiSearchTerm *term = [[ClarifaiSearchTerm alloc] init]; 41 | term.visualSearchImageURL = imageURL; 42 | term.isInputsTerm = NO; 43 | return term; 44 | } 45 | 46 | + (ClarifaiSearchTerm *) searchVisuallyWithImageURL:(NSString *)imageURL andCrop:(ClarifaiCrop *)imageCrop { 47 | ClarifaiSearchTerm *term = [[ClarifaiSearchTerm alloc] init]; 48 | term.visualSearchImageURL = imageURL; 49 | term.imageCrop = imageCrop; 50 | term.isInputsTerm = NO; 51 | return term; 52 | } 53 | 54 | + (ClarifaiSearchTerm *) searchVisuallyWithInputID:(NSString *)inputID { 55 | ClarifaiSearchTerm *term = [[ClarifaiSearchTerm alloc] init]; 56 | term.visualSearchInputID = inputID; 57 | term.isInputsTerm = NO; 58 | return term; 59 | } 60 | 61 | + (ClarifaiSearchTerm *) searchVisuallyWithImageData:(NSData *)imageData { 62 | ClarifaiSearchTerm *term = [[ClarifaiSearchTerm alloc] init]; 63 | term.visualSearchImageData = imageData; 64 | term.isInputsTerm = NO; 65 | return term; 66 | } 67 | 68 | + (ClarifaiSearchTerm *) searchVisuallyWithUIImage:(UIImage *)image { 69 | ClarifaiSearchTerm *term = [[ClarifaiSearchTerm alloc] init]; 70 | term.visualSearchImageData = UIImageJPEGRepresentation(image, 0.9); 71 | term.isInputsTerm = NO; 72 | return term; 73 | } 74 | 75 | + (ClarifaiSearchTerm *) searchByPredictedConcept:(ClarifaiConcept *)concept { 76 | ClarifaiSearchTerm *term = [[ClarifaiSearchTerm alloc] init]; 77 | term.predictedConcept = concept; 78 | term.isInputsTerm = NO; 79 | return term; 80 | } 81 | 82 | #pragma mark Search inputs 83 | 84 | + (ClarifaiSearchTerm *)searchInputsWithImageURL:(NSString *)imageURL { 85 | ClarifaiSearchTerm *term = [[ClarifaiSearchTerm alloc] init]; 86 | term.imageURL = imageURL; 87 | term.isInputsTerm = YES; 88 | return term; 89 | } 90 | 91 | + (ClarifaiSearchTerm *)searchInputsWithInputID:(NSString *)inputID { 92 | ClarifaiSearchTerm *term = [[ClarifaiSearchTerm alloc] init]; 93 | term.inputID = inputID; 94 | term.isInputsTerm = YES; 95 | return term; 96 | } 97 | 98 | + (ClarifaiSearchTerm *)searchInputsWithGeoFilter:(ClarifaiGeo *)geo { 99 | ClarifaiSearchTerm *term = [[ClarifaiSearchTerm alloc] init]; 100 | term.geo = geo; 101 | term.isInputsTerm = YES; 102 | return term; 103 | } 104 | 105 | + (ClarifaiSearchTerm *)searchInputsWithMetadata:(NSDictionary *)metadata { 106 | ClarifaiSearchTerm *term = [[ClarifaiSearchTerm alloc] init]; 107 | term.metadata = metadata; 108 | term.isInputsTerm = YES; 109 | return term; 110 | } 111 | 112 | + (ClarifaiSearchTerm *)searchInputsByConcept:(ClarifaiConcept *)concept { 113 | ClarifaiSearchTerm *term = [[ClarifaiSearchTerm alloc] init]; 114 | term.concept = concept; 115 | term.isInputsTerm = YES; 116 | return term; 117 | } 118 | 119 | - (ClarifaiSearchTerm *)addImageCrop:(ClarifaiCrop *)imageCrop { 120 | if (!_isInputsTerm && (_visualSearchInputID || _visualSearchImageURL || _visualSearchImageData)) { 121 | _imageCrop = imageCrop; 122 | } else { 123 | NSLog(@"Cannot add image crop to an Inputs search."); 124 | } 125 | return self; 126 | } 127 | 128 | - (instancetype)initWithSearchItem:(id)searchItem isInput:(BOOL)isInput { 129 | self = [super init]; 130 | if (self) { 131 | _isInputsTerm = isInput; 132 | if (isInput) { 133 | // Setup inputs search term 134 | if ([searchItem isKindOfClass:[ClarifaiInput class]]) { 135 | ClarifaiInput *inputItem = (ClarifaiInput *)searchItem; 136 | if (inputItem.inputID) { 137 | _inputID = inputItem.inputID; 138 | } 139 | 140 | if (inputItem.metadata) { 141 | _metadata = inputItem.metadata; 142 | } 143 | } 144 | if ([searchItem isKindOfClass:[ClarifaiImage class]]) { 145 | ClarifaiImage *imageItem = (ClarifaiImage *)searchItem; 146 | 147 | if (imageItem.mediaURL) { 148 | _imageURL = imageItem.mediaURL; 149 | } 150 | 151 | } else if ([searchItem isKindOfClass:[ClarifaiConcept class]]) { 152 | ClarifaiConcept *conceptItem = (ClarifaiConcept *)searchItem; 153 | _concept = conceptItem; 154 | } 155 | } else { 156 | // Setup outputs search term 157 | if ([searchItem isKindOfClass:[ClarifaiInput class]]) { 158 | ClarifaiInput *inputItem = (ClarifaiInput *)searchItem; 159 | if (inputItem.inputID) { 160 | _visualSearchInputID = inputItem.inputID; 161 | } 162 | } 163 | 164 | if ([searchItem isKindOfClass:[ClarifaiImage class]]) { 165 | ClarifaiImage *imageItem = (ClarifaiImage *)searchItem; 166 | 167 | if (imageItem.mediaURL) { 168 | _visualSearchImageURL = imageItem.mediaURL; 169 | } 170 | 171 | if (imageItem.mediaData) { 172 | _visualSearchImageData = imageItem.mediaData; 173 | } 174 | 175 | if (imageItem.crop) { 176 | _imageCrop = imageItem.crop; 177 | } 178 | } else if ([searchItem isKindOfClass:[ClarifaiConcept class]]) { 179 | ClarifaiConcept *conceptItem = (ClarifaiConcept *)searchItem; 180 | _predictedConcept = conceptItem; 181 | } 182 | } 183 | } 184 | return self; 185 | } 186 | 187 | - (NSDictionary *)searchTermAsDictionary { 188 | if (_isInputsTerm) { 189 | // Convert Search term for inputs search 190 | NSMutableDictionary *formattedInputTerm = [NSMutableDictionary dictionary]; 191 | NSMutableDictionary *dataDict = [NSMutableDictionary dictionary]; 192 | 193 | if (_geo) { 194 | dataDict[@"geo"] = [_geo geoFilterAsDictionary]; 195 | } 196 | 197 | if (_metadata) { 198 | dataDict[@"metadata"] = _metadata; 199 | } 200 | 201 | if (_inputID) { 202 | formattedInputTerm[@"id"] = _inputID; 203 | dataDict[@"image"] = @{}; 204 | } 205 | 206 | if (_imageURL) { 207 | dataDict[@"image"] = @{@"url":_imageURL}; 208 | } 209 | 210 | if (_concept) { 211 | dataDict[@"concepts"] = @[@{@"name":_concept.conceptName, @"value":[NSNumber numberWithFloat:_concept.score]}]; 212 | } 213 | 214 | formattedInputTerm[@"data"] = dataDict; 215 | return @{@"input": formattedInputTerm}; 216 | } else { 217 | // Convert Search term for outputs search 218 | NSMutableDictionary *formattedOutputsTerm = [NSMutableDictionary dictionary]; 219 | NSMutableDictionary *inputDict = [NSMutableDictionary dictionary]; 220 | NSMutableDictionary *inputDataDict = [NSMutableDictionary dictionary]; 221 | NSMutableDictionary *outputDataDict = [NSMutableDictionary dictionary]; 222 | 223 | if (_predictedConcept) { 224 | outputDataDict[@"concepts"] = @[@{@"name":_predictedConcept.conceptName}]; 225 | } 226 | 227 | if (_visualSearchInputID) { 228 | inputDict[@"id"] = _visualSearchInputID; 229 | inputDataDict[@"image"] = [NSMutableDictionary dictionary]; 230 | } 231 | 232 | if (_visualSearchImageURL) { 233 | NSMutableDictionary *imageDict = [NSMutableDictionary dictionary]; 234 | imageDict[@"url"] = _visualSearchImageURL; 235 | inputDataDict[@"image"] = imageDict; 236 | } 237 | 238 | if (_visualSearchImageData) { 239 | // Overwrites image dictionary as you cannot search with both image data + url in same search term. 240 | NSMutableDictionary *imageDict = [NSMutableDictionary dictionary]; 241 | NSString *dataString = [_visualSearchImageData base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength]; 242 | imageDict[@"base64"] = dataString; 243 | inputDataDict[@"image"] = imageDict; 244 | } 245 | 246 | if (_imageCrop) { 247 | NSArray *cropArray = @[@(_imageCrop.top), 248 | @(_imageCrop.left), 249 | @(_imageCrop.bottom), 250 | @(_imageCrop.right)]; 251 | if (inputDataDict[@"image"] != nil) { 252 | inputDataDict[@"image"][@"crop"] = cropArray; 253 | } else { 254 | //can't add crop if no image data, url or input ID is given! 255 | } 256 | } 257 | 258 | // add input data dictionary to input if used. 259 | if ([inputDataDict.allKeys count] > 0) { 260 | inputDict[@"data"] = inputDataDict; 261 | } 262 | 263 | // add input dictionary to search term only if used. 264 | if ([inputDict.allKeys count] > 0) { 265 | formattedOutputsTerm[@"input"] = inputDict; 266 | } 267 | 268 | // add output data dictionary (containing a concept) if used. 269 | if ([outputDataDict.allKeys count] > 0) { 270 | formattedOutputsTerm[@"data"] = outputDataDict; 271 | } 272 | 273 | return @{@"output": formattedOutputsTerm}; 274 | } 275 | } 276 | 277 | @end 278 | -------------------------------------------------------------------------------- /Clarifai/Classes/ClarifaiModel.m: -------------------------------------------------------------------------------- 1 | // 2 | // ClarifaiModel.m 3 | // ClarifaiApiDemo 4 | // 5 | // Created by John Sloan on 9/1/16. 6 | // Copyright © 2016 Clarifai, Inc. All rights reserved. 7 | // 8 | 9 | #import "ClarifaiModel.h" 10 | #import "ClarifaiApp.h" 11 | #import "NSDictionary+Clarifai.h" 12 | 13 | @interface ClarifaiModel() { 14 | __block BOOL finishedTrainingAttempt; 15 | __block double curStatus; 16 | } 17 | @end 18 | 19 | @implementation ClarifaiModel 20 | 21 | - (instancetype)initWithDictionary:(NSDictionary *)dict { 22 | 23 | NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; 24 | dateFormatter.dateFormat = @"yyyy-MM-dd'T'HH:mm:ss'Z'"; 25 | 26 | self = [super init]; 27 | if (self) { 28 | _name = dict[@"name"]; 29 | _modelID = dict[@"id"]; 30 | _createdAt = [dateFormatter dateFromString:dict[@"created_at"]]; 31 | _appID = dict[@"app_id"]; 32 | 33 | //init model output type 34 | NSString *type = dict[@"output_info"][@"type"]; 35 | if ([type isEqualToString:@"concept"]) { 36 | _modelType = ClarifaiModelTypeConcept; 37 | } else if ([type isEqualToString:@"embed"]) { 38 | _modelType = ClarifaiModelTypeEmbed; 39 | } else if ([type isEqualToString:@"facedetect"]) { 40 | _modelType = ClarifaiModelTypeFaceDetect; 41 | } else if ([type isEqualToString:@"detection"]) { 42 | _modelType = ClarifaiModelTypeDetection; 43 | } else if ([type isEqualToString:@"cluster"]) { 44 | _modelType = ClarifaiModelTypeCluster; 45 | } else if ([type isEqualToString:@"color"]) { 46 | _modelType = ClarifaiModelTypeColor; 47 | } else if ([type isEqualToString:@"focus"]) { 48 | _modelType = ClarifaiModelTypeBlur; 49 | } else if ([type isEqualToString:@"blur"]) { 50 | _modelType = ClarifaiModelTypeBlur; 51 | } else { 52 | _modelType = ClarifaiModelTypeUnsupported; 53 | } 54 | 55 | //init concepts array if there is any 56 | NSMutableArray *concepts = [[NSMutableArray alloc] init]; 57 | for (NSDictionary *conceptDict in dict[@"output_info"][@"data"][@"concepts"]) { 58 | ClarifaiConcept *concept = [[ClarifaiConcept alloc] initWithDictionary:conceptDict]; 59 | [concepts addObject:concept]; 60 | } 61 | _concepts = concepts; 62 | 63 | //init output info 64 | _conceptsMututallyExclusive = [dict[@"output_info"][@"output_config"][@"concepts_mutually_exclusive"] boolValue]; 65 | _closedEnvironment = [dict[@"output_info"][@"output_config"][@"closed_environment"] boolValue]; 66 | 67 | //init version info 68 | ClarifaiModelVersion *version = [[ClarifaiModelVersion alloc] initWithDictionary:dict[@"model_version"]]; 69 | _version = version; 70 | } 71 | return self; 72 | } 73 | 74 | - (void)train:(ClarifaiModelVersionCompletion)completion { 75 | [_app ensureValidAccessToken:^(NSError *error) { 76 | if (error) { 77 | SafeRunBlock(completion, nil, error); 78 | return; 79 | } 80 | finishedTrainingAttempt = NO; 81 | NSString *apiURL = [NSString stringWithFormat:@"%@/models/%@/versions", kApiBaseUrl, self.modelID]; 82 | 83 | [_app.sessionManager POST:apiURL 84 | parameters:nil 85 | progress:nil 86 | success:^(NSURLSessionDataTask *task, id response) { 87 | //update version info 88 | ClarifaiModelVersion *curVersion = [[ClarifaiModelVersion alloc] initWithDictionary:response[@"model"][@"model_version"]]; 89 | _version = curVersion; 90 | curStatus = curVersion.statusCode.doubleValue; 91 | finishedTrainingAttempt = NO; 92 | 93 | // Training is async on the server, poll to check when training completes. 94 | [self pollUntilTrained:completion]; 95 | } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) { 96 | completion(nil, error); 97 | }]; 98 | }]; 99 | } 100 | 101 | - (void) pollUntilTrained:(ClarifaiModelVersionCompletion)completion { 102 | [_app getModelByID:_modelID completion:^(ClarifaiModel *model, NSError *error) { 103 | @synchronized (self) { 104 | if (!finishedTrainingAttempt) { 105 | if (error == nil) { 106 | curStatus = model.version.statusCode.doubleValue; 107 | if (curStatus == 21100 || floor(curStatus/10.0) == 2111) { 108 | finishedTrainingAttempt = YES; 109 | _version = model.version; 110 | completion(model.version, nil); 111 | } 112 | } else { 113 | finishedTrainingAttempt = YES; 114 | completion(nil, error); 115 | } 116 | } 117 | } 118 | }]; 119 | if (!finishedTrainingAttempt) { 120 | dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0), ^{ 121 | [self pollUntilTrained:completion]; 122 | }); 123 | } 124 | } 125 | 126 | - (void)predictOnImages:(NSArray *)images 127 | completion:(ClarifaiPredictionsCompletion)completion { 128 | [_app ensureValidAccessToken:^(NSError *error) { 129 | if (error) { 130 | SafeRunBlock(completion, nil, error); 131 | return; 132 | } 133 | if (_modelType == ClarifaiModelTypeUnsupported) { 134 | NSLog(@"This model is not supported in your current client version. Please update for official support. Alternatively, you can use the responseDict property on each ClarifaiOutput to support the model on your own."); 135 | } 136 | 137 | NSString *apiURL = @""; 138 | if (self.version != nil) { 139 | apiURL = [NSString stringWithFormat:@"%@/models/%@/versions/%@/outputs", kApiBaseUrl, self.modelID, self.version.versionID]; 140 | } else { 141 | apiURL = [NSString stringWithFormat:@"%@/models/%@/outputs", kApiBaseUrl, self.modelID]; 142 | } 143 | 144 | NSString *escapedURL = [apiURL stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; 145 | 146 | NSMutableArray *imagesToPredictOn = [NSMutableArray array]; 147 | for (ClarifaiImage *image in images) { 148 | if (image.mediaURL) { 149 | [imagesToPredictOn addObject:@{@"data": @{@"image": @{@"url": image.mediaURL}}}]; 150 | } else if (image.image) { 151 | NSData *imageData = UIImageJPEGRepresentation(image.image, 0.88); 152 | [imagesToPredictOn addObject:@{@"data": @{@"image": @{@"base64": [imageData base64EncodedStringWithOptions:0]}}}]; 153 | } else if (image.mediaData) { 154 | [imagesToPredictOn addObject:@{@"data": @{@"image": @{@"base64": [image.mediaData base64EncodedStringWithOptions:0]}}}]; 155 | } 156 | } 157 | NSDictionary *params = @{@"inputs": imagesToPredictOn}; 158 | 159 | [_app.sessionManager POST:escapedURL 160 | parameters:params 161 | progress:nil 162 | success:^(NSURLSessionDataTask *task, id response) { 163 | NSArray *outputs = [self formatOutputsFromResponse:response[@"outputs"]]; 164 | completion(outputs, nil); 165 | } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) { 166 | completion(nil, error); 167 | }]; 168 | }]; 169 | } 170 | 171 | - (void)predictOnImages:(NSArray *)images 172 | withLanguage:(NSString *)language 173 | completion:(ClarifaiPredictionsCompletion)completion { 174 | [_app ensureValidAccessToken:^(NSError *error) { 175 | if (error) { 176 | SafeRunBlock(completion, nil, error); 177 | return; 178 | } 179 | if (_modelType == ClarifaiModelTypeUnsupported) { 180 | NSError *err = [[NSError alloc] initWithDomain:kErrorDomain code:400 userInfo:@{@"description":@"Cannot predict, this model is not supported in your current client version. Please update."}]; 181 | completion(nil,err); 182 | return; 183 | } 184 | NSString *apiURL = [NSString stringWithFormat:@"%@/models/%@/versions/%@/outputs", kApiBaseUrl, self.modelID, self.version.versionID]; 185 | NSString *escapedURL = [apiURL stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; 186 | 187 | NSMutableArray *imagesToPredictOn = [NSMutableArray array]; 188 | for (ClarifaiImage *image in images) { 189 | if (image.mediaURL) { 190 | [imagesToPredictOn addObject:@{@"data": @{@"image": @{@"url": image.mediaURL}}}]; 191 | } else if (image.image) { 192 | NSData *imageData = UIImageJPEGRepresentation(image.image, 0.88); 193 | [imagesToPredictOn addObject:@{@"data": @{@"image": @{@"base64": imageData.base64Encoding}}}]; 194 | } else if (image.mediaData) { 195 | [imagesToPredictOn addObject:@{@"data": @{@"image": @{@"base64": image.mediaData.base64Encoding}}}]; 196 | } 197 | } 198 | NSDictionary *params = @{@"inputs": imagesToPredictOn, @"model":@{@"output_info":@{@"output_config":@{@"language":language}}}}; 199 | [_app.sessionManager POST:escapedURL 200 | parameters:params 201 | progress:nil 202 | success:^(NSURLSessionDataTask *task, id response) { 203 | NSArray *outputs = [self formatOutputsFromResponse:response[@"outputs"]]; 204 | completion(outputs, nil); 205 | } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) { 206 | completion(nil, error); 207 | }]; 208 | 209 | }]; 210 | } 211 | 212 | - (NSArray *)formatOutputsFromResponse:(NSArray *)outputsData { 213 | NSMutableArray *outputs = [[NSMutableArray alloc] init]; 214 | for (int i = 0; i < outputsData.count; i++) { 215 | 216 | NSString *type = [outputsData[i] findObjectForKey:@"type"]; 217 | NSString *typeExt = [outputsData[i] findObjectForKey:@"type_ext"]; 218 | 219 | // Construct array of all detected regions. 220 | NSArray *regionsArray = [outputsData[i] findObjectForKey:@"regions"]; 221 | NSMutableArray *regions = [NSMutableArray array]; 222 | for (NSDictionary *regionDict in regionsArray) { 223 | ClarifaiOutputRegion *region = [[ClarifaiOutputRegion alloc] initWithDictionary:regionDict]; 224 | [regions addObject:region]; 225 | } 226 | 227 | if ([regions count] > 0) { 228 | ClarifaiOutputRegion *testRegion = regions[0]; 229 | 230 | if ([testRegion.identity count] > 0 || [testRegion.ageAppearance count] > 0 || [type isEqualToString:@"facedetect"] || [typeExt isEqualToString:@"facedetect"]) { 231 | // Any Facedetect model. Need type only for face model, since it has no unique region information. Even if this changes, it will still work using a normal ClarifaiOutput. 232 | ClarifaiOutputFace *output = [[ClarifaiOutputFace alloc] initWithDictionary:outputsData[i]]; 233 | output.faces = regions; 234 | [outputs addObject:output]; 235 | } else if (testRegion.focusDensity) { 236 | // Focus model 237 | ClarifaiOutputFocus *output = [[ClarifaiOutputFocus alloc] initWithDictionary:outputsData[i]]; 238 | output.focusRegions = regions; 239 | [outputs addObject:output]; 240 | } else { 241 | // default to general output. 242 | ClarifaiOutput *output = [[ClarifaiOutput alloc] initWithDictionary:outputsData[i]]; 243 | output.regions = regions; 244 | [outputs addObject:output]; 245 | } 246 | } else { 247 | // no regions. 248 | ClarifaiOutput *output = [[ClarifaiOutput alloc] initWithDictionary:outputsData[i]]; 249 | [outputs addObject:output]; 250 | } 251 | } 252 | return outputs; 253 | } 254 | 255 | - (void)listVersions:(int)page 256 | resultsPerPage:(int)resultsPerPage 257 | completion:(ClarifaiModelVersionsCompletion)completion { 258 | [_app ensureValidAccessToken:^(NSError *error) { 259 | if (error) { 260 | SafeRunBlock(completion, nil, error); 261 | return; 262 | } 263 | NSString *apiURL = [NSString stringWithFormat:@"%@/models/%@/versions?page=%i&per_page=%i", kApiBaseUrl, _modelID, page, resultsPerPage]; 264 | 265 | [_app.sessionManager GET:apiURL 266 | parameters:nil 267 | progress:nil 268 | success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable response) { 269 | NSMutableArray *versions = [NSMutableArray array]; 270 | NSArray *versionDicts = response[@"model_versions"]; 271 | for (NSDictionary *versionDict in versionDicts) { 272 | ClarifaiModelVersion *version = [[ClarifaiModelVersion alloc] initWithDictionary:versionDict]; 273 | [versions addObject:version]; 274 | } 275 | completion(versions, nil); 276 | } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) { 277 | completion(nil, error); 278 | }]; 279 | }]; 280 | } 281 | 282 | - (void)getVersion:(NSString *)versionID 283 | completion:(ClarifaiModelVersionCompletion)completion { 284 | [_app ensureValidAccessToken:^(NSError *error) { 285 | if (error) { 286 | SafeRunBlock(completion, nil, error); 287 | return; 288 | } 289 | NSString *apiURL = [NSString stringWithFormat:@"%@/models/%@/versions/%@/", kApiBaseUrl, _modelID, versionID]; 290 | 291 | [_app.sessionManager GET:apiURL parameters:nil progress:nil success:^(NSURLSessionDataTask *task, id response) { 292 | ClarifaiModelVersion *version = [[ClarifaiModelVersion alloc] initWithDictionary:response[@"model_version"]]; 293 | completion(version, nil); 294 | } failure:^(NSURLSessionDataTask *task, NSError *error) { 295 | completion(nil, error); 296 | }]; 297 | }]; 298 | } 299 | 300 | - (void)deleteVersion:(NSString *)versionID 301 | completion:(ClarifaiRequestCompletion)completion { 302 | [_app ensureValidAccessToken:^(NSError *error) { 303 | if (error) { 304 | SafeRunBlock(completion, error); 305 | return; 306 | } 307 | NSString *apiURL = [NSString stringWithFormat:@"%@/models/%@/versions/%@/", kApiBaseUrl, _modelID, versionID]; 308 | 309 | [_app.sessionManager DELETE:apiURL parameters:nil success:^(NSURLSessionDataTask *task, id response) { 310 | completion(nil); 311 | } failure:^(NSURLSessionDataTask *task, NSError *error) { 312 | completion(error); 313 | }]; 314 | }]; 315 | } 316 | 317 | - (void)listTrainingInputs:(int)page 318 | resultsPerPage:(int)resultsPerPage 319 | completion:(ClarifaiInputsCompletion)completion { 320 | [_app ensureValidAccessToken:^(NSError *error) { 321 | if (error) { 322 | SafeRunBlock(completion, nil, error); 323 | return; 324 | } 325 | NSString *apiURL = [NSString stringWithFormat:@"%@/models/%@/inputs?page=%i&per_page=%i", kApiBaseUrl, _modelID, page, resultsPerPage]; 326 | 327 | [_app.sessionManager GET:apiURL parameters:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) { 328 | NSMutableArray *inputs = [NSMutableArray array]; 329 | NSArray *inputDicts = responseObject[@"inputs"]; 330 | for (NSDictionary *inputDict in inputDicts) { 331 | ClarifaiInput *input = [[ClarifaiInput alloc] initWithDictionary:inputDict]; 332 | [inputs addObject:input]; 333 | } 334 | completion(inputs, nil); 335 | } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) { 336 | completion(nil, error); 337 | }]; 338 | }]; 339 | } 340 | 341 | - (void)listTrainingInputsForVersion:(NSString *)versionID 342 | page:(int)page 343 | resultsPerPage:(int)resultsPerPage 344 | completion:(ClarifaiInputsCompletion)completion { 345 | [_app ensureValidAccessToken:^(NSError *error) { 346 | if (error) { 347 | SafeRunBlock(completion, nil, error); 348 | return; 349 | } 350 | NSString *apiURL = [NSString stringWithFormat:@"%@/models/%@/versions/%@/inputs?page=%i&per_page=%i", kApiBaseUrl, _modelID, versionID, page, resultsPerPage]; 351 | 352 | [_app.sessionManager GET:apiURL parameters:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) { 353 | NSMutableArray *inputs = [NSMutableArray array]; 354 | NSArray *inputDicts = responseObject[@"inputs"]; 355 | for (NSDictionary *inputDict in inputDicts) { 356 | ClarifaiInput *input = [[ClarifaiInput alloc] initWithDictionary:inputDict]; 357 | [inputs addObject:input]; 358 | } 359 | completion(inputs, nil); 360 | } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) { 361 | completion(nil, error); 362 | }]; 363 | }]; 364 | } 365 | 366 | 367 | 368 | @end 369 | -------------------------------------------------------------------------------- /SwiftExample/ClarifaiSwiftDemo.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 64C42843B1D15B579AE8FE51 /* Pods_ClarifaiSwiftDemo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9DDFD9EEDA12C758FEC20378 /* Pods_ClarifaiSwiftDemo.framework */; }; 11 | EB927A1F1E8EF7A800529D64 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB927A1E1E8EF7A800529D64 /* AppDelegate.swift */; }; 12 | EB927A211E8EF7A800529D64 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB927A201E8EF7A800529D64 /* ViewController.swift */; }; 13 | EB927A241E8EF7A800529D64 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = EB927A221E8EF7A800529D64 /* Main.storyboard */; }; 14 | EB927A261E8EF7A800529D64 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = EB927A251E8EF7A800529D64 /* Assets.xcassets */; }; 15 | EB927A291E8EF7A800529D64 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = EB927A271E8EF7A800529D64 /* LaunchScreen.storyboard */; }; 16 | /* End PBXBuildFile section */ 17 | 18 | /* Begin PBXFileReference section */ 19 | 9DDFD9EEDA12C758FEC20378 /* Pods_ClarifaiSwiftDemo.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_ClarifaiSwiftDemo.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 20 | C57BCA2D6C7145D33EE78B46 /* Pods-ClarifaiSwiftDemo.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ClarifaiSwiftDemo.debug.xcconfig"; path = "Pods/Target Support Files/Pods-ClarifaiSwiftDemo/Pods-ClarifaiSwiftDemo.debug.xcconfig"; sourceTree = ""; }; 21 | CF8C081F7E84C3601237E5F4 /* Pods-ClarifaiSwiftDemo.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ClarifaiSwiftDemo.release.xcconfig"; path = "Pods/Target Support Files/Pods-ClarifaiSwiftDemo/Pods-ClarifaiSwiftDemo.release.xcconfig"; sourceTree = ""; }; 22 | EB927A1B1E8EF7A800529D64 /* ClarifaiSwiftDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ClarifaiSwiftDemo.app; sourceTree = BUILT_PRODUCTS_DIR; }; 23 | EB927A1E1E8EF7A800529D64 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 24 | EB927A201E8EF7A800529D64 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; 25 | EB927A231E8EF7A800529D64 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 26 | EB927A251E8EF7A800529D64 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 27 | EB927A281E8EF7A800529D64 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 28 | EB927A2A1E8EF7A800529D64 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 29 | /* End PBXFileReference section */ 30 | 31 | /* Begin PBXFrameworksBuildPhase section */ 32 | EB927A181E8EF7A800529D64 /* Frameworks */ = { 33 | isa = PBXFrameworksBuildPhase; 34 | buildActionMask = 2147483647; 35 | files = ( 36 | 64C42843B1D15B579AE8FE51 /* Pods_ClarifaiSwiftDemo.framework in Frameworks */, 37 | ); 38 | runOnlyForDeploymentPostprocessing = 0; 39 | }; 40 | /* End PBXFrameworksBuildPhase section */ 41 | 42 | /* Begin PBXGroup section */ 43 | 76E77DD3A21AC1A63E38E258 /* Frameworks */ = { 44 | isa = PBXGroup; 45 | children = ( 46 | 9DDFD9EEDA12C758FEC20378 /* Pods_ClarifaiSwiftDemo.framework */, 47 | ); 48 | name = Frameworks; 49 | sourceTree = ""; 50 | }; 51 | 90CEA50C84AFBC99C58354BE /* Pods */ = { 52 | isa = PBXGroup; 53 | children = ( 54 | C57BCA2D6C7145D33EE78B46 /* Pods-ClarifaiSwiftDemo.debug.xcconfig */, 55 | CF8C081F7E84C3601237E5F4 /* Pods-ClarifaiSwiftDemo.release.xcconfig */, 56 | ); 57 | name = Pods; 58 | sourceTree = ""; 59 | }; 60 | EB927A121E8EF7A800529D64 = { 61 | isa = PBXGroup; 62 | children = ( 63 | EB927A1D1E8EF7A800529D64 /* ClarifaiSwiftDemo */, 64 | EB927A1C1E8EF7A800529D64 /* Products */, 65 | 90CEA50C84AFBC99C58354BE /* Pods */, 66 | 76E77DD3A21AC1A63E38E258 /* Frameworks */, 67 | ); 68 | sourceTree = ""; 69 | }; 70 | EB927A1C1E8EF7A800529D64 /* Products */ = { 71 | isa = PBXGroup; 72 | children = ( 73 | EB927A1B1E8EF7A800529D64 /* ClarifaiSwiftDemo.app */, 74 | ); 75 | name = Products; 76 | sourceTree = ""; 77 | }; 78 | EB927A1D1E8EF7A800529D64 /* ClarifaiSwiftDemo */ = { 79 | isa = PBXGroup; 80 | children = ( 81 | EB927A1E1E8EF7A800529D64 /* AppDelegate.swift */, 82 | EB927A201E8EF7A800529D64 /* ViewController.swift */, 83 | EB927A221E8EF7A800529D64 /* Main.storyboard */, 84 | EB927A251E8EF7A800529D64 /* Assets.xcassets */, 85 | EB927A271E8EF7A800529D64 /* LaunchScreen.storyboard */, 86 | EB927A2A1E8EF7A800529D64 /* Info.plist */, 87 | ); 88 | path = ClarifaiSwiftDemo; 89 | sourceTree = ""; 90 | }; 91 | /* End PBXGroup section */ 92 | 93 | /* Begin PBXNativeTarget section */ 94 | EB927A1A1E8EF7A800529D64 /* ClarifaiSwiftDemo */ = { 95 | isa = PBXNativeTarget; 96 | buildConfigurationList = EB927A2D1E8EF7A800529D64 /* Build configuration list for PBXNativeTarget "ClarifaiSwiftDemo" */; 97 | buildPhases = ( 98 | E08521CE48264469EE8F921F /* [CP] Check Pods Manifest.lock */, 99 | EB927A171E8EF7A800529D64 /* Sources */, 100 | EB927A181E8EF7A800529D64 /* Frameworks */, 101 | EB927A191E8EF7A800529D64 /* Resources */, 102 | E703AC567C7BC6C8849253B2 /* [CP] Embed Pods Frameworks */, 103 | 4F95804EDEE86A4EE589D6CB /* [CP] Copy Pods Resources */, 104 | ); 105 | buildRules = ( 106 | ); 107 | dependencies = ( 108 | ); 109 | name = ClarifaiSwiftDemo; 110 | productName = ClarifaiSwiftDemo; 111 | productReference = EB927A1B1E8EF7A800529D64 /* ClarifaiSwiftDemo.app */; 112 | productType = "com.apple.product-type.application"; 113 | }; 114 | /* End PBXNativeTarget section */ 115 | 116 | /* Begin PBXProject section */ 117 | EB927A131E8EF7A800529D64 /* Project object */ = { 118 | isa = PBXProject; 119 | attributes = { 120 | LastSwiftUpdateCheck = 0810; 121 | LastUpgradeCheck = 0810; 122 | ORGANIZATIONNAME = Clarifai; 123 | TargetAttributes = { 124 | EB927A1A1E8EF7A800529D64 = { 125 | CreatedOnToolsVersion = 8.1; 126 | DevelopmentTeam = 32E6VH74P3; 127 | ProvisioningStyle = Automatic; 128 | }; 129 | }; 130 | }; 131 | buildConfigurationList = EB927A161E8EF7A800529D64 /* Build configuration list for PBXProject "ClarifaiSwiftDemo" */; 132 | compatibilityVersion = "Xcode 3.2"; 133 | developmentRegion = English; 134 | hasScannedForEncodings = 0; 135 | knownRegions = ( 136 | en, 137 | Base, 138 | ); 139 | mainGroup = EB927A121E8EF7A800529D64; 140 | productRefGroup = EB927A1C1E8EF7A800529D64 /* Products */; 141 | projectDirPath = ""; 142 | projectRoot = ""; 143 | targets = ( 144 | EB927A1A1E8EF7A800529D64 /* ClarifaiSwiftDemo */, 145 | ); 146 | }; 147 | /* End PBXProject section */ 148 | 149 | /* Begin PBXResourcesBuildPhase section */ 150 | EB927A191E8EF7A800529D64 /* Resources */ = { 151 | isa = PBXResourcesBuildPhase; 152 | buildActionMask = 2147483647; 153 | files = ( 154 | EB927A291E8EF7A800529D64 /* LaunchScreen.storyboard in Resources */, 155 | EB927A261E8EF7A800529D64 /* Assets.xcassets in Resources */, 156 | EB927A241E8EF7A800529D64 /* Main.storyboard in Resources */, 157 | ); 158 | runOnlyForDeploymentPostprocessing = 0; 159 | }; 160 | /* End PBXResourcesBuildPhase section */ 161 | 162 | /* Begin PBXShellScriptBuildPhase section */ 163 | 4F95804EDEE86A4EE589D6CB /* [CP] Copy Pods Resources */ = { 164 | isa = PBXShellScriptBuildPhase; 165 | buildActionMask = 2147483647; 166 | files = ( 167 | ); 168 | inputPaths = ( 169 | ); 170 | name = "[CP] Copy Pods Resources"; 171 | outputPaths = ( 172 | ); 173 | runOnlyForDeploymentPostprocessing = 0; 174 | shellPath = /bin/sh; 175 | shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-ClarifaiSwiftDemo/Pods-ClarifaiSwiftDemo-resources.sh\"\n"; 176 | showEnvVarsInLog = 0; 177 | }; 178 | E08521CE48264469EE8F921F /* [CP] Check Pods Manifest.lock */ = { 179 | isa = PBXShellScriptBuildPhase; 180 | buildActionMask = 2147483647; 181 | files = ( 182 | ); 183 | inputPaths = ( 184 | ); 185 | name = "[CP] Check Pods Manifest.lock"; 186 | outputPaths = ( 187 | ); 188 | runOnlyForDeploymentPostprocessing = 0; 189 | shellPath = /bin/sh; 190 | 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"; 191 | showEnvVarsInLog = 0; 192 | }; 193 | E703AC567C7BC6C8849253B2 /* [CP] Embed Pods Frameworks */ = { 194 | isa = PBXShellScriptBuildPhase; 195 | buildActionMask = 2147483647; 196 | files = ( 197 | ); 198 | inputPaths = ( 199 | ); 200 | name = "[CP] Embed Pods Frameworks"; 201 | outputPaths = ( 202 | ); 203 | runOnlyForDeploymentPostprocessing = 0; 204 | shellPath = /bin/sh; 205 | shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-ClarifaiSwiftDemo/Pods-ClarifaiSwiftDemo-frameworks.sh\"\n"; 206 | showEnvVarsInLog = 0; 207 | }; 208 | /* End PBXShellScriptBuildPhase section */ 209 | 210 | /* Begin PBXSourcesBuildPhase section */ 211 | EB927A171E8EF7A800529D64 /* Sources */ = { 212 | isa = PBXSourcesBuildPhase; 213 | buildActionMask = 2147483647; 214 | files = ( 215 | EB927A211E8EF7A800529D64 /* ViewController.swift in Sources */, 216 | EB927A1F1E8EF7A800529D64 /* AppDelegate.swift in Sources */, 217 | ); 218 | runOnlyForDeploymentPostprocessing = 0; 219 | }; 220 | /* End PBXSourcesBuildPhase section */ 221 | 222 | /* Begin PBXVariantGroup section */ 223 | EB927A221E8EF7A800529D64 /* Main.storyboard */ = { 224 | isa = PBXVariantGroup; 225 | children = ( 226 | EB927A231E8EF7A800529D64 /* Base */, 227 | ); 228 | name = Main.storyboard; 229 | sourceTree = ""; 230 | }; 231 | EB927A271E8EF7A800529D64 /* LaunchScreen.storyboard */ = { 232 | isa = PBXVariantGroup; 233 | children = ( 234 | EB927A281E8EF7A800529D64 /* Base */, 235 | ); 236 | name = LaunchScreen.storyboard; 237 | sourceTree = ""; 238 | }; 239 | /* End PBXVariantGroup section */ 240 | 241 | /* Begin XCBuildConfiguration section */ 242 | EB927A2B1E8EF7A800529D64 /* Debug */ = { 243 | isa = XCBuildConfiguration; 244 | buildSettings = { 245 | ALWAYS_SEARCH_USER_PATHS = NO; 246 | CLANG_ANALYZER_NONNULL = YES; 247 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 248 | CLANG_CXX_LIBRARY = "libc++"; 249 | CLANG_ENABLE_MODULES = YES; 250 | CLANG_ENABLE_OBJC_ARC = YES; 251 | CLANG_WARN_BOOL_CONVERSION = YES; 252 | CLANG_WARN_CONSTANT_CONVERSION = YES; 253 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 254 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 255 | CLANG_WARN_EMPTY_BODY = YES; 256 | CLANG_WARN_ENUM_CONVERSION = YES; 257 | CLANG_WARN_INFINITE_RECURSION = YES; 258 | CLANG_WARN_INT_CONVERSION = YES; 259 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 260 | CLANG_WARN_SUSPICIOUS_MOVES = YES; 261 | CLANG_WARN_UNREACHABLE_CODE = YES; 262 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 263 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 264 | COPY_PHASE_STRIP = NO; 265 | DEBUG_INFORMATION_FORMAT = dwarf; 266 | ENABLE_STRICT_OBJC_MSGSEND = YES; 267 | ENABLE_TESTABILITY = YES; 268 | GCC_C_LANGUAGE_STANDARD = gnu99; 269 | GCC_DYNAMIC_NO_PIC = NO; 270 | GCC_NO_COMMON_BLOCKS = YES; 271 | GCC_OPTIMIZATION_LEVEL = 0; 272 | GCC_PREPROCESSOR_DEFINITIONS = ( 273 | "DEBUG=1", 274 | "$(inherited)", 275 | ); 276 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 277 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 278 | GCC_WARN_UNDECLARED_SELECTOR = YES; 279 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 280 | GCC_WARN_UNUSED_FUNCTION = YES; 281 | GCC_WARN_UNUSED_VARIABLE = YES; 282 | IPHONEOS_DEPLOYMENT_TARGET = 10.1; 283 | MTL_ENABLE_DEBUG_INFO = YES; 284 | ONLY_ACTIVE_ARCH = YES; 285 | SDKROOT = iphoneos; 286 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 287 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 288 | TARGETED_DEVICE_FAMILY = "1,2"; 289 | }; 290 | name = Debug; 291 | }; 292 | EB927A2C1E8EF7A800529D64 /* Release */ = { 293 | isa = XCBuildConfiguration; 294 | buildSettings = { 295 | ALWAYS_SEARCH_USER_PATHS = NO; 296 | CLANG_ANALYZER_NONNULL = YES; 297 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 298 | CLANG_CXX_LIBRARY = "libc++"; 299 | CLANG_ENABLE_MODULES = YES; 300 | CLANG_ENABLE_OBJC_ARC = YES; 301 | CLANG_WARN_BOOL_CONVERSION = YES; 302 | CLANG_WARN_CONSTANT_CONVERSION = YES; 303 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 304 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 305 | CLANG_WARN_EMPTY_BODY = YES; 306 | CLANG_WARN_ENUM_CONVERSION = YES; 307 | CLANG_WARN_INFINITE_RECURSION = YES; 308 | CLANG_WARN_INT_CONVERSION = YES; 309 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 310 | CLANG_WARN_SUSPICIOUS_MOVES = YES; 311 | CLANG_WARN_UNREACHABLE_CODE = YES; 312 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 313 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 314 | COPY_PHASE_STRIP = NO; 315 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 316 | ENABLE_NS_ASSERTIONS = NO; 317 | ENABLE_STRICT_OBJC_MSGSEND = YES; 318 | GCC_C_LANGUAGE_STANDARD = gnu99; 319 | GCC_NO_COMMON_BLOCKS = YES; 320 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 321 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 322 | GCC_WARN_UNDECLARED_SELECTOR = YES; 323 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 324 | GCC_WARN_UNUSED_FUNCTION = YES; 325 | GCC_WARN_UNUSED_VARIABLE = YES; 326 | IPHONEOS_DEPLOYMENT_TARGET = 10.1; 327 | MTL_ENABLE_DEBUG_INFO = NO; 328 | SDKROOT = iphoneos; 329 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 330 | TARGETED_DEVICE_FAMILY = "1,2"; 331 | VALIDATE_PRODUCT = YES; 332 | }; 333 | name = Release; 334 | }; 335 | EB927A2E1E8EF7A800529D64 /* Debug */ = { 336 | isa = XCBuildConfiguration; 337 | baseConfigurationReference = C57BCA2D6C7145D33EE78B46 /* Pods-ClarifaiSwiftDemo.debug.xcconfig */; 338 | buildSettings = { 339 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 340 | DEVELOPMENT_TEAM = 32E6VH74P3; 341 | INFOPLIST_FILE = ClarifaiSwiftDemo/Info.plist; 342 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 343 | PRODUCT_BUNDLE_IDENTIFIER = cai.ClarifaiSwiftDemo; 344 | PRODUCT_NAME = "$(TARGET_NAME)"; 345 | SWIFT_VERSION = 3.0; 346 | }; 347 | name = Debug; 348 | }; 349 | EB927A2F1E8EF7A800529D64 /* Release */ = { 350 | isa = XCBuildConfiguration; 351 | baseConfigurationReference = CF8C081F7E84C3601237E5F4 /* Pods-ClarifaiSwiftDemo.release.xcconfig */; 352 | buildSettings = { 353 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 354 | DEVELOPMENT_TEAM = 32E6VH74P3; 355 | INFOPLIST_FILE = ClarifaiSwiftDemo/Info.plist; 356 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 357 | PRODUCT_BUNDLE_IDENTIFIER = cai.ClarifaiSwiftDemo; 358 | PRODUCT_NAME = "$(TARGET_NAME)"; 359 | SWIFT_VERSION = 3.0; 360 | }; 361 | name = Release; 362 | }; 363 | /* End XCBuildConfiguration section */ 364 | 365 | /* Begin XCConfigurationList section */ 366 | EB927A161E8EF7A800529D64 /* Build configuration list for PBXProject "ClarifaiSwiftDemo" */ = { 367 | isa = XCConfigurationList; 368 | buildConfigurations = ( 369 | EB927A2B1E8EF7A800529D64 /* Debug */, 370 | EB927A2C1E8EF7A800529D64 /* Release */, 371 | ); 372 | defaultConfigurationIsVisible = 0; 373 | defaultConfigurationName = Release; 374 | }; 375 | EB927A2D1E8EF7A800529D64 /* Build configuration list for PBXNativeTarget "ClarifaiSwiftDemo" */ = { 376 | isa = XCConfigurationList; 377 | buildConfigurations = ( 378 | EB927A2E1E8EF7A800529D64 /* Debug */, 379 | EB927A2F1E8EF7A800529D64 /* Release */, 380 | ); 381 | defaultConfigurationIsVisible = 0; 382 | defaultConfigurationName = Release; 383 | }; 384 | /* End XCConfigurationList section */ 385 | }; 386 | rootObject = EB927A131E8EF7A800529D64 /* Project object */; 387 | } 388 | -------------------------------------------------------------------------------- /Clarifai/Classes/ClarifaiApp.h: -------------------------------------------------------------------------------- 1 | // 2 | // ClarifaiApp.h 3 | // ClarifaiApiDemo 4 | // 5 | // Created by John Sloan on 9/1/16. 6 | // Copyright © 2016 Clarifai, Inc. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | #import "ClarifaiModel.h" 12 | #import "ClarifaiSearchTerm.h" 13 | #import "ClarifaiGeo.h" 14 | #import "ClarifaiConcept.h" 15 | #import "ClarifaiImage.h" 16 | #import "ClarifaiInput.h" 17 | #import "ClarifaiOutput.h" 18 | #import "ClarifaiOutputFace.h" 19 | #import "ClarifaiOutputFocus.h" 20 | #import "ClarifaiConstants.h" 21 | #import "ClarifaiLocation.h" 22 | 23 | /** 24 | * API calls are tied to an account and application. Any model you create or inputs you add, will be contained within an application. After creating an app on the [Clarifai developer page](https://developer.clarifai.com/applications) you can use your app's id and secret to create a ClarifaiApp object. A ClarifaiApp instance will be the main hub of interfacing with an application. It is used to create, get, update, and search the various components of your application including: inputs, concepts, and models. 25 | */ 26 | @interface ClarifaiApp : NSObject 27 | 28 | @property (strong, nonatomic) AFHTTPSessionManager *sessionManager; 29 | @property (strong, nonatomic) NSString *accessToken; 30 | 31 | /** 32 | * Initializes a new ClarifaiApp. 33 | * 34 | * @param appID Your application client ID from https://developer.clarifai.com/applications 35 | * @param appSecret Your application secret from https://developer.clarifai.com/applications 36 | */ 37 | - (instancetype)initWithAppID:(NSString *)appID appSecret:(NSString *)appSecret __attribute__((deprecated)); 38 | 39 | /** 40 | * Initializes a new ClarifaiApp. 41 | * 42 | * @param apiKey An API Key generated for your Application. https://developer.clarifai.com/applications 43 | */ 44 | - (instancetype)initWithApiKey:(NSString *)apiKey; 45 | 46 | #pragma mark INPUTS 47 | 48 | /** 49 | * Saves inputs to your Clarifai application. 50 | * 51 | * @param inputs Array containing ClarifaiInputs to save to your application. 52 | * @param completion Invoked when the request completes. 53 | */ 54 | - (void)addInputs:(NSArray *)inputs completion:(ClarifaiInputsCompletion)completion; 55 | 56 | /** 57 | * Retrieves images that have been saved to your Clarifai application on the specified page. 58 | * 59 | * @param page The page of images that you want to list. 60 | * @param pageSize The size that you'd like pages to be. 61 | * @param completion Invoked when the request completes. 62 | */ 63 | - (void)getInputsOnPage:(int)page pageSize:(int)pageSize completion:(ClarifaiInputsCompletion)completion; 64 | 65 | /** 66 | * Retrieves a single image that has been saved by your Clarifai application. 67 | * 68 | * @param inputID String containing the id of the image you'd like to retrieve. 69 | * @param completion Invoked when the request completes. 70 | */ 71 | - (void)getInput:(NSString *)inputID completion:(ClarifaiStoreInputCompletion)completion; 72 | 73 | /** 74 | * Retrieves the status of all inputs in your Clarifai application. 75 | * 76 | * @param completion Invoked when the request completes. 77 | */ 78 | - (void)getInputsStatus:(ClarifaiInputsStatusCompletion)completion; 79 | 80 | /** 81 | * Deletes image specified by an ID. 82 | * 83 | * @param inputID id of image you want to delete. 84 | * @param completion Invoked when the request completes. 85 | */ 86 | - (void)deleteInput:(NSString *)inputID completion:(ClarifaiRequestCompletion)completion; 87 | 88 | /** 89 | * Deletes images specified by either an array of ClarifaiInputs or inputID NSStrings. Note that each 90 | * ClarifaiInput must contain an inputID at the very least, that matches the input you would like to delete. 91 | * 92 | * @warning This method is async on the server, meaning that the request returns immediately, 93 | * before inputs have finished being deleted. To check for completion, use getInput: above. 94 | * If one input in the list is gone, all have been deleted. 95 | * 96 | * @param inputs Array of ClarifaiInputs containing id's of the inputs you want to delete. 97 | * @param completion Invoked when the request completes. 98 | */ 99 | - (void)deleteInputsByIDList:(NSArray *)inputs completion:(ClarifaiRequestCompletion)completion; 100 | 101 | /** 102 | * Deletes all inputs associated with you app. 103 | * 104 | * @warning This method is async on the server, meaning that the request returns immediately, 105 | * before inputs have finished being deleted. To check for completion, use getInput: above. 106 | * If one input in the list is gone, all have been deleted. 107 | * 108 | * @param completion Invoked when the request completes. 109 | */ 110 | - (void)deleteAllInputs:(ClarifaiRequestCompletion)completion; 111 | 112 | /** 113 | * Update the geo point of an existing input to a new location. 114 | * 115 | * @param inputID String containing the id of the input to be updated. 116 | * @param completion Invoked when the update completes. 117 | */ 118 | - (void)updateGeoPoint:(ClarifaiLocation *)location forInputWithID:(NSString *)inputID completion:(ClarifaiStoreInputCompletion)completion; 119 | 120 | #pragma mark UPDATING CONCEPTS FOR INPUTS 121 | 122 | /** 123 | * Merge tags to an existing input. 124 | * 125 | * @warning Merging will overwrite values for tags with matching id's, or append to the 126 | * input's existing list of tags in the app. 127 | * 128 | * @param concepts Array of new or updated ClarifaiConcepts to merge. 129 | * @param inputID String containing the id of the input you'd like to merge concepts to. 130 | * @param completion Invoked when the update completes. 131 | */ 132 | - (void)mergeConcepts:(NSArray *)concepts forInputWithID:(NSString *)inputID completion:(ClarifaiStoreInputCompletion)completion; 133 | 134 | /** 135 | * Merge tags to one or more existing inputs. 136 | * 137 | * @warning Merging will overwrite values for tags with matching id's, or append to an 138 | * input's existing list of tags in the app. 139 | * 140 | * @param inputs Array of ClarifaiInputs to merge tags to. Each input should contain the 141 | * list of tags to be merged in it's concepts array property. Each input 142 | * must also have an inputID. 143 | * @param completion Invoked when the update completes. 144 | */ 145 | - (void)mergeConceptsForInputs:(NSArray *)inputs completion:(ClarifaiInputsCompletion)completion; 146 | 147 | /** 148 | * Overwrites tags of existing input with given ID. 149 | * 150 | * @warning This method will overwrite values for tags with matching id's, or overwrite the 151 | * input's list of tags with the new list of tags. 152 | * 153 | * @param inputID String containing the id of the input you'd like to overwrite concepts for. 154 | * @param completion Invoked when the update completes. 155 | */ 156 | - (void)setConcepts:(NSArray *)concepts forInputWithID:(NSString *)inputID completion:(ClarifaiStoreInputCompletion)completion; 157 | 158 | /** 159 | * Overwrites tags of one or more existing inputs. 160 | * 161 | * @warning This method will overwrite values for tags with matching id's, or overwrite each 162 | * input's list of tags with the new list of tags. 163 | * 164 | * @param inputs Array of ClarifaiInputs to add tags to. Each input should contain 165 | * the tags to be added in it's concepts array property. Each input must also 166 | * have an inputID. 167 | * @param completion Invoked when the update completes. 168 | */ 169 | - (void)setConceptsForInputs:(NSArray *)inputs completion:(ClarifaiInputsCompletion)completion; 170 | 171 | /** 172 | * Delete tags from an existing input. 173 | * 174 | * @param concepts Array of ClarifaiConcepts to delete. These must have matching conceptID's 175 | * to whichever ones are being deleted. 176 | * @param inputID String containing the id of the input you'd like to delete 177 | * concepts from. 178 | * @param completion Invoked when the update completes. 179 | */ 180 | - (void)deleteConcepts:(NSArray *)concepts forInputWithID:(NSString *)inputID completion:(ClarifaiStoreInputCompletion)completion; 181 | 182 | /** 183 | * Delete tags from one or more existing inputs. 184 | * 185 | * @param inputs Array of ClarifaiInputs to delete tags from. Each input should contain 186 | * a list of tags to be deleted as it's concepts array property. Each input must 187 | * also have an inputID. 188 | * @param completion Invoked when the update completes. 189 | */ 190 | - (void)deleteConceptsForInputs:(NSArray *)inputs completion:(ClarifaiInputsCompletion)completion; 191 | 192 | #pragma mark CONCEPTS 193 | 194 | /** 195 | * Retrieves concepts that have been saved to your Clarifai application on the specified page. 196 | * 197 | * @param page The page of concepts that you want to list. 198 | * @param pageSize The size that you'd like pages to be. 199 | * @param completion Invoked when the request completes. 200 | */ 201 | - (void)getConceptsOnPage:(int)page pageSize:(int)pageSize 202 | completion:(ClarifaiSearchConceptCompletion)completion; 203 | 204 | /** 205 | * Retrieves a single concept that has been saved by your Clarifai application. 206 | * 207 | * @param conceptID String containing the id of the concept you'd like to retrieve. 208 | * @param completion Invoked when the request completes. 209 | */ 210 | - (void)getConcept:(NSString *)conceptID 211 | completion:(ClarifaiStoreConceptCompletion)completion; 212 | 213 | /** 214 | * Saves concepts to your Clarifai application. 215 | * 216 | * @param concepts Array containing ClarifaiConcepts to save. You must populate this 217 | * array and at least set id's for each concept. You can also add 218 | * a name, which does not need to be unique. To create a 219 | * concept, see ClarifaiConcept. 220 | * @param completion Invoked when the request completes. 221 | */ 222 | - (void)addConcepts:(NSArray *)concepts completion:(ClarifaiSearchConceptCompletion)completion; 223 | 224 | #pragma mark UPDATING CONCEPTS FOR MODELS 225 | 226 | /** 227 | * Merge a list of tags to an existing model. 228 | * 229 | * @warning Merging will overwrite values for tags with matching id's, or append to the 230 | * model's existing list of tags in the app. 231 | * 232 | * @param concepts Array of new ClarifaiConcepts. 233 | * @param modelID String containing the id of the model you'd like to update 234 | * concepts for. 235 | * @param completion Invoked when the update completes. 236 | */ 237 | - (void)mergeConcepts:(NSArray *)concepts forModelWithID:(NSString *)modelID completion:(ClarifaiModelCompletion)completion; 238 | 239 | /** 240 | * Overwrite the list of tags of an existing model with a new list of tags. 241 | * 242 | * @param concepts Array of new ClarifaiConcepts. 243 | * @param modelID String containing the id of the model you'd like to update 244 | * concepts for. 245 | * @param completion Invoked when the update completes. 246 | */ 247 | - (void)setConcepts:(NSArray *)concepts forModelWithID:(NSString *)modelID completion:(ClarifaiModelCompletion)completion; 248 | 249 | /** 250 | * Remove tags from an existing model. 251 | * 252 | * @param concepts Array of ClarifaiConcepts with id's matching the tags to be removed. 253 | * @param modelID String containing the id of the model you'd like to update 254 | * concepts for. 255 | * @param completion Invoked when the update completes. 256 | */ 257 | - (void)deleteConcepts:(NSArray *)concepts fromModelWithID:(NSString *)modelID completion:(ClarifaiModelCompletion)completion; 258 | 259 | #pragma mark MODELS 260 | 261 | /** 262 | * Create a model. 263 | * 264 | * @param concepts Concepts that belong to the new model. These MUST be concepts 265 | * that already have been added within the app, either directly or to inputs. 266 | * This will not create new concepts for conceptIDs that the app doesn't 267 | * contain already. You can pass in ClarifaiConcepts or NSStrings. If you 268 | * pass strings this method will create a model with concepts named 269 | * with the given strings. 270 | * 271 | * @param modelName Name of the model. This will automatically use the name as the ModelID as well. 272 | * 273 | * @param conceptsMutuallyExclusive Do you expect to see more than one of 274 | * the concepts in this model in the SAME image? If Yes, then 275 | * conceptsMutuallyExclusive: false (default), if No, then conceptsMutuallyExclusive: true. 276 | * 277 | * @param closedEnvironment Do you expect to run the trained model on images that do not 278 | * contain ANY of the concepts in the model? If yes, closedEnvironment: false (default), 279 | * if no closedEnvironment: true. 280 | * 281 | * @param completion Invoked when the request completes. 282 | */ 283 | - (void)createModel:(NSArray *)concepts 284 | name:(NSString *)modelName 285 | conceptsMutuallyExclusive:(BOOL)conceptsMutuallyExclusive 286 | closedEnvironment:(BOOL)closedEnvironment 287 | completion:(ClarifaiModelCompletion)completion; 288 | 289 | /** 290 | * Create a model. 291 | * 292 | * @param concepts Concepts that belong to the new model. These MUST be concepts 293 | * that already have been added within the app, either directly or to inputs. 294 | * This will not create new concepts for conceptIDs that the app doesn't 295 | * contain already. You can pass in ClarifaiConcepts or NSStrings. If you 296 | * pass strings this method will create a model with concepts named 297 | * with the given strings. 298 | * 299 | * @param modelName Name of the model. 300 | * 301 | * @param modelID ID of the model. ID's MUST be unique for each model. 302 | * 303 | * @param conceptsMutuallyExclusive Do you expect to see more than one of 304 | * the concepts in this model in the SAME image? If Yes, then 305 | * conceptsMutuallyExclusive: false (default), if No, then conceptsMutuallyExclusive: true. 306 | * 307 | * @param closedEnvironment Do you expect to run the trained model on images that do not 308 | * contain ANY of the concepts in the model? If yes, closedEnvironment: false (default), 309 | * if no closedEnvironment: true. 310 | * 311 | * @param completion Invoked when the request completes. 312 | */ 313 | - (void)createModel:(NSArray *)concepts 314 | name:(NSString *)modelName 315 | modelID:(NSString *)modelID 316 | conceptsMutuallyExclusive:(BOOL)conceptsMutuallyExclusive 317 | closedEnvironment:(BOOL)closedEnvironment 318 | completion:(ClarifaiModelCompletion)completion; 319 | 320 | /** 321 | * Get all models in your application. 322 | * 323 | * @param completion Invoked when the request completes. 324 | */ 325 | - (void)getModels:(ClarifaiModelsCompletion)completion; 326 | 327 | /** 328 | * Get models in your application with pagination. 329 | * 330 | * @param page Results page to load. 331 | * @param resultsPerPage Number of results per page. 332 | * @param completion Invoked when the request completes. 333 | */ 334 | - (void)getModels:(int)page resultsPerPage:(int)resultsPerPage completion:(ClarifaiModelsCompletion)completion; 335 | 336 | /** 337 | * Retrieve a specific model by ID. 338 | * 339 | * @param modelID ID of the model to find. 340 | * @param completion Invoked when the request completes. 341 | */ 342 | - (void)getModelByID:(NSString *)modelID completion:(ClarifaiModelCompletion)completion; 343 | 344 | /** 345 | * Search for matching model names and retrieve the first one found. 346 | * 347 | * @warning This method only searches for models of type ClarifaiModelTypeConcept. 348 | * To search for a model by name and type, such as Clarifai's color model, use 349 | * searchForModelByName:modelType: 350 | * 351 | * @param modelName Name of the model to find. 352 | * @param completion Invoked when the request completes. 353 | */ 354 | - (void)getModelByName:(NSString *)modelName completion:(ClarifaiModelCompletion)completion; 355 | 356 | /** 357 | * Returns a ClarifaiModel with the requested ID, containing the outputinfo for the model. The outputinfo contains info like which concepts are associated with the model, the model's output type, etc. 358 | * 359 | * @param modelID id of the model. 360 | * @param completion Invoked when the request completes. 361 | */ 362 | - (void)getOutputInfoForModel:(NSString *)modelID completion:(ClarifaiModelCompletion)completion; 363 | 364 | /** 365 | * Update the name or output info of a model with matching modelID. 366 | * 367 | * @param modelID id of the model to update. 368 | * @param modelName The new name of the model. 369 | * @param conceptsMutuallyExclusive The new value for conceptsMutuallyExclusive. 370 | * @param closedEnvironment The new value for closedEnvironment. 371 | */ 372 | - (void)updateModel:(NSString *)modelID 373 | name:(NSString *)modelName 374 | conceptsMutuallyExclusive:(BOOL)conceptsMutuallyExclusive 375 | closedEnvironment:(BOOL)closedEnvironment 376 | completion:(ClarifaiModelCompletion)completion; 377 | 378 | /** 379 | * Deletes model specified by an ID. 380 | * 381 | * @param modelID id of model you want to delete. 382 | * @param completion Invoked when the request completes. 383 | */ 384 | - (void)deleteModel:(NSString *)modelID completion:(ClarifaiRequestCompletion)completion; 385 | 386 | /** 387 | * Deletes all models associated with your app. 388 | * 389 | * @warning This method is async on the server, meaning that the request returns immediately, 390 | * before models have finished being deleted. To check for completion, use getModelByID: above. 391 | * If one model in the list is gone, all have been deleted. 392 | * 393 | * @param completion Invoked when the request completes. 394 | */ 395 | - (void)deleteAllModels:(ClarifaiRequestCompletion)completion; 396 | 397 | /** 398 | * Deletes models specified by either an array of ClarifaiModels or modelID NSStrings. Note that each 399 | * ClarifaiModel must contain a modelID at the very least, that matches the model you would like to delete. 400 | * 401 | * @warning This method is async on the server, meaning that the request returns immediately, 402 | * before models have finished being deleted. To check for completion, use getModelByID: above. 403 | * If one model in the list is gone, all have been deleted. 404 | * 405 | * @param models Array of ClarifaiModels containing id's of the models you want to delete. 406 | * @param completion Invoked when the request completes. 407 | */ 408 | - (void)deleteModelsByIDList:(NSArray *)models completion:(ClarifaiRequestCompletion)completion; 409 | 410 | /** 411 | * Get training inputs associated with a given model. 412 | * 413 | * @param modelID ID of model to find different versions of. 414 | * @param page Results page to load. 415 | * @param resultsPerPage Number of results to return per page. 416 | * @param completion Invoked when the request completes. 417 | */ 418 | - (void)listTrainingInputsForModel:(NSString *)modelID 419 | page:(int)page 420 | resultsPerPage:(int)resultsPerPage 421 | completion:(ClarifaiInputsCompletion)completion; 422 | 423 | #pragma mark - MODEL VERSIONS 424 | 425 | /** 426 | * Get training inputs associated with a given model and version. 427 | * 428 | * @param modelID ID of model to find version of. 429 | * @param versionID ID of the version you want to retrieve. 430 | * @param page Results page to load. 431 | * @param resultsPerPage Number of results to return per page. 432 | * @param completion Invoked when the request completes. 433 | */ 434 | - (void)listTrainingInputsForModel:(NSString *)modelID 435 | version:(NSString *)versionID 436 | page:(int)page 437 | resultsPerPage:(int)resultsPerPage 438 | completion:(ClarifaiInputsCompletion)completion; 439 | 440 | /** 441 | * List versions of a given model. 442 | * 443 | * @param modelID ID of model to find different versions of. 444 | * @param page Results page to load. 445 | * @param resultsPerPage Number of results to return per page. 446 | * @param completion Invoked when the request completes. 447 | */ 448 | - (void)listVersionsForModel:(NSString *)modelID 449 | page:(int)page 450 | resultsPerPage:(int)resultsPerPage 451 | completion:(ClarifaiModelVersionsCompletion)completion; 452 | 453 | /** 454 | * Get specific version of a given model. 455 | * 456 | * @param modelID ID of model to find different versions of. 457 | * @param versionID ID of the version info you want to retrieve. 458 | * @param completion Invoked when the request completes. 459 | */ 460 | - (void)getVersionForModel:(NSString *)modelID 461 | versionID:(NSString *)versionID 462 | completion:(ClarifaiModelVersionCompletion)completion; 463 | 464 | /** 465 | * Delete specific version of a given model. 466 | * 467 | * @param modelID ID of model to find different versions of. 468 | * @param versionID ID of the version info you want to retrieve. 469 | * @param completion Invoked when the request completes. 470 | */ 471 | - (void)deleteVersionForModel:(NSString *)modelID 472 | versionID:(NSString *)versionID 473 | completion:(ClarifaiRequestCompletion)completion; 474 | 475 | #pragma mark SEARCH 476 | 477 | /** 478 | * Search the inputs and outputs of your application. See the ClarifaiSearchTerm class for details on 479 | * constructing search terms for your search query. 480 | * 481 | * @param searchTerms An array of ClarifaiSearchTerms that are and-ed together to create the search 482 | * query. For ex, two ClarifaiSearchTerm terms with different ClarifaiConcepts 483 | * specified will search for inputs that are associated with both terms' tags. 484 | * @param completion Invoked when the request completes. 485 | */ 486 | - (void)search:(NSArray *)searchTerms 487 | completion:(ClarifaiSearchCompletion)completion; 488 | 489 | /** 490 | * Search the inputs and outputs of your application with pagination. See the ClarifaiSearchTerm 491 | * class for details on constructing search terms for your search query. 492 | * 493 | * @param searchTerms An array of ClarifaiSearchTerms that are and-ed together to create the search 494 | * query. For ex, two ClarifaiSearchTerm terms with different ClarifaiConcepts 495 | * specified will search for inputs that are associated with both terms' tags. 496 | * @param page The page number of results to show. 497 | * @param perPage Number of results per page. 498 | * @param completion Invoked when the request completes. 499 | */ 500 | - (void)search:(NSArray *)searchTerms 501 | page:(NSNumber *)page 502 | perPage:(NSNumber *)perPage 503 | completion:(ClarifaiSearchCompletion)completion; 504 | 505 | /** 506 | * Search the inputs and outputs of your application with pagination and specified language. See 507 | * the ClarifaiSearchTerm class for details on constructing search terms for your search query. 508 | * 509 | * @param searchTerms An array of ClarifaiSearchTerms that are and-ed together to create the search 510 | * query. For ex, two ClarifaiSearchTerm terms with different ClarifaiConcepts 511 | * specified will search for inputs that are associated with both terms' tags. 512 | * @param page The page number of results to show. 513 | * @param perPage Number of results per page. 514 | * @param language When searching by concept name, a language can be specified. If nil, 515 | * defaults to your app's default language setting on devhub. 516 | * @param completion Invoked when the request completes. 517 | */ 518 | - (void)search:(NSArray *)searchTerms 519 | page:(NSNumber *)page 520 | perPage:(NSNumber *)perPage 521 | language:(NSString *)language 522 | completion:(ClarifaiSearchCompletion)completion; 523 | 524 | /** 525 | * Search using metadata previously added to the inputs in your application. 526 | * 527 | * @param metadata Metadata dictionary to search inputs with. This can be any valid json object. 528 | * @param page The page number of results to show. 529 | * @param perPage Number of results per page. 530 | * @param completion Invoked when the request completes. 531 | */ 532 | - (void)searchByMetadata:(NSDictionary *)metadata 533 | page:(NSNumber *)page 534 | perPage:(NSNumber *)perPage 535 | completion:(ClarifaiSearchCompletion)completion; 536 | 537 | /** 538 | * Search concepts by concept name and language. This is well-suited for autocomplete purposes, or 539 | * general concept name searching, as it will search all concepts from clarifai's public general 540 | * model as well as your own custom models. It is extremely useful to use this function to find 541 | * existing concept names (for example, concepts contained in Clarifai's general model) which can 542 | * then be used as a search term in Search to predict images associated with the concept. 543 | * 544 | * @param name A string to search concept names by. Ex: 'l*' will search and return all 545 | * concepts with names starting with an 'l'. 546 | * @param language A string specifying the language code of the concepts to search. For 547 | * example, by default the language is set to 'en' (English). 548 | * @param completion Invoked when the request completes. 549 | */ 550 | - (void)searchForConceptsByName:(NSString *)name 551 | andLanguage:(NSString *)language 552 | completion:(ClarifaiSearchConceptCompletion)completion; 553 | 554 | /** 555 | * Search for model by name and type. 556 | * 557 | * @param modelName Name of the model you'd like to search for. 558 | * @param modelType Type of model you'd like to search for. {embed, concept, cluster, detection, color} 559 | * @param completion Invoked when the request completes. 560 | */ 561 | - (void)searchForModelByName:(NSString *)modelName 562 | modelType:(ClarifaiModelType)modelType 563 | completion:(ClarifaiModelsCompletion)completion; 564 | 565 | 566 | #pragma mark AUTHENTICATION 567 | 568 | - (void)ensureValidAccessToken:(void (^)(NSError *error))handler; 569 | 570 | @end 571 | -------------------------------------------------------------------------------- /Example/Clarifai.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 2964E55F49037F0979A34490 /* libPods-Clarifai.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 83C54A18C2BB78C7FEB65157 /* libPods-Clarifai.a */; }; 11 | 407195211BADD02B0076B650 /* RecognitionViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 407195201BADD02B0076B650 /* RecognitionViewController.m */; }; 12 | 408D395B1BACA1FA00C5608B /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 408D395A1BACA1FA00C5608B /* main.m */; }; 13 | 408D395E1BACA1FA00C5608B /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 408D395D1BACA1FA00C5608B /* AppDelegate.m */; }; 14 | 408D39641BACA1FA00C5608B /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 408D39621BACA1FA00C5608B /* Main.storyboard */; }; 15 | 408D39661BACA1FA00C5608B /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 408D39651BACA1FA00C5608B /* Images.xcassets */; }; 16 | 408D39691BACA1FA00C5608B /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 408D39671BACA1FA00C5608B /* LaunchScreen.xib */; }; 17 | 408D39751BACA1FA00C5608B /* ClarifaiTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 408D39741BACA1FA00C5608B /* ClarifaiTests.m */; }; 18 | AE10DABE73E3DAE6CBE5C904 /* libPods-ClarifaiTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 8169D08DDEFC969649991F41 /* libPods-ClarifaiTests.a */; }; 19 | EA9D8C96D6FCA899D401F124 /* libPods-Clarifai.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5DFD46AB2E189C614DC9CE30 /* libPods-Clarifai.a */; }; 20 | FB714F801CFBE7A6007FD7E3 /* CAIFuture.m in Sources */ = {isa = PBXBuildFile; fileRef = FB714F7F1CFBE7A6007FD7E3 /* CAIFuture.m */; }; 21 | FB714F871CFBF15C007FD7E3 /* geth.jpg in Resources */ = {isa = PBXBuildFile; fileRef = FB714F861CFBF15C007FD7E3 /* geth.jpg */; }; 22 | FB714F891CFBF189007FD7E3 /* geth.jpg in Resources */ = {isa = PBXBuildFile; fileRef = FB714F861CFBF15C007FD7E3 /* geth.jpg */; }; 23 | /* End PBXBuildFile section */ 24 | 25 | /* Begin PBXContainerItemProxy section */ 26 | 408D396F1BACA1FA00C5608B /* PBXContainerItemProxy */ = { 27 | isa = PBXContainerItemProxy; 28 | containerPortal = 408D394D1BACA1FA00C5608B /* Project object */; 29 | proxyType = 1; 30 | remoteGlobalIDString = 408D39541BACA1FA00C5608B; 31 | remoteInfo = ClarifaiApiDemo; 32 | }; 33 | /* End PBXContainerItemProxy section */ 34 | 35 | /* Begin PBXFileReference section */ 36 | 2C6A8A3FC61725EBF52F0A75 /* Pods-ClarifaiTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ClarifaiTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-ClarifaiTests/Pods-ClarifaiTests.release.xcconfig"; sourceTree = ""; }; 37 | 4071951F1BADD02B0076B650 /* RecognitionViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RecognitionViewController.h; sourceTree = ""; }; 38 | 407195201BADD02B0076B650 /* RecognitionViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RecognitionViewController.m; sourceTree = ""; }; 39 | 408D39551BACA1FA00C5608B /* Clarifai.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Clarifai.app; sourceTree = BUILT_PRODUCTS_DIR; }; 40 | 408D39591BACA1FA00C5608B /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 41 | 408D395A1BACA1FA00C5608B /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 42 | 408D395C1BACA1FA00C5608B /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 43 | 408D395D1BACA1FA00C5608B /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 44 | 408D39631BACA1FA00C5608B /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 45 | 408D39651BACA1FA00C5608B /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; 46 | 408D39681BACA1FA00C5608B /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; }; 47 | 408D396E1BACA1FA00C5608B /* Clarifai.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = Clarifai.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 48 | 408D39731BACA1FA00C5608B /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 49 | 408D39741BACA1FA00C5608B /* ClarifaiTests.m */ = {isa = PBXFileReference; indentWidth = 2; lastKnownFileType = sourcecode.c.objc; path = ClarifaiTests.m; sourceTree = ""; tabWidth = 2; }; 50 | 5DFD46AB2E189C614DC9CE30 /* libPods-Clarifai.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Clarifai.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 51 | 8169D08DDEFC969649991F41 /* libPods-ClarifaiTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-ClarifaiTests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 52 | 83C54A18C2BB78C7FEB65157 /* libPods-Clarifai.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; name = "libPods-Clarifai.a"; path = "../Debug-iphonesimulator/libPods-Clarifai.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 53 | 9B331D8DA029B27C8BBE4A0D /* Pods-Clarifai.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Clarifai.release.xcconfig"; path = "Pods/Target Support Files/Pods-Clarifai/Pods-Clarifai.release.xcconfig"; sourceTree = ""; }; 54 | AFFCFF9EEF2817433F721FDC /* Pods-ClarifaiTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ClarifaiTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-ClarifaiTests/Pods-ClarifaiTests.debug.xcconfig"; sourceTree = ""; }; 55 | E7453607865A1F22EC77F669 /* Pods-Clarifai.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Clarifai.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Clarifai/Pods-Clarifai.debug.xcconfig"; sourceTree = ""; }; 56 | FB714F7E1CFBE7A6007FD7E3 /* CAIFuture.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CAIFuture.h; path = ../Clarifai/CAIFuture.h; sourceTree = ""; }; 57 | FB714F7F1CFBE7A6007FD7E3 /* CAIFuture.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = CAIFuture.m; path = ../Clarifai/CAIFuture.m; sourceTree = ""; }; 58 | FB714F861CFBF15C007FD7E3 /* geth.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = geth.jpg; sourceTree = ""; }; 59 | /* End PBXFileReference section */ 60 | 61 | /* Begin PBXFrameworksBuildPhase section */ 62 | 408D39521BACA1FA00C5608B /* Frameworks */ = { 63 | isa = PBXFrameworksBuildPhase; 64 | buildActionMask = 2147483647; 65 | files = ( 66 | 2964E55F49037F0979A34490 /* libPods-Clarifai.a in Frameworks */, 67 | EA9D8C96D6FCA899D401F124 /* libPods-Clarifai.a in Frameworks */, 68 | ); 69 | runOnlyForDeploymentPostprocessing = 0; 70 | }; 71 | 408D396B1BACA1FA00C5608B /* Frameworks */ = { 72 | isa = PBXFrameworksBuildPhase; 73 | buildActionMask = 2147483647; 74 | files = ( 75 | AE10DABE73E3DAE6CBE5C904 /* libPods-ClarifaiTests.a in Frameworks */, 76 | ); 77 | runOnlyForDeploymentPostprocessing = 0; 78 | }; 79 | /* End PBXFrameworksBuildPhase section */ 80 | 81 | /* Begin PBXGroup section */ 82 | 408D394C1BACA1FA00C5608B = { 83 | isa = PBXGroup; 84 | children = ( 85 | 408D39571BACA1FA00C5608B /* Clarifai */, 86 | 408D39711BACA1FA00C5608B /* ClarifaiTests */, 87 | 408D39561BACA1FA00C5608B /* Products */, 88 | F7E4E6FEBA5F8C372CA60249 /* Pods */, 89 | BE00073EC8C5F3E46FBC92C6 /* Frameworks */, 90 | ); 91 | sourceTree = ""; 92 | }; 93 | 408D39561BACA1FA00C5608B /* Products */ = { 94 | isa = PBXGroup; 95 | children = ( 96 | 408D39551BACA1FA00C5608B /* Clarifai.app */, 97 | 408D396E1BACA1FA00C5608B /* Clarifai.xctest */, 98 | ); 99 | name = Products; 100 | sourceTree = ""; 101 | }; 102 | 408D39571BACA1FA00C5608B /* Clarifai */ = { 103 | isa = PBXGroup; 104 | children = ( 105 | FB714F861CFBF15C007FD7E3 /* geth.jpg */, 106 | 408D395C1BACA1FA00C5608B /* AppDelegate.h */, 107 | 408D395D1BACA1FA00C5608B /* AppDelegate.m */, 108 | 4071951F1BADD02B0076B650 /* RecognitionViewController.h */, 109 | 407195201BADD02B0076B650 /* RecognitionViewController.m */, 110 | 408D39621BACA1FA00C5608B /* Main.storyboard */, 111 | 408D39651BACA1FA00C5608B /* Images.xcassets */, 112 | 408D39671BACA1FA00C5608B /* LaunchScreen.xib */, 113 | 408D39581BACA1FA00C5608B /* Supporting Files */, 114 | ); 115 | path = Clarifai; 116 | sourceTree = ""; 117 | }; 118 | 408D39581BACA1FA00C5608B /* Supporting Files */ = { 119 | isa = PBXGroup; 120 | children = ( 121 | 408D39591BACA1FA00C5608B /* Info.plist */, 122 | 408D395A1BACA1FA00C5608B /* main.m */, 123 | ); 124 | name = "Supporting Files"; 125 | sourceTree = ""; 126 | }; 127 | 408D39711BACA1FA00C5608B /* ClarifaiTests */ = { 128 | isa = PBXGroup; 129 | children = ( 130 | FB714F7E1CFBE7A6007FD7E3 /* CAIFuture.h */, 131 | FB714F7F1CFBE7A6007FD7E3 /* CAIFuture.m */, 132 | 408D39741BACA1FA00C5608B /* ClarifaiTests.m */, 133 | 408D39721BACA1FA00C5608B /* Supporting Files */, 134 | ); 135 | path = ClarifaiTests; 136 | sourceTree = ""; 137 | }; 138 | 408D39721BACA1FA00C5608B /* Supporting Files */ = { 139 | isa = PBXGroup; 140 | children = ( 141 | 408D39731BACA1FA00C5608B /* Info.plist */, 142 | ); 143 | name = "Supporting Files"; 144 | sourceTree = ""; 145 | }; 146 | BE00073EC8C5F3E46FBC92C6 /* Frameworks */ = { 147 | isa = PBXGroup; 148 | children = ( 149 | 83C54A18C2BB78C7FEB65157 /* libPods-Clarifai.a */, 150 | 8169D08DDEFC969649991F41 /* libPods-ClarifaiTests.a */, 151 | 5DFD46AB2E189C614DC9CE30 /* libPods-Clarifai.a */, 152 | ); 153 | name = Frameworks; 154 | sourceTree = ""; 155 | }; 156 | F7E4E6FEBA5F8C372CA60249 /* Pods */ = { 157 | isa = PBXGroup; 158 | children = ( 159 | E7453607865A1F22EC77F669 /* Pods-Clarifai.debug.xcconfig */, 160 | 9B331D8DA029B27C8BBE4A0D /* Pods-Clarifai.release.xcconfig */, 161 | AFFCFF9EEF2817433F721FDC /* Pods-ClarifaiTests.debug.xcconfig */, 162 | 2C6A8A3FC61725EBF52F0A75 /* Pods-ClarifaiTests.release.xcconfig */, 163 | ); 164 | name = Pods; 165 | sourceTree = ""; 166 | }; 167 | /* End PBXGroup section */ 168 | 169 | /* Begin PBXNativeTarget section */ 170 | 408D39541BACA1FA00C5608B /* Clarifai */ = { 171 | isa = PBXNativeTarget; 172 | buildConfigurationList = 408D39781BACA1FA00C5608B /* Build configuration list for PBXNativeTarget "Clarifai" */; 173 | buildPhases = ( 174 | F37F8380E127C51D572436F2 /* [CP] Check Pods Manifest.lock */, 175 | 408D39511BACA1FA00C5608B /* Sources */, 176 | 408D39521BACA1FA00C5608B /* Frameworks */, 177 | 408D39531BACA1FA00C5608B /* Resources */, 178 | 50C570BE8B7FFDAD0824A095 /* [CP] Embed Pods Frameworks */, 179 | 3AEE1655FD4C8D9C1BA964AB /* [CP] Copy Pods Resources */, 180 | ); 181 | buildRules = ( 182 | ); 183 | dependencies = ( 184 | ); 185 | name = Clarifai; 186 | productName = ClarifaiApiDemo; 187 | productReference = 408D39551BACA1FA00C5608B /* Clarifai.app */; 188 | productType = "com.apple.product-type.application"; 189 | }; 190 | 408D396D1BACA1FA00C5608B /* ClarifaiTests */ = { 191 | isa = PBXNativeTarget; 192 | buildConfigurationList = 408D397B1BACA1FA00C5608B /* Build configuration list for PBXNativeTarget "ClarifaiTests" */; 193 | buildPhases = ( 194 | 93FD3001696AF475F81A241C /* [CP] Check Pods Manifest.lock */, 195 | 408D396A1BACA1FA00C5608B /* Sources */, 196 | 408D396B1BACA1FA00C5608B /* Frameworks */, 197 | 408D396C1BACA1FA00C5608B /* Resources */, 198 | ADE3F3A3C95D091AE8708673 /* [CP] Embed Pods Frameworks */, 199 | 4581180B51720642DEFC250E /* [CP] Copy Pods Resources */, 200 | ); 201 | buildRules = ( 202 | ); 203 | dependencies = ( 204 | 408D39701BACA1FA00C5608B /* PBXTargetDependency */, 205 | ); 206 | name = ClarifaiTests; 207 | productName = ClarifaiApiDemoTests; 208 | productReference = 408D396E1BACA1FA00C5608B /* Clarifai.xctest */; 209 | productType = "com.apple.product-type.bundle.unit-test"; 210 | }; 211 | /* End PBXNativeTarget section */ 212 | 213 | /* Begin PBXProject section */ 214 | 408D394D1BACA1FA00C5608B /* Project object */ = { 215 | isa = PBXProject; 216 | attributes = { 217 | LastSwiftMigration = 0700; 218 | LastSwiftUpdateCheck = 0700; 219 | LastUpgradeCheck = 0700; 220 | ORGANIZATIONNAME = "Clarifai, Inc."; 221 | TargetAttributes = { 222 | 408D39541BACA1FA00C5608B = { 223 | CreatedOnToolsVersion = 6.4; 224 | DevelopmentTeam = 32E6VH74P3; 225 | LastSwiftMigration = 0800; 226 | }; 227 | 408D396D1BACA1FA00C5608B = { 228 | CreatedOnToolsVersion = 6.4; 229 | DevelopmentTeam = 32E6VH74P3; 230 | TestTargetID = 408D39541BACA1FA00C5608B; 231 | }; 232 | }; 233 | }; 234 | buildConfigurationList = 408D39501BACA1FA00C5608B /* Build configuration list for PBXProject "Clarifai" */; 235 | compatibilityVersion = "Xcode 3.2"; 236 | developmentRegion = English; 237 | hasScannedForEncodings = 0; 238 | knownRegions = ( 239 | en, 240 | Base, 241 | ); 242 | mainGroup = 408D394C1BACA1FA00C5608B; 243 | productRefGroup = 408D39561BACA1FA00C5608B /* Products */; 244 | projectDirPath = ""; 245 | projectRoot = ""; 246 | targets = ( 247 | 408D39541BACA1FA00C5608B /* Clarifai */, 248 | 408D396D1BACA1FA00C5608B /* ClarifaiTests */, 249 | ); 250 | }; 251 | /* End PBXProject section */ 252 | 253 | /* Begin PBXResourcesBuildPhase section */ 254 | 408D39531BACA1FA00C5608B /* Resources */ = { 255 | isa = PBXResourcesBuildPhase; 256 | buildActionMask = 2147483647; 257 | files = ( 258 | 408D39641BACA1FA00C5608B /* Main.storyboard in Resources */, 259 | 408D39691BACA1FA00C5608B /* LaunchScreen.xib in Resources */, 260 | 408D39661BACA1FA00C5608B /* Images.xcassets in Resources */, 261 | FB714F871CFBF15C007FD7E3 /* geth.jpg in Resources */, 262 | ); 263 | runOnlyForDeploymentPostprocessing = 0; 264 | }; 265 | 408D396C1BACA1FA00C5608B /* Resources */ = { 266 | isa = PBXResourcesBuildPhase; 267 | buildActionMask = 2147483647; 268 | files = ( 269 | FB714F891CFBF189007FD7E3 /* geth.jpg in Resources */, 270 | ); 271 | runOnlyForDeploymentPostprocessing = 0; 272 | }; 273 | /* End PBXResourcesBuildPhase section */ 274 | 275 | /* Begin PBXShellScriptBuildPhase section */ 276 | 3AEE1655FD4C8D9C1BA964AB /* [CP] Copy Pods Resources */ = { 277 | isa = PBXShellScriptBuildPhase; 278 | buildActionMask = 2147483647; 279 | files = ( 280 | ); 281 | inputPaths = ( 282 | ); 283 | name = "[CP] Copy Pods Resources"; 284 | outputPaths = ( 285 | ); 286 | runOnlyForDeploymentPostprocessing = 0; 287 | shellPath = /bin/sh; 288 | shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-Clarifai/Pods-Clarifai-resources.sh\"\n"; 289 | showEnvVarsInLog = 0; 290 | }; 291 | 4581180B51720642DEFC250E /* [CP] Copy Pods Resources */ = { 292 | isa = PBXShellScriptBuildPhase; 293 | buildActionMask = 2147483647; 294 | files = ( 295 | ); 296 | inputPaths = ( 297 | ); 298 | name = "[CP] Copy Pods Resources"; 299 | outputPaths = ( 300 | ); 301 | runOnlyForDeploymentPostprocessing = 0; 302 | shellPath = /bin/sh; 303 | shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-ClarifaiTests/Pods-ClarifaiTests-resources.sh\"\n"; 304 | showEnvVarsInLog = 0; 305 | }; 306 | 50C570BE8B7FFDAD0824A095 /* [CP] Embed Pods Frameworks */ = { 307 | isa = PBXShellScriptBuildPhase; 308 | buildActionMask = 2147483647; 309 | files = ( 310 | ); 311 | inputPaths = ( 312 | ); 313 | name = "[CP] Embed Pods Frameworks"; 314 | outputPaths = ( 315 | ); 316 | runOnlyForDeploymentPostprocessing = 0; 317 | shellPath = /bin/sh; 318 | shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-Clarifai/Pods-Clarifai-frameworks.sh\"\n"; 319 | showEnvVarsInLog = 0; 320 | }; 321 | 93FD3001696AF475F81A241C /* [CP] Check Pods Manifest.lock */ = { 322 | isa = PBXShellScriptBuildPhase; 323 | buildActionMask = 2147483647; 324 | files = ( 325 | ); 326 | inputPaths = ( 327 | ); 328 | name = "[CP] Check Pods Manifest.lock"; 329 | outputPaths = ( 330 | ); 331 | runOnlyForDeploymentPostprocessing = 0; 332 | shellPath = /bin/sh; 333 | 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"; 334 | showEnvVarsInLog = 0; 335 | }; 336 | ADE3F3A3C95D091AE8708673 /* [CP] Embed Pods Frameworks */ = { 337 | isa = PBXShellScriptBuildPhase; 338 | buildActionMask = 2147483647; 339 | files = ( 340 | ); 341 | inputPaths = ( 342 | ); 343 | name = "[CP] Embed Pods Frameworks"; 344 | outputPaths = ( 345 | ); 346 | runOnlyForDeploymentPostprocessing = 0; 347 | shellPath = /bin/sh; 348 | shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-ClarifaiTests/Pods-ClarifaiTests-frameworks.sh\"\n"; 349 | showEnvVarsInLog = 0; 350 | }; 351 | F37F8380E127C51D572436F2 /* [CP] Check Pods Manifest.lock */ = { 352 | isa = PBXShellScriptBuildPhase; 353 | buildActionMask = 2147483647; 354 | files = ( 355 | ); 356 | inputPaths = ( 357 | ); 358 | name = "[CP] Check Pods Manifest.lock"; 359 | outputPaths = ( 360 | ); 361 | runOnlyForDeploymentPostprocessing = 0; 362 | shellPath = /bin/sh; 363 | 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"; 364 | showEnvVarsInLog = 0; 365 | }; 366 | /* End PBXShellScriptBuildPhase section */ 367 | 368 | /* Begin PBXSourcesBuildPhase section */ 369 | 408D39511BACA1FA00C5608B /* Sources */ = { 370 | isa = PBXSourcesBuildPhase; 371 | buildActionMask = 2147483647; 372 | files = ( 373 | FB714F801CFBE7A6007FD7E3 /* CAIFuture.m in Sources */, 374 | 408D395E1BACA1FA00C5608B /* AppDelegate.m in Sources */, 375 | 408D395B1BACA1FA00C5608B /* main.m in Sources */, 376 | 407195211BADD02B0076B650 /* RecognitionViewController.m in Sources */, 377 | ); 378 | runOnlyForDeploymentPostprocessing = 0; 379 | }; 380 | 408D396A1BACA1FA00C5608B /* Sources */ = { 381 | isa = PBXSourcesBuildPhase; 382 | buildActionMask = 2147483647; 383 | files = ( 384 | 408D39751BACA1FA00C5608B /* ClarifaiTests.m in Sources */, 385 | ); 386 | runOnlyForDeploymentPostprocessing = 0; 387 | }; 388 | /* End PBXSourcesBuildPhase section */ 389 | 390 | /* Begin PBXTargetDependency section */ 391 | 408D39701BACA1FA00C5608B /* PBXTargetDependency */ = { 392 | isa = PBXTargetDependency; 393 | target = 408D39541BACA1FA00C5608B /* Clarifai */; 394 | targetProxy = 408D396F1BACA1FA00C5608B /* PBXContainerItemProxy */; 395 | }; 396 | /* End PBXTargetDependency section */ 397 | 398 | /* Begin PBXVariantGroup section */ 399 | 408D39621BACA1FA00C5608B /* Main.storyboard */ = { 400 | isa = PBXVariantGroup; 401 | children = ( 402 | 408D39631BACA1FA00C5608B /* Base */, 403 | ); 404 | name = Main.storyboard; 405 | sourceTree = ""; 406 | }; 407 | 408D39671BACA1FA00C5608B /* LaunchScreen.xib */ = { 408 | isa = PBXVariantGroup; 409 | children = ( 410 | 408D39681BACA1FA00C5608B /* Base */, 411 | ); 412 | name = LaunchScreen.xib; 413 | sourceTree = ""; 414 | }; 415 | /* End PBXVariantGroup section */ 416 | 417 | /* Begin XCBuildConfiguration section */ 418 | 408D39761BACA1FA00C5608B /* Debug */ = { 419 | isa = XCBuildConfiguration; 420 | buildSettings = { 421 | ALWAYS_SEARCH_USER_PATHS = NO; 422 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 423 | CLANG_CXX_LIBRARY = "libc++"; 424 | CLANG_ENABLE_MODULES = YES; 425 | CLANG_ENABLE_OBJC_ARC = YES; 426 | CLANG_USE_OPTIMIZATION_PROFILE = NO; 427 | CLANG_WARN_BOOL_CONVERSION = YES; 428 | CLANG_WARN_CONSTANT_CONVERSION = YES; 429 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 430 | CLANG_WARN_EMPTY_BODY = YES; 431 | CLANG_WARN_ENUM_CONVERSION = YES; 432 | CLANG_WARN_INT_CONVERSION = YES; 433 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 434 | CLANG_WARN_UNREACHABLE_CODE = YES; 435 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 436 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 437 | COPY_PHASE_STRIP = NO; 438 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 439 | ENABLE_STRICT_OBJC_MSGSEND = YES; 440 | ENABLE_TESTABILITY = YES; 441 | GCC_C_LANGUAGE_STANDARD = gnu99; 442 | GCC_DYNAMIC_NO_PIC = NO; 443 | GCC_NO_COMMON_BLOCKS = YES; 444 | GCC_OPTIMIZATION_LEVEL = 0; 445 | GCC_PREPROCESSOR_DEFINITIONS = ( 446 | "DEBUG=1", 447 | "$(inherited)", 448 | ); 449 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 450 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 451 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 452 | GCC_WARN_UNDECLARED_SELECTOR = YES; 453 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 454 | GCC_WARN_UNUSED_FUNCTION = YES; 455 | GCC_WARN_UNUSED_VARIABLE = YES; 456 | IPHONEOS_DEPLOYMENT_TARGET = 8.4; 457 | MTL_ENABLE_DEBUG_INFO = YES; 458 | ONLY_ACTIVE_ARCH = YES; 459 | SDKROOT = iphoneos; 460 | }; 461 | name = Debug; 462 | }; 463 | 408D39771BACA1FA00C5608B /* Release */ = { 464 | isa = XCBuildConfiguration; 465 | buildSettings = { 466 | ALWAYS_SEARCH_USER_PATHS = NO; 467 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 468 | CLANG_CXX_LIBRARY = "libc++"; 469 | CLANG_ENABLE_MODULES = YES; 470 | CLANG_ENABLE_OBJC_ARC = YES; 471 | CLANG_USE_OPTIMIZATION_PROFILE = NO; 472 | CLANG_WARN_BOOL_CONVERSION = YES; 473 | CLANG_WARN_CONSTANT_CONVERSION = YES; 474 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 475 | CLANG_WARN_EMPTY_BODY = YES; 476 | CLANG_WARN_ENUM_CONVERSION = YES; 477 | CLANG_WARN_INT_CONVERSION = YES; 478 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 479 | CLANG_WARN_UNREACHABLE_CODE = YES; 480 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 481 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 482 | COPY_PHASE_STRIP = NO; 483 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 484 | ENABLE_NS_ASSERTIONS = NO; 485 | ENABLE_STRICT_OBJC_MSGSEND = YES; 486 | GCC_C_LANGUAGE_STANDARD = gnu99; 487 | GCC_NO_COMMON_BLOCKS = YES; 488 | GCC_OPTIMIZATION_LEVEL = 0; 489 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 490 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 491 | GCC_WARN_UNDECLARED_SELECTOR = YES; 492 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 493 | GCC_WARN_UNUSED_FUNCTION = YES; 494 | GCC_WARN_UNUSED_VARIABLE = YES; 495 | IPHONEOS_DEPLOYMENT_TARGET = 8.4; 496 | MTL_ENABLE_DEBUG_INFO = NO; 497 | SDKROOT = iphoneos; 498 | VALIDATE_PRODUCT = YES; 499 | }; 500 | name = Release; 501 | }; 502 | 408D39791BACA1FA00C5608B /* Debug */ = { 503 | isa = XCBuildConfiguration; 504 | baseConfigurationReference = E7453607865A1F22EC77F669 /* Pods-Clarifai.debug.xcconfig */; 505 | buildSettings = { 506 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 507 | CLANG_ENABLE_MODULES = YES; 508 | DEVELOPMENT_TEAM = 32E6VH74P3; 509 | INFOPLIST_FILE = Clarifai/Info.plist; 510 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 511 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 512 | ONLY_ACTIVE_ARCH = YES; 513 | PRODUCT_BUNDLE_IDENTIFIER = "com.clarifai.$(PRODUCT_NAME:rfc1034identifier)"; 514 | PRODUCT_NAME = Clarifai; 515 | SWIFT_OBJC_BRIDGING_HEADER = ""; 516 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 517 | SWIFT_VERSION = 3.0; 518 | }; 519 | name = Debug; 520 | }; 521 | 408D397A1BACA1FA00C5608B /* Release */ = { 522 | isa = XCBuildConfiguration; 523 | baseConfigurationReference = 9B331D8DA029B27C8BBE4A0D /* Pods-Clarifai.release.xcconfig */; 524 | buildSettings = { 525 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 526 | CLANG_ENABLE_MODULES = YES; 527 | DEVELOPMENT_TEAM = 32E6VH74P3; 528 | INFOPLIST_FILE = Clarifai/Info.plist; 529 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 530 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 531 | ONLY_ACTIVE_ARCH = NO; 532 | PRODUCT_BUNDLE_IDENTIFIER = "com.clarifai.$(PRODUCT_NAME:rfc1034identifier)"; 533 | PRODUCT_NAME = Clarifai; 534 | SWIFT_OBJC_BRIDGING_HEADER = ""; 535 | SWIFT_VERSION = 3.0; 536 | }; 537 | name = Release; 538 | }; 539 | 408D397C1BACA1FA00C5608B /* Debug */ = { 540 | isa = XCBuildConfiguration; 541 | baseConfigurationReference = AFFCFF9EEF2817433F721FDC /* Pods-ClarifaiTests.debug.xcconfig */; 542 | buildSettings = { 543 | BUNDLE_LOADER = "$(TEST_HOST)"; 544 | DEVELOPMENT_TEAM = 32E6VH74P3; 545 | FRAMEWORK_SEARCH_PATHS = "$(inherited)"; 546 | GCC_PREPROCESSOR_DEFINITIONS = ( 547 | "DEBUG=1", 548 | "$(inherited)", 549 | ); 550 | INFOPLIST_FILE = ClarifaiTests/Info.plist; 551 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 552 | PRODUCT_BUNDLE_IDENTIFIER = "com.clarifai.$(PRODUCT_NAME:rfc1034identifier)"; 553 | PRODUCT_NAME = Clarifai; 554 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Clarifai.app/Clarifai"; 555 | }; 556 | name = Debug; 557 | }; 558 | 408D397D1BACA1FA00C5608B /* Release */ = { 559 | isa = XCBuildConfiguration; 560 | baseConfigurationReference = 2C6A8A3FC61725EBF52F0A75 /* Pods-ClarifaiTests.release.xcconfig */; 561 | buildSettings = { 562 | BUNDLE_LOADER = "$(TEST_HOST)"; 563 | DEVELOPMENT_TEAM = 32E6VH74P3; 564 | FRAMEWORK_SEARCH_PATHS = "$(inherited)"; 565 | INFOPLIST_FILE = ClarifaiTests/Info.plist; 566 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 567 | PRODUCT_BUNDLE_IDENTIFIER = "com.clarifai.$(PRODUCT_NAME:rfc1034identifier)"; 568 | PRODUCT_NAME = Clarifai; 569 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Clarifai.app/Clarifai"; 570 | }; 571 | name = Release; 572 | }; 573 | /* End XCBuildConfiguration section */ 574 | 575 | /* Begin XCConfigurationList section */ 576 | 408D39501BACA1FA00C5608B /* Build configuration list for PBXProject "Clarifai" */ = { 577 | isa = XCConfigurationList; 578 | buildConfigurations = ( 579 | 408D39761BACA1FA00C5608B /* Debug */, 580 | 408D39771BACA1FA00C5608B /* Release */, 581 | ); 582 | defaultConfigurationIsVisible = 0; 583 | defaultConfigurationName = Release; 584 | }; 585 | 408D39781BACA1FA00C5608B /* Build configuration list for PBXNativeTarget "Clarifai" */ = { 586 | isa = XCConfigurationList; 587 | buildConfigurations = ( 588 | 408D39791BACA1FA00C5608B /* Debug */, 589 | 408D397A1BACA1FA00C5608B /* Release */, 590 | ); 591 | defaultConfigurationIsVisible = 0; 592 | defaultConfigurationName = Release; 593 | }; 594 | 408D397B1BACA1FA00C5608B /* Build configuration list for PBXNativeTarget "ClarifaiTests" */ = { 595 | isa = XCConfigurationList; 596 | buildConfigurations = ( 597 | 408D397C1BACA1FA00C5608B /* Debug */, 598 | 408D397D1BACA1FA00C5608B /* Release */, 599 | ); 600 | defaultConfigurationIsVisible = 0; 601 | defaultConfigurationName = Release; 602 | }; 603 | /* End XCConfigurationList section */ 604 | }; 605 | rootObject = 408D394D1BACA1FA00C5608B /* Project object */; 606 | } 607 | --------------------------------------------------------------------------------