iOS學習——輸入驗證碼界面封裝

来源:https://www.cnblogs.com/mukekeheart/archive/2018/12/19/10142188.html
-Advertisement-
Play Games

在很多App中都有輸入驗證碼的功能需求,最近項目需要也有這個功能。做完之後簡單整理了一下,將實現的基本思路做下記錄。實現後的效果大致如下圖所示,當四位簽到碼全部輸入時,提交按鈕是可以提交的,否則提交按鈕失效,不允許提交。 1 整體佈局 上圖整個界面的佈局很簡單,就不多說了,重點就是中間這一塊的驗證碼 ...


  在很多App中都有輸入驗證碼的功能需求,最近項目需要也有這個功能。做完之後簡單整理了一下,將實現的基本思路做下記錄。實現後的效果大致如下圖所示,當四位簽到碼全部輸入時,提交按鈕是可以提交的,否則提交按鈕失效,不允許提交。

                    

1 整體佈局

   上圖整個界面的佈局很簡單,就不多說了,重點就是中間這一塊的驗證碼輸入功能,我把它單獨封裝拿出來封裝在一個自定義View(KLCodeResignView)里了,下圖是KLCodeResignView佈局的層次結構。

                    

  驗證碼輸入視圖(KLCodeResignView)的最底層用一個透明的UITextField來接收鍵盤的輸入信息,上面則用4個展示視圖(KLCodeView)來分別展示輸入的驗證碼信息,所有的展示視圖(KLCodeView)都放在一個數組中,方便後續的訪問和調用。所以,KLCodeResignView應該向外提供兩個處理入口,驗證碼輸入完成和輸入未完成時的操作入口,併在完成時提供輸入驗證碼信息,這裡我們採用block的方式進行向外提供操作入口。此外,我們還提供了一個可以修改驗證碼位數的入口,調用 initWithCodeBits: 即可設置驗證碼的位數。KLCodeResignView.h以及KLCodeResignView分類的代碼如下:

#import <UIKit/UIKit.h>

NS_ASSUME_NONNULL_BEGIN

typedef void (^CodeResignCompleted)(NSString *content);
typedef void (^CodeResignUnCompleted)(NSString *content);

@interface KLCodeResignView : UIView

@property (copy, nonatomic) CodeResignCompleted codeResignCompleted;
@property (copy, nonatomic) CodeResignUnCompleted codeResignUnCompleted;

- (instancetype) initWithCodeBits:(NSInteger)codeBits;

@end
@interface KLCodeResignView () <UITextFieldDelegate>

@property (strong, nonatomic) UITextField *contentF; //監聽內容輸入
@property (strong, nonatomic) NSArray<KLCodeView *> *codeViewsArr;//展示驗證碼內容的codeView數組
@property (assign, nonatomic) NSInteger currIndex;//當前待輸入的codeView的下標

@property (assign, nonatomic) NSInteger codeBits;//位數

@end

2 註意點

2.1  信息輸入框UITextField

  信息輸入框UITextField是最重要的一部分,佈局在KLCodeResignView的最底層,主要作用是用於接收驗證碼的輸入,但是對應的游標肯定是不能顯示出來的,而且該UITextField不能進行複製、粘貼、選擇等操作。所以信息輸入框contentF的配置如下:

- (UITextField *)contentF {
    if (!_contentF) {
        _contentF = [[UITextField alloc] init];
        //背景顏色和字體顏色都設置為透明的,這樣在界面上就看不到
        _contentF.backgroundColor = [UIColor clearColor];
        _contentF.textColor = [UIColor clearColor];
        _contentF.keyboardType = UIKeyboardTypeNumberPad;//數字鍵盤
        _contentF.returnKeyType = UIReturnKeyDone;//完成
        _contentF.tintColor = [UIColor clearColor];//設置游標的顏色
        _contentF.delegate = self;
    }
    return _contentF;
}

   最後,我們通過添加UITextField的分類來實現屏蔽複製、粘貼、選擇等操作,其實這些都是在UITextField的 - (BOOL)canPerformAction:(SEL)action withSender:(id)sender 進行控制的,返回YES則允許,否則不允許,所以這裡我們不管什麼操作,全部返回NO,這就屏蔽了所有的操作。

@implementation UITextField (ForbiddenSelect)

/*
 該函數控制是否允許 選擇 全選 剪切 f粘貼等功能,可以針對不同功能進行限制
 返回YES表示允許對應的功能,返回NO則表示不允許對應的功能
 直接返回NO則表示不允許任何編輯
 */
