iOS - QRCode 二维码

简介: 1、QRCode在 iOS7 以前,在 iOS 中实现二维码和条形码扫描,我们所知的有,两大开源组件 ZBar 与 ZXing。iOS7 之后可以利用系统原生 API 生成二维码, iOS8 之后可以生成条形码, 系统默认生成的颜色是黑色。

1、QRCode

  • 在 iOS7 以前,在 iOS 中实现二维码和条形码扫描,我们所知的有,两大开源组件 ZBar 与 ZXing。iOS7 之后可以利用系统原生 API 生成二维码, iOS8 之后可以生成条形码, 系统默认生成的颜色是黑色。

    • 1、ZBar 在扫描的灵敏度上,和内存的使用上相对于 ZXing 上都是较优的,但是对于 “圆角二维码” 的扫描确很困难。
    • 2、ZXing 是 Google Code 上的一个开源的条形码扫描库,是用 java 设计的,连 Google Glass 都在使用的。但有人为了追求更高效率以及可移植性,出现了 c++ port。Github 上的 Objectivc-C port,其实就是用 OC 代码封装了一下而已,而且已经停止维护。这样效率非常低,在 instrument 下面可以看到 CPU 和内存疯涨,在内存小的机器上很容易崩溃。
    • 3、AVFoundation 无论在扫描灵敏度和性能上来说都是最优的,所以毫无疑问我们应该切换到 AVFoundation,需要兼容 iOS 6 或之前的版本可以用 ZBar 或 ZXing 代替。
  • 在 iOS8 + 系统中使用相机需要在 Info.plist 中添加 Privacy - Camera Usage Description,并设置其值。使用相册需要在 Info.plist 中添加 Privacy - Photo Library Usage Description,并设置其值。

    QRCode24

  • 按照下图在 Info.plist 文件中将 Localization native development region 的值改为 China。如果不设置此项弹出的相册页面中显示的按钮等为英文菜单。

    QRCode25

2、系统原生二维码

