iOS如何重新打包静态库,使得模拟器和真机都可以使用(以ZBarSDK为例)

ZBarSDK下载地址:https://github.com/bmorton/ZBarSDK


1、创建工程

导入ZBar的SDK文件。即把ZBarSDK的目录拉入项目,然后选中copy选项

2、添加framework

技术分享

3、添加代码

#import "ZBarSDK.h"
#import "QRCodeGenerator.h"


@interface yxpViewController ()<ZBarReaderDelegate,UIAlertViewDelegate >

@end

@implementation yxpViewController

@synthesize imageview;
@synthesize text;
@synthesize label;


- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization
    }
    return self;
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    [text resignFirstResponder];
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    self.title=@"二维码编辑器";
}

//扫描二维码
- (IBAction)button:(id)sender {
    /*扫描二维码部分:
     导入ZBarSDK文件并引入一下框架
     AVFoundation.framework
     CoreMedia.framework
     CoreVideo.framework
     QuartzCore.framework
     libiconv.dylib
     引入头文件#import “ZBarSDK.h” 即可使用
     当找到条形码时,会执行代理方法
     
     - (void) imagePickerController: (UIImagePickerController*) reader didFinishPickingMediaWithInfo: (NSDictionary*) info
     
     最后读取并显示了条形码的图片和内容。*/
    
    ZBarReaderViewController *reader = [ZBarReaderViewController new];
    reader.readerDelegate = self;
    reader.supportedOrientationsMask = ZBarOrientationMaskAll;
    
    ZBarImageScanner *scanner = reader.scanner;
    
    [scanner setSymbology: ZBAR_I25
                   config: ZBAR_CFG_ENABLE
                       to: 0];
    
    //[self presentModalViewController: reader animated: YES];
    [self presentViewController:reader animated:YES completion:nil];
}

- (IBAction)button2:(id)sender {
    /*字符转二维码
     导入 libqrencode文件
     引入头文件#import "QRCodeGenerator.h" 即可使用
     */
	imageview.image = [QRCodeGenerator qrImageForString:text.text imageSize:imageview.bounds.size.width];
    
}

- (IBAction)Responder:(id)sender {
    //键盘释放
    [text resignFirstResponder];
    
}

//保存照片到本地
- (IBAction)saveImage:(id)sender {
    
    if(imageview.image!=nil)
    {
        UIImage *aImage = imageview.image;
        UIImageWriteToSavedPhotosAlbum(aImage, self, @selector(image:didFinishSavingWithError:contextInfo:), nil);
        
    }
}

