Objective-C ,ios,iphone开发基础:使用第三方库FMDB连接sqlite3 数据库,实现简单的登录...-程序员宅基地

技术标签: 移动开发  数据库  

第一步:下载第三方库,点击 连接 下载,

第二部:准备数据库:按照连接&中博客的步骤实现数据库,

数据库的设计大致如下表:

id        username             password         registertime      realname            groupid             

 
   

 新建一个单视图工程,

 

关闭arc  (Automatic reference count)自动引用计数,

 

添加 sqlite3.dylib 类库的包含,

 

 将准备好的第三方库FMDB 以及准备好的数据库包含在项目中,包含时要注意选中copy 选项,不然只是单纯的引用到项目中,

 

包含后项目结构如下,

 

单击打开 wsqViewController.xib  拖放两个UILable ,并分别设置title属性为 "用户名" 和 " 密码" ,然后拖放两个Text Field ,再拖放一个UIButton title属性设置为登录,布局随意,

 

 为两个TextField 设置Placeholder属性,这个就是水印属性,用来添加水印提示,当点击输入任何一个字符的时候就会消失。。

 

 

为控件连线,分别为两个TextField 连接连个插座变量 分别命名为textUserName 和 textPwd ,为UIButton 连接一个action 事件,命名为btnClick。(注意红色箭头标注的关键点)

           

 

 

为连个TextField 添加键盘消失的方法,首先让 wsqViewController 遵循 UITextFieldDelegate 协议 ,

 

@interface wsqViewController : UIViewController<UITextFieldDelegate>

 

并且在 wsqViewController.m 中重写- (BOOL)textFieldShouldReturn:(UITextField *)textField;方法,

- (BOOL)textFieldShouldReturn:(UITextField *)textField{
    [textField resignFirstResponder];
    return YES;
}

 其实主要是让两个TextField 在结束的时候调用 resignFirstResponder 方法,通过将代理 delegate 指向File's Owner,在单击小键盘return 键和敲键盘回车键的时候让小键盘消失。

因为我们是在单击UIbutton的时候来判断是否登录成功,所以,所有的赋值和取值的操作都可以放在btnClick 事件里面来操作,

但是这样会在单击button的时候增加响应时间,所以我们把一些基本的操作还是放在- (void)viewDidLoad 里面,这里面主要就是

把数据库拷贝直应用程序的沙盒中,因为在mainBundle 目录下,所有系统的文件都是不可以通过程序来操作的,任何操作都会返回nil。

操作其他应用程序也不行,这样每一个应用程序都在自己的沙盒中运行,从而不会影响其他的应用程序。

 

在 wsqViewController.h 添加一个实例变量,为NSString 类型,用来存放数据库在沙盒中的路径。不要忘记在 dealloc 中release,并且在.m文件中实现它:@synthesize tempPath;

 

在viewDidLoad 中添加代码:主要是获取user.db在目录中的路径然后通过 NSFileManager 类中的方法,将数据库拷贝至沙盒目录下。

- (void)viewDidLoad
{
    [super viewDidLoad];
    //获取 user.db在目录中的路径
    NSString* strBundlePath = [[NSBundle mainBundle] pathForResource:@"user.db" ofType:nil];
    //获取应用程序沙盒下所有文件夹 的路径
    NSArray* arrayDocunmentPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    //获取应用程序沙盒下 doucumnet文件夹 的路径
    NSString* strDocunmentPath = [arrayDocunmentPath objectAtIndex:0];
    //为文件夹路径附加文件路径,
    NSString* destinationPath = [strDocunmentPath stringByAppendingString:@"user.db"];
    NSFileManager* fManager = [NSFileManager defaultManager];
    //实例化一个NSFileManager 将文件拷贝至沙盒目录下。
    if(![fManager fileExistsAtPath:destinationPath]){
        NSError* error= nil;
        [fManager copyItemAtPath:strBundlePath toPath:destinationPath error:&error];
        if(error){
            NSLog(@"%@",error);
        }
    }
//retain 一次,不然会在出了括号之后就会释放,
tempPath = [destinationPath retain]; }

 

在wsqViewController.h 文件中包含第三方库的头文件:

#import "FMDatabase.h"

 

 在btnClick 方法中添加代码:

