11/08/2018, 23:55

Phân loại QR code

Ở bài trước "Scan QR Code với AVFoundation Framework" tôi đã nói về việc sử dụng AVFoundation để scan (read) QR code. Sau khi scan ta sẽ thu được text của QR Code đó. Ở bài này tôi sẽ tiếp tục công việc từ bài trước, phát triển thêm app như sau: Tuỳ vào text của QR code mà đã thu được, ta sẽ ...

Ở bài trước "Scan QR Code với AVFoundation Framework" tôi đã nói về việc sử dụng AVFoundation để scan (read) QR code. Sau khi scan ta sẽ thu được text của QR Code đó.

Ở bài này tôi sẽ tiếp tục công việc từ bài trước, phát triển thêm app như sau: Tuỳ vào text của QR code mà đã thu được, ta sẽ quyết định hành động tiếp theo như:

  • Link: Open link trên Web browser
  • Telephone Number: Gọi đến số đó hoặc nhắn tin
  • Email: Open Mail và sẵn sàng gửi mail đến
  • Contact: Lưu lại contact
  • Map: open map
  • ...

Như ở bài trước tôi đã sử dụng AVFoundation để đọc QR code, tuy nhiên theo như tìm hiểu của bản thân thì dường như AVFoundation ko hỗ trợ việc phân loại Text QR code mà ta phải làm bằng tay.

Để có thể phân loại được QR code, ta phải nẳm được format của các loại QR code cơ bản như sau:

  • URL: Các ứng dụng phổ biến nhất của QR Code là để mã hóa các văn bản của URL như http://google.com/m. Để làm như vậy, chỉ đơn giản là mã hóa chính xác các văn bản của các URL trong QR Code: http://google.com/m. Bao gồm các giao thức (http: // ở đây) để đảm bảo nó được công nhận là một URL. Tức là nếu url dưới dạng www.sample.org sẽ là ko hợp lệ. vd:

qrcode.28545665.png

  • Email Address: Để mã hóa một địa chỉ e-mail như thevinh1210@gmail.com, một cách đơn giản có thể mã hóa thevinh1210@gmail.com. Tuy nhiên để đảm bảo nó được công nhận là một địa chỉ e-mail, nó được khuyến khích để tạo ra một tiền tố "mailto:" URI từ địa chỉ: mailto: thevinh1210@gmail.com.

qrcode.28545702.png

  • Telephone numbers: tel URI sẽ được sử dụng để mã hóa một số điện thoại, để đảm bảo rằng các chữ số được hiểu là một số điện thoại. Hơn nữa, nó nên được bao gồm các tiền tố mã vùng quốc tế để có thể truy cập quốc tế. Ví dụ, để mã hóa số điện thoại 0912345678, người ta phải mã hóa tel: +84912345678 . Tel này bao gồm một "+84"sẽ làm cho nó có thể sử dụng bên ngoài Việt Nam.

qrcode.28545740.png

  • Map (Geo location): geo URI có thể được sử dụng để mã hóa một điểm trên trái đất, bao gồm độ cao. Format của nó có dạng: geo:lat,long,alt. Ví dụ, để mã hóa văn phòng New York của Google, mà là ở 40,71872 ° N vĩ độ, kinh độ 73,98905 ° W, tại một điểm 100 mét so với văn phòng, người ta sẽ mã hóa "geo: 40,71872, -73.98905,100". 886EL.png

  • Contact: Contact data - sử dụng MeCard, or vCard (chi tiết hơn), e.g.: MECARD:Surname, First;ADR:123 Some St., Town, Zip Code, Country;EMAIL:somename@some_ip.com;TEL:+11800123123;BDAY:19550231;; scoD6.png

Sau khi hiểu hết được về format của QR Code chúng ta sẽ bắt tay vào code. Chúng ta cần thêm 1 button để sau khi đọc được QR Code sẽ call hoặc Go to link hoặc sent mail…

@property (strong, nonatomic) IBOutlet UIButton *actionBtn;
- (IBAction)actionBtnOnCliked:(id)sender;

Trong hàm

-(void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection

Ta thêm dòng sau vào ngay phía dưới dòng đổi _bbitemStart từ “Stop” thành “Start”

[self performSelectorOnMainThread:@selector(checkAndAction:) withObject:[metadataObj stringValue] waitUntilDone:NO];

Trong đó, method “checkAndAction:” với đầu vào là qrCode đọc được sẽ check xem qrCode text thuộc loại gì và đổi title của actionBtn phù hợp theo:

# pragma mark - Classify

-(void)checkAndAction:(NSString *)qrTextContent {
    if ([self isKindOfUrl:qrTextContent]) {
        [_actionBtn setTitle:@"Go" forState:UIControlStateNormal];
        qrType = kUrlType;
    } else if([self isKindOfMail:qrTextContent]) {
        [_actionBtn setTitle:@"Sent Mail" forState:UIControlStateNormal];
        qrType = kMailType;
    } else if([self isKindOfTelNo:qrTextContent]){
        [_actionBtn setTitle:@"Call" forState:UIControlStateNormal];
        qrType = kTelType;
    } else if([self isKindOfGeo:qrTextContent]) {
        [_actionBtn setTitle:@"Go" forState:UIControlStateNormal];
        qrType = kGeoType;
    }
}

-(BOOL)isKindOfUrl:(NSString *)qrTextContent {
    BOOL isUrl = NO;
    NSString* proper = [qrTextContent substringToIndex:4];
    if ([proper isEqualToString:@"http"]) {
        isUrl = YES;
    }
    return isUrl;
}

-(BOOL)isKindOfMail:(NSString *)qrTextContent {
    BOOL isMail = NO;
    NSString* proper = [qrTextContent substringToIndex:5];
    if ([proper isEqualToString:@"mailto"]) {
        isMail = YES;
    }
    return isMail;
}

-(BOOL)isKindOfTelNo:(NSString *)qrTextContent {
    BOOL isTel = NO;
    NSString *proper = [qrTextContent substringToIndex:3];
    if ([proper isEqualToString:@"tel"]) {
        isTel = YES;
    }
    return isTel;
}

-(BOOL)isKindOfGeo:(NSString *)qrTextContent {
    BOOL isGeo = NO;
    NSString *proper = [qrTextContent substringToIndex:3];
    if ([proper isEqualToString:@"geo"]) {
        isGeo = YES;
    }
    return isGeo;
}

- (IBAction)actionBtnOnCliked:(id)sender {
    switch (qrType) {
        case kUrlType:
            [[UIApplication sharedApplication] openURL:[NSURL URLWithString:_lblStatus.text]];
            break;
        case kMailType:
            [[UIApplication sharedApplication] openURL:[NSURL URLWithString:_lblStatus.text]];
            break;
        case kTelType:
        {
            NSString *tel = [_lblStatus.text substringFromIndex:4];
            NSString *phoneNumber = [@"tel://" stringByAppendingString:tel];
            [[UIApplication sharedApplication] openURL:[NSURL URLWithString:phoneNumber]];
            break;
        }
        case kGeoType:
        {
            NSString *latlong = [_lblStatus.text substringFromIndex:4];
            NSString *url = [NSString stringWithFormat: @"http://maps.apple.com/?q=%@",
                             [latlong stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
            [[UIApplication sharedApplication] openURL:[NSURL URLWithString:url]];
            break;
        }

        default:
            break;
    }
}
0