昨天张梦格App的第二版已经提交上线审核。从第一天接手项目开始到第一次、第二次被苹果打回,再到第一版、第二版上线,我经历了一个完整的App从开发到上线的全过程。我想应该对这个项目做一些总结,把自己在这个项目中的收获记录下来。帮助加深记忆,巩固和提高技术

一、代码管理工具----分布式版本控制系统github,在上边新建一个项目的代码仓库,把代码同步到git服务器上。下边介绍一个常用的git终端命令:

git clone "SSH网址"从github上克隆代码到本地、

git branch 列出已有的分支、

git checkout "branchname" 切换分支名称、

git add .  添加新文件或者更改新文件、

git status 查看更新状态、

git rm "文件名" 删除github上文件、

git commit -m "name"提交更改文件到本地并且添加一个名字、

git pull /git pull origin "branchname"从服务器上拉取信息、

git push origin "branchname"提交到服务器上、

git merge 合并版本、

git log查看提交修改目录。

gitk 打开github自带图形用户界面

mate "Zhangmengge.xcodeproj" 用textmate打开工程文件

二、iphone工程命名规范:

进入工程后有四个文件夹:

第一个Resources存放的是第一次美工给的图片,包含测试图和坐标图并不是最终要添加到工程里的文件。

第二个是工程名字的文件夹。

第三个Frameworks里存放了工程所有用到的框架。

第四个是这个工程的app文件。

在工程名的文件夹里包含有5个文件夹:

第一个config是一个全局的配置文件,里边主要放所有用到的宏定义。

第二个App文件夹里放的是所有的代码文件。

第三个libs文件夹里放所有用到的第三方框架。

第四个Resources里边存放的是工程中所有用到的图片素材。

第五个supporting files是一个支持文件,里边主要是自动生成文件,例如plist文件、main函数、pch文件,在pch文件里写的主要是一些被很多页面都要引用的框架名称,写在这里边就会自动引用到所有页面。

三、  自定义Button形状的第三方框架OBShapedButton:

图片素材的其它区域要给成透明的,然后用OBShapedButton初始化创建一个对象,后边用法跟创建系统Button一样:

    OBShapedButton * sharebtn = [OBShapedButton buttonWithType:UIButtonTypeCustom];sharebtn.frame = CGRectMake(10, 40, 300, 436);[sharebtn setImage:[UIImage imageNamed:@"xiepinglun_backgound_cut.png"] forState:UIControlStateNormal];[sharebtn addTarget:self action:@selector(onTop) forControlEvents:UIControlEventTouchUpInside];[self.view addSubview:sharebtn];

四、textview、textfield回收键盘方法:

都需要把delegate设成自己:

