之前写了一个本地数据库版本 戳这里

现在这个就是增加了后台 登录注册页面以及web的上传记录展示页面

含有少量php有兴趣可以看下

另外demo中包括数据库操作、json、网络请求等都没有用到第三方库,所以网络方面的逻辑可能有所欠缺,大神请轻拍。

效果

分析

很简单的分析把大致需要编写的模块列出

客户端部分

分析

  • 与本地版的demo相比主要是多了服务器请求操作

新增数据库内容:

  • Users表

    与Tally表关系:一对多



    相反Tally与Users的关系就是:一对多

  • flag字段 决定是否上传

  • 需要发送请求的位置

  • 登录
  • 注册
  • 登录成功后第一次加载
  • 新增账单
  • 修改账单
  • 删除账单

代码

登录

登录时向服务器发送用户名和密码,当然只有两个结果:未注册 和 密码错误

#import "LoginViewController.h"

@interface LoginViewController ()<ServerOperationsDelegate>
@property (weak, nonatomic) IBOutlet UITextField *userNameField;
@property (weak, nonatomic) IBOutlet UITextField *userPswField; @end @implementation LoginViewController - (void)viewDidLoad {
    [super viewDidLoad];
    self.title = @"登录";
    [[CoreDataOperations sharedInstance] loadTallyTypeToSqlite];
    // Do any additional setup after loading the view.
} - (void)viewWillAppear:(BOOL)animated{
    self.userNameField.text = [[NSUserDefaults standardUserDefaults] objectForKey:@"userName"];
    self.userPswField.text = nil;
} - (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}
//去注册
- (IBAction)clickRegister:(id)sender {
    [self.userPswField resignFirstResponder];
    [self.userPswField resignFirstResponder];
} //输入检查 6-20为正常字符
- (BOOL)inputCheck:(NSString*)passWord{
    NSString *passWordRegex = @"^[a-zA-Z0-9]{6,20}+$";
    NSPredicate *passWordPredicate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@",passWordRegex];
    return [passWordPredicate evaluateWithObject:passWord];
    
} //去登录
- (IBAction)clickLogin:(id)sender {
    
    //输入检查
    BOOL userNameCheck = [self inputCheck:self.userNameField.text];
    BOOL userPswCheck = [self inputCheck:self.userPswField.text];
    if (!userNameCheck | !userPswCheck) {
        [self showAlertInfoWithTag:999 andMessage:@"用户名或密码出错\n请输入6-20位合法字符"];
        return;
    }
    //键盘收起
    [self.userPswField resignFirstResponder];
    [self.userNameField resignFirstResponder];
    
    ServerOperations *op = [ServerOperations sharedInstance];
    op.delegate = self;
    [op loginWithUser:self.userNameField.text andPsw:self.userPswField.text];
} //登录结果
- (void)didLoginBackWithTag:(int)tag{
    [self loginAlertWithReslut:tag];
} //验证登录
- (void)loginAlertWithReslut:(int)result{
    switch (result) {
        case 0:
            //连接远程数据库失败
            [self showAlertInfoWithTag:result andMessage:@"连接远程数据库失败"];
            break;
        case 1:
            //验证成功
            [self performSegueWithIdentifier:@"toHome" sender:nil];
            break;
        case 2:
            //密码错误
            [self showAlertInfoWithTag:result andMessage:@"密码错误"];
            break;
        case 3:
            //用户不存在
            [self showAlertInfoWithTag:result andMessage:@"用户名不存在\n请注册"];
            break;
        default:
            break;
    }
} //弹出提示框
- (void)showAlertInfoWithTag:(int)tag andMessage:(NSString*)message {
    UIAlertController *alertVC =[UIAlertController alertControllerWithTitle:@"提示" message:message preferredStyle:UIAlertControllerStyleAlert];
    [alertVC addAction:[UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:nil]];
    if (tag == 3) {
        [alertVC addAction:[UIAlertAction actionWithTitle:@"注册" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
            [self performSegueWithIdentifier:@"toRegister" sender:nil];
        }]];
    }
    [self presentViewController:alertVC animated:YES completion:nil];
} -(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
    NSLog(@"准备push");
    //本地保存用户名
    [[NSUserDefaults standardUserDefaults] setBool:NO forKey:@"isLoaded"];
    [[NSUserDefaults standardUserDefaults] setObject:self.userNameField.text forKey:@"userName"];
    
}
@end