- (IBAction)btnClick:(id)sender {
    [textUserName resignFirstResponder];
    [textPwd resignFirstResponder];
    
    //创建一个第三方库的对象 ,用数据库路径来初始化,
    FMDatabase* fmDatebase = [[FMDatabase alloc] initWithPath:tempPath];
    //连接数据库,并做判断
    if(![fmDatebase open]){
        UIAlertView* alert = [[UIAlertView alloc] initWithTitle:@"数据库连接" message:@"连接失败" delegate:self cancelButtonTitle:@"cancel" otherButtonTitles:@"ok", nil];
        //显示消息框,
        [alert show];
        // alloc 出来的空间必须释放
        [alert release];
    }
    //sql语句
    NSString* executeStr = [NSString stringWithFormat:@"select * from \"member\" where username =\"%@\" and password = \"%@\"",textUserName.text,textPwd.text];
    //sql语句执行之后返回一个FMResultSet容器。
    FMResultSet * fmSet = [fmDatebase executeQuery:executeStr];
    //扑捉sql异常错误,
    if([fmDatebase hadError]){
        NSLog(@"%i ,%@",[fmDatebase lastErrorCode],[fmDatebase lastErrorMessage]);
        return ;
    }
   //循环容器
    while ([fmSet next]) {
        
        UIAlertView* alert = [[UIAlertView alloc] initWithTitle:@"Login" message:@"success" delegate:self cancelButtonTitle:@"cancel" otherButtonTitles:@"ok", nil];
        [alert show];
        [alert release];
    }
    if([fmDatebase hadError]){
        NSLog(@"%i ,%@",[fmDatebase lastErrorCode],[fmDatebase lastErrorMessage]);
        return ;
    }
    
    //关闭连接,以及容器
    [fmDatebase close];
    [fmSet close];
    //alloc 出来的空间必须释放。
    [fmDatebase release];
  
}

 

然后点击run 运行结果如下:

 

 

最后为应用程序添加事先准备的图标和应用程序启动动画:

lanch.jpg 和icon.jpg

 

打开 .plist文件 ,修改icon 。并且添加 一项lanch

修改后结果如下图:

 

#import <UIKit/UIKit.h>
#import "FMDatabase.h"

@interface wsqViewController : UIViewController<UITextFieldDelegate> {
    UITextField *textUserName;
    UITextField *textPwd;
    NSString* tempPath;
}

@property (retain, nonatomic) IBOutlet UITextField *textUserName;
@property (retain, nonatomic) IBOutlet UITextField *textPwd;
@property (retain,nonatomic) NSString* tempPath;
- (IBAction)btnClick:(id)sender;

@end

 

 

 

//
//  wsqViewController.m
//  loginTest
//
//  Created by administrator on 13-9-4.
//  Copyright (c) 2013年 __MyCompanyName__. All rights reserved.
//

#import "wsqViewController.h"

@implementation wsqViewController
@synthesize textUserName;
@synthesize textPwd;
@synthesize tempPath;

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Release any cached data, images, etc that aren't in use.
}

#pragma mark - View lifecycle

- (void)viewDidLoad
{
    [super viewDidLoad];
    //获取 user.db在目录中的路径
    NSString* strBundlePath = [[NSBundle mainBundle] pathForResource:@"user.db" ofType:nil];
    //获取应用程序沙盒下所有文件夹 的路径
    NSArray* arrayDocunmentPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    //获取应用程序沙盒下 doucumnet文件夹 的路径
    NSString* strDocunmentPath = [arrayDocunmentPath objectAtIndex:0];
    //为文件夹路径附加文件路径,
    NSString* destinationPath = [strDocunmentPath stringByAppendingString:@"user.db"];
    NSFileManager* fManager = [NSFileManager defaultManager];
    //实例化一个NSFileManager 将文件拷贝至沙盒目录下。
    if(![fManager fileExistsAtPath:destinationPath]){
        NSError* error= nil;
        [fManager copyItemAtPath:strBundlePath toPath:destinationPath error:&error];
        if(error){
            NSLog(@"%@",error);
        }
    }
    
    tempPath = [destinationPath retain];
    
    
}

- (void)viewDidUnload
{
    [self setTextUserName:nil];
    [self setTextPwd:nil];
    [super viewDidUnload];
    
}

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
}

- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];
}

- (void)viewWillDisappear:(BOOL)animated
{
    [super viewWillDisappear:animated];
}

- (void)viewDidDisappear:(BOOL)animated
{
    [super viewDidDisappear:animated];
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    // Return YES for supported orientations
    return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}

- (BOOL)textFieldShouldEndEditing:(UITextField *)textField{
    [textUserName resignFirstResponder];
    [textPwd resignFirstResponder];
    return YES;
}