- (BOOL)canPerformAction:(SEL)action withSender:(id)sender {
    return NO;
}

@end

 2.2 展示視圖(KLCodeView)

  展示視圖(KLCodeView)就很簡單了,佈局就是一個UILabel在上面,最下麵一個UIView的下劃線,唯一需要考慮的點就是下劃線的顏色問題,如何根據是否有內容進行顏色變化。這個問題的解決也很簡單,因為這個 UILabel的內容是通過一個屬性text來進行設置的,所以我們重寫text的設置方法就OK了,當設置的text內容不為空時,我們就設置對應的顏色為需要的顏色(藍色),否則設置為灰色。

- (void)setText:(NSString *)text {
    if (text.length > 0) {//有數據時設置為藍色
        self.codeLabel.text = [text substringToIndex:1];//只取一位數
        self.lineView.backgroundColor = [UIColor blueColor];
    } else {
        self.codeLabel.text = @"";
        self.lineView.backgroundColor = [UIColor grayColor];
    }
}

2.3 輸入邏輯處理

  輸入處理邏輯就是在輸入和刪除時進內容進行判斷,並將對應的內容顯示到對應的展示視圖(KLCodeView)中,內容的輸入就都在UITextField的代理UITextFieldDelegate中的 - (BOOL)textField: shouldChangeCharactersInRange: replacementString:  方法中。

  • 我們用屬性currIndex來表示當前待輸入的展示視圖KLCodeView的下標,所以,當輸入一個合法的驗證碼時,currIndex要加1,當刪除一個驗證碼時,currIndex要減1,並且當currIndex == 0時,刪除按鈕不起作用,currIndex不再減1了。
  • 如果在驗證碼輸入完成和未完成時做不同的處理,通過我們前面提供的兩個block  codeResignCompleted 和 codeResignUnCompleted 就可以了,我們再這裡通過判斷currIndex 是否等於 self.codeBits,相等則完成,否則沒有完成,並且調用對應的block進行處理。
  • 對輸入內容進行判斷是否是純數字,這個很簡單,判斷方法網上有很多方案,這裡也簡單地貼在下麵的代碼中。
  • 對輸入的字元串的長度進行判斷,如果超過當前位數,則輸入無效。
  • 完成、刪除操作的判斷一定要在是否是純數字以及位數過長判斷之前,否則可能會導致完成、刪除操作失效。
#pragma mark --- UITextField delegate
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
    //完成 則收回鍵盤
    if ([string isEqualToString:@"\n"]) {
        [textField resignFirstResponder];
        return NO;
    }
    //刪除 操作
    if ([string isEqualToString:@""]) {
        if (self.currIndex == 0) {//待輸入的下標為0時 刪除時下標不變化,否則下標減1
            self.codeViewsArr[self.currIndex].text = string;
        } else {
            self.codeViewsArr[--self.currIndex].text = string;
            if (self.codeResignUnCompleted) {
                NSString *content = [textField.text substringToIndex:self.currIndex];
                self.codeResignUnCompleted(content);
            }
        }
        return YES;
    }
    //判斷 輸入的是否是純數字,不是純數字 輸入無效
    if (![self judgePureInt:string]) {
        return NO;
    }
    //如果輸入的內容超過了驗證碼的長度 則輸入無效
    if ((textField.text.length + string.length) > self.codeBits) {
        return NO;
    }
    //輸入的數字,則當前待輸入的下標對應的 view中添加輸入的數字,並且下標加1
    self.codeViewsArr[self.currIndex++].text = string;
    //噹噹前待輸入的下標為codebits時表示已經輸入了對應位數的驗證碼,執行完成操作
    if (self.currIndex == self.codeBits && self.codeResignCompleted) {
        NSString *content = [NSString stringWithFormat:@"%@%@", textField.text, string];
        self.codeResignCompleted(content);
    } else {
        if (self.codeResignUnCompleted) {
            NSString *content = [NSString stringWithFormat:@"%@%@", textField.text, string];
            self.codeResignUnCompleted(content);
        }
    }
    
    return YES;
}
//判斷一個字元串是都是純數字
- (BOOL)judgePureInt:(NSString *)content {
    NSScanner *scan = [NSScanner scannerWithString:content];
    int val;
    return [scan scanInt:&val] && [scan isAtEnd];
}

