• 摄影师张梦格App项目总结


         昨天张梦格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

  • 相关阅读:
    URL重写,asp.net URL重写,URLRewriter.dll下载,URLRewriter,URLRewriter下载,URL重写学习
    C#制作图像旋转的程序范例

    去掉qq空间不能添加带“=”号的网络音乐地址限制
    《Javascript高级程序设计》读书笔记(二)
    NExcelAPI使用测试
    常用的开源组件
    [转]编程的首要原则(s)是什么?
    《Javascript高级程序设计》读书笔记(一)
    [转]SQL错误处理的脆弱性演示
  • 原文地址:https://www.cnblogs.com/zhangmangyuan/p/zhangmengge.html
Copyright © 2020-2023  润新知