- (BOOL)textFieldShouldReturn:(UITextField *)textField{
    [textField resignFirstResponder];
    return YES;
}

- (void)dealloc {
    [textUserName release];
    [textPwd release];
    [tempPath release];
    [super dealloc];
}
- (IBAction)btnClick:(id)sender {
    [textUserName resignFirstResponder];
    [textPwd resignFirstResponder];
    
    //创建一个第三方库的对象 ,用数据库路径来初始化,
    FMDatabase* fmDatebase = [[FMDatabase alloc] initWithPath:tempPath];
    //连接数据库,并做判断
    if(![fmDatebase open]){
        UIAlertView* alert = [[UIAlertView alloc] initWithTitle:@"数据库连接" message:@"连接失败" delegate:self cancelButtonTitle:@"cancel" otherButtonTitles:@"ok", nil];
        //显示消息框,
        [alert show];
        // alloc 出来的空间必须释放
        [alert release];
    }
    //sql语句
    NSString* executeStr = [NSString stringWithFormat:@"select * from \"member\" where username =\"%@\" and password = \"%@\"",textUserName.text,textPwd.text];
    //sql语句执行之后返回一个FMResultSet容器。
    FMResultSet * fmSet = [fmDatebase executeQuery:executeStr];
    //扑捉sql异常错误,
    if([fmDatebase hadError]){
        NSLog(@"%i ,%@",[fmDatebase lastErrorCode],[fmDatebase lastErrorMessage]);
        return ;
    }
   //循环容器
    while ([fmSet next]) {
        
        UIAlertView* alert = [[UIAlertView alloc] initWithTitle:@"Login" message:@"success" delegate:self cancelButtonTitle:@"cancel" otherButtonTitles:@"ok", nil];
        [alert show];
        [alert release];
    }
    if([fmDatebase hadError]){
        NSLog(@"%i ,%@",[fmDatebase lastErrorCode],[fmDatebase lastErrorMessage]);
        return ;
    }
    
    //关闭连接,以及容器
    [fmDatebase close];
    [fmSet close];
    //alloc 出来的空间必须释放。
    [fmDatebase release];
  
}
@end

 

 

 

 

 

 

转载于:https://www.cnblogs.com/wsq724439564/p/3301943.html

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_30369087/article/details/97535719

智能推荐

Java 解决同步数据时 Read timed out; nested exception is java.net.SocketTimeoutException: Read timed out_read timed out; nested exception is java.net.socke-程序员宅基地

文章浏览阅读1.3k次,点赞12次,收藏6次。Java 解决同步数据时 Read timed out; nested exception is java.net.SocketTimeoutException: Read timed out_read timed out; nested exception is java.net.sockettimeoutexception: read ti

Docker安装Nginx详细步骤-程序员宅基地

文章浏览阅读880次。安装Nginx服务器可以使用Docker容器,详细步骤如下:1. 使用docker pull命令从Docker Hub下载Nginx镜像:docker pull nginx2. 使用docker run命令运行Nginx容器:docker run --name my_nginx -d -p 80:80 nginx3. 进入容器:docker exec -it my_nginx /bin/bash4..._docker 安装nginx

Dubbo源码分析,读完定能有所收获_dubbo源码和-程序员宅基地

文章浏览阅读6.1k次,点赞25次,收藏29次。Dubbo、源码、调用关系、整体设计、分层、服务注册与消费源码分析、注册中心Zookeeper剖析、目录结构、注册过程分析、URL规则分析、消费过程分析、拓展SPI源码分析、getExtensionLoader加载过程、Adaptive功能实现原理、集群容错源码分析、信息缓存Directory、路由规则实现原理、Cluster组件、负载均衡源码分析、Invoker执行逻辑、网络通信原理剖析、数据包结构分析、数据协议详解、粘包和拆包问题_dubbo源码和

x722网卡支持百兆吗_英特尔(Intel)X722-DA2以太网网络适配器万兆服务器网卡X722DA2...-程序员宅基地

文章浏览阅读1.4k次。英特尔 以太网网络适配器 X722-DA2基本要素产品集700 系列网络适配器(高达 40GbE)状态Launched发行日期:Q4'18垂直市场:Server中等电缆:Copper布线类型:SFP+ Direct Attached Twinaxial Cabling up to 10m支架高度:Low Profile and Full Height支持的操作系统订购与规格信息Intel Et..._塔式服务器中的intel(r) ethernet connection x722 for 1gbe是网线接口吗