注册

注册也很简单,发送注册信息给服务器,服务器判断下用户名是否存在就行。

#import "RegisterViewController.h"

@interface RegisterViewController ()<ServerOperationsDelegate>
@property (weak, nonatomic) IBOutlet UITextField *userNameField;
@property (weak, nonatomic) IBOutlet UITextField *userPswField; @end @implementation RegisterViewController - (void)viewDidLoad {
    [super viewDidLoad];
    self.title = @"注册";
} - (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
} //输入检查 6-20为正常字符
- (BOOL)inputCheck:(NSString*)passWord{
    NSString *passWordRegex = @"^[a-zA-Z0-9]{6,20}+$";
    NSPredicate *passWordPredicate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@",passWordRegex];
    return [passWordPredicate evaluateWithObject:passWord];
    
} - (void)didRegisterBackWithTag:(int)tag{
    [self loginAlertWithReslut:tag];
} //提交注册
- (IBAction)clickRegister:(id)sender {
    
    //输入检查
    BOOL userNameCheck = [self inputCheck:self.userNameField.text];
    BOOL userPswCheck = [self inputCheck:self.userPswField.text];
    if (!userNameCheck | !userPswCheck) {
        [self showAlertInfoWithTag:0 andMessage:@"用户名或密码出错\n请输入6-20位合法字符"];
        return;
    }
    
    //取消键盘响应
    [self.userNameField resignFirstResponder];
    [self.userPswField resignFirstResponder];     ServerOperations *ops = [ServerOperations sharedInstance];
    ops.delegate = self;
    [ops registerWithUser:self.userNameField.text andPsw:self.userPswField.text];
} //登录提示
- (void)loginAlertWithReslut:(int)result{
    switch (result) {
        case 0:
            //连接远程数据库失败
            [self showAlertInfoWithTag:0 andMessage:@"连接远程数据库失败"];
            break;
        case 1:
            //注册成功
            [self showAlertInfoWithTag:1 andMessage:@"注册成功"];
            break;
        case 2:
            //注册失败 用户已经存在
            [self showAlertInfoWithTag:2 andMessage:@"注册失败\n用户已经存在"];
            break;
        default:
            break;
    }
} //弹出提示框
- (void)showAlertInfoWithTag:(int)tag andMessage:(NSString*)message {
    UIAlertController *alertVC =[UIAlertController alertControllerWithTitle:@"提示" message:message preferredStyle:UIAlertControllerStyleAlert];
    if (tag == 1) {
        [alertVC addAction:[UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
            [[NSUserDefaults standardUserDefaults] setObject:self.userNameField.text forKey:@"userName"];
            [self.navigationController popViewControllerAnimated:YES];
        }]];     }else{
        [alertVC addAction:[UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:nil]];     }
    [self presentViewController:alertVC animated:YES completion:nil];
} @end

向服务器发送的请求操作

整个操作写成一个单例

#import <Foundation/Foundation.h>
#import "CoreDataOperations.h" //服务器地址
//static NSString* const kServerUrl = @"http://localhost/timetally/";
static NSString* const kServerUrl = @"http://timetallydemo.duapp.com/"; @protocol ServerOperationsDelegate <NSObject> @optional //登录结果回调
- (void)didLoginBackWithTag:(int)tag;
//注册结果回调
- (void)didRegisterBackWithTag:(int)tag;
//成功上传
- (void)didUploadTallySuccessed;
//上传失败
- (void)didUploadTallyFaild; @end @interface ServerOperations : NSObject @property(nonatomic,strong)id<ServerOperationsDelegate> delegate; + (instancetype)sharedInstance;
//发送服务器请求加载数据
- (void)loadDataFormServer;
//上传账单至服务器
- (void)uploadTallyToServer;
//服务器删除指定账单
- (void)deleteTallyInServerWithIdentity:(NSString*)identity; //登录到服务器
- (void)loginWithUser:(NSString*)username andPsw:(NSString*)psw;
//注册到服务器
- (void)registerWithUser:(NSString*)username andPsw:(NSString*)psw;
@end
#import "ServerOperations.h"