3 使用

  使用時只需要創建對應的View進行佈局就OK了,然後設置驗證碼輸入完成和驗證碼輸入未完成對應的處理方案。

- (void)viewDidLoad {
    [super viewDidLoad];
    self.view.backgroundColor = [UIColor whiteColor];
    WEAKSELF
    KLCodeResignView *codeView = [[KLCodeResignView alloc] initWithCodeBits:4];
    codeView.codeResignCompleted = ^(NSString * _Nonnull content) {
        //對應位數輸入完成時 允許提交按鈕有效 允許提交
        NSLog(@"%@", content);
        weakSelf.submitBtn.enabled = YES;
        weakSelf.submitBtn.alpha = 1.0f;
    };
    codeView.codeResignUnCompleted = ^(NSString * _Nonnull content) {
        //對應位數未輸入完成時 提交按鈕失效 不允許提交
        weakSelf.submitBtn.enabled = NO;
        weakSelf.submitBtn.alpha = 0.5f;
    };
    [self.view addSubview:codeView];
    
    [codeView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.left.mas_equalTo(weakSelf.view).mas_offset(15.0f);
        make.right.mas_equalTo(weakSelf.view).mas_offset(-15.0f);
        make.top.mas_equalTo(weakSelf.view).mas_offset(100.0f);
        make.height.mas_equalTo(40.0f);
    }];
    
    _submitBtn = [UIButton buttonWithType:UIButtonTypeCustom];
    _submitBtn.titleLabel.font = FONT(17.0f);
    [_submitBtn setTitle:@"提交" forState:UIControlStateNormal];
    [_submitBtn setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
    [_submitBtn setBackgroundColor:XRGB(3d,9a,e8)];
    _submitBtn.enabled = NO;
    _submitBtn.alpha = 0.5f;
    _submitBtn.layer.cornerRadius = 5.0f;
//    [submitBtn addTarget:self action:@selector(submitBtnClicked:) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:_submitBtn];
    [_submitBtn mas_makeConstraints:^(MASConstraintMaker *make) {
        make.left.mas_equalTo(weakSelf.view).mas_offset(20.0f);
        make.right.mas_equalTo(weakSelf.view).mas_offset(-20.0f);
        make.top.mas_equalTo(weakSelf.view).mas_offset(260.0f);
        make.height.mas_equalTo(45.0f);
    }];
}

  所有的代碼如下,主要分為兩個文件,一個 KLCodeResignView.h,一個KLCodeResignView.m,如下:

#import <UIKit/UIKit.h>

NS_ASSUME_NONNULL_BEGIN

typedef void (^CodeResignCompleted)(NSString *content);
typedef void (^CodeResignUnCompleted)(NSString *content);

@interface KLCodeResignView : UIView

@property (copy, nonatomic) CodeResignCompleted codeResignCompleted;
@property (copy, nonatomic) CodeResignUnCompleted codeResignUnCompleted;

- (instancetype) initWithCodeBits:(NSInteger)codeBits;

@end
KLCodeResignView.h
#import "KLCodeResignView.h"

#define WEAKSELF typeof(self) __weak weakSelf = self;
//自定義 驗證碼展示視圖 view,由一個label和一個下劃線組成
@interface KLCodeView : UIView

@property (strong, nonatomic) NSString *text;
@property (strong, nonatomic) UILabel *codeLabel;
@property (strong, nonatomic) UIView *lineView;

@end


@interface KLCodeResignView () <UITextFieldDelegate>

@property (strong, nonatomic) UITextField *contentF; //監聽內容輸入
@property (strong, nonatomic) NSArray<KLCodeView *> *codeViewsArr;//顯示輸入內容的codeView數組
@property (assign, nonatomic) NSInteger currIndex;//當前待輸入的codeView的下標

@property (assign, nonatomic) NSInteger codeBits;//位數

@end

@implementation KLCodeResignView

- (instancetype)initWithCodeBits:(NSInteger)codeBits {
    self = [super init];
    self.backgroundColor = [UIColor whiteColor];
    self.codeBits = codeBits;
    if (self) {
        //驗證碼預設是4位
        if (self.codeBits < 1) {
            self.codeBits = 4;
        }
        WEAKSELF
        [self addSubview:self.contentF];
        [self.contentF mas_makeConstraints:^(MASConstraintMaker *make) {
            make.top.bottom.right.left.mas_equalTo(weakSelf).mas_offset(0.0f);
        }];
        
        for(NSInteger i = 0; i < self.codeBits; i++) {
            KLCodeView *codeView = self.codeViewsArr[i];
            [self addSubview:codeView];
        }
    }
    return self;
}