2.1 扫描二维码

  • 官方提供的接口非常简单,直接看代码,主要使用的是 AVFoundation。

        // 包含头文件
        #import <AVFoundation/AVFoundation.h>
    
        // 遵守协议
        <AVCaptureMetadataOutputObjectsDelegate>
    
        // 输入输出的中间桥梁
        @property (nonatomic, strong) AVCaptureSession *session;
    
        // 扫描窗口
        @property (nonatomic, strong) UIImageView *scanView;
    
        // 创建扫描视图窗口,自定义方法
        - (void)createdScanView {
    
            CGFloat margin = 50;
            CGRect scanFrame = CGRectMake(margin,
                                          margin + 20,
                                          self.view.bounds.size.width - margin * 2,
                                          self.view.bounds.size.width - margin * 2);
    
            self.scanView = [[UIImageView alloc] initWithFrame:scanFrame];
    
            self.scanView.image = [UIImage imageNamed:@"scan_bg2"];
    
            [self.view addSubview:self.scanView];
    
            // 创建扫描
            [self startScan];
        }
    
        // 创建扫描,自定义方法
        - (void)startScan {
    
            // 获取摄像设备
            AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
    
            // 创建输入流
            AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:device error:nil];
    
            // 创建输出流
            AVCaptureMetadataOutput *output = [[AVCaptureMetadataOutput alloc] init];
    
            // 设置代理,在主线程里刷新
            [output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];
    
            // 设置有效扫描区域
            output.rectOfInterest = [self getScanCropWithScanViewFrame:self.scanView.frame readerViewBounds:self.view.bounds];
    
            // 初始化链接对象
            self.session = [[AVCaptureSession alloc] init];
    
            // 设置采集率,高质量
            [self.session setSessionPreset:AVCaptureSessionPresetHigh];
    
            [self.session addInput:input];
            [self.session addOutput:output];
    
            // 设置扫码支持的编码格式(如下设置条形码和二维码兼容)
            output.metadataObjectTypes = @[AVMetadataObjectTypeQRCode,
                                           AVMetadataObjectTypeEAN13Code,
                                           AVMetadataObjectTypeEAN8Code,
                                           AVMetadataObjectTypeCode128Code];
    
            AVCaptureVideoPreviewLayer *layer = [AVCaptureVideoPreviewLayer layerWithSession:self.session];
            layer.videoGravity = AVLayerVideoGravityResizeAspectFill;
            layer.frame = self.view.layer.bounds;
            [self.view.layer insertSublayer:layer atIndex:0];
    
            // 开始捕获
            [self.session startRunning];
        }
    
        // 设置扫描区域的比例关系,自定义方法
        - (CGRect)getScanCropWithScanViewFrame:(CGRect)scanViewFrame readerViewBounds:(CGRect)readerViewBounds {
    
            CGFloat x, y, width, height;
    
            x = scanViewFrame.origin.y / readerViewBounds.size.height;
            y = scanViewFrame.origin.x / readerViewBounds.size.width;
            width = scanViewFrame.size.height / readerViewBounds.size.height;
            height = scanViewFrame.size.width / readerViewBounds.size.width;
    
            return CGRectMake(x, y, width, height);
        }
    
        // 获取扫描结果,AVCaptureMetadataOutputObjectsDelegate 协议方法
        - (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects
                                                                         fromConnection:(AVCaptureConnection *)connection {
    
            if (metadataObjects.count > 0) {
    
                // 停止扫描
                [self.session stopRunning];
    
                AVMetadataMachineReadableCodeObject *metadataObject = [metadataObjects objectAtIndex:0];
    
                // 获取扫描结果
                NSString *resultString = metadataObject.stringValue;
    
                // 输出扫描字符串
                [[[UIAlertView alloc] initWithTitle:@"扫描成功"
                                            message:resultString
                                           delegate:nil
                                  cancelButtonTitle:@"确定"
                                  otherButtonTitles:nil] show];
            }
        }
  • 一些初始化的代码加上实现代理方法便完成了二维码扫描的工作,这里我们需要注意的是,在二维码扫描的时候,我们一般都会在屏幕中间放一个方框,用来显示二维码扫描的大小区间,这里我们在AVCaptureMetadataOutput 类中有一个 rectOfInterest 属性,它的作用就是设置扫描范围。这个 CGRect 参数和普通的 Rect 范围不太一样,它的四个值的范围都是 0-1,表示比例。rectOfInterest 都是按照横屏来计算的,所以当竖屏的情况下 x 轴和 y 轴要交换一下,宽度和高度设置的情况也是类似。

  • 效果

    QRCode10QRCode11

2.2 读取二维码

  • 读取主要用到 CoreImage 不过要强调的是读取二维码的功能只有在 iOS8 之后才支持,我们需要在相册中调用一个二维码,将其读取,代码如下

        // 遵守协议
        <UIImagePickerControllerDelegate, UINavigationControllerDelegate>
    
        // 打开相册,选取图片,自定义方法
        - (void)readQRCode {
    
            if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypePhotoLibrary]) {
    
                // 初始化相册拾取器
                UIImagePickerController *picker = [[UIImagePickerController alloc] init];
    
                // 设置资源
                picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
    
                // 设置代理
                picker.delegate = self;
    
                [self presentViewController:picker animated:YES completion:nil];
    
            } else {
    
                NSString *errorStr = [NSString stringWithFormat:@"请在系统设置->隐私->照片中允许 \"%@\" 使用照片。",
                                      [[[NSBundle mainBundle] infoDictionary] objectForKey:(NSString *)kCFBundleNameKey]];
    
                [[[UIAlertView alloc] initWithTitle:@"读取失败"
                                            message:errorStr
                                           delegate:nil
                                  cancelButtonTitle:@"确定"
                                  otherButtonTitles:nil] show];
            }
        }
    
        // 获取选中的图片,imagePickerController 协议方法
        - (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
    
            // 获取选择的图片
            UIImage *image = info[UIImagePickerControllerOriginalImage];
    
            // 识别图片中的二维码
            NSString *resultString = [self recognizeQRCodeFromImage:image];
    
            // 输出扫描字符串
            [[[UIAlertView alloc] initWithTitle:@"读取成功"
                                        message:resultString
                                       delegate:nil
                              cancelButtonTitle:@"确定"
                              otherButtonTitles:nil] show];
    
            // 返回
            [picker dismissViewControllerAnimated:YES completion:nil];
        }
    
        // 识别图片中的二维码
        - (NSString *)recognizeQRCodeFromImage:(UIImage *)image {
    
            CIImage *ciImage = [CIImage imageWithCGImage:image.CGImage];
    
            // 初始化扫描仪,设置识别类型和识别质量
            CIDetector *detector = [CIDetector detectorOfType:CIDetectorTypeQRCode
                                                      context:nil
                                                      options:@{CIDetectorAccuracy: CIDetectorAccuracyHigh}];
    
            // 扫描获取的特征组
            NSArray *features = [detector featuresInImage:ciImage];
    
            if (features.count >= 1) {
    
                // 获取扫描结果
                CIQRCodeFeature *feature = [features objectAtIndex:0];
                NSString *resultString = feature.messageString;
    
                return resultString;
    
            } else {
    
                return @"该图片不包含二维码";
            }
        }
  • 效果

    QRCode12QRCode13