Docker容器下Redis/ES/RabbitMQ/MongoDB/FastDFS启动命令总结_bitnami etcd镜像地址-程序员宅基地

文章浏览阅读1k次。1.Docker启动命令介绍例:docker run -d --name myredis -p 6379:6379 redis 命令解析: run:运行容器 -d:表示后台运行,守护进程 --name [myredis]:自定义一个名称 //[中括号内的是自己写,且命令里面没有中括号] -p 6379:6379 容器里面的端口映射到外部电脑的端口2.Docker中..._bitnami etcd镜像地址

git 使用场景 本地分支 关联 远程分支-程序员宅基地

文章浏览阅读796次,点赞8次,收藏7次。【代码】git 使用场景 本地分支 关联 远程分支。

随便推点

完美解决丨 - [SyntaxError: invalid syntax](#SyntaxError-invalid-syntax)_invalid create index syntax, use `create index for-程序员宅基地

文章浏览阅读3.6k次,点赞76次,收藏5次。「SQL面试题库」是由不吃西红柿发起,全员免费参与的SQL学习活动。我每天发布1道SQL面试真题,从简单到困难,涵盖所有SQL知识点,我敢保证只要做完这100道题,不仅能轻松搞定面试,代码能力和工作效率也会有明显提升。_invalid create index syntax, use `create index for ...` instead. (line 1, co

[网络安全自学篇] 三十五.恶意代码攻击检测及恶意样本分析_如何在数据包中分析那些是带有恶意攻击的和正常语句-程序员宅基地

文章浏览阅读1.7w次,点赞14次,收藏78次。本文主要结合作者的《系统安全前沿》作业,相关论文及绿盟李东宏老师的博客,从产业界和学术界分别详细讲解恶意代码攻击溯源的相关知识。在学术界方面,用类似于综述来介绍攻击追踪溯源的不同方法;在产业界方面,主要参考李东宏老师从企业恶意样本分析的角度介绍溯源工作。关于攻击溯源的博客和论文都比较少,希望这篇文章对您有所帮助,如果文章中存在错误或理解不到位的地方,还请告知作者与海涵~_如何在数据包中分析那些是带有恶意攻击的和正常语句

如何带好一个团队?团队管理的要点有哪些?_如何管理好一个团队-程序员宅基地

文章浏览阅读2k次。以目标为基准,以结果为导向,一个目标明确的团队,项目成员的个人目标也会更加明确,从而发挥最大的效率。合理运用自己的权限是管理者必修的一门功课,因为你的一个决策会影响到员工的工作态度、发展等要素,所以一定要深思熟虑,对团队和团队中的每一个人负责。在项目管理中,使用项目管理软件可以实现全面,可视化管理,在软件上制定计划,统一分配任务,不仅能够提高效率,还能够实现更好的管理。作为管理者,要学会适度的放权,有的放矢,管理者手中的权限是为了团队更好的发展,肩负着重要的责任。实现有效沟通,避免信息孤岛的出现。_如何管理好一个团队

暗影精灵9休眠时间间歇性风扇转动解决方法_暗影精灵9睡眠风扇突然转-程序员宅基地

文章浏览阅读1.3k次。HP最近一次更新后本人的暗影精灵9在休眠的时候风扇经常性地突然高速转动,带来了不小的噪音困扰,查阅惠普社区后先是安装了最新的BIOS文件F.11版本,仍不能解决问题。目前方法:惠普管家上找到之前版本的BIOS文件(本人使用F.08)并下载,按向导安装并重启电脑,即可解决问题。即回退BIOS版本文件。这两天电脑不再出现休眠后风扇时不时地疯狂转动的现象,应该是个有效的方法。_暗影精灵9睡眠风扇突然转

常用Web漏洞扫描工具汇总(持续更新中)_网站扫描工具-程序员宅基地

文章浏览阅读1.1k次。常用Web漏洞扫描工具汇总_网站扫描工具

python图形化界面pyqt_python pyqt5 图形化界面编程-程序员宅基地

文章浏览阅读116次。库的成功融合。Qt库是目前最强大的库之一。PyQt是由Phil Thompson开发。#说到PyQt,我们不妨了解一下什么是Qt# Qt是一个1991年由Qt Company开发的跨平台C++图形用户界面应用程序开发框架。它既可以开发GUI程序,也可用于开发非GUI程序,比如控制台工具和服务器。Qt是面向对象的框架,使用特殊的代码生成扩展(称为元对象编译器(Meta ObjectCompiler,...

推荐文章

热门文章

相关标签