demo/TencentCloudDemo/TencentCloudDemo.xcodeproj.demo/OcrSwiftDemo/OcrSwiftDemo.xcodeproj.OcrSDK folder in the left directory tree, and expand Localizable.strings to view multiple language directories:en.lproj/ - Englishzh-Hans.lproj/ - Simplified Chinesezh-Hant.lproj/ - Traditional Chineseid.lproj/ - Indonesian
Localizable.strings file.// Before modification"ocr_cancel"="Cancel";// Change to"ocr_cancel"="Close";
TencentCloudDemo).
Localizable.strings file under the OcrSDK folder.
ja.lproj/) is automatically generated under the OcrSDK directory.Localizable.strings file (the initial content is in English).
OcrSDK.Info.plist file, delete it to avoid affecting App Store review.
.bundle file (such as OcrSDK.bundle) into your project.CustomConfigUI when initializing the SDK:CustomConfigUI *custom = [[CustomConfigUI alloc] init];// Set the path of the custom multilingual bundle.custom.custLanguageBundlePath = [[NSBundle mainBundle] pathForResource:@"CustomOcrSDK" ofType:@"bundle"];// Specify the language file to use.custom.custLanguageFile = @"zh-Hans.lproj";OcrCloudConfig *cloudConfig = [[OcrCloudConfig alloc] init];cloudConfig.customConfigUI = custom;
let custom = CustomConfigUI()// Set the path of the custom multilingual bundle.custom.custLanguageBundlePath = Bundle.main.path(forResource: "CustomOcrSDK", ofType: "bundle")// Specify the language file to use.custom.custLanguageFile = "en.lproj"let cloudConfig = OcrCloudConfig()cloudConfig.customConfigUI = custom
demo/TencentCloudDemo/TencentCloudDemo.xcodeproj.demo/OcrSwiftDemo/OcrSwiftDemo.xcodeproj.