2.3 长按识别二维码

  • 这个功能有很多的地方在用,最让人熟知的我想便是微信了,其实实现方法还是很简单的。

        // 创建图片,添加长按手势
        - (void)recognizeQRCode {
    
            CGFloat margin = 50;
            CGRect scanFrame = CGRectMake(margin,
                                          margin + 20,
                                          self.view.bounds.size.width - margin * 2,
                                          self.view.bounds.size.width - margin * 2);
    
            UIImageView *imageView = [[UIImageView alloc] initWithFrame:scanFrame];
            imageView.image = [UIImage imageNamed:@"demo"];
    
            imageView.userInteractionEnabled = YES;
    
            [self.view addSubview:imageView];
    
            UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self 
                                                                                                    action:@selector(dealLongPress:)];
            [imageView addGestureRecognizer:longPress];
        }
    
        // 处理长按手势,识别图片中的二维码
        - (void)dealLongPress:(UIGestureRecognizer *)gesture {
    
            if (gesture.state == UIGestureRecognizerStateBegan) {
    
                UIImageView *pressedImageView = (UIImageView *)gesture.view;
    
                if (pressedImageView.image) {
    
                    // 识别图片中的二维码
                    NSString *resultString = [self recognizeQRCodeFromImage:pressedImageView.image];
    
                    // 输出扫描字符串
                    [[[UIAlertView alloc] initWithTitle:@"识别成功"
                                                message:resultString
                                               delegate:nil
                                      cancelButtonTitle:@"确定"
                                      otherButtonTitles:nil] show];
    
                } else {
                    [[[UIAlertView alloc] initWithTitle:@"识别失败"
                                                message:@"该图片不包含二维码"
                                               delegate:nil
                                      cancelButtonTitle:@"确定"
                                      otherButtonTitles:nil] show];
                }
            }
        }
    
        // 识别图片中的二维码
        - (NSString *)recognizeQRCodeFromImage:(UIImage *)image {
    
            CIImage *ciImage = [CIImage imageWithCGImage:image.CGImage];
    
            // 初始化扫描仪,设置识别类型和识别质量
            CIDetector *detector = [CIDetector detectorOfType:CIDetectorTypeQRCode
                                                      context:nil
                                                      options:@{CIDetectorAccuracy: CIDetectorAccuracyHigh}];
    
            // 扫描获取的特征组
            NSArray *features = [detector featuresInImage:ciImage];
    
            if (features.count >= 1) {
    
                // 获取扫描结果
                CIQRCodeFeature *feature = [features objectAtIndex:0];
                NSString *resultString = feature.messageString;
    
                return resultString;
    
            } else {
    
                return @"该图片不包含二维码";
            }
        }
  • 效果

    QRCode14QRCode15