-(BOOL)textFieldShouldReturn:(UITextField *)textField
{[textField resignFirstResponder];return YES;
}-(BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text
{  if ([text isEqualToString:@"\n"]) {  [textView resignFirstResponder];  return NO;  }  return YES;
}  

五、字符串替换、数组反向排序:

//字符串替换
self.finalStr = [self.tempStr stringByReplacingOccurrencesOfString:@"</p>" withString:@" "];
//将数组元素反向排列
[self.articleList reverseObjectEnumerator];

六、修改编译文件(Build)位置:

编写程序时经常会出现一些莫名其妙的错误,而且怎么找都找不到错误,这个时候就该考虑一下是不是build的问题,需要clean build一下。在xcode里Preferences里的Locations把Derived Data的Default改成Relative,然后把后边括号里改成build,这样每次编译会在你的工程目录里多出一个build文件夹,在出现奇怪错误时可以build目录清理一下。

七、DLog:

编写程序时经常需要用NSLog输出一些数据,当整个程序写完时可能已经写了无数个NSLog,不可能一个一个删了,而且日后如果修改还需要在写非常麻烦。解决办法在.pch里写这样一段宏命令

//把NSLog换成DLog,以后就不用一个一个删除
#ifdef DEBUG
#    define DLog(fmt, ...) NSLog((@"%s [Line %d] " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__);
#else
#    define DLog(...)
#endif// ALog always displays output regardless of the DEBUG setting
#define ALog(fmt, ...) NSLog((@"%s [line %d] " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__);

然后在程序中需要用NSLog的地方全部换成DLog。编写程序时把Edit SchemeL里Build Configuration选项改成Debug(默认就是Debug),程序会正常输出打印。当上线发布时把Debug改成Release,所以DLog就不会打印输出了。

八、如何判断设备是iphone5:

在.pch里添加一段宏命令

//判断设备是不是iphone5
#define iPhone5 ([UIScreen instancesRespondToSelector:@selector(currentMode)] ? CGSizeEqualToSize(CGSizeMake(640, 1136), [[UIScreen mainScreen] currentMode].size) : NO)

在程序中只需判断:

    if (iPhone5) {// Initialization code ...}

九、去掉cell选中时的蓝色背景:

在cellForRowAtIndexPath里加上一句话:

    static NSString *CellIdentifier = @"Cell";MyCustomCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];// Configure the cell...if (cell == nil) {cell = [[[MyCustomCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier]autorelease];}//设置选中后cell的背景颜色,有黑色,灰色,蓝色,和不显示颜色四种cell.selectionStyle = UITableViewCellAccessoryNone;

十、如何判断程序第一次进入:

在AppDelegate里开始位置写

    //判断程序是否第一次进入if (![[NSUserDefaults standardUserDefaults]boolForKey:@"everLaunched"]) {[[NSUserDefaults standardUserDefaults]setBool:YES forKey:@"everLaunched"];[[NSUserDefaults standardUserDefaults]setBool:YES forKey:@"firstLaunch"];}else{[[NSUserDefaults standardUserDefaults]setBool:NO forKey:@"firstLaunch"];}// Save changes to disk[[NSUserDefaults standardUserDefaults] synchronize];

在需要对第一次进行操作时写:

-(void)firstLaunch
{if ([[NSUserDefaults standardUserDefaults]boolForKey:@"firstLaunch"]){// Initialization code}else{// Initialization code
    }
}

十一、IOS的沙盒机制:

IOS为每个应用程序都创建了一个文件系统,每个应用程序只能读取这个文件系统中的文件,不能访问其他程序的文件系统。此区域就被称为沙盒,所有的非代码文件都保存在这里。例如图像、声音、属性列表、本地文件等。有两点需要注意:

1.每个应用程序都有属于自己的储存空间。

2.每个应用程序只能访问自己的空间,不能访问其他程序的储存空间。

每台MAC电脑的用户名文件夹下都有一个默认隐藏的文件夹,叫资源库:

1.显示资源库的终端命令:chflags nohidden ~/Library/

2.隐藏资源库的终端命令:chflags hidden ~/Library/

显示Mac隐藏文件的命令:defaults write com.apple.finder AppleShowAllFiles -bool true

隐藏Mac隐藏文件的命令:defaults write com.apple.finder AppleShowAllFiles -bool false

怎样找到应用程序的沙河路径:

每个沙盒中都有3个文件夹:1.Documents 2.Library 3.tmp

Documents:程序中建立的或在程序中浏览到的文件数据保存在该目录下,iTunes备份和恢复的时候会包括此目录

Library:存储程序的默认设置或其它状态信息;

Library/Caches:存放缓存文件,iTunes不会备份此目录,此目录下文件不会在应用退出删除

tmp:提供一个即时创建临时文件的地方。

itunes在与iphone同步时,备份所有的Documents和Library文件。

iphone在重启时,会丢弃所有的tmp文件。

十二、程序多语言支持或者经常程序会丢失Info.Plist.String(Chinese):

在工程里PROJECT------Localizations下边有个加号,点击一下就会出来很多国家的plist.string文件

十三、检测网路:

用第三方框架NetworkChecker来判断,代码如下,首先引入头文件

#import "NetworkChecker.h" 

然后在.h里定义一个实例方法

-(BOOL)checkNetwork;

在.m文件中写

- (BOOL)checkNetwork {NetworkChecker *networkchecker = [NetworkChecker sharedNetworkChecker];if ([networkchecker networkStatus] == NotReachable) {return NO;//返回NO是没网状态} else {return YES;//返回YES是有网状态
    }
}

写完后当要用到判断网络的地方,这样写

if (![self checkNetwork]) {//当没有网络时执行的方法             

}else{//有网情况下执行方法   

}

十四、用Blocks写网络请求:

 NSString * str = [NSString stringWithFormat:@"http://star.eliteworkltd.com:8002/?json=1&p=1413"];NSURL * url = [NSURL URLWithString:str];//__block的作用是能在setCompletionBlock的内部访问外部的方法__block ASIHTTPRequest * request = [ASIHTTPRequest requestWithURL:url];[request setRequestMethod:@"GET"];[request setCompletionBlock:^{//相当于ASi的RequestFinished方法
}];[request setFailedBlock:^{//相当于ASI的RequestFailed方法
UIAlertView * alert = [[UIAlertView alloc]initWithTitle:@"亲" message:@"非常抱歉" delegate:nil cancelButtonTitle:@"您的网络不给力(︶︿︶)。。。" otherButtonTitles:nil, nil];[alert show];[alert release];}];//启动异步执行[request startAsynchronous];

