一、说明
今天就和小编一起来制作一个小demo吧。首先,要做一下说明:
- wikitude使用javascript来控制AR的实现,因此,开发者必须要有一定的js基础。
- 在制作demo之前,要获取wikitude的license,获取方式,我已经在初始篇说过了,可以去了解一下。
二、提交自己的识别图和获取wtc文件
- 咱们上传的图片不能是透明的,具体要求,可以在下面的链接中查看,点击进入。
- 上传识别图,点击这里进入。
- ok,准备工作已经完成,开始在Xcode创建工程,上代码。
三、准备工作
- 创建新的工程
- 引入WikitudeSDK.framework,并添加以下框架到工程中:
- Accelerate.framework
- AssetLibrary.framework
- AVFoundation.framework
- CFNetwork.framework
- CoreGraphics.framework
- CoreLocation.framework
- CoreMedia.framework
- CoreMotion.framework
- CoreVideo.framework
- JavaScriptCore.framework
- Foundation.framework
- MediaPlayer.framework
- OpenGLES.framework
- Photos.framework
- QuartzCore.framework
- SafariServices.framework
- Security.framework
- SystemConfiguration.framework
- UIKit.framework
- libc++.tbd
- libz.tbd
- 设置Bulid Setting 中的Other Linker Flags,添加-Objc。
- 在info.plist中设置访问摄像头的描述:Privacy - Camera Usage Description。
- 引入wikitude的识别文件
- 并替换01_ImageRecognition_1_ImageOnTarget/assets 文件下的magazine.wtc为我们自己下载的wtc文件,并重新命名为magazine.wtc.
四、代码实现
通过以上的配置,我们已经配置好了项目,并将自己生成的wtc文件添加到了项目中,下面就进行代码实现。
#import "ViewController.h"
#import
#import
@interface ViewController ( )
@property (nonatomic, strong) WTArchitectView *architectView;
@property (nonatomic, weak) WTNavigation *architectWorldNavigation;
@end
@implementation ViewController
- (void)dealloc
{
//移除所有通知
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
- (void)viewDidLoad {
[super viewDidLoad];
NSError *deviceSupportError = nil;
/***WTArchitectView是现实的视图
@ WTFeature_ImageTracking:使WTArchitectView具有图片追踪的功能
**/
//判断WTArchitectView是否具有图片追踪的功能
if ( [WTArchitectView isDeviceSupportedForRequiredFeatures:WTFeature_ImageTracking error:&deviceSupportError] ) {
self.architectView = [[WTArchitectView alloc] initWithFrame:CGRectZero motionManager:nil];
self.architectView.delegate = self;
self.architectView.debugDelegate = self;
[self.architectView setLicenseKey:"此处是我们下载的license"];
//载入识别文件
NSURL *url=[[NSBundle mainBundle] URLForResource:@"index" withExtension:@"html" subdirectory:@"01_ImageRecognition_1_ImageOnTarget"];
self.architectWorldNavigation = [self.architectView
loadArchitectWorldFromURL:url withRequiredFeatures:WTFeature_ImageTracking];
[[NSNotificationCenter defaultCenter] addObserverForName:UIApplicationDidBecomeActiveNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *note) {
if (self.architectWorldNavigation.wasInterrupted) {
[self.architectView reloadArchitectWorld];
}
[self startWikitudeSDKRendering];
}];
[[NSNotificationCenter defaultCenter] addObserverForName:UIApplicationWillResignActiveNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *note) {
/* Standard WTArchitectView rendering suspension when the application resignes active */
[self stopWikitudeSDKRendering];
}];
/* Standard subview handling using Autolayout */
[self.view addSubview:self.architectView];
self.architectView.translatesAutoresizingMaskIntoConstraints = NO;
NSDictionary *views = NSDictionaryOfVariableBindings(_architectView);
[self.view addConstraints: [NSLayoutConstraint constraintsWithVisualFormat:@"|[_architectView]|" options:0 metrics:nil views:views] ];
[self.view addConstraints: [NSLayoutConstraint constraintsWithVisualFormat:@"V:|[_architectView]|" options:0 metrics:nil views:views] ];
}
else {
NSLog(@"This device is not supported. Show either an alert or use this class method even before presenting the view controller that manages the WTArchitectView. Error: %@", [deviceSupportError localizedDescription]);
}
}
#pragma mark - View Lifecycle
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
self.tabBarItem.title=@"图片";
[ self.tabBarItem setTitleTextAttributes:[NSDictionary dictionaryWithObjectsAndKeys:[UIColor redColor], NSForegroundColorAttributeName, nil] forState:UIControlStateNormal];
[ self.tabBarItem setTitleTextAttributes:[NSDictionary dictionaryWithObjectsAndKeys:[UIColor greenColor], NSForegroundColorAttributeName, nil] forState:UIControlStateSelected];
/* WTArchitectView rendering is started once the view controllers view will appear */
[self startWikitudeSDKRendering];
}
- (void)viewDidDisappear:(BOOL)animated {
[super viewDidDisappear:animated];
/* WTArchitectView rendering is stopped once the view controllers view did disappear */
[self stopWikitudeSDKRendering];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - View Rotation
- (BOOL)shouldAutorotate {
return YES;
}
- (NSUInteger)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskAll;
}
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
/* When the device orientation changes, specify if the WTArchitectView object should rotate as well */
[self.architectView setShouldRotate:YES toInterfaceOrientation:toInterfaceOrientation];
}
#pragma mark - Private Methods
/* Convenience methods to manage WTArchitectView rendering. */
- (void)startWikitudeSDKRendering{
/* To check if the WTArchitectView is currently rendering, the isRunning property can be used */
if ( ![self.architectView isRunning] ) {
/* To start WTArchitectView rendering and control the startup phase, the -start:completion method can be used */
[self.architectView start:^(WTStartupConfiguration *configuration) {
/* Use the configuration object to take control about the WTArchitectView startup phase */
/* You can e.g. start with an active front camera instead of the default back camera */
// configuration.captureDevicePosition = AVCaptureDevicePositionFront;
} completion:^(BOOL isRunning, NSError *error) {
/* The completion block is called right after the internal start method returns.
NOTE: In case some requirements are not given, the WTArchitectView might not be started and returns NO for isRunning.
To determine what caused the problem, the localized error description can be used.
*/
if ( !isRunning ) {
NSLog(@"WTArchitectView could not be started. Reason: %@", [error localizedDescription]);
}
}];
}
}
- (void)stopWikitudeSDKRendering {
/* The stop method is blocking until the rendering and camera access is stopped */
if ( [self.architectView isRunning] ) {
[self.architectView stop];
}
}
/* The WTArchitectView provides two delegates to interact with. */
#pragma mark - Delegation
/* The standard delegate can be used to get information about:
* The Architect World loading progress
* architectsdk:// protocol invocations using document.location inside JavaScript
* Managing view capturing
* Customizing view controller presentation that is triggered from the WTArchitectView
*/
#pragma mark WTArchitectViewDelegate
- (void)architectView:(WTArchitectView *)architectView didFinishLoadArchitectWorldNavigation:(WTNavigation *)navigation {
/* Architect World did finish loading */
NSLog(@"******originalURL=%@\n*****finalURL=%@",navigation.originalURL,navigation.finalURL);
}
- (void)architectView:(WTArchitectView *)architectView didFailToLoadArchitectWorldNavigation:(WTNavigation *)navigation withError:(NSError *)error {
NSLog(@"Architect World from URL '%@' could not be loaded. Reason: %@", navigation.originalURL, [error localizedDescription]);
}
/* The debug delegate can be used to respond to internal issues, e.g. the user declined camera or GPS access.
NOTE: The debug delegate method -architectView:didEncounterInternalWarning is currently not used.
*/
#pragma mark WTArchitectViewDebugDelegate
- (void)architectView:(WTArchitectView *)architectView didEncounterInternalWarning:(WTWarning *)warning {
/* Intentionally Left Blank */
}
- (void)architectView:(WTArchitectView *)architectView didEncounterInternalError:(NSError *)error {
NSLog(@"WTArchitectView encountered an internal error '%@'", [error localizedDescription]);
}
@end
ok,在手机上运行我们的程序,扫描我们自己的识别图,就可以了。
五、结语
本篇只是简单的制作了一个识别图片的demo,熟悉应用的开发流程,在一下篇中,将会对WikitudeSDK的类进行讲解。