2.4 生成二维码

  • 生成二维码,其实也是用到 CoreImage,但是步骤繁琐一些,代码如下

        // 创建 ImageView,存放生成的二维码
        - (void)createQRCode {
    
            CGFloat margin = 50;
            CGRect frame = CGRectMake(margin,
                                      margin + 20,
                                      self.view.bounds.size.width - margin * 2,
                                      self.view.bounds.size.width - margin * 2);
    
            UIImageView *imageView = [[UIImageView alloc] initWithFrame:frame];
            [self.view addSubview:imageView];
    
            // 生成二维码
            [self createQRCodeToImageView:imageView
                               fromString:@"qianchia"
                                 withIcon:[UIImage imageNamed:@"demo1"]
                                withColor:[UIColor redColor]];
        }
    
        // 生成二维码
        - (void)createQRCodeToImageView:(UIImageView *)imageView
                             fromString:(NSString *)inputString
                               withIcon:(UIImage *)icon
                              withColor:(UIColor *)color {
    
            // 创建过滤器
            CIFilter *filter = [CIFilter filterWithName:@"CIQRCodeGenerator"];
    
            // 恢复默认
            [filter setDefaults];
    
            // 给过滤器添加数据
            NSData *data = [inputString dataUsingEncoding:NSUTF8StringEncoding];
    
            // 通过 KVO 设置滤镜 inputMessage 数据
            [filter setValue:data forKey:@"inputMessage"];
    
            // 设置二维码颜色
            UIColor *onColor = color ? : [UIColor blackColor];
            UIColor *offColor = [UIColor whiteColor];
    
            CIFilter *colorFilter = [CIFilter filterWithName:@"CIFalseColor"
                                               keysAndValues:@"inputImage", filter.outputImage,
                                                             @"inputColor0", [CIColor colorWithCGColor:onColor.CGColor],
                                                             @"inputColor1", [CIColor colorWithCGColor:offColor.CGColor],
                                                             nil];
    
            // 获取输出的二维码
            CIImage *outputImage = colorFilter.outputImage;
            // CIImage *outputImage = [filter outputImage];
    
            CIContext *context = [CIContext contextWithOptions:nil];
            CGImageRef cgImage = [context createCGImage:outputImage
                                               fromRect:[outputImage extent]];
    
            // 将 CIImage 转换成 UIImage,并放大显示
            UIImage *qrImage = [UIImage imageWithCGImage:cgImage
                                                 scale:1.0
                                           orientation:UIImageOrientationUp];
    
            // 重绘 UIImage,默认情况下生成的图片比较模糊
            CGFloat scale = 100;
            CGFloat width = qrImage.size.width * scale;
            CGFloat height = qrImage.size.height * scale;
    
            UIGraphicsBeginImageContext(CGSizeMake(width, height));
            CGContextRef context1 = UIGraphicsGetCurrentContext();
            CGContextSetInterpolationQuality(context1, kCGInterpolationNone);
            [qrImage drawInRect:CGRectMake(0, 0, width, height)];
            qrImage = UIGraphicsGetImageFromCurrentImageContext();
            UIGraphicsEndImageContext();
            CGImageRelease(cgImage);
    
            // 添加头像
    
            if (icon) {
                UIGraphicsBeginImageContext(qrImage.size);
                [qrImage drawInRect:CGRectMake(0, 0, qrImage.size.width, qrImage.size.height)];
    
                // 设置头像大小
                CGFloat scale = 5;
                CGFloat width = qrImage.size.width / scale;
                CGFloat height = qrImage.size.height / scale;
                CGFloat x = (qrImage.size.width - width) / 2;
                CGFloat y = (qrImage.size.height - height) / 2;
                [icon drawInRect:CGRectMake( x,  y, width, height)];
    
                UIImage *newImage =  UIGraphicsGetImageFromCurrentImageContext();
                UIGraphicsEndImageContext();
    
                imageView.image = newImage;
    
            } else {
                imageView.image = qrImage;
            }
        }
  • 效果

    QRCode16QRCode17