OcrOverseasCustomConfigUI *customUI = [[OcrOverseasCustomConfigUI alloc] init];// Set the path of the custom UI bundle.customUI.custBundlePath = [[NSBundle mainBundle] pathForResource:@"CustOCR" ofType:@"bundle"];OcrCloudConfig *cloudConfig = [[OcrCloudConfig alloc] init];cloudConfig.customConfigUI = customUI;
let customUI = OcrOverseasCustomConfigUI()// Set the path of the custom UI bundle.customUI.custBundlePath = Bundle.main.path(forResource: "CustOCR", ofType: "bundle")let cloudConfig = OcrCloudConfig()cloudConfig.customConfigUI = customUI
OcrOverseasViewDelegate is the core protocol for UI interaction between the SDK and the business party. All methods are @optional, and the SDK uses default behavior when they are not implemented.OcrOverseasCustomConfigUI *customUI = [[OcrOverseasCustomConfigUI alloc] init];customUI.delegate = self; // self conforms to OcrOverseasViewDelegateOcrCloudConfig *cloudConfig = [[OcrCloudConfig alloc] init];cloudConfig.customConfigUI = customUI;
let customUI = OcrOverseasCustomConfigUI()customUI.delegate = self // self conforms to OcrOverseasViewDelegatelet cloudConfig = OcrCloudConfig()cloudConfig.customConfigUI = customUI
authView is the root View of the current recognition page. You can add custom business components (such as a brand Logo or a notification banner) to authView at this point.- (void)onMainViewCreate:(UIView *)authView;
- (void)onMainViewCreate:(UIView *)authView {// Overlay a Logo in the upper right corner of the recognition page.UIImageView *logo = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"brand_logo"]];logo.translatesAutoresizingMaskIntoConstraints = NO;[authView addSubview:logo];[NSLayoutConstraint activateConstraints:@[[logo.topAnchor constraintEqualToAnchor:authView.safeAreaLayoutGuide.topAnchor constant:12],[logo.trailingAnchor constraintEqualToAnchor:authView.trailingAnchor constant:-16],[logo.widthAnchor constraintEqualToConstant:80],[logo.heightAnchor constraintEqualToConstant:30],]];}
onMainViewCreate or release related resources here.- (void)onMainViewDestroy;
- (void)onMainViewDestroy {NSLog(@"OCR page closed");// Clean up custom component references and release resources.}
- (void)onEventParamMap:(NSDictionary *)paramMap;
Key Constant | Type | Description |
TXYOcrSdkEventParamMapCenterMarkRect | NSString (string format of CGRect) | Position and size of the current viewfinder on the screen (CGRect), which can be used to align custom components. |
TXYOcrSdkEventTimeoutStatus | NSString | Countdown status: "start" (countdown starts), "stop" (countdown paused), "end" (timed out) |
TXYOcrSdkEventSwitchToManualMode | Any non-nil value | Switched to manual capture mode. |
- (void)onEventParamMap:(NSDictionary *)paramMap {// Obtain the viewfinder position to align custom prompt components.NSString *rectStr = paramMap[TXYOcrSdkEventParamMapCenterMarkRect];if (rectStr) {CGRect markRect = CGRectFromString(rectStr);// Position the custom component directly below the viewfinder.self.hintLabel.frame = CGRectMake(markRect.origin.x,CGRectGetMaxY(markRect) + 12,markRect.size.width,30);}// Listen for the countdown status.NSString *timeoutStatus = paramMap[TXYOcrSdkEventTimeoutStatus];if ([timeoutStatus isEqualToString:@"start"]) {NSLog(@"Countdown started");} else if ([timeoutStatus isEqualToString:@"end"]) {NSLog(@"Countdown timed out");}}
YES is returned, the SDK does not display the default confirmation dialog, and the business party implements it on their own.- (BOOL)onShowBestFrameConfirmDialog:(NSDictionary *)infoimageView:(UIImageView *)imageViewparentView:(UIView *)parentViewconfirmBlock:(void(^)(void))confirmBlockcancelBlock:(void(^)(void))cancelBlock;
OcrOverseasCustomConfigUI.showBestImgConfirmDialog = YES for this callback to be triggered.Parameter | Description |
info[OcrDialogInfoKeyTitle] | Popup title text (localized according to language settings) |
info[OcrDialogInfoKeyMessage] | Popup description text |
imageView | UIImageView containing the best frame image, which can be directly added to a custom popup for display. |
parentView | Root View of the current recognition page. Add the custom popup to this View. |
confirmBlock | Must be called after user confirmation, and the SDK will continue the upload process. |
cancelBlock | Must be called after user cancellation, and the SDK will restart capture. |
- (BOOL)onShowBestFrameConfirmDialog:(NSDictionary *)infoimageView:(UIImageView *)imageViewparentView:(UIView *)parentViewconfirmBlock:(void(^)(void))confirmBlockcancelBlock:(void(^)(void))cancelBlock {// Build a custom dialog.UIAlertController *alert = [UIAlertControlleralertControllerWithTitle:info[OcrDialogInfoKeyTitle]message:info[OcrDialogInfoKeyMessage]preferredStyle:UIAlertControllerStyleAlert];[alert addAction:[UIAlertAction actionWithTitle:@"Use This Photo"style:UIAlertActionStyleDefaulthandler:^(UIAlertAction *_) {if (confirmBlock) confirmBlock(); // Must be called.}]];[alert addAction:[UIAlertAction actionWithTitle:@"Retake"style:UIAlertActionStyleCancelhandler:^(UIAlertAction *_) {if (cancelBlock) cancelBlock(); // Must be called.}]];// Find the current topmost ViewController to present.UIViewController *topVC = [self topViewController];[topVC presentViewController:alert animated:YES completion:nil];return YES; // Return YES to prevent the SDK from displaying the default dialog.}
YES is returned, the business party displays a custom dialog.- (BOOL)onShowNextSideDialog:(NSDictionary *)infoparentView:(UIView *)parentViewconfirmBlock:(void(^)(void))confirmBlock;
Parameter | Description |
info[OcrDialogInfoKeyTitle] | Popup title |
info[OcrDialogInfoKeyMessage] | Popup description |
parentView | Root View of the current recognition page |
confirmBlock | Must be called after the user clicks Confirm, and the SDK continues the side-switching recognition process. |
- (BOOL)onShowNextSideDialog:(NSDictionary *)infoparentView:(UIView *)parentViewconfirmBlock:(void(^)(void))confirmBlock {UIAlertController *alert = [UIAlertControlleralertControllerWithTitle:info[OcrDialogInfoKeyTitle]message:info[OcrDialogInfoKeyMessage]preferredStyle:UIAlertControllerStyleAlert];[alert addAction:[UIAlertAction actionWithTitle:@"OK"style:UIAlertActionStyleDefaulthandler:^(UIAlertAction *_) {if (confirmBlock) confirmBlock(); // Must be called.}]];[[self topViewController] presentViewController:alert animated:YES completion:nil];return YES;}
OCR_DETECT_AUTO_MANUAL), the SDK calls this method to ask the user whether to switch to manual capture mode. If YES is returned, the business party displays a custom dialog.- (BOOL)onShowChangeModeDialog:(NSDictionary *)infoparentView:(UIView *)parentViewconfirmBlock:(void(^)(void))confirmBlockcancelBlock:(void(^)(void))cancelBlock;
Parameter | Description |
confirmBlock | Called after the user clicks "Switch to Manual". The SDK enters manual capture mode. |
cancelBlock | Called after the user clicks "Continue Waiting". The SDK restarts the countdown. |
- (BOOL)onShowChangeModeDialog:(NSDictionary *)infoparentView:(UIView *)parentViewconfirmBlock:(void(^)(void))confirmBlockcancelBlock:(void(^)(void))cancelBlock {UIAlertController *alert = [UIAlertControlleralertControllerWithTitle:info[OcrDialogInfoKeyTitle]message:info[OcrDialogInfoKeyMessage]preferredStyle:UIAlertControllerStyleAlert];[alert addAction:[UIAlertAction actionWithTitle:@"Switch to Manual"style:UIAlertActionStyleDefaulthandler:^(UIAlertAction *_) {if (confirmBlock) confirmBlock();}]];[alert addAction:[UIAlertAction actionWithTitle:@"Keep Waiting"style:UIAlertActionStyleCancelhandler:^(UIAlertAction *_) {if (cancelBlock) cancelBlock();}]];[[self topViewController] presentViewController:alert animated:YES completion:nil];return YES;}
YES is returned, the business party displays a custom error dialog.- (BOOL)onShowCloudErrorDialog:(NSDictionary *)infoparentView:(UIView *)parentViewretryBlock:(void(^_Nullable)(void))retryBlockexitBlock:(void(^)(void))exitBlock;
Parameter | Description |
info[OcrDialogInfoKeyTitle] | Error dialog title |
info[OcrDialogInfoKeyMessage] | Error description (localized by error code) |
info[OcrDialogInfoKeyErrorCode] | Server error code (NSNumber, for example, @(400101)) |
retryBlock | Called after the user clicks "Retry". When the value is nil, it indicates that the error cannot be retried, and the retry button should not be displayed in the dialog box. |
exitBlock | Called after the user clicks "Exit". The SDK will trigger the failure callback, and one of them must be called. |
- (BOOL)onShowCloudErrorDialog:(NSDictionary *)infoparentView:(UIView *)parentViewretryBlock:(void(^_Nullable)(void))retryBlockexitBlock:(void(^)(void))exitBlock {NSString *title = info[OcrDialogInfoKeyTitle] ?: @"Recognition Failed";NSString *message = info[OcrDialogInfoKeyMessage] ?: @"Please try again.";UIAlertController *alert = [UIAlertControlleralertControllerWithTitle:titlemessage:messagepreferredStyle:UIAlertControllerStyleAlert];// Display the retry button only when retry is available.if (retryBlock) {[alert addAction:[UIAlertAction actionWithTitle:@"Retry"style:UIAlertActionStyleDefaulthandler:^(UIAlertAction *_) {retryBlock();}]];}[alert addAction:[UIAlertAction actionWithTitle:@"Exit"style:UIAlertActionStyleCancelhandler:^(UIAlertAction *_) {exitBlock(); // Must be called.}]];[[self topViewController] presentViewController:alert animated:YES completion:nil];return YES;}
YES is returned, the business party displays a custom permission guide dialog.- (BOOL)onShowCameraPermissionDialog:(NSDictionary *)infoparentView:(UIView *)parentViewsettingsBlock:(void(^)(void))settingsBlockcancelBlock:(void(^)(void))cancelBlock;
Parameter | Description |
settingsBlock | Called after the user clicks "Go to Settings". The SDK automatically redirects to the system settings page. |
cancelBlock | Called after the user clicks "Cancel/Deny". The SDK triggers the failure callback ( TXY_SDK_CAMERA_PERMISSION_ERROR_CODE). |
- (BOOL)onShowCameraPermissionDialog:(NSDictionary *)infoparentView:(UIView *)parentViewsettingsBlock:(void(^)(void))settingsBlockcancelBlock:(void(^)(void))cancelBlock {UIAlertController *alert = [UIAlertControlleralertControllerWithTitle:@"Camera Permission Required"message:@"Please allow camera access in Settings to continue."preferredStyle:UIAlertControllerStyleAlert];[alert addAction:[UIAlertAction actionWithTitle:@"Go to Settings"style:UIAlertActionStyleDefaulthandler:^(UIAlertAction *_) {settingsBlock(); // The SDK automatically redirects to Settings.}]];[alert addAction:[UIAlertAction actionWithTitle:@"Cancel"style:UIAlertActionStyleCancelhandler:^(UIAlertAction *_) {cancelBlock();}]];[[self topViewController] presentViewController:alert animated:YES completion:nil];return YES;}
onShowLoading when a recognition request is submitted or the album is opened, and calls onHideLoading after the request ends. If YES is returned, the SDK does not display the built-in Loading indicator, and the business party takes full control of the Loading UI.- (BOOL)onShowLoading:(NSDictionary *)info parentView:(UIView *)parentView;- (BOOL)onHideLoading:(UIView *)parentView;
Key Constant | Value | Description |
OcrDialogInfoKeyLoadingType | OcrLoadingTypeOcrProcessing("loadingTypeOcrProcessing") | OCR recognition request in progress |
OcrDialogInfoKeyLoadingType | OcrLoadingTypeImagePicking("loadingTypeImagePicking") | Opening album and selecting image in progress |
onShowLoading and onHideLoading must be implemented in pairs. If onShowLoading returns YES but onHideLoading returns NO, the SDK's internal HUD hiding logic will not be executed, which may cause residual Loading.- (BOOL)onShowLoading:(NSDictionary *)info parentView:(UIView *)parentView {// Remove the old Loading indicator to prevent duplicate additions.[[parentView viewWithTag:9527] removeFromSuperview];UIView *container = [[UIView alloc] initWithFrame:parentView.bounds];container.tag = 9527;container.backgroundColor = [UIColor colorWithWhite:0 alpha:0.4];container.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;UIActivityIndicatorView *indicator;if (@available(iOS 13.0, *)) {indicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleLarge];} else {indicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];}indicator.center = container.center;indicator.autoresizingMask = UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin| UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin;[container addSubview:indicator];[indicator startAnimating];[parentView addSubview:container];return YES;}- (BOOL)onHideLoading:(UIView *)parentView {UIView *loading = [parentView viewWithTag:9527];[loading removeFromSuperview];return loading != nil; // Return YES only when Loading exists.}
confirmBlock, cancelBlock, exitBlock, settingsBlock, and others. Otherwise, the SDK flow cannot continue, and the recognition page will be permanently stuck.YES: The business party takes over the UI, and the SDK does not display the default implementation.NO (or do not implement this method): The SDK uses the built-in default UI.parentView is the View of the SDK recognition page. It is recycled immediately after onMainViewDestroy, so do not hold it for a long time outside the callback.Was this page helpful?
You can also Contact sales or Submit a Ticket for help.
Help us improve! Rate your documentation experience in 5 mins.
Feedback