@implementation ServerOperations
static ServerOperations *instance = nil; + (instancetype)sharedInstance
{
    return [[ServerOperations alloc] init];
} + (instancetype)allocWithZone:(struct _NSZone *)zone
{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        instance = [super allocWithZone:zone];
    });
    return instance;
} - (instancetype)init
{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        instance = [super init];
    });
    return instance;
} //发送服务器请求加载数据
- (void)loadDataFormServer{
    
    NSMutableURLRequest *quest = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:[kServerUrl stringByAppendingString:@"showusertally.php"]]];
    [quest setHTTPMethod:@"POST"];
    //POST 用户名
    NSString *userName = [[NSUserDefaults standardUserDefaults] objectForKey:@"userName"];
    NSDictionary *dict = [[NSDictionary alloc] initWithObjectsAndKeys:userName,@"username", nil];
    NSData *postData = [NSJSONSerialization dataWithJSONObject:dict options:NSJSONWritingPrettyPrinted error:nil];
    [quest setHTTPBody:postData];
    NSURLSession *session = [NSURLSession sharedSession];
    NSURLSessionTask *task = [session dataTaskWithRequest:quest completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        //json解码
        NSString *dataStr = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
        NSLog(@"server下载结果-----%@",dataStr);
        if ([dataStr isEqualToString:@"0"]) {
            return ;
        }
        NSArray *jsonArray = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:nil];
        if (jsonArray.count != 0) {
            [[CoreDataOperations sharedInstance] loadFromServerWithDataArray:jsonArray];
        }
    }];
    
    [task resume]; } //上传账单至服务器
- (void)uploadTallyToServer{
    NSMutableURLRequest *quest = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:[kServerUrl stringByAppendingString:@"uploadtally.php"]]];
    [quest setHTTPMethod:@"POST"];
    //POST 信息
    NSArray *postArray = [[CoreDataOperations sharedInstance] getAllTallyWithArray];
    NSData *postData = [NSJSONSerialization dataWithJSONObject:postArray options:NSJSONWritingPrettyPrinted error:nil];
    [quest setHTTPBody:postData];
    NSURLSession *session = [NSURLSession sharedSession];
    NSURLSessionTask *task = [session dataTaskWithRequest:quest completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        
        int flag = [[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] intValue];
        NSLog(@"server上传结果 %d",flag);
        if (flag==1 || flag == 9) {
            //写入成功
            for (NSDictionary *dict in postArray) {
                [[CoreDataOperations sharedInstance] uploadServerSucceedWithIdentity:dict[@"identity"]];
            }
            dispatch_async(dispatch_get_main_queue(), ^{
                if ([self.delegate respondsToSelector:@selector(didUploadTallySuccessed)]) {
                    [self.delegate didUploadTallySuccessed];
                }
            });
           
        }else{
            dispatch_async(dispatch_get_main_queue(), ^{
                if ([self.delegate respondsToSelector:@selector(didUploadTallyFaild)]) {
                    [self.delegate didUploadTallyFaild];
                }
            });         }
        
    }];
    
    [task resume]; } //登录到服务器