2.5 对原生二维码的封装

  • 具体实现代码见 GitHub 源码 QExtension

        // 包含头文件
        #import "QExtension.h"
  • 扫描/识别二维码

        // 创建二维码扫描视图控制器
        QQRCode *qrCode = [QQRCode q_qrCodeWithResult:^(BOOL isSucceed, NSString *result) {
    
            if (isSucceed) {
    
                [[[UIAlertView alloc] initWithTitle:@"Succeed"
                                            message:result
                                           delegate:nil
                                  cancelButtonTitle:@"确定"
                                  otherButtonTitles:nil] show];
    
            } else {
    
                [[[UIAlertView alloc] initWithTitle:@"Failed"
                                            message:result
                                           delegate:nil
                                  cancelButtonTitle:@"确定"
                                  otherButtonTitles:nil] show];
            }
        }];
    
        // 设置我的二维码信息
        qrCode.myQRCodeInfo = @"http://weixin.qq.com/r/xUqbg1-ENgJJrRvg9x-X";
        qrCode.headIcon = [UIImage imageNamed:@"demo6"];
    
        // 打开扫描视图控制器
        [self presentViewController:qrCode animated:YES completion:nil];
    • 效果

      QRCode18QRCode19

      QRCode20QRCode21

  • 识别二维码

        // 创建图片,添加长按手势
        self.imageView.image = [UIImage imageNamed:@"demo4"];
    
        UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(dealLongPress:)];
        [self.imageView addGestureRecognizer:longPress];
    
        // 处理长按手势,识别图片中的二维码
        - (void)dealLongPress:(UIGestureRecognizer *)gesture {
    
            if (gesture.state == UIGestureRecognizerStateBegan) {
    
                UIImageView *pressedImageView = (UIImageView *)gesture.view;
                UIImage *image = pressedImageView.image;
    
                // 识别图片中的二维码
                NSString *result = [image q_stringByRecognizeQRCode];
    
                [[[UIAlertView alloc] initWithTitle:@"Succeed"
                                            message:result
                                           delegate:nil
                                  cancelButtonTitle:@"确定"
                                  otherButtonTitles:nil] show];
            }
        }
    • 效果

      QRCode23

  • 生成二维码

        // 生成普通的二维码
        UIImage *qrImage = [UIImage q_imageWithQRCodeFromString:@"http://weixin.qq.com/r/xUqbg1-ENgJJrRvg9x-X"
                                                       headIcon:nil
                                                          color:nil
                                                      backColor:nil];
    
        // 生成带头像的二维码
        UIImage *qrImage = [UIImage q_imageWithQRCodeFromString:@"http://weixin.qq.com/r/xUqbg1-ENgJJrRvg9x-X"
                                                       headIcon:[UIImage imageNamed:@"demo6"]
                                                          color:[UIColor blackColor]
                                                      backColor:[UIColor whiteColor]];
    
        // 生成指定图片大小的二维码
        UIImage *qrImage = [UIImage q_imageWithQRCodeFromString:@"http://weixin.qq.com/r/xUqbg1-ENgJJrRvg9x-X"
                                                      imageSize:CGSizeMake(2048, 2048)
                                                       headIcon:[UIImage imageNamed:@"demo6"]
                                                      headFrame:CGRectMake(819, 819, 410, 410)
                                                          color:nil
                                                      backColor:nil];
    • 效果

      QRCode28QRCode22

2.6 对原生条形码的封装

  • 具体实现代码见 GitHub 源码 QExtension

        // 包含头文件
        #import "QExtension.h"
  • 扫描条形码

    • 同上面 2.5 的 "扫描/识别二维码"。
  • 生成条形码

    
        // 生成条形码
        UIImage *qrImage = [UIImage q_imageWithBarCodeFromString:@"cnblogs: QianChia"
                                                           color:nil
                                                       backColor:nil];
    
        // 生成指定图片大小的条形码
        UIImage *qrImage = [UIImage q_imageWithBarCodeFromString:@"cnblogs: QianChia"
                                                       imageSize:CGSizeMake(1024, 512)
                                                           color:[UIColor blueColor]
                                                       backColor:[UIColor redColor]];
    
    • 效果

      QRCode26QRCode27

3、ZBarSDK 二维码使用

  • 使用 ZBarSDK,可以扫描条形码和二维码。

  • 配置

    • 1、添加 SDK 的依赖库和框架。在 项目设置 => TARGETS => Build Phases => Link Binary With Libraries 中依次添加以下库或框架:

          AVFoundation.framework
          CoreMedia.framework
          CoreVideo.framework
          QuartzCore.framework
          libiconv.tbd

      QRCode1

    • 2、由于 ZBarSDK 不支持 Bitcode,需要在 Xcode 的项目设置 => TARGETS => Build Settings => Build Options => Enable Bitcode 的值设置为 NO,否则无法进行真机调试。

      QRCode2

    • 3、在 iOS8 + 系统中使用相机需要在 Info.plist 中添加 Privacy - Camera Usage Description,并设置其值。

      QRCode3

    • 4、在需要使用 ZBarSDK 的文件中

          // 包含头文件
          #import "ZBarSDK.h"
      
          // 遵守协议
          <ZBarReaderViewDelegate>
  • 创建扫描

        // 声明扫描视图
        @property (nonatomic, strong) ZBarReaderView *scanView;
    
        // 实例化扫描视图
        self.scanView = [[ZBarReaderView alloc] init];
    
        // 设置扫描视图的位置尺寸
        float width = self.view.bounds.size.width - 40;
        self.scanView.frame = CGRectMake(20, 30, width, width);
    
        // 设置代理人
        self.scanView.readerDelegate = self;
    
        // 添加扫描视图
        [self.view addSubview:self.scanView];
    
        // 关闭闪光灯
        self.scanView.torchMode = 0;
    
        // 开始扫描
        [self.scanView start];
  • 获取扫描结果

        // ZBarReaderViewDelegate 协议方法
        - (void)readerView:(ZBarReaderView *)readerView didReadSymbols:(ZBarSymbolSet *)symbols fromImage:(UIImage *)image {
    
            for (ZBarSymbol *symbol in symbols) {
    
                // 获取扫描结果
                NSString *scanString = symbol.data;
    
                // 显示扫描结果
                self.scanResult.text = scanString;
            }
    
            // 停止扫描
            [self.scanView stop];
        }
  • 效果

    QRCode6QRCode7