- (void)layoutSubviews {
    [super layoutSubviews];
    WEAKSELF
    //設定每個數字之間的間距為數字view寬度的一半 總寬度就是 bits + (bits - 1)* 0.5
    CGFloat codeViewWidth = self.bounds.size.width/(self.codeBits * 1.5 - 0.5);
    for(NSInteger i = 0; i < self.codeBits; i++) {
        KLCodeView *codeView = self.codeViewsArr[i];
        [codeView mas_updateConstraints:^(MASConstraintMaker *make) {
            CGFloat left = codeViewWidth * 1.5 * i;
            make.left.mas_equalTo(weakSelf).mas_offset(left);
            make.top.bottom.mas_equalTo(weakSelf).mas_offset(0.0f);
            make.width.mas_equalTo(codeViewWidth);
        }];
    }
}

#pragma mark --- UITextField delegate
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
    //完成 則收回鍵盤
    if ([string isEqualToString:@"\n"]) {
        [textField resignFirstResponder];
        return NO;
    }
    //刪除 操作
    if ([string isEqualToString:@""]) {
        if (self.currIndex == 0) {//待輸入的下標為0時 刪除時下標不變化,否則下標減1
            self.codeViewsArr[self.currIndex].text = string;
        } else {
            self.codeViewsArr[--self.currIndex].text = string;
            if (self.codeResignUnCompleted) {
                NSString *content = [textField.text substringToIndex:self.currIndex];
                self.codeResignUnCompleted(content);
            }
        }
        return YES;
    }
    //判斷 輸入的是否是純數字,不是純數字 輸入無效
    if (![self judgePureInt:string]) {
        return NO;
    }
    //如果輸入的內容超過了驗證碼的長度 則輸入無效
    if ((textField.text.length + string.length) > self.codeBits) {
        return NO;
    }
    //輸入的數字,則當前待輸入的下標對應的 view中添加輸入的數字,並且下標加1
    self.codeViewsArr[self.currIndex++].text = string;
    //噹噹前待輸入的下標為codebits時表示已經輸入了對應位數的驗證碼,執行完成操作
    if (self.currIndex == self.codeBits && self.codeResignCompleted) {
        NSString *content = [NSString stringWithFormat:@"%@%@", textField.text, string];
        self.codeResignCompleted(content);
    } else {
        if (self.codeResignUnCompleted) {
            NSString *content = [NSString stringWithFormat:@"%@%@", textField.text, string];
            self.codeResignUnCompleted(content);
        }
    }
    
    return YES;
}

- (UITextField *)contentF {
    if (!_contentF) {
        _contentF = [[UITextField alloc] init];
        //背景顏色和字體顏色都設置為透明的,這樣在界面上就看不到
        _contentF.backgroundColor = [UIColor clearColor];
        _contentF.textColor = [UIColor clearColor];
        _contentF.keyboardType = UIKeyboardTypeNumberPad;//數字鍵盤
        _contentF.returnKeyType = UIReturnKeyDone;//完成
        _contentF.tintColor = [UIColor clearColor];//設置游標的顏色
        _contentF.delegate = self;
    }
    return _contentF;
}

- (NSArray<KLCodeView *> *)codeViewsArr {
    if (!_codeViewsArr) {
        NSMutableArray *arr = [NSMutableArray array];
        for (NSInteger i = 0; i < self.codeBits; i++) {
            KLCodeView *codeView = [[KLCodeView alloc] init];
            [arr addObject:codeView];
        }
        _codeViewsArr = [NSArray arrayWithArray:arr];
    }
    return _codeViewsArr;
}

//判斷一個字元串是都是純數字
- (BOOL)judgePureInt:(NSString *)content {
    NSScanner *scan = [NSScanner scannerWithString:content];
    int val;
    return [scan scanInt:&val] && [scan isAtEnd];
}

@end


@implementation UITextField (ForbiddenSelect)

/*
 該函數控制是否允許 選擇 全選 剪切 f粘貼等功能,可以針對不同功能進行限制
 返回YES表示允許對應的功能,返回NO則表示不允許對應的功能
 直接返回NO則表示不允許任何編輯
 */