- (void)loginWithUser:(NSString*)username andPsw:(NSString*)psw {
    //创建URL请求
    NSMutableURLRequest *quest = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:[kServerUrl stringByAppendingString:@"login.php"]]];
    //post请求
    [quest setHTTPMethod:@"POST"];
    NSDictionary *dict = [[NSDictionary alloc] initWithObjectsAndKeys:username,@"username",psw,@"userpsw", nil];
    //字典转json
    NSData *postData = [NSJSONSerialization dataWithJSONObject:dict options:NSJSONWritingPrettyPrinted error:nil];
    [quest setHTTPBody:postData];
    
    //建立连接
    NSURLSession *session = [NSURLSession sharedSession];
    NSURLSessionTask *task = [session dataTaskWithRequest:quest completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        int result = [[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] intValue];
        NSLog(@"server登录结果 %d ",result);         dispatch_async(dispatch_get_main_queue(), ^{
            if ([self.delegate respondsToSelector:@selector(didLoginBackWithTag:)]) {
                [self.delegate didLoginBackWithTag:result];
            }
            
        });
        
    }];
    
    [task resume]; } //注册到服务器
- (void)registerWithUser:(NSString*)username andPsw:(NSString*)psw{
    //创建URL请求
    NSMutableURLRequest *quest = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:[kServerUrl stringByAppendingString:@"register.php"]]];
    //post请求
    [quest setHTTPMethod:@"POST"];
    NSDictionary *dict = [[NSDictionary alloc] initWithObjectsAndKeys:username,@"username",psw,@"userpsw", nil];
    //字典转json
    NSData *postData = [NSJSONSerialization dataWithJSONObject:dict options:NSJSONWritingPrettyPrinted error:nil];
    [quest setHTTPBody:postData];
    
    //建立连接
    NSURLSession *session = [NSURLSession sharedSession];
    NSURLSessionTask *task = [session dataTaskWithRequest:quest completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        
        int result = [[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] intValue];
        NSLog(@"server注册结果 %d ",result);
        //回到主线程
        dispatch_async(dispatch_get_main_queue(), ^{
            if ([self.delegate respondsToSelector:@selector(didRegisterBackWithTag:)]) {
                [self.delegate didRegisterBackWithTag:result];
            }
        });
    }];
    
    [task resume];
} //从服务器删除账单
- (void)deleteTallyInServerWithIdentity:(NSString*)identity{
    //创建URL请求
    NSMutableURLRequest *quest = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:[kServerUrl stringByAppendingString:@"deletetally.php"]]];
    //post请求
    [quest setHTTPMethod:@"POST"];
    NSDictionary *dict = [[NSDictionary alloc] initWithObjectsAndKeys:identity,@"identity", nil];
    //字典转json
    NSData *postData = [NSJSONSerialization dataWithJSONObject:dict options:NSJSONWritingPrettyPrinted error:nil];
    [quest setHTTPBody:postData];
    //建立连接
    NSURLSession *session = [NSURLSession sharedSession];
    NSURLSessionTask *task = [session dataTaskWithRequest:quest completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        
        int result = [[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] intValue];
        if (result == 0) {
            NSLog(@"%d server链接数据库失败",result);
        }else if (result == 1){
            NSLog(@"%d server删除账单成功",result);
        }else if (result == 2){
            NSLog(@"%d server删除账单失败",result);
        }
    }];
    
    [task resume];
}
@end

服务端部分

php新手 高手勿喷

文件结构

其中index.php 和 useruploadrecords.php是web断的登录展示页面

数据库部分字段和表基本与客户端相同可以看CREATE的代码

代码

配置文件

<?php
define('MYSQL_HOST','localhost');
define('MYSQL_USER','root');
define('MYSQL_PSW','');
define('MYSQL_DBNAME','TimeTally');

所有数据库操作

<?php
require_once 'config.php'; /**链接并选择数据表
 * @param $table 链接表
 * @return mysqli 链接link
 */