- (void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo
{
    
    if (error != NULL) {
        UIAlertView *photoSave = [[UIAlertView alloc] initWithTitle:@"保存出错" message:[NSString stringWithFormat:@"%@",error] delegate:nil cancelButtonTitle:nil otherButtonTitles:nil];
        [photoSave show];
        photoSave = nil;
    }else {
        UIAlertView *photoSave = [[UIAlertView alloc] initWithTitle:@"保存成功" message:nil delegate:nil cancelButtonTitle:nil otherButtonTitles:nil];
        [photoSave show];
        //程序自动完成点击buttonIndex的button 并dismiss 整个alertView的操作
        [photoSave dismissWithClickedButtonIndex:0 animated:YES];
        photoSave = nil;
    }
}

- (void)imagePickerController: (UIImagePickerController*) reader
 didFinishPickingMediaWithInfo: (NSDictionary*) info
{
    id<NSFastEnumeration> results =
    [info objectForKey: ZBarReaderControllerResults];
    ZBarSymbol *symbol = nil;
    for(symbol in results)
        break;
    
    imageview.image =
    [info objectForKey: UIImagePickerControllerOriginalImage];
    
    //[reader dismissModalViewControllerAnimated: YES];
    [reader dismissViewControllerAnimated:YES completion:nil];
    
    //判断是否包含 头'http:'
    NSString *regex = @"http+:[^\\s]*";
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@",regex];
    
    //判断是否包含 头'ssid:'
    NSString *ssid = @"ssid+:[^\\s]*";;
    NSPredicate *ssidPre = [NSPredicate predicateWithFormat:@"SELF MATCHES %@",ssid];
    
    label.text =  symbol.data ;
    
    if ([predicate evaluateWithObject:label.text]) {
        
        UIAlertView * alert = [[UIAlertView alloc]initWithTitle:nil
                                                        message:@"It will use the browser to this URL。"
                                                       delegate:nil
                                              cancelButtonTitle:@"Close"
                                              otherButtonTitles:@"Ok", nil];
        alert.delegate = self;
        alert.tag=1;
        [alert show];
    }
    else if([ssidPre evaluateWithObject:label.text]){
        
        NSArray *arr = [label.text componentsSeparatedByString:@";"];
        
        NSArray * arrInfoHead = [[arr objectAtIndex:0] componentsSeparatedByString:@":"];
        
        NSArray * arrInfoFoot = [[arr objectAtIndex:1] componentsSeparatedByString:@":"];
        
        
        label.text=
        [NSString stringWithFormat:@"ssid: %@ \n password:%@",
         [arrInfoHead objectAtIndex:1],[arrInfoFoot objectAtIndex:1]];
        
        
        UIAlertView * alert = [[UIAlertView alloc]initWithTitle:label.text
                                                        message:@"The password is copied to the clipboard , it will be redirected to the network settings interface"
                                                       delegate:nil
                                              cancelButtonTitle:@"Close"
                                              otherButtonTitles:@"Ok", nil];
        
        
        alert.delegate = self;
        alert.tag=2;
        [alert show];
        
        UIPasteboard *pasteboard=[UIPasteboard generalPasteboard];
        //        然后,可以使用如下代码来把一个字符串放置到剪贴板上:
        pasteboard.string = [arrInfoFoot objectAtIndex:1];
    }
}

4、编译运行

加入真机测试,则可直接运行。如果是模拟器运行,则需要重新打包libzbar.a的静态库。因为,我们下载的库是用于真机的库,如果在模拟器上跑程序,还需重新生成。步骤在下面介绍。

静态包的重新编译

1、添加target

在原来的工程中,选择Xcode工具栏的File->New->Target->iOS/Framework & Library,创建Cocoa Touch Static Library项目。新建的项目同样有XXX和XXXTests目录。XXX目录下还包括XXX.h和XXX.m的头文件。我们此处删除即可。

2、添加ZBarSDK

在Xcode页面下,将刚才下载的ZBarSDK拖拽到刚才创建的XXX目录下,选择copy。

3、设置Architectures和valid Architectures

选择工程目录->TARGETS->XXX->Build Settings,搜索Architectures和valid Architectures,将二者改为arm64、armv7、armv7s,同时设置一下iOS Deployment Target为iOS7.0或更高。

4、设置Schema

选择工程菜单:XXX->Edit Schema->Run->Build Configuration为release。

5、编译

设置上面步骤后,选择XXX,点击不同的模拟器设备,run即可。

6、生成静态库

在Xcode中的Products下找到红色的libber.a右键找到其所在目录。返回上一级。在终端中执行下面命令:
lipo  -create  原libzbar.a目录  -o  新生成libzbar.a目录
到新生成的目录下找到libzbar.a即可。

7、重新导入libzbar.a

将原来的libzbar.a替换为上一步生成的即可。run。成功!

8、可能遇到的部分问题

此部分转载自:http://www.cnblogs.com/ToDoToTry/p/3986366.html

1. zbar下载后使用其libzbar.a 发现无法再arm7上运行。
2. zbar使用过程中,如果多次打开摄像头扫描Qrcode,会出现memory leak problem, 导致其内存指数型增长,大概8次调用后即耗费了85M 左右的内存, 最后导致app崩溃。
3. libzbar.a 在重新编译后, 无法再在simulator中运行,编译链接时出现错误提示:
Undefined symbols for architecture armv7:
  "_OBJC_CLASS_$_ZBarReaderViewController", referenced from:
      objc-class-ref in HelloWorldViewController.o
  "_ZBarReaderControllerResults", referenced from:
      -[HelloWorldViewController imagePickerController:didFinishPickingMediaWithInfo:] in HelloWorldViewController.o
ld: symbol(s) not found for architecture armv7
clang: error: linker command failed with exit code 1 (use -v to see invocation)
 
 
1.libzbar.a无法编译链接成功的问题。
打开zbar.xcodeprj ,在指定的a7 simulator平台或者实机上重新编译,将libzbar.a替换原有的。
 
 
2. mem leak 问题的解决。
找到ZBarReaderViewController.m 修改其loadView方法,改成如下形式。
 
- (void) loadView
{
   self.view = [[[UIView alloc]
                   initWithFrame: CGRectMake (0 , 0 , 320 , 480 )] autorelease ];
}
 
添加了autorelease之后, 其内存使用状况就可以稳定在0.1M的范围内。

9、参考文档:

http://blog.csdn.net/yxiaoping/article/details/39027079

http://blog.csdn.net/remote_roamer/article/details/7657845







郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。