- (BOOL)canPerformAction:(SEL)action withSender:(id)sender {
    return NO;
}

@end


//驗證碼展示視圖 的實現
@implementation KLCodeView

- (instancetype)initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
        WEAKSELF
        self.backgroundColor = [UIColor whiteColor];
        self.userInteractionEnabled = NO;
        //數字編碼 label
        _codeLabel = [[UILabel alloc] init];
        _codeLabel.textColor = [UIColor blueColor];
        _codeLabel.font = FONT(25.0f);
        _codeLabel.textAlignment = NSTextAlignmentCenter;
        [self addSubview:_codeLabel];
        [_codeLabel mas_makeConstraints:^(MASConstraintMaker *make) {
            make.top.left.right.mas_equalTo(weakSelf).mas_offset(0.0f);
            make.bottom.mas_equalTo(weakSelf).mas_offset(-10.0f);
        }];
        
        _lineView = [[UIView alloc] init];
        _lineView.backgroundColor = [UIColor grayColor];
        [self addSubview:_lineView];
        [_lineView mas_makeConstraints:^(MASConstraintMaker *make) {
            make.bottom.left.right.mas_equalTo(weakSelf).mas_offset(0.0f);
            make.height.mas_equalTo(2.0f);
        }];
    }
    return self;
}

- (void)setText:(NSString *)text {
    if (text.length > 0) {
        self.codeLabel.text = [text substringToIndex:1];
        self.lineView.backgroundColor = [UIColor blueColor];
    } else {
        self.codeLabel.text = @"";
        self.lineView.backgroundColor = [UIColor grayColor];
    }
}


@end
KLCodeResignView.m

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 公眾號:SAP Technical 本文作者:matinal 原文出處:http://www.cnblogs.com/SAPmatinal/ 原文鏈接:【HANA系列】SAP HANA XS使用JavaScript數據交互詳解 前言部分 我們都知道web程式都有潛在的安全隱患問題,那麼SAP HAN ...
  • 公眾號:SAP Technical 本文作者:matinal 原文出處:http://www.cnblogs.com/SAPmatinal/ 原文鏈接:【HANA系列】SAP HANA XS使用JavaScript數據交互詳解 前言部分 在第一篇的時候,我們說過如下內容: SAP HANA XS支持 ...
  • 公眾號:SAP Technical 本文作者:matinal 原文出處:http://www.cnblogs.com/SAPmatinal/ 原文鏈接:【HANA系列】SAP HANA XS使用JavaScript數據交互詳解 前言部分 下麵幾篇文章來詳細瞭解一下SAP HANA XS的內容。 HA ...
  • 存儲過程和存儲函數類似於面向對象程式設計語言中的方法,可以簡化代碼,提高代碼的重用性。本文主要介紹如何創建存儲過程和存儲函數,以及存儲過程與函數的使用、修改、刪除等操作。 ...
  • PostgreSQL 流複製監控腳本 https://github.com/AndyYHM/Writing/blob/PostgreSQL/20181219 PostgreSQL%20Stream%20MON.md _整理之前的腳本文檔,搬家至博客園,梳理一下之前寫的shell腳本_ _適用於Pos ...
  • 表分區 從以下幾個方面來整理關於分區表的概念及操作: 1.表空間及分區表的概念 表空間:是一個或多個數據文件的集合,所有的數據對象都存放在指定的表空間中,但主要存放的是表, 所以稱作表空間。 分區表:當表中的數據量不斷增大,查詢數據的速度就會變慢,應用程式的性能就會下降,這時就應該考慮對錶進行分區。 ...
  • 如今每逢一個長假,朋友圈裡的旅游游玩照片就是一批一批的,現在的我們更加喜歡拍照留念,更喜歡把自己的快樂經歷分享給別人,其實方法很簡單,把手機照片視頻投放在電腦或者電視機,大家可以一起觀賞,豈不是兩全其美的事情,iPhone是有鏡像投屏功能的,那麼蘋果手機視頻如何快速的投屏電腦觀看呢? 使用工具: 手 ...
  • (孤山不見蓬萊客,點點星雲落九洲) 什麼是碎片? 碎片(Fragment)是一種可以嵌入在活動當中的UI片段,它能讓程式更加合理和充分地利用大屏幕的空間,因而在平板上應用的非常廣泛。可以把Fragment當成Activity一個界面的一部分,那麼 Activity的界面就由完全不同的Fragment ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...