function connectDBandSelectTable($table) {
    $con = mysqli_connect(MYSQL_HOST,MYSQL_USER,MYSQL_PSW);
    mysqli_set_charset($con,'utf8');
    if ($con){
        mysqli_select_db($con,MYSQL_DBNAME);
        if(mysqli_num_rows(mysqli_query($con,"SHOW TABLES LIKE '".$table."'"))==0) {
            if ($table == 'Tally'){
                $sql = "CREATE TABLE $table 
                        ( id INT NOT NULL AUTO_INCREMENT , 
                        username VARCHAR(50) NOT NULL ,
                        date VARCHAR(50) NOT NULL , 
                        identity VARCHAR(1024) NOT NULL , 
                        typename VARCHAR(50) NOT NULL , 
                        income DOUBLE NOT NULL , 
                        expenses DOUBLE NOT NULL , 
                        timestamp DOUBLE NOT NULL ,
                        uploadtime TIMESTAMP NOT NULL,
                        PRIMARY KEY (id))";
                mysqli_query($con,$sql);             }elseif ($table == 'Users'){
                $sql = "CREATE TABLE $table 
                        (id INT  NOT  NULL AUTO_INCREMENT, 
                        username VARCHAR (100) NOT  NULL ,
                        userpsw VARCHAR (100) NOT  NULL , 
                        session INT  NOT  NULL  DEFAULT  0,
                        PRIMARY KEY (id))";
                mysqli_query($con,$sql);
            }
        }
    }
    return $con;
} /**注册
 * @param $table 表
 * @param $username 用户名
 * @param $userpsw 用户密码
 * @return int 0:连接失败 1:注册成功 2:用户已存在
 */
function register($table,$username,$userpsw){
    $con = connectDBandSelectTable($table);
    if ($con){
        $isExist = existQuery($table,"username",$username);
        if ($isExist == 2){
            $sql = "INSERT INTO $table (username, userpsw) VALUES ('$username',MD5('$userpsw'))";
            $result = mysqli_query($con,$sql);
            if ($result){
                //成功
                return 1;
            }
        }else if ($isExist == 1){
            //已存在
            return 2;
        }
        //关闭数据库
        mysqli_close($con);
    }
    //连接数据库失败
    return 0;
} /**查询字段是否存在
 * @param $table 表名
 * @param $field 查询字段名
 * @param $obj 查询对象
 * @return 0:连接失败 1:存在 2:不存在
 */
function existQuery($table,$field,$obj){
    $con = connectDBandSelectTable($table);
    if ($con){
        $sql = "SELECT * FROM $table WHERE $field = '$obj'";
        $result = mysqli_query($con,$sql);
        if (mysqli_num_rows($result) > 0){
            return 1;
        }else{
            return 2;
        }
    }
    return 0;
} /**获取该用户下所有账单
 * @param $table 表名
 * @param $user 用户名
 * @return int|string 0:连接失败或无法查询  string:json数组;
 */
function getUserTally($table,$user){
    $con = connectDBandSelectTable($table);
    if ($con){
        $sql = "SELECT * FROM $table WHERE username = '$user'";
        $arr = mysqli_query($con,$sql);
        $num = mysqli_num_rows($arr);
        if ($num > 0){
            for ($i=0;$i<$num;$i++){
                $results[] = mysqli_fetch_assoc($arr);
            }
            mysqli_close($con);
            return json_encode($results);
        }
    }
    //连接失败或无法查询
    return 0;
} /**登录验证
 * @param $username 用户名
 * @param $userpsw  用户密码
 * @return int  0:连接失败 1:验证成功 2:密码错误 3:用户不存在
 */
function verifyLogin($username,$userpsw){
    //查询用户名是否存在
    $table = 'Users';
    $con = connectDBandSelectTable($table);
    if ($con){
        $sql = "SELECT * FROM $table WHERE username = '$username'";
        $isExist = mysqli_query($con,$sql);
        if (mysqli_num_rows($isExist) > 0) {
            //存在并继续验证 密码
            $result = mysqli_fetch_array($isExist);
            $psw = $result['userpsw'];
            if (md5($userpsw) == $psw){
                //密码正确
                return 1;
            }else {
                //密码错误
                return 2;
            }         }else {
            //用户不存在
            return 3;
        }
        mysqli_close($con);
    }     //数据库连接失败
    return 0; } /**上传更新或新增账单数据
 * @param $table  写入表名
 * @param $tallyJson 传入解析后的json
 * @return int -1:数据库连接失败 0:没有写入 1:写入成功 2:写入失败 9:更新数据
 */