4、ZCZBarSDK 二维码使用

  • 使用 ZCZBarSDK,可以扫描条形码和二维码。

  • 配置

    • 1、添加 SDK 的依赖库和框架。在 项目设置 => TARGETS => Build Phases => Link Binary With Libraries 中依次添加以下库或框架:

          libiconv.tbd

      QRCode4

    • 2、由于 ZCZBarSDK 不支持 Bitcode,需要在 Xcode 的项目设置 => TARGETS => Build Settings => Build Options => Enable Bitcode 的值设置为 NO,否则无法进行真机调试。

      QRCode2

    • 3、在 iOS8 + 系统中使用相机需要在 Info.plist 中添加 Privacy - Camera Usage Description,并设置其值。使用相册需要在 Info.plist 中添加 Privacy - Photo Library Usage Description,并设置其值。

      QRCode5

    • 4、在需要使用 ZCZBarSDK 的文件中

          // 包含头文件
          #import "ZCZBarViewController.h"
  • 生成二维码

        // 将字符串 self.detailTF.text 中的内容生成的二维码存放到 ImageView(self.codeImageView)中。
    
        if (self.detailTF.text.length != 0) {
    
            [ZCZBarViewController createImageWithImageView:self.codeImageView String:self.detailTF.text Scale:100];
        }
  • 扫描二维码

        // isQRCode: 是否关闭条形码扫描,专门扫描二维码。
    
        ZCZBarViewController *zzvc = [[ZCZBarViewController alloc] initWithIsQRCode:NO Block:^(NSString *result, BOOL isSucceed) {
    
            if (isSucceed) {
    
                self.scanResult.text = [NSString stringWithFormat:@"%@", result];
            }
        }];
    
        // 打开扫描视图控制器
        [self presentViewController:zzvc animated:YES completion:nil];
  • 效果

    QRCode8QRCode9

