├── net.sixfivezero.BKCameraController.docset
└── Contents
│ ├── Resources
│ ├── docSet.mom
│ ├── docSet.toc
│ ├── docSet.dsidx
│ ├── docSet.skidx
│ ├── docSet.dsidx-shm
│ ├── docSet.dsidx-wal
│ ├── docSet.tokencache
│ ├── Tokens3.xml
│ ├── Tokens4.xml
│ ├── Documents
│ │ ├── img
│ │ │ ├── disclosure.png
│ │ │ ├── disclosure_open.png
│ │ │ ├── title_background.png
│ │ │ ├── library_background.png
│ │ │ └── button_bar_background.png
│ │ ├── css
│ │ │ ├── stylesPrint.css
│ │ │ └── styles.css
│ │ ├── index.html
│ │ ├── hierarchy.html
│ │ ├── Blocks
│ │ │ ├── asset_capture_completion_t.html
│ │ │ └── ciimage_capture_completion_t.html
│ │ ├── Protocols
│ │ │ └── BKCameraControllerDelegate.html
│ │ └── Classes
│ │ │ └── BKCameraController.html
│ ├── Tokens2.xml
│ ├── Nodes.xml
│ └── Tokens1.xml
│ └── Info.plist
├── BKCameraController.podspec
├── LICENSE
├── BKCameraController
├── BKCameraController+Simulator.h
├── BKCameraController+Simulator.m
├── BKCameraController.h
└── BKCameraController.m
├── .gitignore
├── README.md
└── BKCameraController.xcodeproj
└── project.pbxproj
/net.sixfivezero.BKCameraController.docset/Contents/Resources/docSet.mom:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/basket/BKCameraController/HEAD/net.sixfivezero.BKCameraController.docset/Contents/Resources/docSet.mom
--------------------------------------------------------------------------------
/net.sixfivezero.BKCameraController.docset/Contents/Resources/docSet.toc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/basket/BKCameraController/HEAD/net.sixfivezero.BKCameraController.docset/Contents/Resources/docSet.toc
--------------------------------------------------------------------------------
/net.sixfivezero.BKCameraController.docset/Contents/Resources/docSet.dsidx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/basket/BKCameraController/HEAD/net.sixfivezero.BKCameraController.docset/Contents/Resources/docSet.dsidx
--------------------------------------------------------------------------------
/net.sixfivezero.BKCameraController.docset/Contents/Resources/docSet.skidx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/basket/BKCameraController/HEAD/net.sixfivezero.BKCameraController.docset/Contents/Resources/docSet.skidx
--------------------------------------------------------------------------------
/net.sixfivezero.BKCameraController.docset/Contents/Resources/docSet.dsidx-shm:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/basket/BKCameraController/HEAD/net.sixfivezero.BKCameraController.docset/Contents/Resources/docSet.dsidx-shm
--------------------------------------------------------------------------------
/net.sixfivezero.BKCameraController.docset/Contents/Resources/docSet.dsidx-wal:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/basket/BKCameraController/HEAD/net.sixfivezero.BKCameraController.docset/Contents/Resources/docSet.dsidx-wal
--------------------------------------------------------------------------------
/net.sixfivezero.BKCameraController.docset/Contents/Resources/docSet.tokencache:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/basket/BKCameraController/HEAD/net.sixfivezero.BKCameraController.docset/Contents/Resources/docSet.tokencache
--------------------------------------------------------------------------------
/net.sixfivezero.BKCameraController.docset/Contents/Resources/Tokens3.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/net.sixfivezero.BKCameraController.docset/Contents/Resources/Tokens4.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/net.sixfivezero.BKCameraController.docset/Contents/Resources/Documents/img/disclosure.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/basket/BKCameraController/HEAD/net.sixfivezero.BKCameraController.docset/Contents/Resources/Documents/img/disclosure.png
--------------------------------------------------------------------------------
/net.sixfivezero.BKCameraController.docset/Contents/Resources/Documents/img/disclosure_open.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/basket/BKCameraController/HEAD/net.sixfivezero.BKCameraController.docset/Contents/Resources/Documents/img/disclosure_open.png
--------------------------------------------------------------------------------
/net.sixfivezero.BKCameraController.docset/Contents/Resources/Documents/img/title_background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/basket/BKCameraController/HEAD/net.sixfivezero.BKCameraController.docset/Contents/Resources/Documents/img/title_background.png
--------------------------------------------------------------------------------
/net.sixfivezero.BKCameraController.docset/Contents/Resources/Documents/img/library_background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/basket/BKCameraController/HEAD/net.sixfivezero.BKCameraController.docset/Contents/Resources/Documents/img/library_background.png
--------------------------------------------------------------------------------
/net.sixfivezero.BKCameraController.docset/Contents/Resources/Documents/img/button_bar_background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/basket/BKCameraController/HEAD/net.sixfivezero.BKCameraController.docset/Contents/Resources/Documents/img/button_bar_background.png
--------------------------------------------------------------------------------
/net.sixfivezero.BKCameraController.docset/Contents/Resources/Documents/css/stylesPrint.css:
--------------------------------------------------------------------------------
1 |
2 | header {
3 | display: none;
4 | }
5 |
6 | div.main-navigation, div.navigation-top {
7 | display: none;
8 | }
9 |
10 | div#overview_contents, div#contents.isShowingTOC, div#contents {
11 | overflow: visible;
12 | position: relative;
13 | top: 0px;
14 | border: none;
15 | left: 0;
16 | }
17 | #tocContainer.isShowingTOC {
18 | display: none;
19 | }
20 | nav {
21 | display: none;
22 | }
--------------------------------------------------------------------------------
/BKCameraController.podspec:
--------------------------------------------------------------------------------
1 | Pod::Spec.new do |s|
2 | s.name = "BKCameraController"
3 | s.version = "0.0.1"
4 | s.summary = "A class to simplify the process of capturing photos and make testing in the simulator less of a hassle for photo-based apps."
5 | s.homepage = "https://github.com/Basket/BKCameraController"
6 | s.license = 'MIT'
7 | s.author = { "Andrew Toulouse" => "andrew@atoulou.se" }
8 | s.source = { :git => "https://github.com/Basket/BKCameraController.git", :tag => s.version.to_s }
9 |
10 | s.platform = :ios, '7.0'
11 | s.requires_arc = true
12 |
13 | s.source_files = 'BKCameraController/*.{h,m}'
14 | s.frameworks = 'AssetsLibrary', 'AVFoundation', 'CoreMedia', 'ImageIO', 'UIKit'
15 | end
16 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2014 650 Industries, Inc.
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in
13 | all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | THE SOFTWARE.
22 |
--------------------------------------------------------------------------------
/BKCameraController/BKCameraController+Simulator.h:
--------------------------------------------------------------------------------
1 | // Copyright 2014-present 650 Industries. All rights reserved.
2 |
3 | #import "BKCameraController.h"
4 |
5 | @class CIColor;
6 | @class UIColor;
7 |
8 | @interface BKCameraController (Simulator)
9 |
10 | /**
11 | Getter for the fake image data used by the simulator.
12 |
13 | @return The fake image data used by the simulator.
14 | */
15 | + (NSData *)fakeImageData;
16 |
17 | /**
18 | Setter for the fake image data used by the simulator
19 |
20 | @param fakeImageData The fake image data to be used by the simulator.
21 | */
22 | + (void)setFakeImageData:(NSData *)fakeImageData;
23 |
24 | /**
25 | Getter for the fake image color used by the simulator.
26 |
27 | @return The fake image color used by the simulator.
28 | */
29 | + (CIColor *)fakeImageColor;
30 |
31 | /**
32 | Setter for the fake image color used by the simulator
33 |
34 | @param fakeImageColor The fake image color to be used by the simulator.
35 | */
36 | + (void)setFakeImageColor:(NSData *)fakeImageColor;
37 |
38 | /**
39 | Setter for fake image color from UIColor
40 |
41 | @param fakeImageColor UIColor
42 | */
43 | + (void)setFakeImageColorFromUIColor:(UIColor *)fakeImageColor;
44 |
45 |
46 | @end
47 |
--------------------------------------------------------------------------------
/net.sixfivezero.BKCameraController.docset/Contents/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleIdentifier
8 | net.sixfivezero.BKCameraController
9 | CFBundleName
10 | BKCameraController Documentation
11 | CFBundleShortVersionString
12 | 1.0
13 | CFBundleVersion
14 | 1.0
15 |
16 |
17 |
18 |
19 | DocSetFeedName
20 | BKCameraController Documentation
21 |
22 | DocSetMinimumXcodeVersion
23 | 3.0
24 | DocSetPlatformFamily
25 | iphoneos
26 | DashDocSetFamily
27 | appledoc
28 | DocSetPublisherIdentifier
29 | net.sixfivezero.documentation
30 | DocSetPublisherName
31 | 650 Industries, Inc.
32 | NSHumanReadableCopyright
33 | Copyright © 2014 650 Industries, Inc.. All rights reserved.
34 |
35 |
36 |
--------------------------------------------------------------------------------
/net.sixfivezero.BKCameraController.docset/Contents/Resources/Tokens2.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | //apple_ref/occ/intf/BKCameraControllerDelegate
7 | The delegate of a BKCameraController object must adopt the <BKCameraControllerDelegate> protocol.
8 | BKCameraController.h
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 | //apple_ref/occ/intfm/BKCameraControllerDelegate/cameraControllerWillCyclePosition:
17 | Tells the delegate that the camera controller will cycle the camera position.
18 | BKCameraController.h
19 |
20 | - (void)cameraControllerWillCyclePosition:(id)cameraController
21 |
22 |
23 | cameraController
24 | The camera controller object informing the delegate of this event.
25 |
26 |
27 |
28 | //api/name/cameraControllerWillCyclePosition:
29 |
30 |
31 |
32 |
33 | //apple_ref/occ/intfm/BKCameraControllerDelegate/cameraControllerDidCyclePosition:
34 | Tells the delegate that the camera controller cycled the camera position.
35 | BKCameraController.h
36 |
37 | - (void)cameraControllerDidCyclePosition:(id)cameraController
38 |
39 |
40 | cameraController
41 | The camera controller that cycled position.
42 |
43 |
44 |
45 | //api/name/cameraControllerDidCyclePosition:
46 |
47 |
48 |
49 |
50 |
51 |
52 |
--------------------------------------------------------------------------------
/net.sixfivezero.BKCameraController.docset/Contents/Resources/Documents/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | BKCameraController Reference
6 |
7 |
8 |
9 |
10 |
11 |
22 |
23 |
24 |
27 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
Class References
40 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
Protocol References
52 |
57 |
58 |
59 |
60 |
Block References
61 |
68 |
69 |
70 |
71 |
72 |
73 |
76 |
86 |
87 |
88 |
89 |
--------------------------------------------------------------------------------
/net.sixfivezero.BKCameraController.docset/Contents/Resources/Documents/hierarchy.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | BKCameraController Hierarchy
6 |
7 |
8 |
9 |
10 |
11 |
22 |
23 |
24 |
27 |
32 |
33 |
34 |
35 |
Class Hierarchy
36 |
37 |
38 |
39 | NSObject
40 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
Protocol References
56 |
61 |
62 |
63 |
64 |
Block References
65 |
72 |
73 |
74 |
75 |
76 |
77 |
80 |
90 |
91 |
92 |
93 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | #########################
2 | # .gitignore file for Xcode4 / OS X Source projects
3 | #
4 | # Version 2.0
5 | # For latest version, see: http://stackoverflow.com/questions/49478/git-ignore-file-for-xcode-projects
6 | #
7 | # 2013 updates:
8 | # - fixed the broken "save personal Schemes"
9 | #
10 | # NB: if you are storing "built" products, this WILL NOT WORK,
11 | # and you should use a different .gitignore (or none at all)
12 | # This file is for SOURCE projects, where there are many extra
13 | # files that we want to exclude
14 | #
15 | #########################
16 |
17 | #####
18 | # OS X temporary files that should never be committed
19 |
20 | .DS_Store
21 | *.swp
22 | *.lock
23 | profile
24 |
25 |
26 | ####
27 | # Xcode temporary files that should never be committed
28 | #
29 | # NB: NIB/XIB files still exist even on Storyboard projects, so we want this...
30 |
31 | *~.nib
32 |
33 |
34 | ####
35 | # Xcode build files -
36 | #
37 | # NB: slash on the end, so we only remove the FOLDER, not any files that were badly named "DerivedData"
38 |
39 | DerivedData/
40 |
41 | # NB: slash on the end, so we only remove the FOLDER, not any files that were badly named "build"
42 |
43 | build/
44 |
45 |
46 | #####
47 | # Xcode private settings (window sizes, bookmarks, breakpoints, custom executables, smart groups)
48 | #
49 | # This is complicated:
50 | #
51 | # SOMETIMES you need to put this file in version control.
52 | # Apple designed it poorly - if you use "custom executables", they are
53 | # saved in this file.
54 | # 99% of projects do NOT use those, so they do NOT want to version control this file.
55 | # ..but if you're in the 1%, comment out the line "*.pbxuser"
56 |
57 | *.pbxuser
58 | *.mode1v3
59 | *.mode2v3
60 | *.perspectivev3
61 | # NB: also, whitelist the default ones, some projects need to use these
62 | !default.pbxuser
63 | !default.mode1v3
64 | !default.mode2v3
65 | !default.perspectivev3
66 |
67 |
68 | ####
69 | # Xcode 4 - semi-personal settings
70 | #
71 | #
72 | # OPTION 1: ---------------------------------
73 | # throw away ALL personal settings (including custom schemes!
74 | # - unless they are "shared")
75 | #
76 | # NB: this is exclusive with OPTION 2 below
77 | xcuserdata
78 |
79 | # OPTION 2: ---------------------------------
80 | # get rid of ALL personal settings, but KEEP SOME OF THEM
81 | # - NB: you must manually uncomment the bits you want to keep
82 | #
83 | # NB: this is exclusive with OPTION 1 above
84 | #
85 | #xcuserdata/**/*
86 |
87 | # (requires option 2 above): Personal Schemes
88 | #
89 | #!xcuserdata/**/xcschemes/*
90 |
91 | ####
92 | # XCode 4 workspaces - more detailed
93 | #
94 | # Workspaces are important! They are a core feature of Xcode - don't exclude them :)
95 | #
96 | # Workspace layout is quite spammy. For reference:
97 | #
98 | # /(root)/
99 | # /(project-name).xcodeproj/
100 | # project.pbxproj
101 | # /project.xcworkspace/
102 | # contents.xcworkspacedata
103 | # /xcuserdata/
104 | # /(your name)/xcuserdatad/
105 | # UserInterfaceState.xcuserstate
106 | # /xcsshareddata/
107 | # /xcschemes/
108 | # (shared scheme name).xcscheme
109 | # /xcuserdata/
110 | # /(your name)/xcuserdatad/
111 | # (private scheme).xcscheme
112 | # xcschememanagement.plist
113 | #
114 | #
115 |
116 | ####
117 | # Xcode 4 - Deprecated classes
118 | #
119 | # Allegedly, if you manually "deprecate" your classes, they get moved here.
120 | #
121 | # We're using source-control, so this is a "feature" that we do not want!
122 |
123 | *.moved-aside
124 |
125 |
126 | ####
127 | # UNKNOWN: recommended by others, but I can't discover what these files are
128 | #
129 | # ...none. Everything is now explained.
--------------------------------------------------------------------------------
/BKCameraController/BKCameraController+Simulator.m:
--------------------------------------------------------------------------------
1 | // Copyright 2014-present 650 Industries. All rights reserved.
2 |
3 | #import "BKCameraController+Simulator.h"
4 |
5 | @import AssetsLibrary;
6 | @import CoreImage;
7 | @import ObjectiveC;
8 | @import UIKit;
9 |
10 | @interface BKCameraController ()
11 | @property (nonatomic, strong) dispatch_queue_t avQueue;
12 | @end
13 |
14 | void __swizzled_captureAssetWithCompletion(BKCameraController *self, SEL _cmd, asset_capture_completion_t completion) {
15 | dispatch_async(self.avQueue, ^{
16 | NSData *data = [BKCameraController fakeImageData];
17 | ALAssetsLibrary *assetsLibrary = [[ALAssetsLibrary alloc] init];
18 | [assetsLibrary writeImageDataToSavedPhotosAlbum:data metadata:nil completionBlock:^(NSURL *assetURL, NSError *error) {
19 | if (error) {
20 | dispatch_async(dispatch_get_main_queue(), ^{
21 | completion(nil, error);
22 | });
23 | } else {
24 | dispatch_async(dispatch_get_main_queue(), ^{
25 | completion(assetURL, nil);
26 | });
27 | }
28 | }];
29 | });
30 | }
31 |
32 | void __swizzled_captureSampleWithCompletion(BKCameraController *self, SEL _cmd, ciimage_capture_completion_t completion) {
33 | dispatch_async(((BKCameraController *)self).avQueue, ^{
34 | CIImage *image;
35 | if ([BKCameraController fakeImageData]) {
36 | image = [CIImage imageWithData:[BKCameraController fakeImageData]];
37 | } else {
38 | CIColor *fakeImageColor = [BKCameraController fakeImageColor];
39 | if (!fakeImageColor) {
40 | CGFloat hue = ( arc4random() % 256 / 256.0 ); // 0.0 to 1.0
41 | CGFloat saturation = ( arc4random() % 128 / 256.0 ) + 0.5; // 0.5 to 1.0, away from white
42 | CGFloat brightness = ( arc4random() % 128 / 256.0 ) + 0.5; // 0.5 to 1.0, away from black
43 | UIColor *color = [UIColor colorWithHue:hue saturation:saturation brightness:brightness alpha:1];
44 | fakeImageColor = [CIColor colorWithCGColor:color.CGColor];
45 | }
46 | image = [CIImage imageWithColor:fakeImageColor];
47 | }
48 |
49 | dispatch_async(dispatch_get_main_queue(), ^{
50 | completion(image, nil);
51 | });
52 | });
53 | }
54 |
55 | @implementation BKCameraController (Simulator)
56 |
57 | static IMP __original_captureAssetWithCompletion;
58 | static IMP __original_captureSampleWithCompletion;
59 | + (void)load
60 | {
61 | if ([[[UIDevice currentDevice].model lowercaseString] rangeOfString:@"simulator"].location != NSNotFound){
62 | Method assetMethod = class_getInstanceMethod([self class], @selector(captureAssetWithCompletion:));
63 | IMP assetImp = (IMP)__swizzled_captureAssetWithCompletion;
64 | __original_captureAssetWithCompletion = method_setImplementation(assetMethod, assetImp);
65 |
66 | Method sampleMethod = class_getInstanceMethod([self class], @selector(captureSampleWithCompletion:));
67 | IMP sampleImp = (IMP)__swizzled_captureSampleWithCompletion;
68 | __original_captureSampleWithCompletion = method_setImplementation(sampleMethod, sampleImp);
69 | }
70 | }
71 |
72 | static NSData *_fakeImageData;
73 |
74 | + (NSData *)fakeImageData
75 | {
76 | return _fakeImageData;
77 | }
78 |
79 | + (void)setFakeImageData:(NSData *)fakeImageData;
80 | {
81 | _fakeImageData = fakeImageData;
82 | }
83 |
84 | static CIColor *_fakeImageColor;
85 |
86 | + (CIColor *)fakeImageColor
87 | {
88 | return _fakeImageColor;
89 | }
90 |
91 | + (void)setFakeImageColor:(CIColor *)fakeImageColor
92 | {
93 | _fakeImageColor = fakeImageColor;
94 | }
95 |
96 | + (void)setFakeImageColorFromUIColor:(UIColor *)fakeImageColor
97 | {
98 | _fakeImageColor = [CIColor colorWithCGColor:fakeImageColor.CGColor];
99 | }
100 |
101 | @end
102 |
--------------------------------------------------------------------------------
/net.sixfivezero.BKCameraController.docset/Contents/Resources/Nodes.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | BKCameraController
6 | index.html
7 |
8 |
9 |
10 |
11 | Classes
12 | index.html
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 | Protocols
23 | index.html
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 | Blocks
34 | index.html
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 | BKCameraController
49 | Classes/BKCameraController.html
50 |
51 |
52 |
53 | Classes/BKCameraController.html
54 | Overview
55 | overview
56 |
57 |
58 | Classes/BKCameraController.html
59 | Tasks
60 | tasks
61 |
62 |
63 |
64 | Classes/BKCameraController.html
65 | Properties
66 | properties
67 |
68 |
69 |
70 |
71 | Classes/BKCameraController.html
72 | Class Methods
73 | class_methods
74 |
75 |
76 |
77 |
78 | Classes/BKCameraController.html
79 | Instance Methods
80 | instance_methods
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 | BKCameraControllerDelegate
90 | Protocols/BKCameraControllerDelegate.html
91 |
92 |
93 |
94 | Protocols/BKCameraControllerDelegate.html
95 | Overview
96 | overview
97 |
98 |
99 | Protocols/BKCameraControllerDelegate.html
100 | Tasks
101 | tasks
102 |
103 |
104 |
105 |
106 |
107 | Protocols/BKCameraControllerDelegate.html
108 | Instance Methods
109 | instance_methods
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 | asset_capture_completion_t
119 | Blocks/asset_capture_completion_t.html
120 |
121 |
122 |
123 | ciimage_capture_completion_t
124 | Blocks/ciimage_capture_completion_t.html
125 |
126 |
127 |
128 |
129 |
--------------------------------------------------------------------------------
/BKCameraController/BKCameraController.h:
--------------------------------------------------------------------------------
1 | // Copyright 2014-present 650 Industries. All rights reserved.
2 |
3 | @import AVFoundation.AVCaptureDevice;
4 | @import AVFoundation.AVCaptureSession;
5 |
6 | @class CIImage;
7 | @protocol BKCameraControllerDelegate;
8 |
9 | /** Completion callback invoked upon capture. */
10 | typedef void (^ciimage_capture_completion_t)(CIImage *image, NSError *error);
11 |
12 | /** Completion callback invoked upon asset capture. */
13 | typedef void (^asset_capture_completion_t)(NSURL *assetURL, NSError *error);
14 |
15 | /**
16 | A wrapper for AVCaptureSession to simplify the process of capturing photos.
17 | */
18 | @interface BKCameraController : NSObject
19 |
20 | /**
21 | The receiver’s delegate or nil if it doesn’t have a delegate.
22 |
23 | @discussion For a list of methods your delegate object can implement, see [BKCameraControllerDelegate Protocol Reference](BKCameraControllerDelegate)
24 | */
25 | @property (nonatomic, weak) id delegate;
26 |
27 | /** The controller-owned `AVCaptureSession` instance. */
28 | @property (nonatomic, strong, readonly) AVCaptureSession *session;
29 | /** The current camera position. */
30 | @property (nonatomic, assign, readonly) AVCaptureDevicePosition position;
31 | /** The current camera flash mode. */
32 | @property (nonatomic, assign, readonly) AVCaptureFlashMode flashMode;
33 | /** Whether the current camera has the capability to flash. */
34 | @property (nonatomic, assign, readonly) BOOL flashCapable;
35 |
36 | /** @name Initializing a BKCameraController object */
37 |
38 | /**
39 | Initializes the camera controller using the specified starting parameters.
40 |
41 | @param position The position used to select the initial capture device used by the camera controller. Defaults to `AVCaptureDevicePositionBack`.
42 | @param enabled YES if the camera controller should include `AVCaptureFlashModeAuto` when cycling the flash mode. Defaults to `NO`.
43 | @return An initialized `BKCameraController` instance.
44 | */
45 | - (instancetype)initWithInitialPosition:(AVCaptureDevicePosition)position
46 | autoFlashEnabled:(BOOL)enabled __attribute__((objc_designated_initializer));
47 |
48 | /** @name Starting/Stopping Capture Session State */
49 |
50 | /**
51 | Tells the receiver to start the capture session.
52 |
53 | @discussion This method is used to start the receiver's capture session. This method is asynchronous and runs on a serial background queue owned by the receiver.
54 | */
55 | - (void)startCaptureSession;
56 |
57 | /**
58 | Tells the receiver to stop the capture session.
59 |
60 | @discussion This method is used to stop the receiver's capture session. This method is asynchronous and runs on a serial background queue owned by the receiver.
61 | */
62 | - (void)stopCaptureSession;
63 |
64 | /** @name Adjusting Camera Settings */
65 |
66 | /**
67 | Sets the focus and exposure point to the specified point, if supported.
68 |
69 | @param point The point to set the exposure and focus.
70 | */
71 | - (void)autoAdjustCameraToPoint:(CGPoint)point;
72 |
73 | /**
74 | Cycles through supported flash modes. Skips `AVCaptureFlashModeAuto` if the receiver was initialized with `autoFlashEnabled` set to `NO`.
75 | */
76 | - (void)cycleFlashMode;
77 |
78 | /**
79 | Cycles through supported flash modes. If no flash mode at all is supported (such as on the front-facing camera), is set to `NO`, otherwise `YES`.
80 | */
81 | - (void)cyclePosition;
82 |
83 | /** @name Capturing Photos */
84 |
85 | /**
86 | Capture a photo and save it, along with its EXIF metadata, to the camera roll.
87 |
88 | @param completion A completion block supplying either a valid Asset or a . Executed on the main thread.
89 |
90 | - *assetURL* The Asset URL to the captured media. nil if an error occurred.
91 | - *error* The error, if a problem occurred during capture.
92 | */
93 | - (void)captureAssetWithCompletion:(asset_capture_completion_t)completion;
94 |
95 | /**
96 | Capture a photo.
97 |
98 | @param completion A completion block supplying either a or a . Executed on the main thread.
99 |
100 | - *image* A CIImage wrapping the sample buffer's pixel buffer, captured by the camera. nil if an error occurred.
101 | - *error* The error, if a problem occurred during capture.
102 | */
103 | - (void)captureSampleWithCompletion:(ciimage_capture_completion_t)completion;
104 | @end
105 |
106 | /**
107 | The delegate of a object must adopt the protocol.
108 | */
109 | @protocol BKCameraControllerDelegate
110 |
111 | @optional
112 |
113 | /**
114 | Tells the delegate that the camera controller will cycle the camera position.
115 |
116 | @param cameraController The camera controller object informing the delegate of this event.
117 | */
118 | - (void)cameraControllerWillCyclePosition:(BKCameraController *)cameraController;
119 |
120 | /**
121 | Tells the delegate that the camera controller cycled the camera position.
122 |
123 | @param cameraController The camera controller that cycled position.
124 | */
125 | - (void)cameraControllerDidCyclePosition:(BKCameraController *)cameraController;
126 |
127 | @end
128 |
129 | #if TARGET_IPHONE_SIMULATOR
130 | #import "BKCameraController+Simulator.h"
131 | #endif
132 |
--------------------------------------------------------------------------------
/net.sixfivezero.BKCameraController.docset/Contents/Resources/Documents/Blocks/asset_capture_completion_t.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | asset_capture_completion_t Block Reference
6 |
7 |
8 |
9 |
10 |
11 |
12 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
55 |
60 |
61 |
62 |
63 |
64 | Declared in
65 | BKCameraController.h
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
Block Definition
81 |
asset_capture_completion_t
82 |
83 |
84 |
85 |
Completion callback invoked upon asset capture.
86 |
87 |
88 |
89 |
90 |
typedef void (^asset_capture_completion_t) (NSURL *assetURL, NSError *error)
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
Declared In
104 | BKCameraController.h
105 |
106 |
107 |
108 |
109 |
110 |
111 |
117 |
126 |
127 |
128 |
219 |
220 |
--------------------------------------------------------------------------------
/net.sixfivezero.BKCameraController.docset/Contents/Resources/Documents/Blocks/ciimage_capture_completion_t.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | ciimage_capture_completion_t Block Reference
6 |
7 |
8 |
9 |
10 |
11 |
12 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
55 |
60 |
61 |
62 |
63 |
64 | Declared in
65 | BKCameraController.h
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
Block Definition
81 |
ciimage_capture_completion_t
82 |
83 |
84 |
85 |
Completion callback invoked upon capture.
86 |
87 |
88 |
89 |
90 |
typedef void (^ciimage_capture_completion_t) (CIImage *image, NSError *error)
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
Declared In
104 | BKCameraController.h
105 |
106 |
107 |
108 |
109 |
110 |
111 |
117 |
126 |
127 |
128 |
219 |
220 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # BKCameraController
2 |
3 | A class to simplify the process of capturing photos and make testing in the simulator less of a hassle for photo-based apps.
4 |
5 | ## Installation
6 |
7 | 1. Add BKCameraController to your Podfile.
8 | 2. In your terminal, run `pod install`.
9 |
10 | ## Usage
11 |
12 |
13 | 1. Add `#import ` to your source file.
14 | 2. Initialize the camera controller: `_cameraController = [[BKCameraController alloc] initWithInitialPosition:AVCaptureDevicePositionBack autoFlashEnabled:YES];` (The default camera position is the front, and auto-flash is disabled by default)
15 | 3. Call `- (void)startCaptureSession` to start capturing and `- (void)stopCaptureSession` to stop capturing. One good place to do this is in `- (void)viewWillAppear:` and `- (void)viewDidDisppear:`, so the camera doesn't overheat from being left on.
16 | 4. Use the `session` property as necessary, i.e. for camera preview layers, and the other methods for camera position cycling, flash mode cycling, focus adjustment, and photo capture callbacks.
17 | 5. Add the following to set the camera controller's image response for testing in the simulator, revising the path as necessary:
18 | ```objc
19 | #if TARGET_IPHONE_SIMULATOR
20 | [BKCameraController setFakeImageData:[NSData dataWithContentsOfURL:[NSURL URLWithString:@"file:///path-to/image.jpeg"]]];
21 | #endif
22 | ```
23 |
24 | ## FAQ
25 |
26 | **Q:** Why is this necessary?
27 | **A:** **You can use it in the simulator!** Testing in the simulator is insanely annoying when some functions simply aren't available. However, it's not always reasonable to expect the simulator to virtualize the response of low-level frameworks.
28 |
29 | AVFoundation is a complex and very useful API, but every application that wants to customize its photo-taking experience needs to opt into this API, even when their needs are fairly straightforward. Because of this complexity, it's not hard to achieve an end result that works, but is subpar. For example, AVFoundation works best when it runs on a background queue, so that its blocking operations don't affect the main thread -- but not everyone does this.
30 |
31 | This is an ideal problem to solve with an abstraction layer to serve those typical needs. In creating a standard component to interface with AVFoundation for the camera, we can also take on a little extra complexity and use a background queue properly on behalf of the consumers of BKCameraController's API.
32 |
33 | *tl;dr:* __BKCameraController is usable in the simulator, and doesn't block the main (UI) thread.__
34 |
35 | **Q:** My photos are rotated weirdly! What gives?
36 | **A:** Well, the camera doesn't necessarily return the photo rotated with the direction "up" necessarily what you'd expect. It's not currently clear what the best approach to this is -- i.e. internally correct, offer a method in the public API to perform the transformation, or leave it to the developer -- but this snippet of code may prove useful for common use:
37 |
38 | ```objc
39 | [_cameraController captureSampleWithCompletion:^(CIImage *image, NSError *error) {
40 | dispatch_async(dispatch_get_main_queue(), ^{
41 | UIImage *photo;
42 |
43 | if (error) {
44 | NSLog(@"WARNING: Couldn't capture photo: %@", error);
45 | photo = nil;
46 | } else {
47 | CGFloat screenScale = [UIScreen mainScreen].scale;
48 | CGSize photoSizeInPixels = CGSizeMake(CGRectGetWidth(self.bounds), CGRectGetHeight(self.bounds));
49 |
50 | // Compute the scale from the source image to the output image, both measured in pixels
51 | size_t outputWidth = ceil(photoSizeInPixels.width);
52 | size_t outputHeight = ceil(photoSizeInPixels.height);
53 |
54 | // Swap the width and height since the source image is rotated
55 | size_t inputWidth = CGRectGetHeight(image.extent);
56 | size_t inputHeight = CGRectGetWidth(image.extent);
57 |
58 | CGFloat scale = fmax((CGFloat)outputWidth / inputWidth, (CGFloat)outputHeight / inputHeight);
59 |
60 | // Normalize the orientation
61 | CGAffineTransform transform;
62 | if (_videoPreview.connection.isVideoMirrored) {
63 | transform = CGAffineTransformMakeRotation(M_PI_2);
64 |
65 | transform = CGAffineTransformTranslate(transform, inputWidth, 0);
66 | transform = CGAffineTransformScale(transform, -1, 1);
67 | } else {
68 | transform = CGAffineTransformMakeRotation(3 * M_PI_2);
69 | }
70 |
71 | // Scale the image
72 | transform = CGAffineTransformScale(transform, scale, scale);
73 | CIImage *transformedImage = [image imageByApplyingTransform:transform];
74 |
75 | // Crop the scaled image
76 | CGRect cropRect = CGRectCenterInRect(CGRectFromSize(photoSizeInPixels), [transformedImage extent]);
77 | CIImage *correctedImage = [transformedImage imageByCroppingToRect:cropRect];
78 | photo = [UIImage imageWithCIImage:correctedImage scale:screenScale orientation:UIImageOrientationUp];
79 | }
80 |
81 | // Do something with UIImage *photo here
82 | });
83 | }];
84 | ```
85 |
86 | Note that this code requires access to the `AVCaptureConnection` to determine whether or not to mirror the image.
87 |
88 | **Q:** Why does direct capturing use `CIImage`? Why not `CMSampleBuffer` or `CVPixelBuffer`? Why not `CGImage`?
89 | **A:** The original interface *did* use `CMSampleBuffer`, but that's before simulator support was added. One of the goals is to be able to very cheaply transform the photo once taken, with as little loss of information as possible. Rendering to a `CGImage` only to have to re-import *that* into a `CIImage` is a wasted transformation.
90 |
91 | While it seems theoretically possible to render a `CGImage` into a `CVPixelBuffer`, and in turn to a `CMSampleBuffer`, and to preserve the metadata dictionary -- and indeed this was the initial approach to adding simulator support -- `+[CIImage imageWithCVPixelBuffer:]` is either picky about its input format, or is simply non-functional in the iOS Simulator, and during development, only ever seemed to return `nil`. Additionally, there were many parameters to specify for the conversion to `CVPixelBuffer` and `CMSampleBuffer` which made assumptions about the image type (JPEG/PNG), color space, and color format -- assumptions that might not have held true for all example images.
92 |
93 | Relegating `CMSampleBuffer` and `CVPixelBuffer` to implementation details of the `CIImage` presented to the user on devices allowed the simulator to take a much simpler path and simply use the more forgiving `+[CIImage imageWithData:` initializer.
94 |
95 | *tl;dr:* __BKCameraController is fast and simple.__
96 |
97 | **Q:** Support for video? Still Image brackets?
98 | **A:** Definitely possible, but also not something being actively worked on. Pull requests are very much welcome!
99 |
100 | **Q:** This sucks!
101 | **Q:** It doesn't do X!
102 | **Q:** The way you structured your API sucks!
103 | **A:** This was built to make taking photos smooth. If you have a specific need, I'd be happy to incorporate that input into future revisions. If you have any suggestions or bug reports, please feel free to file an issue on GitHub. And if there's any concrete way to improve the API, I'd love to hear your input!
104 |
105 | ## Documentation
106 |
107 | BKCameraController is fully documented. Check out the included docset!
108 |
--------------------------------------------------------------------------------
/BKCameraController.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 6B4F31B8198B10C7009B4667 /* BKCameraController+Simulator.m in Sources */ = {isa = PBXBuildFile; fileRef = 6B4F31B7198B10C7009B4667 /* BKCameraController+Simulator.m */; };
11 | 6BEE0A8F1987255200D73B41 /* BKCameraController.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 6BEE0A8E1987255200D73B41 /* BKCameraController.h */; };
12 | 6BEE0A911987255200D73B41 /* BKCameraController.m in Sources */ = {isa = PBXBuildFile; fileRef = 6BEE0A901987255200D73B41 /* BKCameraController.m */; };
13 | /* End PBXBuildFile section */
14 |
15 | /* Begin PBXCopyFilesBuildPhase section */
16 | 6BEE0A891987255200D73B41 /* CopyFiles */ = {
17 | isa = PBXCopyFilesBuildPhase;
18 | buildActionMask = 2147483647;
19 | dstPath = "include/$(PRODUCT_NAME)";
20 | dstSubfolderSpec = 16;
21 | files = (
22 | 6BEE0A8F1987255200D73B41 /* BKCameraController.h in CopyFiles */,
23 | );
24 | runOnlyForDeploymentPostprocessing = 0;
25 | };
26 | /* End PBXCopyFilesBuildPhase section */
27 |
28 | /* Begin PBXFileReference section */
29 | 6B4F31B6198B10C7009B4667 /* BKCameraController+Simulator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "BKCameraController+Simulator.h"; sourceTree = ""; };
30 | 6B4F31B7198B10C7009B4667 /* BKCameraController+Simulator.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "BKCameraController+Simulator.m"; sourceTree = ""; };
31 | 6BEE0A8B1987255200D73B41 /* libBKCameraController.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libBKCameraController.a; sourceTree = BUILT_PRODUCTS_DIR; };
32 | 6BEE0A8E1987255200D73B41 /* BKCameraController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = BKCameraController.h; sourceTree = ""; };
33 | 6BEE0A901987255200D73B41 /* BKCameraController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = BKCameraController.m; sourceTree = ""; };
34 | /* End PBXFileReference section */
35 |
36 | /* Begin PBXFrameworksBuildPhase section */
37 | 6BEE0A881987255200D73B41 /* Frameworks */ = {
38 | isa = PBXFrameworksBuildPhase;
39 | buildActionMask = 2147483647;
40 | files = (
41 | );
42 | runOnlyForDeploymentPostprocessing = 0;
43 | };
44 | /* End PBXFrameworksBuildPhase section */
45 |
46 | /* Begin PBXGroup section */
47 | 6BEE0A821987255200D73B41 = {
48 | isa = PBXGroup;
49 | children = (
50 | 6BEE0A8D1987255200D73B41 /* BKCameraController */,
51 | 6BEE0A8C1987255200D73B41 /* Products */,
52 | );
53 | sourceTree = "";
54 | };
55 | 6BEE0A8C1987255200D73B41 /* Products */ = {
56 | isa = PBXGroup;
57 | children = (
58 | 6BEE0A8B1987255200D73B41 /* libBKCameraController.a */,
59 | );
60 | name = Products;
61 | sourceTree = "";
62 | };
63 | 6BEE0A8D1987255200D73B41 /* BKCameraController */ = {
64 | isa = PBXGroup;
65 | children = (
66 | 6B4F31B6198B10C7009B4667 /* BKCameraController+Simulator.h */,
67 | 6B4F31B7198B10C7009B4667 /* BKCameraController+Simulator.m */,
68 | 6BEE0A8E1987255200D73B41 /* BKCameraController.h */,
69 | 6BEE0A901987255200D73B41 /* BKCameraController.m */,
70 | );
71 | path = BKCameraController;
72 | sourceTree = "";
73 | };
74 | /* End PBXGroup section */
75 |
76 | /* Begin PBXNativeTarget section */
77 | 6BEE0A8A1987255200D73B41 /* BKCameraController */ = {
78 | isa = PBXNativeTarget;
79 | buildConfigurationList = 6BEE0A9F1987255200D73B41 /* Build configuration list for PBXNativeTarget "BKCameraController" */;
80 | buildPhases = (
81 | 6BEE0A871987255200D73B41 /* Sources */,
82 | 6BEE0A881987255200D73B41 /* Frameworks */,
83 | 6BEE0A891987255200D73B41 /* CopyFiles */,
84 | );
85 | buildRules = (
86 | );
87 | dependencies = (
88 | );
89 | name = BKCameraController;
90 | productName = BKCameraController;
91 | productReference = 6BEE0A8B1987255200D73B41 /* libBKCameraController.a */;
92 | productType = "com.apple.product-type.library.static";
93 | };
94 | /* End PBXNativeTarget section */
95 |
96 | /* Begin PBXProject section */
97 | 6BEE0A831987255200D73B41 /* Project object */ = {
98 | isa = PBXProject;
99 | attributes = {
100 | LastUpgradeCheck = 0600;
101 | ORGANIZATIONNAME = "650 Industries, Inc.";
102 | TargetAttributes = {
103 | 6BEE0A8A1987255200D73B41 = {
104 | CreatedOnToolsVersion = 6.0;
105 | };
106 | };
107 | };
108 | buildConfigurationList = 6BEE0A861987255200D73B41 /* Build configuration list for PBXProject "BKCameraController" */;
109 | compatibilityVersion = "Xcode 3.2";
110 | developmentRegion = English;
111 | hasScannedForEncodings = 0;
112 | knownRegions = (
113 | en,
114 | );
115 | mainGroup = 6BEE0A821987255200D73B41;
116 | productRefGroup = 6BEE0A8C1987255200D73B41 /* Products */;
117 | projectDirPath = "";
118 | projectRoot = "";
119 | targets = (
120 | 6BEE0A8A1987255200D73B41 /* BKCameraController */,
121 | );
122 | };
123 | /* End PBXProject section */
124 |
125 | /* Begin PBXSourcesBuildPhase section */
126 | 6BEE0A871987255200D73B41 /* Sources */ = {
127 | isa = PBXSourcesBuildPhase;
128 | buildActionMask = 2147483647;
129 | files = (
130 | 6B4F31B8198B10C7009B4667 /* BKCameraController+Simulator.m in Sources */,
131 | 6BEE0A911987255200D73B41 /* BKCameraController.m in Sources */,
132 | );
133 | runOnlyForDeploymentPostprocessing = 0;
134 | };
135 | /* End PBXSourcesBuildPhase section */
136 |
137 | /* Begin XCBuildConfiguration section */
138 | 6BEE0A9D1987255200D73B41 /* Debug */ = {
139 | isa = XCBuildConfiguration;
140 | buildSettings = {
141 | ALWAYS_SEARCH_USER_PATHS = NO;
142 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
143 | CLANG_CXX_LIBRARY = "libc++";
144 | CLANG_ENABLE_MODULES = YES;
145 | CLANG_ENABLE_OBJC_ARC = YES;
146 | CLANG_WARN_BOOL_CONVERSION = YES;
147 | CLANG_WARN_CONSTANT_CONVERSION = YES;
148 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
149 | CLANG_WARN_EMPTY_BODY = YES;
150 | CLANG_WARN_ENUM_CONVERSION = YES;
151 | CLANG_WARN_INT_CONVERSION = YES;
152 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
153 | CLANG_WARN_UNREACHABLE_CODE = YES;
154 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
155 | COPY_PHASE_STRIP = NO;
156 | ENABLE_STRICT_OBJC_MSGSEND = YES;
157 | GCC_C_LANGUAGE_STANDARD = gnu99;
158 | GCC_DYNAMIC_NO_PIC = NO;
159 | GCC_OPTIMIZATION_LEVEL = 0;
160 | GCC_PREPROCESSOR_DEFINITIONS = (
161 | "DEBUG=1",
162 | "$(inherited)",
163 | );
164 | GCC_SYMBOLS_PRIVATE_EXTERN = NO;
165 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
166 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
167 | GCC_WARN_UNDECLARED_SELECTOR = YES;
168 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
169 | GCC_WARN_UNUSED_FUNCTION = YES;
170 | GCC_WARN_UNUSED_VARIABLE = YES;
171 | IPHONEOS_DEPLOYMENT_TARGET = 7.0;
172 | MTL_ENABLE_DEBUG_INFO = YES;
173 | ONLY_ACTIVE_ARCH = YES;
174 | SDKROOT = iphoneos;
175 | };
176 | name = Debug;
177 | };
178 | 6BEE0A9E1987255200D73B41 /* Release */ = {
179 | isa = XCBuildConfiguration;
180 | buildSettings = {
181 | ALWAYS_SEARCH_USER_PATHS = NO;
182 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
183 | CLANG_CXX_LIBRARY = "libc++";
184 | CLANG_ENABLE_MODULES = YES;
185 | CLANG_ENABLE_OBJC_ARC = YES;
186 | CLANG_WARN_BOOL_CONVERSION = YES;
187 | CLANG_WARN_CONSTANT_CONVERSION = YES;
188 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
189 | CLANG_WARN_EMPTY_BODY = YES;
190 | CLANG_WARN_ENUM_CONVERSION = YES;
191 | CLANG_WARN_INT_CONVERSION = YES;
192 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
193 | CLANG_WARN_UNREACHABLE_CODE = YES;
194 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
195 | COPY_PHASE_STRIP = YES;
196 | ENABLE_NS_ASSERTIONS = NO;
197 | ENABLE_STRICT_OBJC_MSGSEND = YES;
198 | GCC_C_LANGUAGE_STANDARD = gnu99;
199 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
200 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
201 | GCC_WARN_UNDECLARED_SELECTOR = YES;
202 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
203 | GCC_WARN_UNUSED_FUNCTION = YES;
204 | GCC_WARN_UNUSED_VARIABLE = YES;
205 | IPHONEOS_DEPLOYMENT_TARGET = 7.0;
206 | MTL_ENABLE_DEBUG_INFO = NO;
207 | SDKROOT = iphoneos;
208 | VALIDATE_PRODUCT = YES;
209 | };
210 | name = Release;
211 | };
212 | 6BEE0AA01987255200D73B41 /* Debug */ = {
213 | isa = XCBuildConfiguration;
214 | buildSettings = {
215 | OTHER_LDFLAGS = "-ObjC";
216 | PRODUCT_NAME = "$(TARGET_NAME)";
217 | SKIP_INSTALL = YES;
218 | };
219 | name = Debug;
220 | };
221 | 6BEE0AA11987255200D73B41 /* Release */ = {
222 | isa = XCBuildConfiguration;
223 | buildSettings = {
224 | OTHER_LDFLAGS = "-ObjC";
225 | PRODUCT_NAME = "$(TARGET_NAME)";
226 | SKIP_INSTALL = YES;
227 | };
228 | name = Release;
229 | };
230 | /* End XCBuildConfiguration section */
231 |
232 | /* Begin XCConfigurationList section */
233 | 6BEE0A861987255200D73B41 /* Build configuration list for PBXProject "BKCameraController" */ = {
234 | isa = XCConfigurationList;
235 | buildConfigurations = (
236 | 6BEE0A9D1987255200D73B41 /* Debug */,
237 | 6BEE0A9E1987255200D73B41 /* Release */,
238 | );
239 | defaultConfigurationIsVisible = 0;
240 | defaultConfigurationName = Release;
241 | };
242 | 6BEE0A9F1987255200D73B41 /* Build configuration list for PBXNativeTarget "BKCameraController" */ = {
243 | isa = XCConfigurationList;
244 | buildConfigurations = (
245 | 6BEE0AA01987255200D73B41 /* Debug */,
246 | 6BEE0AA11987255200D73B41 /* Release */,
247 | );
248 | defaultConfigurationIsVisible = 0;
249 | defaultConfigurationName = Release;
250 | };
251 | /* End XCConfigurationList section */
252 | };
253 | rootObject = 6BEE0A831987255200D73B41 /* Project object */;
254 | }
255 |
--------------------------------------------------------------------------------
/net.sixfivezero.BKCameraController.docset/Contents/Resources/Documents/Protocols/BKCameraControllerDelegate.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | BKCameraControllerDelegate Protocol Reference
6 |
7 |
8 |
9 |
10 |
11 |
12 |
56 |
57 |
86 |
87 |
88 |
89 |
90 |
96 |
101 |
102 |
103 |
104 |
105 | Conforms to
106 | NSObject
107 |
108 | Declared in
109 | BKCameraController.h
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
Overview
119 |
The delegate of a BKCameraController object must adopt the protocol.
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
Tasks
129 |
130 |
131 |
132 |
133 |
134 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
Instance Methods
163 |
164 |
165 |
166 |
cameraControllerDidCyclePosition:
167 |
168 |
169 |
170 |
171 |
Tells the delegate that the camera controller cycled the camera position.
172 |
173 |
174 |
175 |
176 |
- (void)cameraControllerDidCyclePosition:(id)cameraController
177 |
178 |
179 |
180 |
181 |
Parameters
182 |
183 |
184 | cameraController
185 | The camera controller that cycled position.
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 |
Declared In
204 | BKCameraController.h
205 |
206 |
207 |
208 |
209 |
210 |
211 |
212 |
cameraControllerWillCyclePosition:
213 |
214 |
215 |
216 |
217 |
Tells the delegate that the camera controller will cycle the camera position.
218 |
219 |
220 |
221 |
222 |
- (void)cameraControllerWillCyclePosition:(id)cameraController
223 |
224 |
225 |
226 |
227 |
Parameters
228 |
229 |
230 | cameraController
231 | The camera controller object informing the delegate of this event.
232 |
233 |
234 |
235 |
236 |
237 |
238 |
239 |
240 |
241 |
242 |
243 |
244 |
245 |
246 |
247 |
248 |
249 |
Declared In
250 | BKCameraController.h
251 |
252 |
253 |
254 |
255 |
256 |
257 |
258 |
259 |
260 |
261 |
262 |
263 |
264 |
265 |
271 |
280 |
281 |
282 |
373 |
374 |
--------------------------------------------------------------------------------
/net.sixfivezero.BKCameraController.docset/Contents/Resources/Documents/css/styles.css:
--------------------------------------------------------------------------------
1 | body {
2 | font-family: 'Lucida Grande',Geneva,Helvetica,Arial,sans-serif;
3 | font-size: 13px;
4 | }
5 |
6 | code {
7 | font-family: Courier, Consolas, monospace;
8 | font-size: 13px;
9 | color: #666;
10 | }
11 |
12 | pre {
13 | font-family: Courier, Consolas, monospace;
14 | font-size: 13px;
15 | line-height: 18px;
16 | tab-interval: 0.5em;
17 | border: 1px solid #C7CFD5;
18 | background-color: #F1F5F9;
19 | color: #666;
20 | padding: 0.3em 1em;
21 | }
22 |
23 | ul {
24 | list-style-type: square;
25 | }
26 |
27 | li {
28 | margin-bottom: 10px;
29 | }
30 |
31 | a, a code {
32 | text-decoration: none;
33 | color: #36C;
34 | }
35 |
36 | a:hover, a:hover code {
37 | text-decoration: underline;
38 | color: #36C;
39 | }
40 |
41 | h2 {
42 | border-bottom: 1px solid #8391A8;
43 | color: #3C4C6C;
44 | font-size: 187%;
45 | font-weight: normal;
46 | margin-top: 1.75em;
47 | padding-bottom: 2px;
48 | }
49 |
50 | table {
51 | margin-bottom: 4em;
52 | border-collapse:collapse;
53 | vertical-align: middle;
54 | }
55 |
56 | td {
57 | border: 1px solid #9BB3CD;
58 | padding: .667em;
59 | font-size: 100%;
60 | }
61 |
62 | th {
63 | border: 1px solid #9BB3CD;
64 | padding: .3em .667em .3em .667em;
65 | background: #93A5BB;
66 | font-size: 103%;
67 | font-weight: bold;
68 | color: white;
69 | text-align: left;
70 | }
71 |
72 | /* @group Common page elements */
73 |
74 | #top_header {
75 | height: 91px;
76 | left: 0;
77 | min-width: 598px;
78 | position: absolute;
79 | right: 0;
80 | top: 0;
81 | z-index: 900;
82 | }
83 |
84 | #footer {
85 | clear: both;
86 | padding-top: 20px;
87 | text-align: center;
88 | }
89 |
90 | #contents, #overview_contents {
91 | -webkit-overflow-scrolling: touch;
92 | border-top: 1px solid #A9A9A9;
93 | position: absolute;
94 | top: 90px;
95 | left: 0;
96 | right: 0;
97 | bottom: 0;
98 | overflow-x: hidden;
99 | overflow-y: auto;
100 | padding-left: 2em;
101 | padding-right: 2em;
102 | padding-top: 1em;
103 | min-width: 550px;
104 | }
105 |
106 | #contents.isShowingTOC {
107 | left: 230px;
108 | min-width: 320px;
109 | }
110 |
111 | .copyright {
112 | font-size: 12px;
113 | }
114 |
115 | .generator {
116 | font-size: 11px;
117 | }
118 |
119 | .main-navigation ul li {
120 | display: inline;
121 | margin-left: 15px;
122 | list-style: none;
123 | }
124 |
125 | .navigation-top {
126 | clear: both;
127 | float: right;
128 | }
129 |
130 | .navigation-bottom {
131 | clear: both;
132 | float: right;
133 | margin-top: 20px;
134 | margin-bottom: -10px;
135 | }
136 |
137 | .open > .disclosure {
138 | background-image: url("../img/disclosure_open.png");
139 | }
140 |
141 | .disclosure {
142 | background: url("../img/disclosure.png") no-repeat scroll 0 0;
143 | }
144 |
145 | .disclosure, .nodisclosure {
146 | display: inline-block;
147 | height: 8px;
148 | margin-right: 5px;
149 | position: relative;
150 | width: 9px;
151 | }
152 |
153 | /* @end */
154 |
155 | /* @group Header */
156 |
157 | #top_header #library {
158 | background: url("../img/library_background.png") repeat-x 0 0 #485E78;
159 | background-color: #ccc;
160 | height: 35px;
161 | font-size: 115%;
162 | }
163 |
164 | #top_header #library #libraryTitle {
165 | color: #FFFFFF;
166 | margin-left: 15px;
167 | text-shadow: 0 -1px 0 #485E78;
168 | top: 8px;
169 | position: absolute;
170 | }
171 |
172 | #libraryTitle {
173 | left: 0;
174 | }
175 |
176 | #top_header #library #developerHome {
177 | color: #92979E;
178 | right: 15px;
179 | top: 8px;
180 | position: absolute;
181 | }
182 |
183 | #top_header #library a:hover {
184 | text-decoration: none;
185 | }
186 |
187 | #top_header #title {
188 | background: url("../img/title_background.png") repeat-x 0 0 #8A98A9;
189 | border-bottom: 1px solid #757575;
190 | height: 25px;
191 | overflow: hidden;
192 | }
193 |
194 | #top_header h1 {
195 | font-size: 105%;
196 | font-weight: normal;
197 | margin: 0;
198 | padding: 3px 0 2px;
199 | text-align: center;
200 | /*text-shadow: 0 1px 0 #D5D5D5;*/
201 | white-space: nowrap;
202 | }
203 |
204 | #headerButtons {
205 | background-color: #D8D8D8;
206 | background-image: url("../img/button_bar_background.png");
207 | border-bottom: 0px solid #EDEDED;
208 | border-top: 0px solid #a8a8a8;
209 | font-size: 8pt;
210 | height: 28px;
211 | left: 0;
212 | list-style: none outside none;
213 | margin: 0;
214 | overflow: hidden;
215 | padding: 0;
216 | position: absolute;
217 | right: 0;
218 | top: 61px;
219 | }
220 |
221 | #headerButtons li {
222 | background-repeat: no-repeat;
223 | display: inline;
224 | margin-top: 0;
225 | margin-bottom: 0;
226 | padding: 0;
227 | }
228 |
229 | #toc_button button {
230 | background-color: #EBEEF1;
231 | border-color: #ACACAC;
232 | border-style: none solid none none;
233 | border-width: 0 1px 0 0;
234 | height: 28px;
235 | margin: 0;
236 | padding-left: 30px;
237 | text-align: left;
238 | width: 230px;
239 | }
240 |
241 | li#jumpto_button {
242 | left: 230px;
243 | margin-left: 0;
244 | position: absolute;
245 | }
246 |
247 | li#jumpto_button select {
248 | height: 22px;
249 | margin: 5px 2px 0 10px;
250 | max-width: 300px;
251 | }
252 |
253 | /* @end */
254 |
255 | /* @group Table of contents */
256 |
257 | #tocContainer.isShowingTOC {
258 | border-right: 1px solid #ACACAC;
259 | display: block;
260 | overflow-x: hidden;
261 | overflow-y: auto;
262 | padding: 0;
263 | }
264 |
265 | #tocContainer {
266 | background-color: #EBEEF1;
267 | border-top: 1px solid #ACACAC;
268 | bottom: 0;
269 | display: none;
270 | left: 0;
271 | overflow: hidden;
272 | position: absolute;
273 | top: 90px;
274 | width: 229px;
275 | }
276 |
277 | #tocContainer > ul#toc {
278 | font-size: 11px;
279 | margin: 0;
280 | padding: 12px 0 18px;
281 | width: 209px;
282 | -moz-user-select: none;
283 | -webkit-user-select: none;
284 | user-select: none;
285 | }
286 |
287 | #tocContainer > ul#toc > li {
288 | margin: 0;
289 | padding: 0 0 7px 30px;
290 | text-indent: -15px;
291 | }
292 |
293 | #tocContainer > ul#toc > li > .sectionName a {
294 | color: #000000;
295 | font-weight: bold;
296 | }
297 |
298 | #tocContainer > ul#toc > li > .sectionName a:hover {
299 | text-decoration: none;
300 | }
301 |
302 | #tocContainer > ul#toc li.children > ul {
303 | display: none;
304 | height: 0;
305 | }
306 |
307 | #tocContainer > ul#toc > li > ul {
308 | margin: 0;
309 | padding: 0;
310 | }
311 |
312 | #tocContainer > ul#toc > li > ul, ul#toc > li > ul > li {
313 | margin-left: 0;
314 | margin-bottom: 0;
315 | padding-left: 15px;
316 | }
317 |
318 | #tocContainer > ul#toc > li ul {
319 | list-style: none;
320 | margin-right: 0;
321 | padding-right: 0;
322 | }
323 |
324 | #tocContainer > ul#toc li.children.open > ul {
325 | display: block;
326 | height: auto;
327 | margin-left: -15px;
328 | padding-left: 0;
329 | }
330 |
331 | #tocContainer > ul#toc > li > ul, ul#toc > li > ul > li {
332 | margin-left: 0;
333 | padding-left: 15px;
334 | }
335 |
336 | #tocContainer li ul li {
337 | margin-top: 0.583em;
338 | overflow: hidden;
339 | text-overflow: ellipsis;
340 | white-space: nowrap;
341 | }
342 |
343 | #tocContainer li ul li span.sectionName {
344 | white-space: normal;
345 | }
346 |
347 | #tocContainer > ul#toc > li > ul > li > .sectionName a {
348 | font-weight: bold;
349 | }
350 |
351 | #tocContainer > ul#toc > li > ul a {
352 | color: #4F4F4F;
353 | }
354 |
355 | /* @end */
356 |
357 | /* @group Index formatting */
358 |
359 | .index-title {
360 | font-size: 13px;
361 | font-weight: normal;
362 | }
363 |
364 | .index-column {
365 | float: left;
366 | width: 30%;
367 | min-width: 200px;
368 | font-size: 11px;
369 | }
370 |
371 | .index-column ul {
372 | margin: 8px 0 0 0;
373 | padding: 0;
374 | list-style: none;
375 | }
376 |
377 | .index-column ul li {
378 | margin: 0 0 3px 0;
379 | padding: 0;
380 | }
381 |
382 | .hierarchy-column {
383 | min-width: 400px;
384 | }
385 |
386 | .hierarchy-column ul {
387 | margin: 3px 0 0 15px;
388 | }
389 |
390 | .hierarchy-column ul li {
391 | list-style-type: square;
392 | }
393 |
394 | /* @end */
395 |
396 | /* @group Common formatting elements */
397 |
398 | .title {
399 | font-weight: normal;
400 | font-size: 215%;
401 | margin-top:0;
402 | }
403 |
404 | .subtitle {
405 | font-weight: normal;
406 | font-size: 180%;
407 | color: #3C4C6C;
408 | border-bottom: 1px solid #5088C5;
409 | }
410 |
411 | .subsubtitle {
412 | font-weight: normal;
413 | font-size: 145%;
414 | height: 0.7em;
415 | }
416 |
417 | .note {
418 | border: 1px solid #5088C5;
419 | background-color: white;
420 | margin: 1.667em 0 1.75em 0;
421 | padding: 0 .667em .083em .750em;
422 | }
423 |
424 | .warning {
425 | border: 1px solid #5088C5;
426 | background-color: #F0F3F7;
427 | margin-bottom: 0.5em;
428 | padding: 0.3em 0.8em;
429 | }
430 |
431 | .bug {
432 | border: 1px solid #000;
433 | background-color: #ffffcc;
434 | margin-bottom: 0.5em;
435 | padding: 0.3em 0.8em;
436 | }
437 |
438 | .deprecated {
439 | color: #F60425;
440 | }
441 |
442 | /* @end */
443 |
444 | /* @group Common layout */
445 |
446 | .section {
447 | margin-top: 3em;
448 | }
449 |
450 | /* @end */
451 |
452 | /* @group Object specification section */
453 |
454 | .section-specification {
455 | margin-left: 2.5em;
456 | margin-right: 2.5em;
457 | font-size: 12px;
458 | }
459 |
460 | .section-specification table {
461 | margin-bottom: 0em;
462 | border-top: 1px solid #d6e0e5;
463 | }
464 |
465 | .section-specification td {
466 | vertical-align: top;
467 | border-bottom: 1px solid #d6e0e5;
468 | border-left-width: 0px;
469 | border-right-width: 0px;
470 | border-top-width: 0px;
471 | padding: .6em;
472 | }
473 |
474 | .section-specification .specification-title {
475 | font-weight: bold;
476 | }
477 |
478 | /* @end */
479 |
480 | /* @group Tasks section */
481 |
482 | .task-list {
483 | list-style-type: none;
484 | padding-left: 0px;
485 | }
486 |
487 | .task-list li {
488 | margin-bottom: 3px;
489 | }
490 |
491 | .task-item-suffix {
492 | color: #996;
493 | font-size: 12px;
494 | font-style: italic;
495 | margin-left: 0.5em;
496 | }
497 |
498 | span.tooltip span.tooltip {
499 | font-size: 1.0em;
500 | display: none;
501 | padding: 0.3em;
502 | border: 1px solid #aaa;
503 | background-color: #fdfec8;
504 | color: #000;
505 | text-align: left;
506 | }
507 |
508 | span.tooltip:hover span.tooltip {
509 | display: block;
510 | position: absolute;
511 | margin-left: 2em;
512 | }
513 |
514 | /* @end */
515 |
516 | /* @group Method section */
517 |
518 | .section-method {
519 | margin-top: 2.3em;
520 | }
521 |
522 | .method-title {
523 | margin-bottom: 1.5em;
524 | }
525 |
526 | .method-subtitle {
527 | margin-top: 0.7em;
528 | margin-bottom: 0.2em;
529 | }
530 |
531 | .method-subsection p {
532 | margin-top: 0.4em;
533 | margin-bottom: 0.8em;
534 | }
535 |
536 | .method-declaration {
537 | margin-top:1.182em;
538 | margin-bottom:.909em;
539 | }
540 |
541 | .method-declaration code {
542 | font:14px Courier, Consolas, monospace;
543 | color:#000;
544 | }
545 |
546 | .declaration {
547 | color: #000;
548 | }
549 |
550 | .termdef {
551 | margin-bottom: 10px;
552 | margin-left: 0px;
553 | margin-right: 0px;
554 | margin-top: 0px;
555 | }
556 |
557 | .termdef dt {
558 | margin: 0;
559 | padding: 0;
560 | }
561 |
562 | .termdef dd {
563 | margin-bottom: 6px;
564 | margin-left: 16px;
565 | margin-right: 0px;
566 | margin-top: 1px;
567 | }
568 |
569 | .termdef dd p {
570 | margin-bottom: 6px;
571 | margin-left: 0px;
572 | margin-right: 0px;
573 | margin-top: -1px;
574 | }
575 |
576 | .argument-def {
577 | margin-top: 0.3em;
578 | margin-bottom: 0.3em;
579 | }
580 |
581 | .argument-def dd {
582 | margin-left: 1.25em;
583 | }
584 |
585 | .see-also-section ul {
586 | list-style-type: none;
587 | padding-left: 0px;
588 | margin-top: 0;
589 | }
590 |
591 | .see-also-section li {
592 | margin-bottom: 3px;
593 | }
594 |
595 | .declared-in-ref {
596 | color: #666;
597 | }
598 |
599 | #tocContainer.hideInXcode {
600 | display: none;
601 | border: 0px solid black;
602 | }
603 |
604 | #top_header.hideInXcode {
605 | display: none;
606 | }
607 |
608 | #contents.hideInXcode {
609 | border: 0px solid black;
610 | top: 0px;
611 | left: 0px;
612 | }
613 |
614 | /* @end */
615 |
616 |
--------------------------------------------------------------------------------
/net.sixfivezero.BKCameraController.docset/Contents/Resources/Tokens1.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | //apple_ref/occ/cl/BKCameraController
7 | A wrapper for AVCaptureSession to simplify the process of capturing photos.
8 | BKCameraController.h
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 | //apple_ref/occ/instm/BKCameraController/setDelegate:
17 | The receiver’s delegate or nil if it doesn’t have a delegate.
18 | BKCameraController.h
19 |
20 | @property (nonatomic, weak) id<BKCameraControllerDelegate> delegate
21 |
22 |
23 | //api/name/delegate
24 |
25 |
26 |
27 |
28 | //apple_ref/occ/instm/BKCameraController/delegate
29 | The receiver’s delegate or nil if it doesn’t have a delegate.
30 | BKCameraController.h
31 |
32 | @property (nonatomic, weak) id<BKCameraControllerDelegate> delegate
33 |
34 |
35 | //api/name/delegate
36 |
37 |
38 |
39 |
40 | //apple_ref/occ/instp/BKCameraController/delegate
41 | The receiver’s delegate or nil if it doesn’t have a delegate.
42 | BKCameraController.h
43 |
44 | @property (nonatomic, weak) id<BKCameraControllerDelegate> delegate
45 |
46 |
47 | //api/name/delegate
48 |
49 |
50 |
51 |
52 | //apple_ref/occ/instm/BKCameraController/setSession:
53 | The controller-owned AVCaptureSession instance.
54 | BKCameraController.h
55 |
56 | @property (nonatomic, strong, readonly) AVCaptureSession *session
57 |
58 |
59 | //api/name/session
60 |
61 |
62 |
63 |
64 | //apple_ref/occ/instm/BKCameraController/session
65 | The controller-owned AVCaptureSession instance.
66 | BKCameraController.h
67 |
68 | @property (nonatomic, strong, readonly) AVCaptureSession *session
69 |
70 |
71 | //api/name/session
72 |
73 |
74 |
75 |
76 | //apple_ref/occ/instp/BKCameraController/session
77 | The controller-owned AVCaptureSession instance.
78 | BKCameraController.h
79 |
80 | @property (nonatomic, strong, readonly) AVCaptureSession *session
81 |
82 |
83 | //api/name/session
84 |
85 |
86 |
87 |
88 | //apple_ref/occ/instm/BKCameraController/setPosition:
89 | The current camera position.
90 | BKCameraController.h
91 |
92 | @property (nonatomic, assign, readonly) AVCaptureDevicePosition position
93 |
94 |
95 | //api/name/position
96 |
97 |
98 |
99 |
100 | //apple_ref/occ/instm/BKCameraController/position
101 | The current camera position.
102 | BKCameraController.h
103 |
104 | @property (nonatomic, assign, readonly) AVCaptureDevicePosition position
105 |
106 |
107 | //api/name/position
108 |
109 |
110 |
111 |
112 | //apple_ref/occ/instp/BKCameraController/position
113 | The current camera position.
114 | BKCameraController.h
115 |
116 | @property (nonatomic, assign, readonly) AVCaptureDevicePosition position
117 |
118 |
119 | //api/name/position
120 |
121 |
122 |
123 |
124 | //apple_ref/occ/instm/BKCameraController/setFlashMode:
125 | The current camera flash mode.
126 | BKCameraController.h
127 |
128 | @property (nonatomic, assign, readonly) AVCaptureFlashMode flashMode
129 |
130 |
131 | //api/name/flashMode
132 |
133 |
134 |
135 |
136 | //apple_ref/occ/instm/BKCameraController/flashMode
137 | The current camera flash mode.
138 | BKCameraController.h
139 |
140 | @property (nonatomic, assign, readonly) AVCaptureFlashMode flashMode
141 |
142 |
143 | //api/name/flashMode
144 |
145 |
146 |
147 |
148 | //apple_ref/occ/instp/BKCameraController/flashMode
149 | The current camera flash mode.
150 | BKCameraController.h
151 |
152 | @property (nonatomic, assign, readonly) AVCaptureFlashMode flashMode
153 |
154 |
155 | //api/name/flashMode
156 |
157 |
158 |
159 |
160 | //apple_ref/occ/instm/BKCameraController/setFlashCapable:
161 | Whether the current camera has the capability to flash.
162 | BKCameraController.h
163 |
164 | @property (nonatomic, assign, readonly) BOOL flashCapable
165 |
166 |
167 | //api/name/flashCapable
168 |
169 |
170 |
171 |
172 | //apple_ref/occ/instm/BKCameraController/flashCapable
173 | Whether the current camera has the capability to flash.
174 | BKCameraController.h
175 |
176 | @property (nonatomic, assign, readonly) BOOL flashCapable
177 |
178 |
179 | //api/name/flashCapable
180 |
181 |
182 |
183 |
184 | //apple_ref/occ/instp/BKCameraController/flashCapable
185 | Whether the current camera has the capability to flash.
186 | BKCameraController.h
187 |
188 | @property (nonatomic, assign, readonly) BOOL flashCapable
189 |
190 |
191 | //api/name/flashCapable
192 |
193 |
194 |
195 |
196 | //apple_ref/occ/instm/BKCameraController/initWithInitialPosition:autoFlashEnabled:
197 | Initializes the camera controller using the specified starting parameters.
198 | BKCameraController.h
199 |
200 | - (instancetype)initWithInitialPosition:(id)position autoFlashEnabled:(id)enabled
201 |
202 |
203 | position
204 | The position used to select the initial capture device used by the camera controller. Defaults to AVCaptureDevicePositionBack.
205 |
206 | enabled
207 | YES if the camera controller should include AVCaptureFlashModeAuto when cycling the flash mode. Defaults to NO.
208 |
209 |
210 | An initialized BKCameraController instance.
211 | //api/name/initWithInitialPosition:autoFlashEnabled:
212 |
213 |
214 |
215 |
216 | //apple_ref/occ/instm/BKCameraController/startCaptureSession
217 | Tells the receiver to start the capture session.
218 | BKCameraController.h
219 |
220 | - (void)startCaptureSession
221 |
222 |
223 | //api/name/startCaptureSession
224 |
225 |
226 |
227 |
228 | //apple_ref/occ/instm/BKCameraController/stopCaptureSession
229 | Tells the receiver to stop the capture session.
230 | BKCameraController.h
231 |
232 | - (void)stopCaptureSession
233 |
234 |
235 | //api/name/stopCaptureSession
236 |
237 |
238 |
239 |
240 | //apple_ref/occ/instm/BKCameraController/autoAdjustCameraToPoint:
241 | Sets the focus and exposure point to the specified point, if supported.
242 | BKCameraController.h
243 |
244 | - (void)autoAdjustCameraToPoint:(id)point
245 |
246 |
247 | point
248 | The point to set the exposure and focus.
249 |
250 |
251 |
252 | //api/name/autoAdjustCameraToPoint:
253 |
254 |
255 |
256 |
257 | //apple_ref/occ/instm/BKCameraController/cycleFlashMode
258 | Cycles through supported flash modes. Skips AVCaptureFlashModeAuto if the receiver was initialized with autoFlashEnabled set to NO.
259 | BKCameraController.h
260 |
261 | - (void)cycleFlashMode
262 |
263 |
264 | //api/name/cycleFlashMode
265 |
266 |
267 |
268 |
269 | //apple_ref/occ/instm/BKCameraController/cyclePosition
270 | Cycles through supported flash modes. If no flash mode at all is supported (such as on the front-facing camera), flashCapable is set to NO, otherwise YES.
271 | BKCameraController.h
272 |
273 | - (void)cyclePosition
274 |
275 |
276 | //api/name/cyclePosition
277 |
278 |
279 |
280 |
281 | //apple_ref/occ/instm/BKCameraController/captureAssetWithCompletion:
282 | Capture a photo and save it, along with its EXIF metadata, to the camera roll.
283 | BKCameraController.h
284 |
285 | - (void)captureAssetWithCompletion:(id)completion
286 |
287 |
288 | completion
289 | A completion block supplying either a valid Asset <NSURL> or a <NSError>. Executed on the main thread.
290 |
291 | - assetURL The Asset URL to the captured media. nil if an error occurred.
292 | - error The error, if a problem occurred during capture.
293 |
294 |
295 |
296 | //api/name/captureAssetWithCompletion:
297 |
298 |
299 |
300 |
301 | //apple_ref/occ/instm/BKCameraController/captureSampleWithCompletion:
302 | Capture a photo.
303 | BKCameraController.h
304 |
305 | - (void)captureSampleWithCompletion:(id)completion
306 |
307 |
308 | completion
309 | A completion block supplying either a <CIImage> or a <NSError>. Executed on the main thread.
310 |
311 | - image A CIImage wrapping the sample buffer's pixel buffer, captured by the camera. nil if an error occurred.
312 | - error The error, if a problem occurred during capture.
313 |
314 |
315 |
316 | //api/name/captureSampleWithCompletion:
317 |
318 |
319 |
320 |
321 | //apple_ref/occ/clm/BKCameraController/fakeImageData
322 | Getter for the fake image data used by the simulator.
323 | BKCameraController+Simulator.h
324 |
325 | + (NSData *)fakeImageData
326 |
327 | The fake image data used by the simulator.
328 | //api/name/fakeImageData
329 |
330 |
331 |
332 |
333 | //apple_ref/occ/clm/BKCameraController/setFakeImageData:
334 | Setter for the fake image data used by the simulator
335 | BKCameraController+Simulator.h
336 |
337 | + (void)setFakeImageData:(id)fakeImageData
338 |
339 |
340 | fakeImageData
341 | The fake image data to be used by the simulator.
342 |
343 |
344 |
345 | //api/name/setFakeImageData:
346 |
347 |
348 |
349 |
350 |
351 |
352 |
--------------------------------------------------------------------------------
/BKCameraController/BKCameraController.m:
--------------------------------------------------------------------------------
1 | // Copyright 2014-present 650 Industries. All rights reserved.
2 |
3 | #import "BKCameraController.h"
4 |
5 | @import AssetsLibrary.ALAssetsLibrary;
6 | @import AVFoundation.AVCaptureInput;
7 | @import AVFoundation.AVCaptureOutput;
8 | @import AVFoundation.AVMediaFormat;
9 | @import AVFoundation.AVVideoSettings;
10 | @import CoreImage.CIImage;
11 | @import ImageIO.CGImageProperties;
12 |
13 | @interface BKCameraController ()
14 | @property (nonatomic, strong) dispatch_queue_t avQueue;
15 | @end
16 |
17 | @implementation BKCameraController {
18 | BOOL _autoFlashEnabled;
19 |
20 | BOOL _sessionInitialized;
21 | BOOL _inputIsCycling;
22 |
23 | AVCaptureDeviceInput *_activeDeviceInput;
24 | AVCaptureStillImageOutput *_stillImageOutput;
25 |
26 | AVCaptureFlashMode _avFlashMode; // avQueue-affined flash mode
27 | AVCaptureDevicePosition _avPosition; // avQueue-affined device position
28 | }
29 |
30 | - (instancetype)initWithInitialPosition:(AVCaptureDevicePosition)position
31 | autoFlashEnabled:(BOOL)enabled
32 | {
33 | if (self = [super init]) {
34 | _autoFlashEnabled = enabled;
35 |
36 | _avQueue = dispatch_queue_create("net.sixfivezero.av", DISPATCH_QUEUE_SERIAL);
37 |
38 | _position = position;
39 | _session = [[AVCaptureSession alloc] init];
40 | }
41 | return self;
42 | }
43 |
44 | - (instancetype)init
45 | {
46 | if (self = [self initWithInitialPosition:AVCaptureDevicePositionBack autoFlashEnabled:NO]) {
47 | }
48 | return self;
49 | }
50 |
51 | - (void)_initialSessionSetup
52 | {
53 | NSAssert(![NSThread isMainThread], @"Method should not be run on the main thread");
54 | NSAssert(!_sessionInitialized, @"Session already initialized!");
55 |
56 | if ([_session canSetSessionPreset:AVCaptureSessionPresetPhoto]) {
57 | _session.sessionPreset = AVCaptureSessionPresetPhoto;
58 | }
59 |
60 | _stillImageOutput = [[AVCaptureStillImageOutput alloc] init];
61 | [_session addOutput:_stillImageOutput];
62 |
63 | NSError *error = nil;
64 | AVCaptureDevice *initialDevice = [self _captureDeviceForPosition:_position];
65 | AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:initialDevice error:&error];
66 | NSAssert(TARGET_IPHONE_SIMULATOR || error == nil, @"Error getting device input");
67 |
68 | [self _updateSessionWithInput:input error:&error];
69 | NSAssert(TARGET_IPHONE_SIMULATOR || error == nil, @"Error updating session with input");
70 |
71 | _sessionInitialized = YES;
72 | }
73 |
74 | - (void)startCaptureSession
75 | {
76 | dispatch_async(_avQueue, ^{
77 | if (!_sessionInitialized) {
78 | [self _initialSessionSetup];
79 | }
80 | [_session startRunning];
81 | });
82 | }
83 |
84 | - (void)stopCaptureSession
85 | {
86 | dispatch_async(_avQueue, ^{
87 | [_session stopRunning];
88 | });
89 | }
90 |
91 | #pragma mark - Camera control
92 |
93 | - (AVCaptureDevice *)_captureDeviceForPosition:(AVCaptureDevicePosition)position
94 | {
95 | NSAssert(![NSThread isMainThread], @"Method should not be run on the main thread");
96 | for (AVCaptureDevice *device in [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo]) {
97 | if (device.position == position) {
98 | return device;
99 | }
100 | }
101 | return nil;
102 | }
103 |
104 | - (BOOL)_updateSessionWithInput:(AVCaptureDeviceInput *)newInput error:(NSError * __autoreleasing *)error
105 | {
106 | NSAssert(![NSThread isMainThread], @"Method should not be run on the main thread");
107 | [_session beginConfiguration];
108 | if (_activeDeviceInput) {
109 | [_session removeInput:_activeDeviceInput];
110 | }
111 |
112 | if (![_session canAddInput:newInput]) {
113 | // Roll back the changes
114 | if (_activeDeviceInput) {
115 | [_session addInput:_activeDeviceInput];
116 | }
117 | [_session commitConfiguration];
118 | NSString *message = [NSString stringWithFormat:@"Something went wrong when switching to the %@", newInput.device.localizedName];
119 | if (error) {
120 | *error = [NSError errorWithDomain:@"net.sixfivezero" code:0 userInfo:@{NSLocalizedDescriptionKey: message}];
121 | }
122 | return YES;
123 | }
124 |
125 | [_session addInput:newInput];
126 | _activeDeviceInput = newInput;
127 | [_session commitConfiguration];
128 | return NO;
129 | }
130 |
131 | - (void)autoAdjustCameraToPoint:(CGPoint)point
132 | {
133 | dispatch_async(_avQueue, ^{
134 | NSError *error = nil;
135 | AVCaptureDevice *camera = [_activeDeviceInput device];
136 | [camera lockForConfiguration:&error];
137 | if (error) {
138 | NSLog(@"ERROR: problem adjusting camera: %@", error);
139 | // TODO: handle error
140 | return;
141 | }
142 | if (camera.isFocusPointOfInterestSupported) {
143 | camera.focusPointOfInterest = point;
144 | }
145 | if (camera.isExposurePointOfInterestSupported) {
146 | camera.exposurePointOfInterest = point;
147 | }
148 | if ([camera isFocusModeSupported:AVCaptureFocusModeContinuousAutoFocus]) {
149 | camera.focusMode = AVCaptureFocusModeContinuousAutoFocus;
150 | }
151 | if ([camera isExposureModeSupported:AVCaptureExposureModeContinuousAutoExposure]) {
152 | camera.exposureMode = AVCaptureExposureModeContinuousAutoExposure;
153 | }
154 | if ([camera isWhiteBalanceModeSupported:AVCaptureWhiteBalanceModeContinuousAutoWhiteBalance]) {
155 | camera.whiteBalanceMode = AVCaptureWhiteBalanceModeContinuousAutoWhiteBalance;
156 | }
157 | [camera unlockForConfiguration];
158 | });
159 | }
160 |
161 | - (void)cycleFlashMode
162 | {
163 | dispatch_async(_avQueue, ^{
164 | AVCaptureDevice *camera = _activeDeviceInput.device;
165 | AVCaptureFlashMode currentFlashMode = camera.flashMode;
166 | AVCaptureFlashMode nextFlashMode = AVCaptureFlashModeOff;
167 |
168 | switch (currentFlashMode) {
169 | case AVCaptureFlashModeOff:
170 | if ([camera isFlashModeSupported:AVCaptureFlashModeOn]) {
171 | nextFlashMode = AVCaptureFlashModeOn;
172 | }
173 | break;
174 | case AVCaptureFlashModeOn:
175 | if ([camera isFlashModeSupported:AVCaptureFlashModeAuto] && _autoFlashEnabled) {
176 | nextFlashMode = AVCaptureFlashModeAuto;
177 | } else {
178 | nextFlashMode = AVCaptureFlashModeOff;
179 | }
180 | break;
181 | case AVCaptureFlashModeAuto:
182 | nextFlashMode = AVCaptureFlashModeOff;
183 | break;
184 | default:
185 | nextFlashMode = AVCaptureFlashModeOff;
186 | NSAssert(NO, @"Unknown flash mode: %d", (int)currentFlashMode);
187 | }
188 |
189 | // The front camera doesn't even support _setting_ flashMode, even to off.
190 | BOOL flashCapable = YES;
191 | if (![camera isFlashModeSupported:nextFlashMode]) {
192 | flashCapable = NO;
193 | }
194 |
195 | // Optimistically update button
196 | dispatch_async(dispatch_get_main_queue(), ^{
197 | [self willChangeValueForKey:@"flashCapable"];
198 | _flashCapable = flashCapable;
199 | [self didChangeValueForKey:@"flashCapable"];
200 | [self willChangeValueForKey:@"flashMode"];
201 | _flashMode = nextFlashMode;
202 | [self didChangeValueForKey:@"flashMode"];
203 | });
204 |
205 | // Don't bother trying to change flash mode if not capable
206 | if (!flashCapable) {
207 | return;
208 | }
209 |
210 | NSError *error = nil;
211 | [camera lockForConfiguration:&error];
212 | if (error) {
213 | NSLog(@"error cycling flash: %@", error);
214 | // Roll back icon change
215 | dispatch_async(dispatch_get_main_queue(), ^{
216 | [self willChangeValueForKey:@"flashCapable"];
217 | _flashCapable = flashCapable;
218 | [self didChangeValueForKey:@"flashCapable"];
219 | [self willChangeValueForKey:@"flashMode"];
220 | _flashMode = nextFlashMode;
221 | [self didChangeValueForKey:@"flashMode"];
222 | });
223 | return;
224 | }
225 |
226 | camera.flashMode = nextFlashMode;
227 | [camera unlockForConfiguration];
228 | });
229 | }
230 |
231 | - (void)cyclePosition
232 | {
233 | if (_inputIsCycling) {
234 | return;
235 | }
236 |
237 | _inputIsCycling = YES;
238 |
239 | if ([_delegate respondsToSelector:@selector(cameraControllerWillCyclePosition:)]) {
240 | [_delegate cameraControllerWillCyclePosition:self];
241 | }
242 |
243 | dispatch_async(_avQueue, ^{
244 | AVCaptureDevice *camera = _activeDeviceInput.device;
245 | AVCaptureDevicePosition currentPosition = camera.position;
246 | AVCaptureDevicePosition nextPosition = AVCaptureDevicePositionUnspecified;
247 |
248 | switch (currentPosition) {
249 | case AVCaptureDevicePositionBack:
250 | nextPosition = AVCaptureDevicePositionFront;
251 | break;
252 | case AVCaptureDevicePositionFront:
253 | nextPosition = AVCaptureDevicePositionBack;
254 | break;
255 | default:
256 | nextPosition = AVCaptureDevicePositionUnspecified;
257 | NSAssert(NO, @"Unknown position: %d", (int)currentPosition);
258 | }
259 |
260 | NSError *error = nil;
261 | AVCaptureDevice *newCamera = [self _captureDeviceForPosition:nextPosition];
262 | AVCaptureDeviceInput *newInput = [AVCaptureDeviceInput deviceInputWithDevice:newCamera error:&error];
263 | if (error) {
264 | NSLog(@"ERROR: problem cycling position: %@", error);
265 | return;
266 | }
267 | [self _updateSessionWithInput:newInput error:&error];
268 | if (error) {
269 | NSLog(@"ERROR: problem cycling position: %@", error);
270 | return;
271 | }
272 |
273 | AVCaptureFlashMode newFlashMode = newCamera.flashMode;
274 | BOOL flashCapable = YES;
275 | if (![newCamera isFlashModeSupported:newFlashMode]) {
276 | flashCapable = NO;
277 | }
278 |
279 | _avFlashMode = newFlashMode;
280 | _avPosition = nextPosition;
281 |
282 | dispatch_async(dispatch_get_main_queue(), ^{
283 | _inputIsCycling = NO;
284 | [self willChangeValueForKey:@"flashCapable"];
285 | _flashCapable = flashCapable;
286 | [self didChangeValueForKey:@"flashCapable"];
287 | [self willChangeValueForKey:@"flashMode"];
288 | _flashMode = newFlashMode;
289 | [self didChangeValueForKey:@"flashMode"];
290 | [self willChangeValueForKey:@"position"];
291 | _position = nextPosition;
292 | [self didChangeValueForKey:@"position"];
293 |
294 | if ([_delegate respondsToSelector:@selector(cameraControllerDidCyclePosition:)]) {
295 | [_delegate cameraControllerDidCyclePosition:self];
296 | }
297 | });
298 | });
299 | }
300 |
301 | #pragma mark - Photo capture
302 |
303 | - (void)captureAssetWithCompletion:(asset_capture_completion_t)completion
304 | {
305 | dispatch_async(_avQueue, ^{
306 | AVCaptureConnection *connection = [_stillImageOutput connectionWithMediaType:AVMediaTypeVideo];
307 | _stillImageOutput.outputSettings = @{AVVideoCodecKey: AVVideoCodecJPEG};
308 | [_stillImageOutput captureStillImageAsynchronouslyFromConnection:connection
309 | completionHandler:
310 | ^(CMSampleBufferRef imageSampleBuffer, NSError *error) {
311 | if (error) {
312 | NSLog(@"ERROR: problem capturing photo: %@", [error localizedDescription]);
313 | dispatch_async(dispatch_get_main_queue(), ^{
314 | completion(nil, error);
315 | });
316 | return;
317 | }
318 |
319 | CFDictionaryRef exifAttachments = CMGetAttachment(imageSampleBuffer, kCGImagePropertyExifDictionary, NULL);
320 | NSDictionary *exif;
321 | if (exifAttachments) {
322 | exif = [NSDictionary dictionaryWithDictionary:(__bridge NSDictionary *)(exifAttachments)];
323 | } else {
324 | exif = nil;
325 | }
326 |
327 | NSData *data = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageSampleBuffer];
328 | ALAssetsLibrary *assetsLibrary = [[ALAssetsLibrary alloc] init];
329 | [assetsLibrary writeImageDataToSavedPhotosAlbum:data metadata:exif completionBlock:^(NSURL *assetURL, NSError *error) {
330 | if (error) {
331 | dispatch_async(dispatch_get_main_queue(), ^{
332 | completion(nil, error);
333 | });
334 | } else {
335 | dispatch_async(dispatch_get_main_queue(), ^{
336 | completion(assetURL, nil);
337 | });
338 | }
339 | }];
340 | }];
341 | });
342 | }
343 |
344 | - (void)captureSampleWithCompletion:(ciimage_capture_completion_t)completion
345 | {
346 | dispatch_async(_avQueue, ^{
347 | AVCaptureConnection *connection = [_stillImageOutput connectionWithMediaType:AVMediaTypeVideo];
348 | _stillImageOutput.outputSettings = @{(NSString *)kCVPixelBufferPixelFormatTypeKey: @(kCVPixelFormatType_32BGRA)};
349 | [_stillImageOutput captureStillImageAsynchronouslyFromConnection:connection
350 | completionHandler:
351 | ^(CMSampleBufferRef imageSampleBuffer, NSError *error) {
352 | if (error) {
353 | NSLog(@"ERROR: problem capturing photo: %@", [error localizedDescription]);
354 | dispatch_async(dispatch_get_main_queue(), ^{
355 | completion(nil, error);
356 | });
357 | return;
358 | }
359 |
360 | CVPixelBufferRef pixelBuffer = CMSampleBufferGetImageBuffer(imageSampleBuffer);
361 | NSDictionary *attachments = (__bridge_transfer NSDictionary *)CMCopyDictionaryOfAttachments(NULL, imageSampleBuffer, kCMAttachmentMode_ShouldPropagate);
362 | CIImage *image = [CIImage imageWithCVPixelBuffer:pixelBuffer options:@{kCIImageProperties: attachments}];
363 |
364 | dispatch_async(dispatch_get_main_queue(), ^{
365 | completion(image, nil);
366 | });
367 | }];
368 | });
369 | }
370 |
371 | @end
372 |
--------------------------------------------------------------------------------
/net.sixfivezero.BKCameraController.docset/Contents/Resources/Documents/Classes/BKCameraController.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | BKCameraController Class Reference
6 |
7 |
8 |
9 |
10 |
11 |
12 |
88 |
89 |
162 |
163 |
164 |
165 |
166 |
172 |
177 |
178 |
179 |
180 |
181 | Inherits from
182 | NSObject
183 |
184 | Declared in
185 | BKCameraController.h
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
Overview
195 |
A wrapper for AVCaptureSession to simplify the process of capturing photos.
196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 |
204 |
Tasks
205 |
206 |
207 |
208 |
Other Methods
209 |
210 |
211 |
212 |
213 | delegate
214 |
215 | property
216 |
217 |
218 |
219 | session
220 |
221 | property
222 |
223 |
224 |
225 | position
226 |
227 | property
228 |
229 |
230 |
231 | flashMode
232 |
233 | property
234 |
235 |
236 |
237 | flashCapable
238 |
239 | property
240 |
241 |
242 |
243 |
244 |
245 |
246 |
Initializing a BKCameraController object
247 |
248 |
257 |
258 |
259 |
260 |
Starting/Stopping Capture Session State
261 |
262 |
277 |
278 |
279 |
280 |
Adjusting Camera Settings
281 |
282 |
303 |
304 |
305 |
306 |
Capturing Photos
307 |
308 |
323 |
324 |
325 |
326 |
Simulator Methods
327 |
328 |
343 |
344 |
345 |
346 |
347 |
348 |
349 |
350 |
351 |
352 |
Properties
353 |
354 |
355 |
356 |
delegate
357 |
358 |
359 |
360 |
361 |
The receiver’s delegate or nil if it doesn’t have a delegate.
362 |
363 |
364 |
365 |
366 |
@property (nonatomic, weak) id<BKCameraControllerDelegate> delegate
367 |
368 |
369 |
370 |
371 |
372 |
373 |
374 |
375 |
376 |
380 |
381 |
382 |
383 |
384 |
385 |
386 |
387 |
388 |
Declared In
389 | BKCameraController.h
390 |
391 |
392 |
393 |
394 |
395 |
396 |
397 |
flashCapable
398 |
399 |
400 |
401 |
402 |
Whether the current camera has the capability to flash.
403 |
404 |
405 |
406 |
407 |
@property (nonatomic, assign, readonly) BOOL flashCapable
408 |
409 |
410 |
411 |
412 |
413 |
414 |
415 |
416 |
417 |
418 |
419 |
420 |
421 |
422 |
423 |
424 |
Declared In
425 | BKCameraController.h
426 |
427 |
428 |
429 |
430 |
431 |
432 |
433 |
flashMode
434 |
435 |
436 |
437 |
438 |
The current camera flash mode.
439 |
440 |
441 |
442 |
443 |
@property (nonatomic, assign, readonly) AVCaptureFlashMode flashMode
444 |
445 |
446 |
447 |
448 |
449 |
450 |
451 |
452 |
453 |
454 |
455 |
456 |
457 |
458 |
459 |
460 |
Declared In
461 | BKCameraController.h
462 |
463 |
464 |
465 |
466 |
467 |
468 |
469 |
position
470 |
471 |
472 |
473 |
474 |
The current camera position.
475 |
476 |
477 |
478 |
479 |
@property (nonatomic, assign, readonly) AVCaptureDevicePosition position
480 |
481 |
482 |
483 |
484 |
485 |
486 |
487 |
488 |
489 |
490 |
491 |
492 |
493 |
494 |
495 |
496 |
Declared In
497 | BKCameraController.h
498 |
499 |
500 |
501 |
502 |
503 |
504 |
505 |
session
506 |
507 |
508 |
509 |
510 |
The controller-owned AVCaptureSession instance.
511 |
512 |
513 |
514 |
515 |
@property (nonatomic, strong, readonly) AVCaptureSession *session
516 |
517 |
518 |
519 |
520 |
521 |
522 |
523 |
524 |
525 |
526 |
527 |
528 |
529 |
530 |
531 |
532 |
Declared In
533 | BKCameraController.h
534 |
535 |
536 |
537 |
538 |
539 |
540 |
541 |
542 |
543 |
544 |
545 |
Class Methods
546 |
547 |
548 |
549 |
fakeImageData
550 |
551 |
552 |
553 |
554 |
Getter for the fake image data used by the simulator.
555 |
556 |
557 |
558 |
559 |
+ (NSData *)fakeImageData
560 |
561 |
562 |
563 |
564 |
565 |
566 |
Return Value
567 |
The fake image data used by the simulator.
568 |
569 |
570 |
571 |
572 |
573 |
574 |
575 |
576 |
577 |
578 |
579 |
580 |
581 |
Declared In
582 | BKCameraController+Simulator.h
583 |
584 |
585 |
586 |
587 |
588 |
589 |
590 |
setFakeImageData:
591 |
592 |
593 |
594 |
595 |
Setter for the fake image data used by the simulator
596 |
597 |
598 |
599 |
600 |
+ (void)setFakeImageData:(id)fakeImageData
601 |
602 |
603 |
604 |
605 |
Parameters
606 |
607 |
608 | fakeImageData
609 | The fake image data to be used by the simulator.
610 |
611 |
612 |
613 |
614 |
615 |
616 |
617 |
618 |
619 |
620 |
621 |
622 |
623 |
624 |
625 |
626 |
627 |
Declared In
628 | BKCameraController+Simulator.h
629 |
630 |
631 |
632 |
633 |
634 |
635 |
636 |
637 |
638 |
639 |
640 |
Instance Methods
641 |
642 |
643 |
644 |
autoAdjustCameraToPoint:
645 |
646 |
647 |
648 |
649 |
Sets the focus and exposure point to the specified point, if supported.
650 |
651 |
652 |
653 |
654 |
- (void)autoAdjustCameraToPoint:(id)point
655 |
656 |
657 |
658 |
659 |
Parameters
660 |
661 |
662 | point
663 | The point to set the exposure and focus.
664 |
665 |
666 |
667 |
668 |
669 |
670 |
671 |
672 |
673 |
674 |
675 |
676 |
677 |
678 |
679 |
680 |
681 |
Declared In
682 | BKCameraController.h
683 |
684 |
685 |
686 |
687 |
688 |
689 |
690 |
captureAssetWithCompletion:
691 |
692 |
693 |
694 |
695 |
Capture a photo and save it, along with its EXIF metadata, to the camera roll.
696 |
697 |
698 |
699 |
700 |
- (void)captureAssetWithCompletion:(id)completion
701 |
702 |
703 |
704 |
705 |
Parameters
706 |
707 |
708 | completion
709 | A completion block supplying either a valid Asset or a . Executed on the main thread.
710 |
711 |
712 | assetURL The Asset URL to the captured media. nil if an error occurred.
713 | error The error, if a problem occurred during capture.
714 |
715 |
716 |
717 |
718 |
719 |
720 |
721 |
722 |
723 |
724 |
725 |
726 |
727 |
728 |
729 |
730 |
731 |
732 |
733 |
Declared In
734 | BKCameraController.h
735 |
736 |
737 |
738 |
739 |
740 |
741 |
742 |
captureSampleWithCompletion:
743 |
744 |
745 |
746 |
747 |
Capture a photo.
748 |
749 |
750 |
751 |
752 |
- (void)captureSampleWithCompletion:(id)completion
753 |
754 |
755 |
756 |
757 |
Parameters
758 |
759 |
760 | completion
761 | A completion block supplying either a or a . Executed on the main thread.
762 |
763 |
764 | image A CIImage wrapping the sample buffer’s pixel buffer, captured by the camera. nil if an error occurred.
765 | error The error, if a problem occurred during capture.
766 |
767 |
768 |
769 |
770 |
771 |
772 |
773 |
774 |
775 |
776 |
777 |
778 |
779 |
780 |
781 |
782 |
783 |
784 |
785 |
Declared In
786 | BKCameraController.h
787 |
788 |
789 |
790 |
791 |
792 |
793 |
794 |
cycleFlashMode
795 |
796 |
797 |
798 |
799 |
Cycles through supported flash modes. Skips AVCaptureFlashModeAuto if the receiver was initialized with autoFlashEnabled set to NO.
800 |
801 |
802 |
803 |
804 |
- (void)cycleFlashMode
805 |
806 |
807 |
808 |
809 |
810 |
811 |
812 |
813 |
814 |
815 |
816 |
817 |
818 |
819 |
820 |
821 |
Declared In
822 | BKCameraController.h
823 |
824 |
825 |
826 |
827 |
828 |
829 |
830 |
cyclePosition
831 |
832 |
833 |
834 |
835 |
Cycles through supported flash modes. If no flash mode at all is supported (such as on the front-facing camera), flashCapable is set to NO, otherwise YES.
836 |
837 |
838 |
839 |
840 |
- (void)cyclePosition
841 |
842 |
843 |
844 |
845 |
846 |
847 |
848 |
849 |
850 |
851 |
852 |
853 |
854 |
855 |
856 |
857 |
Declared In
858 | BKCameraController.h
859 |
860 |
861 |
862 |
863 |
864 |
865 |
866 |
initWithInitialPosition:autoFlashEnabled:
867 |
868 |
869 |
870 |
871 |
Initializes the camera controller using the specified starting parameters.
872 |
873 |
874 |
875 |
876 |
- (instancetype)initWithInitialPosition:(id)position autoFlashEnabled:(id)enabled
877 |
878 |
879 |
880 |
881 |
Parameters
882 |
883 |
884 | position
885 | The position used to select the initial capture device used by the camera controller. Defaults to AVCaptureDevicePositionBack.
886 |
887 |
888 |
889 | enabled
890 | YES if the camera controller should include AVCaptureFlashModeAuto when cycling the flash mode. Defaults to NO.
891 |
892 |
893 |
894 |
895 |
896 |
897 |
898 |
Return Value
899 |
An initialized BKCameraController instance.
900 |
901 |
902 |
903 |
904 |
905 |
906 |
907 |
908 |
909 |
910 |
911 |
912 |
913 |
Declared In
914 | BKCameraController.h
915 |
916 |
917 |
918 |
919 |
920 |
921 |
922 |
startCaptureSession
923 |
924 |
925 |
926 |
927 |
Tells the receiver to start the capture session.
928 |
929 |
930 |
931 |
932 |
- (void)startCaptureSession
933 |
934 |
935 |
936 |
937 |
938 |
939 |
940 |
941 |
942 |
943 |
Discussion
944 |
This method is used to start the receiver’s capture session. This method is asynchronous and runs on a serial background queue owned by the receiver.
945 |
946 |
947 |
948 |
949 |
950 |
951 |
952 |
953 |
954 |
Declared In
955 | BKCameraController.h
956 |
957 |
958 |
959 |
960 |
961 |
962 |
963 |
stopCaptureSession
964 |
965 |
966 |
967 |
968 |
Tells the receiver to stop the capture session.
969 |
970 |
971 |
972 |
973 |
- (void)stopCaptureSession
974 |
975 |
976 |
977 |
978 |
979 |
980 |
981 |
982 |
983 |
984 |
Discussion
985 |
This method is used to stop the receiver’s capture session. This method is asynchronous and runs on a serial background queue owned by the receiver.
986 |
987 |
988 |
989 |
990 |
991 |
992 |
993 |
994 |
995 |
Declared In
996 | BKCameraController.h
997 |
998 |
999 |
1000 |
1001 |
1002 |
1003 |
1004 |
1005 |
1006 |
1007 |
1008 |
1009 |
1010 |
1011 |
1017 |
1026 |
1027 |
1028 |
1119 |
1120 |
--------------------------------------------------------------------------------