十五、SDWebImage:

跟以前的AsycImage用法有些相似,只用给一个图片的url地址即可,sdweb会自动帮你读出图片并且缓存,sdweb和Asy不同之处是sdweb需要给一张占位图,在图片没加载出来之前会先显示这张占位图。sdweb里边有个UIImageView+WebCache类,它是一个继承imageview的类目,在.m文件中引入头文件

#import "UIImageView+WebCache.h"

用法

[cell.imageview2 setImageWithURL:[NSURL URLWithString:url] placeholderImage:[UIImage imageNamed:@"57.png"]];

十六、截取当前页面到相册:

需要添加QuartzCore.framework框架,并且引入头文件

#import <QuartzCore/QuartzCore.h>

        //保存图片到相册UIGraphicsBeginImageContext(self.view.bounds.size);//当前视图
        [self.view.layer renderInContext:UIGraphicsGetCurrentContext()];UIImage * viewImage = UIGraphicsGetImageFromCurrentImageContext();UIGraphicsEndImageContext();UIImageWriteToSavedPhotosAlbum(viewImage, nil, nil, nil);UIAlertView * alert = [[UIAlertView alloc]initWithTitle:@"亲" message:@"图片已经为您保存到相册" delegate:nil cancelButtonTitle:@"确定" otherButtonTitles:nil, nil];[alert show];[alert release];

十七、在程序内发邮件:

在程序内发送Email,需要添加MessageUI.framework框架,import头文件,加MFMailComposeViewControllerDelegate代理

#import <MessageUI/MFMailComposeViewController.h>@interface DetailViewController : UIViewController<MFMailComposeViewControllerDelegate>
{}@end

然后调用方法:

//激活邮件功能
[self sendMailInApp];

然后在下边写sendMailInApp方法