目录
相关文章
|
iOS开发
iOS QRCode(二维码)
实现思路 输入设备(用来获取外界信息) 摄像头, 麦克风, 键盘 输出设备 (将收集到的信息, 做解析, 来获取收到的内容) 会话session (用来连接输入和输出设备) 特殊的layer (展示输入设备所采集的信息) 1.
884 0
|
iOS开发
IOS创建二维码
IOS创建二维码
94 0
|
4天前
|
JavaScript 搜索推荐 Android开发
【01】仿站技术之python技术,看完学会再也不用去购买收费工具了-用python扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-客户的麻将软件需要下载落地页并且要做搜索引擎推广-本文用python语言快速开发爬取落地页下载-优雅草卓伊凡
【01】仿站技术之python技术,看完学会再也不用去购买收费工具了-用python扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-客户的麻将软件需要下载落地页并且要做搜索引擎推广-本文用python语言快速开发爬取落地页下载-优雅草卓伊凡
23 8
【01】仿站技术之python技术,看完学会再也不用去购买收费工具了-用python扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-客户的麻将软件需要下载落地页并且要做搜索引擎推广-本文用python语言快速开发爬取落地页下载-优雅草卓伊凡
|
1月前
|
iOS开发 开发者
uniapp开发ios打包Error code = -5000 Error message: Error: certificate file(p12) import failed!报错问题如何解决
uniapp开发ios打包Error code = -5000 Error message: Error: certificate file(p12) import failed!报错问题如何解决
143 67
uniapp开发ios打包Error code = -5000 Error message: Error: certificate file(p12) import failed!报错问题如何解决
|
2月前
|
存储 监控 API
app开发之安卓Android+苹果ios打包所有权限对应解释列表【长期更新】-以及默认打包自动添加权限列表和简化后的基本打包权限列表以uniapp为例-优雅草央千澈
app开发之安卓Android+苹果ios打包所有权限对应解释列表【长期更新】-以及默认打包自动添加权限列表和简化后的基本打包权限列表以uniapp为例-优雅草央千澈
90 11
|
2月前
|
iOS开发 开发者 MacOS
深入探索iOS开发中的SwiftUI框架
【10月更文挑战第21天】 本文将带领读者深入了解Apple最新推出的SwiftUI框架,这一革命性的用户界面构建工具为iOS开发者提供了一种声明式、高效且直观的方式来创建复杂的用户界面。通过分析SwiftUI的核心概念、主要特性以及在实际项目中的应用示例,我们将展示如何利用SwiftUI简化UI代码,提高开发效率,并保持应用程序的高性能和响应性。无论你是iOS开发的新手还是有经验的开发者,本文都将为你提供宝贵的见解和实用的指导。
143 66
|
2月前
|
开发框架 Android开发 iOS开发
安卓与iOS开发中的跨平台策略:一次编码,多平台部署
在移动应用开发的广阔天地中,安卓和iOS两大阵营各占一方。随着技术的发展,跨平台开发框架应运而生,它们承诺着“一次编码,到处运行”的便捷。本文将深入探讨跨平台开发的现状、挑战以及未来趋势,同时通过代码示例揭示跨平台工具的实际运用。
173 3
|
2月前
|
Java 调度 Android开发
安卓与iOS开发中的线程管理差异解析
在移动应用开发的广阔天地中,安卓和iOS两大平台各自拥有独特的魅力。如同东西方文化的差异,它们在处理多线程任务时也展现出不同的哲学。本文将带你穿梭于这两个平台之间,比较它们在线程管理上的核心理念、实现方式及性能考量,助你成为跨平台的编程高手。
|
3月前
|
存储 前端开发 Swift
探索iOS开发:从新手到专家的旅程
本文将带您领略iOS开发的奇妙之旅,从基础概念的理解到高级技巧的掌握,逐步深入iOS的世界。文章不仅分享技术知识,还鼓励读者在编程之路上保持好奇心和创新精神,实现个人成长与技术突破。

热门文章

最新文章

  • 1
    Cellebrite UFED 4PC 7.71 (Windows) - Android 和 iOS 移动设备取证软件
    24
  • 2
    【03】仿站技术之python技术,看完学会再也不用去购买收费工具了-修改整体页面做好安卓下载发给客户-并且开始提交网站公安备案-作为APP下载落地页文娱产品一定要备案-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
    32
  • 3
    【02】仿站技术之python技术,看完学会再也不用去购买收费工具了-本次找了小影-感觉页面很好看-本次是爬取vue需要用到Puppeteer库用node.js扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
    27
  • 4
    【01】仿站技术之python技术,看完学会再也不用去购买收费工具了-用python扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-客户的麻将软件需要下载落地页并且要做搜索引擎推广-本文用python语言快速开发爬取落地页下载-优雅草卓伊凡
    23
  • 5
    uniapp开发ios打包Error code = -5000 Error message: Error: certificate file(p12) import failed!报错问题如何解决
    143
  • 6
    【05】2025年1月首发完整版-篇幅较长-苹果app如何上架到app store完整流程·不借助第三方上架工具的情况下无需花钱但需仔细学习-优雅草央千澈详解关于APP签名以及分发-们最关心的一篇来了-IOS上架app
    232
  • 7
    app开发之安卓Android+苹果ios打包所有权限对应解释列表【长期更新】-以及默认打包自动添加权限列表和简化后的基本打包权限列表以uniapp为例-优雅草央千澈
    90
  • 8
    深入探索iOS开发中的SwiftUI框架
    143
  • 9
    ios样式开关按钮jQuery插件
    58
  • 10
    Android与iOS生态差异深度剖析:技术架构、开发体验与市场影响####
    75