function uploadTally($table,$tallyJson){
    $con = connectDBandSelectTable($table);
    $r = 0;
    if ($con){
        //根据json解析出来的数组的长度 更新对应identity数值
        for ($i=0;$i<count($tallyJson);$i++){
            $identity = $tallyJson[$i]->identity;
            $isExistSql = "SELECT * FROM $table WHERE identity LIKE '$identity'";
            $isExisResult = mysqli_query($con,$isExistSql);
            if (mysqli_num_rows($isExisResult) > 0){
                $typename = $tallyJson[$i]->typename;
                $income = $tallyJson[$i]->income;
                $expenses = $tallyJson[$i]->expenses;
                $timestamp = $tallyJson[$i]->timestamp;
                $updateSql = "UPDATE $table 
                          SET typename = '$typename',
                          income='$income' ,
                          expenses = '$expenses',
                          uploadtime = CURRENT_TIMESTAMP,
                          timestamp = '$timestamp'
                          WHERE identity = '$identity'";
                mysqli_query($con,$updateSql);
                $r = 9;
            } else{
                //没有查询到identity则进入新增
                $typename = $tallyJson[$i]->typename;
                $income = $tallyJson[$i]->income;
                $expenses = $tallyJson[$i]->expenses;
                $username = $tallyJson[$i]->username;
                $date = $tallyJson[$i]->date;
                $timestamp = $tallyJson[$i]->timestamp;
                //mysql插入
                $intoSql = "INSERT INTO $table
                          (id,username,date,identity,typename,income,expenses,timestamp,uploadtime)
                          VALUES (NULL, '$username', '$date','$identity','$typename','$income','$expenses','$timestamp',CURRENT_TIMESTAMP)";
                $insertResult = mysqli_query($con,$intoSql);
                if ($insertResult){
                    //新增成功
                   $r = 1;
                }else{
                    //新增失败
                    $r = 2;
                }
            }
        }
    mysqli_close($con);
    }else{
        //连接失败
        $r = -1;
    }
    return $r;
} /**
 * @param $table 表名
 * @param $identity 需要删除的标识
 * @return int 0:链接数据库失败 1:删除成功 2:删除失败
 */
function deleteTally($table,$identity){
    $con = connectDBandSelectTable($table);
    if ($con){
        $sql = "DELETE FROM $table WHERE identity = '$identity'";
        $result = mysqli_query($con,$sql);
        if ($result){
            return 1;
        }else{
            return 2;
        }
    }
    mysqli_close($con);
    return 0;
} /**获取post的json数据 并连接数据库表
 * @param $table 表名
 * @return mixed json数据
 */
function getPostJsonValue($table){
//获取post数据
    $postValue = file_get_contents("php://input");
//json解析
    $postJson = json_decode($postValue);
    $currentTable = $table;
//连接并选择数据库
    connectDBandSelectTable($currentTable);
    return $postJson;
}

各个调用页面

登录

<?php
require_once 'dboperations.php';
//获取post数据
$table = 'Users';
$postValue = getPostJsonValue($table);
//登录验证
$result = verifyLogin($postValue->username,$postValue->userpsw);
echo $result;

注册

<?php
require_once 'dboperations.php';
//获取post数据并连接数据库表
$currentTable = 'Users';
$postJson = getPostJsonValue($currentTable);
//注册
$result = register($currentTable,$postJson->username,$postJson->userpsw);
echo $result;

下载服务端数据

<?php
require_once 'dboperations.php';
$table = 'Tally';
$postValue = getPostJsonValue($table);
$reslut = getUserTally($table,$postValue->username);
echo $reslut;

上传

<?php
require_once 'dboperations.php';
$table = 'Tally';
$postJson = getPostJsonValue($table);
$result = uploadTally($table,$postJson);
echo $result;