#pragma mark ------- Send Email-(void)sendMailInApp
{Class mailClass = (NSClassFromString(@"MFMailComposeViewController"));if (mailClass != nil){if ([mailClass canSendMail]) {[self displayComposerSheet];}else {[self launchMailAppOnDevice];}}else {[self launchMailAppOnDevice];}
}-(void)displayComposerSheet
{MFMailComposeViewController * mailPicker = [[[MFMailComposeViewController alloc]init] autorelease];mailPicker.mailComposeDelegate = self;//设置主题[mailPicker setSubject:[NSString stringWithFormat:@"%@%@%@%@",@"分享自张梦格APP",@"《",self.titleString,@"》"]];//添加发送者NSArray * toRecipients = [NSArray arrayWithObject:@"first@example.com"];[mailPicker setToRecipients:toRecipients];/*//email正文里添加图片UIImage * addPic = [UIImage imageNamed:@"123.jpg"];NSData * imageData = UIImagePNGRepresentation(addPic);[mailPicker addAttachmentData:imageData mimeType:@"" fileName:@"123.jpg"];*/NSString * emailBody = nil;[mailPicker setMessageBody:emailBody isHTML:YES];[self presentModalViewController:mailPicker animated:YES];   }-(void)launchMailAppOnDevice
{NSString * recipients = @"mailto:first@example.com&subject=my email!";NSString * body = @"&body=email body!";NSString * email = [NSString stringWithFormat:@"%@%@",recipients,body];email = [email stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];[[UIApplication sharedApplication]openURL:[NSURL URLWithString:email]];}-(void)mailComposeController:(MFMailComposeViewController *)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError *)error
{NSString * message;switch (result) {case MFMailComposeResultCancelled://用户取消编辑邮件message = @"邮件发送取消";break;case MFMailComposeResultSaved:    //用户成功保存邮件message = @"邮件保存成功";break;case MFMailComposeResultSent:     //用户点击发送,将邮件放到队列中message = @"邮件发送成功";break;case MFMailComposeResultFailed:   //用户试图保存或者发送邮件失败message = @"邮件发送失败";break;default:break;}DLog(@"%@", message);[self dismissModalViewControllerAnimated:YES];
} 

十八、iphone开发的一些总结(原文出自编程神人老莫):

1.Done is better than perfect(尤其是程序第一次提交,不要想着把东西做的多好多炫多么天花乱坠之后在上线,一定要以一个简单又能通过的方式先提交第一版,然后在做第二版更新);

2.优先、尽早的学习苹果的新技术,因为你迟早都是要学的;

3.好的平面设计不等于好的iphone设计,web的一套设计在移动设备上并不适用;

4.选择被证实的成功上线案列走,因为前人已经为你走过无数次的reject之路;

5.你的app要值得用户反复去用,要区别于同类产品。

十九、最后总结几点苹果审核几个要点(都是经过血泪的教训才总结出来的经验),不遵循这些规则你的应用很可能被打回:

1.我的应用第一次被打回来苹果给了原因是服务器太慢,程序里的图片出不来,后来换了服务器,并且在代码上做了优化;第二次又被驳回,苹果给你的原因是not very useful,Simply web sites bundled as apps,苹果认为程序过于简单,就跟一个web的应用一样;don’t provide  any lasting entertainment value(不能提供任何的持续的娱乐价值) ,后来把程序主题框架换成了Path菜单,又加入了用户留言板功能才通过。

2.bug和崩溃:首先最重要一点提交的程序一定不能有bug和崩溃,如果有必定会被打回。

3.条款违规:不符合国家法律规定的,含有严重暴力色情内容的。

4.侵权:也就是说不要有侵权行为或者是窃取用户隐私,被发现的化一定会被打回。

5.功能描述与事实不符,软件说明上吹的多牛X多牛叉,实际上根本就没有 。

6.不能用苹果私有的API

7.山寨:抄袭别人软件创意,严重雷同

8.软件功能不能影响苹果自己的产品,抢苹果生意的,最后都会被pass

转载于:https://www.cnblogs.com/zhangmangyuan/archive/2013/01/23/zhangmengge.html

摄影师张梦格App项目总结相关推荐

  1. 视频教程-React全栈:前后端分离的招聘Web App项目(含资料)-ReactJS

    React全栈:前后端分离的招聘Web App项目(含资料) 张长志技术全才.擅长领域:区块链.大数据.Java等.10余年软件研发及企业培训经验,曾为多家大型企业提供企业内训如中石化,中国联通,中国 ...

  2. 【SwiftUI项目】0011、SwiftUI项目-费用跟踪-记账App项目-第3/3部分 -日期指定选定-新增费用页面

    SwiftUI小功能模块系列 0001.SwiftUI自定义Tabbar动画效果 0002.SwiftUI自定义3D动画导航抽屉效果 0003.SwiftUI搭建瀑布流-交错网格-效果 0004.Sw ...

  3. “失”失物招领App——项目需求分析

    "失"失物招领App--项目需求分析 作业描述 项目 内容 课程名 服务计算与软件服务工程 作业正文 "失"失物招领App--项目需求分析 项目名称 失 工作流 ...

  4. App项目实战之路(四):UI篇

    原创文章,转载请注明:转载自Keegan小钢 并标明原文链接:http://keeganlee.me/post/practice/20160903 微信订阅号:keeganlee_me 写于2016- ...

  5. HarmonyOS(鸿蒙)App项目实战(1)运动手表篇学习笔记

    HarmonyOS(鸿蒙)APP项目实战(1)运动手表篇学习笔记 前言 概括 创建项目 创建主页面 创建index中的组件 设定index中组件的样式 为主页面添加应有的功能 创建倒计时页面 创建da ...

  6. 数据库系统需求分析、概念模型设计及逻辑结构设计——以“到梦空间”APP为例

    "到梦空间"APP的数据库系统需求分析.概念模型设计及逻辑结构设计 1.需求分析 1.1 选定数据库设计对象 1.1.1 组织机构图 组织机构图 1.1.2 数据流图 数据流图 1 ...

  7. 盘点 Github 上的高仿 app 项目

    点击上方蓝色"方志朋",选择"设为星标" 回复"666"获取独家整理的学习资料! 作者:水哥:来源:GitHubClub 学技术的,多多少少 ...

  8. App项目实战之路(二):API篇

    原创文章,转载请注明:转载自Keegan小钢 并标明原文链接:http://keeganlee.me/post/practice/20160812 微信订阅号:keeganlee_me 写于2016- ...

  9. 第一次,触碰Web App项目,栽过的那些坑。

    此项目是一个IPad上的Web App项目,页面的滚动用了最新的IScroll 5.0 插件, 确实是挺潮的. 项目用时 1个月 完成的, 准备今天晚上上线. 这是年前的最后一篇文章了,与众位博友分享 ...

最新文章

  1. 双十一:你收到了多少商家短信
  2. db2 如何导出insert语句_实用技术:MYSQL特别实用的几种SQL语句送给大家,让你的SQL高大上...
  3. python深入和扩展_用Python来扩展Postgresql(一)
  4. Bootstrap:弹出框和提示框效果以及代码展示
  5. 智能会议系统(23)---移动端视频通话开源软件比较
  6. Java 之 Annotation(注解)介绍
  7. Nginx负载调度器+双Tomcat负载及会话共享+MySQL后端数据库
  8. java复试容易被刷掉吗_推免生一定被录取吗复试会被刷吗
  9. 网络创新激活西部科技,戴尔2013软件定义网络圆桌会谈的启示
  10. 【学习OpenCV4】几何图形的绘制方法
  11. python实现多智能体一致性_多智能体深度学习算法MADDPG的PARL实践
  12. vscode开发ExtJs安装插件以及破解方法
  13. 前端学习路线之html5 (一)
  14. wos 文献被引_WoS和ESI数据库高被引论文的界定.pdf
  15. NFT 游戏含义:游戏中的 NFT 是什么?
  16. 人生第一次面试还是霸面----cvte
  17. Windows的任务调度机制
  18. IPC清晰的分类总结
  19. 英文缩略词——全程及中文含义
  20. Greenshot 学习笔记(2) Greenshot.Drawing.Gripper类

热门文章

  1. APT案例之点击事件
  2. wordpress 分类使用不同的模版
  3. Android 中查看内存的使用情况集经常使用adb命令
  4. Matlab中mat2cell的使用
  5. 出来工作五年的经历总结(五年前,你在干嘛?)
  6. 印章WinForm自定义控件封装,提供源码下载
  7. 阿里云ECS主机自定义进程监控
  8. [python] 之all()和any()内置函数
  9. iOS网络 把数据存入钥匙串
  10. LINUX怎么修改IP地址