删除

<?php
require_once 'dboperations.php';
$table = 'Tally';
$postValue = getPostJsonValue($table);
$reslut = deleteTally($table,$postValue->identity);
echo $reslut;

web端

首页登录

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<link rel="stylesheet" type="text/css" href="css/style.css" />
<title>Document</title>
</head>
<body>
<form id="slick-login" action="useruploadrecords.php" method="get" >
<input type="text" name="username" placeholder="用户名">
<input type="password" name="userpsw" placeholder="密码">
<input type="submit" value="Log In"/>
</form>
</body>
</html>

内容页



<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<link rel="stylesheet" type="text/css" href="css/tablestyle.css" />
<title>Document</title>
</head>
<body>
<?php
require_once 'dboperations.php';
if (isset($_GET["username"]) && isset($_GET["userpsw"])){
$username = $_GET["username"];
$userpsw = $_GET["userpsw"];
} $verifty = verifyLogin($username,$userpsw);
if ($verifty == 1){
$table = 'Tally';
$con = connectDBandSelectTable($table);
$sql = "SELECT * FROM $table WHERE username = '$username' ORDER BY uploadtime DESC ";
$res = mysqli_query($con,$sql); echo "<table>
<tr><th>欢迎用户:$username</th><th></th><th></th><th></th><th></th></tr>
<tr><th>操作记录</th><th>上传时间</th><th>账单类型</th><th>支出</th><th>收入</th></tr>";
for ($i=0;$i<mysqli_num_rows($res);$i++){
$resarray = mysqli_fetch_assoc($res);
$uploadtime = $resarray["uploadtime"];
$typename = $resarray["typename"];
$income= $resarray["income"];
$expenses = $resarray["expenses"];
?>
<tr>
<td>
<?php echo $i+1?>
</td>
<td>
<?php echo $uploadtime?>
</td>
<td>
<?php echo $typename?>
</td>
<td>
<?php echo $expenses?>
</td>
<td>
<?php echo $income?>
</td>
</tr>
<?php
}
echo "</table>";
}elseif ($verifty == 2){ echo "<script> alert('密码错误');parent.location.href='index.php'; </script>"; }elseif ($verifty == 3){
echo "<script> alert('用户不存在');parent.location.href='index.php'; </script>";
}
?>
</body>
</html>

Demo地址

https://github.com/gongxiaokai/TimeTallyOnlineDemo

其中包含server端的php代码和客户端的oc代码

简书主页

http://www.jianshu.com/u/7897b0bd4a55

iOS开发实战-时光记账Demo 网络版的更多相关文章

  1. iOS开发实战-时光记账Demo 本地数据库版

    现在记账APP也是用途比较广泛 自己写了个简单的demo 欢迎指正 效果 分析 1.思维推导 首先简单的做了下思维推导 2.文件结构 大致框架想好后就可以着手开始准备了 数据库管理:coreData ...

  2. iOS开发——实战OC篇&环境搭建之Xib(玩转UINavigationController与UITabBarController)

    iOS开发——实战OC篇&环境搭建之Xib(玩转UINavigationController与UITabBarController)   前面我们介绍了StoryBoard这个新技术,和纯技术 ...

  3. iOS开发——实战OC篇&环境搭建之纯代码(玩转UINavigationController与UITabBarController)

    iOS开发——实战OC篇&环境搭建之纯代码(玩转UINavigationController与UITabBarController)   这里我们就直接上实例: 一:新建一个项目singleV ...

  4. Xamarin iOS开发实战第1章使用C#编写第一个iOS应用程序

    Xamarin iOS开发实战第1章使用C#编写第一个iOS应用程序 C#原本是用来编写Windows以及Windows Phone的应用程序.自从Xamarin问世后.C#的作用就发生了非常大的变化 ...

  5. 《iOS开发实战 从入门到上架App Store(第2版)》书籍目录

    第1章 开发准备 1.1 iOS 10新特性简述 1.1.1 新增触觉反馈编程接口 1.1.2 SiriKit框架的开放 1.1.3 引入Messages App 1.1.4 通知框架的整合与扩展 1 ...

  6. iOS开发——实战OC篇&环境搭建之StoryBoard(玩转UINavigationController与UITabBarController)

      环境搭建之StoryBoard(玩转UINavigationController与UITabBarController)   研究了这么就IOS开发,都没有所处一个像样或者自己忙一点的项目.最近自 ...

  7. iOS开发实战-基于SpriteKit的FlappyBird小游戏

    写在前面 最近一直在忙自己的维P恩的事情 公司项目也是一团乱 于是...随手找了个游戏项目改了改就上线了,就当充数了. SpriteKit简介 SpriteKit是iOS 7之后苹果推出的2D游戏框架 ...

  8. IOS开发实战-Xcode创建HelloWorld项目

    一.创建工程打开Xcode开发工具,在Welcome界面选择”Create a new Xcode project”选项 在选择模板窗口,选择”Single View Application” 确定模 ...

  9. iOS开发——实战总结OC篇&网易彩票开发知识点总结

    网易彩票开发知识点总结 关于网易彩票开发中遇到了不少的坑,弄了好久才弄懂,或者有些犹豫很久没用就不记得了,所以这里就总结了一下,希望以后不会忘记,就算忘记也能快速查看! /************** ...

随机推荐

  1. 使用类似于中介者模式实现不同VC之间的跳转

    在2013年的时候,我们就已经实现了类似于http地址进行页面跳转, 那个时候,主要是用继承ViewController和给 UIViewController和UINavigationControll ...

  2. linux iptables规则介绍

    今天又学习了一下iptables,做一点总结来方便以后查阅. Netfilter(网络过滤器)是Linux操作系统核心层内部的一个数据包处理模块,主要负责数据包的拦截和转发,而iptables是Net ...

  3. 深入理解JavaScript中的闭包

    闭包没有想象的那么简单 闭包的概念在JavaScript中占据了十分重要的地位,有不少开发者分不清匿名函数和闭包的概念,把它们混为一谈,我希望借这篇文章能够让大家对闭包有一个清晰的认识. 大家都知道变 ...

  4. EF架构~Migration数据迁移的执行顺序

    回到目录 对于单个分支项目来说,只要你生成一个migration的版本,就会有一个时间戳文件的对应,而在update-database时,会从最小的时间开始,一直执行到当前版本的migration,而 ...

  5. 【源码分享】mui实现简单的手机音乐播放器

    mui实现简单的手机音乐播放器 最近先来无事,我用mui写了一个可以跨页面控制的音乐播放器.主要功能有上一曲,下一曲,播放,暂停,感兴趣的可以继续看下去. 说的总是不实在,直接上源码,有兴趣的可以读下 ...

  6. 很好的复习资料: SQL语句到底怎么写 ?

    本文用到的数据库如下: CREATE DATABASE exam; /*创建部门表*/ CREATE TABLE dept( deptno INT PRIMARY KEY, dname VARCHAR ...

  7. VS2012打开项目 提示Asp.net4.5未在web服务器上注册

    在用vs2012代开项目时,没回都显示Asp.net4.5未在web服务器上注册,最后是由于没有下载一个补丁的原因,只需要下载安装补丁 VS11-KB3002339.exe ,下载地址:https:/ ...

  8. 【LeetCode】144. Binary Tree Preorder Traversal

    题目: Given a binary tree, return the preorder traversal of its nodes' values. For example:Given binar ...

  9. 遇到的Mysql的一个坑

    自己写的Java代码怎么也无法操作MySQL的写操作,打印SQL语句没有问题,检查连接也没有问题,最后手动写了一条记录,发现主键重复了,但是当时表是空的!所以就很震惊,于是选择删表重新来一次,这回成功 ...

  10. java基础之集合框架(1)

    一.介绍Collection 1.概念:Collection是最基本的集合接口,一个Collection代表一组Object,即Collection的元素(Elements).一些Collection ...