parse配置ios 使用地址_ios date.parse - CSDN
  • 开放平台:Parse for iOS

    2015-03-26 11:06:21
    Parse一款基于Baas的后端云存储服务平台,为开发者提供云端数据存储和读取的能力,Parse团队在其SDK方面花费了大功夫,实现了很多非常有用的功能.并且,非常的稳定,兼容和灵活性,相对于其他Baas平台,Parse在上手方面是...

    引言:

    Parse一款基于Baas的后端云存储服务平台,为开发者提供云端数据存储和读取的能力,Parse团队在其SDK方面花费了大功夫,实现了很多非常有用的功能.并且,非常的稳定,兼容和灵活性,相对于其他Baas平台,Parse在上手方面是最为容易的.



    Parse的特性如下:

    1:自定义数据字典

    2:消息推送

    3:地理位置

    4:数据缓存

    5:离线数据同步

    6:云端自定义代码

    7:二进制文件读取



    参考资料: 

    1:Parse的主页

    https://www.parse.com

    2:


    安装:

    1.首选的安装方式是跟着Parse自家提供的官方起步教程即可完成,非常简单!

    2.也可以用CocoPods,只是SDK太肥了,而且装的话,还会有一个Facebook SDK的依赖.



    使用:

    Parse支持的数据类型主要如下:

    Number: 对应各种类型,包括:整形,浮点型 转换成NSNumber后存储到Parse Cloud

    Date: 对应NSDate

    Array:对应NSArray. 万能的数组(Parse的强大之处)

    String:对应NSString 

    Null:  很少用到

    Pointer: 指针:相当于表与表之间的外键关系, 只存储着某个对象的ID

    Relation:关系:应付多对多关系时的方案,但是可以用Array达到同意的功能.



    查询:

    Parse设定了尽可能多样的查询方式,并且它还支持NSPredicate. 这对于使用过CoreData的人来说,是比较容易上手的.

    首先来说说Parse提供哪些查询接口


    时间:

    查询创建时间大于某个时间的数据行:

    NSDate *lastQueryDate = [self lastQueryTime];
    if (lastQueryDate == nil) {
        lastQueryDate = [NSDate date];
    }
    [query whereKey:@"createdAt" greaterThan:lastQueryDate];

    查询缓存策略:

    kPFCachePolicyIgnoreCache 
    查询不从缓存加载结果或将结果保存到缓存。默认缓存策略为 kPFCachePolicyIgnoreCache。
    kPFCachePolicyCacheOnly 
    查询会忽略网络,仅从缓存加载结果。如果没有缓存的结果,则会引发 PFError。
    kPFCachePolicyNetworkOnly 
    查询不从缓存加载结果,但会将结果保存到缓存。
    kPFCachePolicyCacheElseNetwork 
    查询首先尝试从缓存加载结果,但如果加载失败则从网络加载结果。如果缓存和网络加载都不成功,则会出现 PFError。
    kPFCachePolicyNetworkElseCache 
    查询首先尝试从网络加载结果,但如果加载失败则从缓存加载结果。如果网络和缓存加载都不成功,则会出现 PFError。
    kPFCachePolicyCacheThenNetwork 
    查询首先从缓存加载结果,然后再从网络加载。在此情况下,实际上会调用两次回调 - 第一次针对缓存的结果,随后针对网络结果。由于会在不同的时间返回两个结果,因此该缓存策略不能与 findObjects 同时使用。




    Push:

    官方提供了一个详细的消息推送配置流程:

    https://parse.com/tutorials/ios-push-notifications

    Parse远程推送教程实在是太详细了,图文并茂.

    在这里我简单复述了一下整个过程方便理解:

    1.申请苹果的开发者招生计划,并成功激活.

    2.通过本地的Mac系统生成一个证书签名请求(Certificate Signing Request),

    3:接下去苹果开发者主页的Member Center(会员中心)创建一个新的App IDs. 并通过证书签名请求激活这个App IDs的远程推送服务功能.

    4.下载这个App IDs的推送许可服务,并通过钥匙访问串导出密匙(p12).

    5.最后生成这个App IDs的描述文件,并应用到工程中.

    6.编写Parse所提供的Push的相关API代码. 实现远程消息推送.


    其中有一个步骤是当你通过Certificate Signing Request(证书签名请求)激活了苹果的远程推送通知服务以后.

    并下载了推送许可证书:aps_development.cer.  教程中要求从钥匙访问串(Keychain Access)中导出.p12后缀的密匙.

    在导出时有两点需要注意:

    1:请在名称为 Apple Development IOS Push Services : ***** 或 Apple Prodoction IOS Push Services : ***** 的栏位上直接右键,如下图:


    图中方框中的三角箭头,请直接无视和忽略他。 里面是证书的创建者信息而已。 虽然也可以导出p12, 但是这个p12是无效(请特别注意)


    2:在导出时要求你输入密码,请直接忽视,也就是空密码即可,否则Parse 的 App Settings - Push Notifications里要求上传的p12密匙无法成功.




    最后还有一个细节要注意,也就是当你的产品成功发布到应用商店以后,你之前用来测试的开发版本证书,应该替换为发布版本证书(aps_production.cer). 否则从App Store上面下载的应用将无法收到消息推送.. 所以,你需要重新上传发布版本的密匙.跟开发版本的上传方式一样. 成功后如下图所示:




    总结:





    可能遇到的问题:

    1:编译问题.


    解决方案:

    http://stackoverflow.com/questions/15457136/parse-for-ios-errors-when-trying-to-run-the-app





    展开全文
  • 最近在学习Parse,但是Parse的中文教程比较少,看到这篇英文教程,把它翻译一下与大家共享,本人的英语水平不是很高,有的地方可能译得不好,望大神轻拍。。 原文地址...

           最近在学习Parse,但是Parse的中文教程比较少,看到这篇英文教程,把它翻译一下与大家共享,本人的英语水平不是很高,有的地方可能译得不好,望大神轻拍。。

    原文地址http://www.raywenderlich.com/19341/how-to-easily-create-a-web-backend-for-your-apps-with-parse


    首先—创建你的后台服务

           在开始编写你的app前,你首先要做的是创建你的Parse后台,每个开发人员和每个app都需要一个不同的标识,否则你的数据和账号会和别人的混淆,虽然这会带来一些有趣的副作用,但是你应该使你的数据和别人的区别开来。

           第一步就是访问Parse.com,然后在右上角点击Sign Up创建一个新账号。

           账号创建好后,你会被要求创建你的第一个app,每个你想要使用后台服务的应用都要单独地注册。在这里,我们把这个应用命名为“tutorialApp”;在Parse中可能存在着很多同名的app,但是你注册的只有一个。

           你的app创建好后,来到Dashboard页面,在这里你可以查看你app的数据,这里有一系列的操作按钮,有点像UISegmentedControl,如以下截图:

           这里是对屏幕上方一些操作按钮的说明:

    • Overview:在这里你可以看到一些关于你app统计信息,如流量,推送信息,调用API的次数等。
    • Data Browser:这里你可以看到所有放到你后台里的数据。你也可以看到账号,你可以手动地操作数据,这里就像一个数据库编辑器。
    • Push Notifications:可以在这里向你的用户发送推送信息,或者向一个特定组发送推送信息。
    • Setting:你可以在这里设置你的app,管理它的安全性,和导出你的数据。

    Parse示例项目

           为了在这篇教程中创建一个后台服务,这里提供了一个简单的项目来使大家容易入手。你可以下载它并跟着本教程添加Parse服务。示例项目就放在github上。

           你可以在https://github.com/toniomg/TutorialBase上下载这个项目,也可以使用以下终端命令:

            git clone https://github.com/toniomg/TutorialBase
           在Xcode中打开这个项目,编译运行!首先你会看到一个登陆界面,但目前为止,这个项目还没有加入后台服务,你很快就会完成这些功能。

           在继续学习之前,先打开MainStoryboard.storyboard来看一下程序的结构和流程。

           这个项目分为4个主要的视图,每个视图在storyboard中都有自己的视图控制器和视图

    • Log In:登陆页面有用户名和密码文本框,还有一个Sign Up按钮,在你想注册一个新账号的时候用来前往Sign Up页面。
    • Sign Up:在这个视图,用户输入用户名和密码,用来在后台服务中创建一个新账号。
    • Wall:这是这个app中的主要界面,这里用户可以看到其他用户上传的带有评论的图片。
    • Upload:在这里,用户可以上传带有评论的图片到照片墙上。

           注意segue线表示了这个app的流向,包括绕过了Sign Up界面的流向。如下图所示:

          

    准备Parse服务

           第一步自然是要配置你的项目使它可以加入Parse服务!

           在这个地址下载Parse框架:https://parse.com/downloads/ios/parse-library/latest

           下载完框架后,解压并把Parse.framework文件夹拖入你的Xcode项目的Framework文件夹内。记得勾选“Copy item...”和“Create groups...”。

           默认下Parse框架会加入到“tutorialBase”中,这也是我们期望的,然后添加其他的框架,完成后的框架列表如下:

          

           (怎么添加框架的步骤就不说了,网上一大把)

           下一步就是在app启动时注册后台服务,在AppDelegate.m文件中加入头文件:

            #import <Parse/Parse.h>
    
           然后,在函数didFinishLaunchingWithOptions的开头,加入语句:
            [Parse setApplicationId:AppID clientKey:clientKey];
           你会看到有错误出现了,Application ID和Client Key需要一个常量,但是它们现在还是空的——是时候改正了!

           为了找到需要的API keys,要去到Parse Dashboard(1),选择你的app(2),然后找到左侧栏,复制Application ID和Client Keys(3),如下图所示:

           

           (注意,我看到的界面与上图有的不同,我是在Settings——Application keys界面中找到所需的App ID和Client Key的)

           你可以直接把keys复制到setApplicationId方法中,它们只需使用一次。完成后,这个方法看起来和下面代码是相似的,只是keys有所不同:

           - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
           {
                // Register our parse app with the service
               [Parse setApplicationId:@"UXuHVmNRX44rcczbv1NIIHHbazteYfQU4GAJ8EOS"
                         clientKey:@"cqFwq5Vpb19VKPKSe1dOZJrjsQbytPzKa2bEdakx"];
     
                return YES;
           }

           编译运行你的app!确定没有任何错误。一切顺利的话,意味着你的app已经绑定Parse后台服务了。你即将开始使用后台服务!

           下一步就是创建一些示例对象!


    创建示例对象

           现在你的项目已经配置好了并连接上Parse,现在花一点时间来复习一下发送对象到后台和从后台获取对象的概念。

           你可以根据之前的步骤创建一个新的项目,或者在示例项目中交替地使用AppDelegate文件。

           在这个例子中,你会使用PFObject类,这是一个基本的类,提供一些基本的对象操作方法。对于PFObject类的详细详细,你可以参照这个文档:https://parse.com/docs/ios/api/Classes/PFObject.html

           在示例中,你会上传一个叫“Player”的对象,这个对象有“Name”和“Score”字段。在你的数据库中,你会有一个名为“Player”的表,和你上传的所有对象,下面来看看例子:

           找到didFinishLaunchingWithOptions方法,之后添加以下代码,连接到Parse后台服务:

    PFObject *player = [PFObject objectWithClassName:@"Player"];//1
    [player setObject:@"John" forKey:@"Name"];
    [player setObject:[NSNumber numberWithInt:1230] forKey:@"Score"];//2
    [player save];//3
           注释1:在这一行你创建了一个类名为“Player”的对象。

           注释2:在这里你对字段赋上值,name字段的值为“John”,score字段的值为“1230”。

           注释3:在这里你保存了对象,对象会同步发送到Parse服务器。

           这就可以了!最厉害的是你无须在浏览器上的Parse界面去创建一个表,这个表将根据你上传的对象自动创建。

           编译运行你的程序!如果你正确地在代码中设置了keys,还有你的app在上传对象前正确注册到了Parse服务器,那么一切都会很顺利。

           但上传的对象在哪?

           为了检查你的对象是否正确保存了,在浏览器中打开Parse dashboard界面,点击“Data Browser”,在这里你应该可以看到你上传的对象,如下图:

          

           这就是保存对象最简单的方法。恭喜你成功地和后台进行了交互!


    异步操作

           你可能已经注意到了,在控制带出现了警告信息,你的app会被阻塞直到你的对象完成上传,这是同步的网络操作!这样你不但不能检查调用的结果,你的用户也会被卡在调用API的等待上。

           你的应用可能会因此获得一星评分!当然,还是有解决的办法的。

           注释掉之前在didFinishLaunchingWithOptions方法添加的代码,否则你的app在每次运行时都会上传一个新的对象。再添加以下的代码:

         PFObject *anotherPlayer = [PFObject objectWithClassName:@"Player"];
        [anotherPlayer setObject:@"Jack" forKey:@"Name"];
        [anotherPlayer setObject:[NSNumber numberWithInt:840] forKey:@"Score"];
        [anotherPlayer saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
     
            if (succeeded){
                NSLog(@"Object Uploaded!");
            }
            else{
                NSString *errorString = [[error userInfo] objectForKey:@"error"];
                NSLog(@"Error: %@", errorString);
            }
     
        }];
           正如你所看到,你使用了异步的方式上传了对象,还有在一个代码块中检查返回结果。随着代码块在iOS中越来越多的使用,你应该对代码块感到熟悉。每个简单的UIView动画目前都是在代码块中完成的。幸运的是,这里有一个教程让你更加熟悉代码块这种特性,链接为How To Use Block in iOS 5 Tutorial - Part 1(英文教程)。

           编译运行你的app吧!

           在Parse Dashboard中检查你是否正确上传了对象到服务器。不同的是这次你的app在上传对象时不会阻塞了。

           你应该会注意到你的设备(或模拟器)会出现一个网络活动指示器,指示器旋转时登陆界面会弹出来。过了一会儿,当交互完成后,你会看到控制台中出现NSLog消息。当要上传想image那种要花更长时间去传输的对象时,这是十分有用的。

           像之前那样,去到Data Browser界面你就会看到,在通过同步上传的对象的旁边出现了一个通过异步上传的对象。


    取得对象

           现在,是时候去获取对象了。为了实现这个目的,Parse有一个类PFQuery——它执行查询操作,具体可看PFQuery documentation

           你将会编写代码,去查询Score超过1000,Name为“John”的对象。在这之前,注释掉之前的代码,否则每次运行程序都会上传新的对象。加入以下代码:

    PFQuery *query = [PFQuery queryWithClassName:@"Player"]; //1
    [query whereKey:@"Name" equalTo:@"John"];//2
    [query whereKey:@"Score" greaterThan:[NSNumber numberWithInt:1000]]; //3
    [query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {//4
        if (!error) {
            NSLog(@"Successfully retrieved: %@", objects);
        } else {
            NSString *errorString = [[error userInfo] objectForKey:@"error"];
            NSLog(@"Error: %@", errorString);
        }
    }];
           注释1:你创建了一个查询对象,“Player”是你想进行查询的表。

           注释2:你只想获取name为“John”的对象。。。

           注释3:。。。还有score要超过1000的

           注释4:发送查询,在代码块中打印结果。

           编译运行你的app!由于操作是异步的,你的UI界面不会卡住——这是让你的用户感到高兴的关键。在控制台中,你会看到符合查询条件的所有对象,如下图所示:

          

           在对基本的存储和查询操作有了简单探索后,你可以继续在项目中操作了。

           回到项目中,注释掉刚才的代码。


    用户注册

           你的用户使用你的app时的第一步就是在注册账号。

           在项目中打开RegisterViewController.m文件,添加以下Parse头文件:

    #import <Parse/Parse.h>
           正如你所看到的,现在注册视图除了打开和关闭外,还没有添加任何功能。你的任务就是在用户点击“Sign Up”按钮时,可以进行注册操作。

           为了实现这个目的,你可以找到关联了这个按钮的IBAction:

    //Sign Up Button pressed
    -(IBAction)signUpUserPressed:(id)sender
    {
        //TODO
        //If signup sucessful:
        //[self performSegueWithIdentifier:@"SignupSuccesful" sender:self];
    }
          你需要在这里添加注册操作的代码,然后检查是否可以成功注册。

          用以下的代码替代上面signUpUserPressed方法中的内容:

    //Sign Up Button pressed
    -(IBAction)signUpUserPressed:(id)sender
    {
        //1
        PFUser *user = [PFUser user];
        //2
        user.username = self.userRegisterTextField.text;
        user.password = self.passwordRegisterTextField.text;
        //3
        [user signUpInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
            if (!error) {
                //The registration was successful, go to the wall
                [self performSegueWithIdentifier:@"SignupSuccesful" sender:self];
     
            } else {
                //Something bad has occurred
                NSString *errorString = [[error userInfo] objectForKey:@"error"];
                UIAlertView *errorAlertView = [[UIAlertView alloc] initWithTitle:@"Error" message:errorString delegate:nil cancelButtonTitle:@"Ok" otherButtonTitles:nil, nil];
                [errorAlertView show];
            }
        }];
    }
           在以上代码中,创建一个用户的步骤是:

           注释1:创建一个新的PFUser对象,这个类是用来登陆和注册的。它会保储已经通过验证的用户,你可以在你想要的时候访问这个用户的数据。你可以在这里找到关        于PFUser的文档。

           注释2:指定TextFields中的内容为用户名和密码。

           注释3:调用在后台注册用户的方法,在代码块中检查结果。结果有两种可能,一种是注册成功,新用户被创建,然后视图转到照片墙视图。或者是注册失败,产生错误信息,你可以对用户显示错误描述。

           编译运行你的app看是否有错误!

           为了检查用户注册操作,运行程序,在Log In界面按下Sign Up按钮,你会看到下图:

          

           输入用户名和密码,按下Sign Up按钮,如果顺利的话,app会转到照片墙视图。

           好极了!但你仍需要确认你的新用户是否已经保存了。打开Data Browser来确认新用户是否存在,如下图所示:

          

           恭喜!你第一个用户已经创建了!现在是时候让用户登陆并和后台交互了!


    用户登陆

           在这一节,你会学习怎样让你在上面创建的用户进行登陆。

           打开LoginviewController.m文件,加上头文件:

    #import <Parse/Parse.h>
           然后看到以下代码:
    //Login button pressed
    -(IBAction)logInPressed:(id)sender
    {
        //If user logged succesful:
        //[self performSegueWithIdentifier:@"LoginSuccesful" sender:self];
     
    }
           正如你所看到的,这一部分和注册部分的代码很相似!你会再次使用PFUser类,但这次你是用它来进行登陆操作的。用以下的代码替换掉loginPressed方法中的内容:

    //Login button pressed
    -(IBAction)logInPressed:(id)sender
    {
        [PFUser logInWithUsernameInBackground:self.userTextField.text password:self.passwordTextField.text block:^(PFUser *user, NSError *error) {
            if (user) {
                //Open the wall
                 [self performSegueWithIdentifier:@"LoginSuccesful" sender:self];
            } else {
                //Something bad has ocurred
                NSString *errorString = [[error userInfo] objectForKey:@"error"];
                UIAlertView *errorAlertView = [[UIAlertView alloc] initWithTitle:@"Error" message:errorString delegate:nil cancelButtonTitle:@"Ok" otherButtonTitles:nil, nil];
                [errorAlertView show];
            }
        }];
    }
          代码和注册代码很相似。运行app,你会看到以下界面:

          

           尝试用你刚才创建的用户进行登陆,如果顺利的话,app应该会转到照片墙视图。


    照片墙

           刚才的操作(注册和登陆)都会使视图转到照片墙视图,在这个视图中,你可以看到所用的注册用户上传到后台服务器的带有评论的照片。

           但这在看到照片之前,也得先有照片上传上去啊!

           在Parse上传文件非常简单,先看一看UploadImageViewController.m文件,文件就是在这里进行上传的。

           一个已经登陆的用户可以点击在照片墙视图的Upload按钮,就是导航栏右边的按钮,上传文件的过程就在下面给出。

           用户点击Upload按钮时,就会触发selectPicturePressed方法。系统的照片库就会出现,让用户从中选择一张图片,如下所示:

    -(IBAction)selectPicturePressed:(id)sender
    {
        //Open a UIImagePickerController to select the picture
        UIImagePickerController *imgPicker = [[UIImagePickerController alloc] init];
        imgPicker.delegate = self;
        imgPicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
     
        [self.navigationController presentModalViewController:imgPicker animated:YES];
    }
          选好图片后,图片就会出现在主界面的UIImageView中,如下所示:

    - (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingImage:(UIImage *)img editingInfo:(NSDictionary *)editInfo 
    {
        [picker dismissModalViewControllerAnimated:YES];
        //Place the image in the imageview
        self.imgToUpload.image = img;
    }
           用户可以在文本框中输入对照片的评论,也可以不输评论,这是可选的。

           这些都已经为你做好了!现在应该添加代码来实现sendPressed方法了。这个方法是导航栏上的按钮触发的,用来上传图片和评论到服务器。

           过程分开两个部分。首先,用PFFile对象上传图片;然后把对象附到PFObject上传到服务器。

           先在UploadImageViewController.m文件开头加上头文件:

    #import <Parse/Parse.h>
           在-(IBAction)sendPressed:(id)sender方法中加入以下代码:

      //Upload a new picture
        //1
        PFFile *file = [PFFile fileWithName:@"img" data:pictureData];
        [file saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
     
            if (succeeded){
                //2
                //Add the image to the object, and add the comment and the user
                PFObject *imageObject = [PFObject objectWithClassName:@"WallImageObject"];
                [imageObject setObject:file forKey:@"image"];
                [imageObject setObject:[PFUser currentUser].username forKey:@"user"];
                [imageObject setObject:self.commentTextField.text forKey:@"comment"];
                //3
                [imageObject saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
                    //4
                    if (succeeded){
                        //Go back to the wall
                        [self.navigationController popViewControllerAnimated:YES];
                    }
                    else{
                        NSString *errorString = [[error userInfo] objectForKey:@"error"];
                        UIAlertView *errorAlertView = [[UIAlertView alloc] initWithTitle:@"Error" message:errorString delegate:nil cancelButtonTitle:@"Ok" otherButtonTitles:nil, nil];
                        [errorAlertView show];
                    }
                }];
            }
            else{
                //5
                NSString *errorString = [[error userInfo] objectForKey:@"error"];
                UIAlertView *errorAlertView = [[UIAlertView alloc] initWithTitle:@"Error" message:errorString delegate:nil cancelButtonTitle:@"Ok" otherButtonTitles:nil, nil];
                [errorAlertView show];
            }        
        } progressBlock:^(int percentDone) {
            NSLog(@"Uploaded: %d %%", percentDone);
        }];
           下面来解析一下以上代码:

           注释1:用图片创建PFFile对象,然后在后台保存它。在代码块的末尾你可以检查上传的进度。

           注释2:上传成功后,创建含有图片和数据的PFObject对象,对象中设置文件,用户名和评论。

           注释3:在后台中保存PFObject对象。

           注释4:如果成功了,就返回到照片墙视图。

           注释5:失败了就通知用户。

           编译运行你的app!用之前创建的用户名登陆,来到Upload界面,如下图所示:

          

           按下Select Picture在相册中选择一张图片,如果想的话,可以写上评论,在按下Send按钮。

           你可以在控制台中看到上传的进度。

           现在去到Data Browser界面看看,你会看到一个新的名为“WallImageObject”的表和里面的对象,但等等,在app中还没看到这些图片对象呢!!

           现在是时候获取这些图片了!


    在照片墙上贴上图片

           WallPicturesViewController.m文件用于展示用户已上传的照片。

           在WallPictureController.m文件开头加上头文件:

    #import <Parse/Parse.h>
           getWallImage方法会在视图加载获取图片时调用,现在这个方法还是空的,在这个方法中加入以下代码:

    -(void)getWallImages
    {
        //Prepare the query to get all the images in descending order
        //1
        PFQuery *query = [PFQuery queryWithClassName:@"WallImageObject"];
    //2
        [query orderByDescending:@"createdAt"];
        [query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
            //3 
            if (!error) {
                //Everything was correct, put the new objects and load the wall
                self.wallObjectsArray = nil;
                self.wallObjectsArray = [[NSArray alloc] initWithArray:objects];
                [self loadWallViews];
     
            } else {
     
                //4
                NSString *errorString = [[error userInfo] objectForKey:@"error"];
                UIAlertView *errorAlertView = [[UIAlertView alloc] initWithTitle:@"Error" message:errorString delegate:nil cancelButtonTitle:@"Ok" otherButtonTitles:nil, nil];
                [errorAlertView show];
            }
        }];
     
    }
           解释一下:

           注释1:用你想查询的表的名字创建一个查询对象。

           注释2:查询结果根据“createdAt”属性降序排列。

           注释3:找到符合条件的对象,把WallImageObject类型的对象展示出来。如果顺利的话,把下载到的对象替代wallObjectArray数组中的内容。

           注释4:出错了的话就告知用户。

           对象下载好后,就要在照片墙上展示它了!看到loadWallImage方法,加入以下代码:

    -(void)loadWallViews
    {
        //Clean the scroll view
        for (id viewToRemove in [self.wallScroll subviews]){
     
            if ([viewToRemove isMemberOfClass:[UIView class]])
                [viewToRemove removeFromSuperview];
        }
     
        //For every wall element, put a view in the scroll
        int originY = 10;
     
        for (PFObject *wallObject in self.wallObjectsArray){
     
            //1
            //Build the view with the image and the comments
            UIView *wallImageView = [[UIView alloc] initWithFrame:CGRectMake(10, originY, self.view.frame.size.width - 20 , 300)];
     
            //2
            //Add the image
            PFFile *image = (PFFile *)[wallObject objectForKey:@"image"];
            UIImageView *userImage = [[UIImageView alloc] initWithImage:[UIImage imageWithData:image.getData]];
            userImage.frame = CGRectMake(0, 0, wallImageView.frame.size.width, 200);
            [wallImageView addSubview:userImage];
     
            //3
            //Add the info label (User and creation date)
            NSDate *creationDate = wallObject.createdAt;
            NSDateFormatter *df = [[NSDateFormatter alloc] init];
            [df setDateFormat:@"HH:mm dd/MM yyyy"];
            //4
            UILabel *infoLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 210, wallImageView.frame.size.width,15)];
            infoLabel.text = [NSString stringWithFormat:@"Uploaded by: %@, %@", [wallObject objectForKey:@"user"], [df stringFromDate:creationDate]];
            infoLabel.font = [UIFont fontWithName:@"Arial-ItalicMT" size:9];
            infoLabel.textColor = [UIColor whiteColor];
            infoLabel.backgroundColor = [UIColor clearColor];
            [wallImageView addSubview:infoLabel];
     
            //5
            //Add the comment
            UILabel *commentLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 240, wallImageView.frame.size.width, 15)];
            commentLabel.text = [wallObject objectForKey:@"comment"];
            commentLabel.font = [UIFont fontWithName:@"ArialMT" size:13];
            commentLabel.textColor = [UIColor whiteColor];
            commentLabel.backgroundColor = [UIColor clearColor];
            [wallImageView addSubview:commentLabel];
     
            //6
            [self.wallScroll addSubview:wallImageView];
     
     
            originY = originY + wallImageView.frame.size.width + 20;
     
        }
     
        //7
        //Set the bounds of the scroll
        self.wallScroll.contentSize = CGSizeMake(self.wallScroll.frame.size.width, originY);
     
    }
           第一步就是清理scrollView中的东西,然后你遍历了数组中的内容。每个数组元素就是一个PFObject对象,对象包含了一个PFFile。

           对于数组中的每个对象:

           注释1:创建包含图片和评论的视图。

           注释2:取得图片对象数据(从PFFile中),然后用数据初始化一个UIImageView对象。

           注释3:取得对象的创建信息。

           注释4:取得上传图片的用户名,把它和创建数据放到一个label中。

           注释5:将评论放到另一个label中。

           注释6:将内容添加到scrollView中。

           当每个对象都被解析过后,就根据最后的视图的大小和位置来设置scrollview的边界。

           编译运行app!不出意外的话,你就会看到你之前上传的图片和评论了。花点时间上传更多的图片和评论,看看它们在照片墙上展示出来的效果吧。

           感觉很好吧?


    退出登陆

           这篇教程的最后一部分就是怎么让用户退出登陆。为此,看到WallPictureViewController.m文件中的logoutPressed方法,在这个方法中加入以下代码:

    -(IBAction)logoutPressed:(id)sender
    {
        [PFUser logOut];
        [self.navigationController popViewControllerAnimated:YES];
    }
           运行项目,这就搞定了!


    教程来到这里也差不多结束了,希望这篇教程能给需要的人带来一点帮助。PS:翻译真的很累。。向那些默默为我们翻译各种外国好文章的大神们致敬!

    展开全文
  • Parse 使用- iOS 后台数据 本文是Ctrl+C文章: 原文地址:http://blog.csdn.net/vipwangl/article/details/8846415  最近在学习Parse,但是Parse的中文教程比较少,看到这篇英文教程,把它翻译一下与大家...

    Parse 使用- iOS 后台数据

    本文是Ctrl+C文章:

    原文地址:http://blog.csdn.net/vipwangl/article/details/8846415

     最近在学习Parse,但是Parse的中文教程比较少,看到这篇英文教程,把它翻译一下与大家共享,本人的英语水平不是很高,有的地方可能译得不好,望大神轻拍。。

    原文地址http://www.raywenderlich.com/19341/how-to-easily-create-a-web-backend-for-your-apps-with-parse

     

    首先—创建你的后台服务

           在开始编写你的app前,你首先要做的是创建你的Parse后台,每个开发人员和每个app都需要一个不同的标识,否则你的数据和账号会和别人的混淆,虽然这会带来一些有趣的副作用,但是你应该使你的数据和别人的区别开来。

           第一步就是访问Parse.com,然后在右上角点击Sign Up创建一个新账号。

           账号创建好后,你会被要求创建你的第一个app,每个你想要使用后台服务的应用都要单独地注册。在这里,我们把这个应用命名为“tutorialApp”;在Parse中可能存在着很多同名的app,但是你注册的只有一个。

           你的app创建好后,来到Dashboard页面,在这里你可以查看你app的数据,这里有一系列的操作按钮,有点像UISegmentedControl,如以下截图:

           这里是对屏幕上方一些操作按钮的说明:

    • Overview:在这里你可以看到一些关于你app统计信息,如流量,推送信息,调用API的次数等。
    • Data Browser:这里你可以看到所有放到你后台里的数据。你也可以看到账号,你可以手动地操作数据,这里就像一个数据库编辑器。
    • Push Notifications:可以在这里向你的用户发送推送信息,或者向一个特定组发送推送信息。
    • Setting:你可以在这里设置你的app,管理它的安全性,和导出你的数据。

    Parse示例项目

           为了在这篇教程中创建一个后台服务,这里提供了一个简单的项目来使大家容易入手。你可以下载它并跟着本教程添加Parse服务。示例项目就放在github上。

           你可以在https://github.com/toniomg/TutorialBase上下载这个项目,也可以使用以下终端命令:

    1. git clone https://github.com/toniomg/TutorialBase  

           在Xcode中打开这个项目,编译运行!首先你会看到一个登陆界面,但目前为止,这个项目还没有加入后台服务,你很快就会完成这些功能。

     

           在继续学习之前,先打开MainStoryboard.storyboard来看一下程序的结构和流程。

           这个项目分为4个主要的视图,每个视图在storyboard中都有自己的视图控制器和视图

    • Log In:登陆页面有用户名和密码文本框,还有一个Sign Up按钮,在你想注册一个新账号的时候用来前往Sign Up页面。
    • Sign Up:在这个视图,用户输入用户名和密码,用来在后台服务中创建一个新账号。
    • Wall:这是这个app中的主要界面,这里用户可以看到其他用户上传的带有评论的图片。
    • Upload:在这里,用户可以上传带有评论的图片到照片墙上。

           注意segue线表示了这个app的流向,包括绕过了Sign Up界面的流向。如下图所示:

           

    准备Parse服务

           第一步自然是要配置你的项目使它可以加入Parse服务!

           在这个地址下载Parse框架:https://parse.com/downloads/ios/parse-library/latest

           下载完框架后,解压并把Parse.framework文件夹拖入你的Xcode项目的Framework文件夹内。记得勾选“Copy item...”和“Create groups...”。

           默认下Parse框架会加入到“tutorialBase”中,这也是我们期望的,然后添加其他的框架,完成后的框架列表如下:

           

           (怎么添加框架的步骤就不说了,网上一大把)

           下一步就是在app启动时注册后台服务,在AppDelegate.m文件中加入头文件:

    1. #import <Parse/Parse.h>  

           然后,在函数didFinishLaunchingWithOptions的开头,加入语句:

    1. [Parse setApplicationId:AppID clientKey:clientKey];  

           你会看到有错误出现了,Application ID和Client Key需要一个常量,但是它们现在还是空的——是时候改正了!

     

           为了找到需要的API keys,要去到Parse Dashboard(1),选择你的app(2),然后找到左侧栏,复制Application ID和Client Keys(3),如下图所示:

            

           (注意,我看到的界面与上图有的不同,我是在Settings——Application keys界面中找到所需的App ID和Client Key的)

           你可以直接把keys复制到setApplicationId方法中,它们只需使用一次。完成后,这个方法看起来和下面代码是相似的,只是keys有所不同:

     
    1. - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions  
    2. {  
    3.      // Register our parse app with the service  
    4.     [Parse setApplicationId:@"UXuHVmNRX44rcczbv1NIIHHbazteYfQU4GAJ8EOS"  
    5.               clientKey:@"cqFwq5Vpb19VKPKSe1dOZJrjsQbytPzKa2bEdakx"];  
    6.   
    7.      return YES;  
    8. }  

           编译运行你的app!确定没有任何错误。一切顺利的话,意味着你的app已经绑定Parse后台服务了。你即将开始使用后台服务!

           下一步就是创建一些示例对象!

     

    创建示例对象

           现在你的项目已经配置好了并连接上Parse,现在花一点时间来复习一下发送对象到后台和从后台获取对象的概念。

           你可以根据之前的步骤创建一个新的项目,或者在示例项目中交替地使用AppDelegate文件。

           在这个例子中,你会使用PFObject类,这是一个基本的类,提供一些基本的对象操作方法。对于PFObject类的详细详细,你可以参照这个文档:https://parse.com/docs/ios/api/Classes/PFObject.html

           在示例中,你会上传一个叫“Player”的对象,这个对象有“Name”和“Score”字段。在你的数据库中,你会有一个名为“Player”的表,和你上传的所有对象,下面来看看例子:

           找到didFinishLaunchingWithOptions方法,之后添加以下代码,连接到Parse后台服务:

    1. PFObject *player = [PFObject objectWithClassName:@"Player"];//1  
    2. [player setObject:@"John" forKey:@"Name"];  
    3. [player setObject:[NSNumber numberWithInt:1230] forKey:@"Score"];//2  
    4. [player save];//3  

           注释1:在这一行你创建了一个类名为“Player”的对象。

     

           注释2:在这里你对字段赋上值,name字段的值为“John”,score字段的值为“1230”。

           注释3:在这里你保存了对象,对象会同步发送到Parse服务器。

           这就可以了!最厉害的是你无须在浏览器上的Parse界面去创建一个表,这个表将根据你上传的对象自动创建。

           编译运行你的程序!如果你正确地在代码中设置了keys,还有你的app在上传对象前正确注册到了Parse服务器,那么一切都会很顺利。

           但上传的对象在哪?

           为了检查你的对象是否正确保存了,在浏览器中打开Parse dashboard界面,点击“Data Browser”,在这里你应该可以看到你上传的对象,如下图:

           

           这就是保存对象最简单的方法。恭喜你成功地和后台进行了交互!

     

    异步操作

           你可能已经注意到了,在控制带出现了警告信息,你的app会被阻塞直到你的对象完成上传,这是同步的网络操作!这样你不但不能检查调用的结果,你的用户也会被卡在调用API的等待上。

           你的应用可能会因此获得一星评分!当然,还是有解决的办法的。

           注释掉之前在didFinishLaunchingWithOptions方法添加的代码,否则你的app在每次运行时都会上传一个新的对象。再添加以下的代码:

     

    1.  PFObject *anotherPlayer = [PFObject objectWithClassName:@"Player"];  
    2. [anotherPlayer setObject:@"Jack" forKey:@"Name"];  
    3. [anotherPlayer setObject:[NSNumber numberWithInt:840] forKey:@"Score"];  
    4. [anotherPlayer saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {  
    5.   
    6.     if (succeeded){  
    7.         NSLog(@"Object Uploaded!");  
    8.     }  
    9.     else{  
    10.         NSString *errorString = [[error userInfo] objectForKey:@"error"];  
    11.         NSLog(@"Error: %@", errorString);  
    12.     }  
    13.   
    14. }];  

           正如你所看到,你使用了异步的方式上传了对象,还有在一个代码块中检查返回结果。随着代码块在iOS中越来越多的使用,你应该对代码块感到熟悉。每个简单的UIView动画目前都是在代码块中完成的。幸运的是,这里有一个教程让你更加熟悉代码块这种特性,链接为How To Use Block in iOS 5 Tutorial - Part 1(英文教程)。

     

           编译运行你的app吧!

           在Parse Dashboard中检查你是否正确上传了对象到服务器。不同的是这次你的app在上传对象时不会阻塞了。

           你应该会注意到你的设备(或模拟器)会出现一个网络活动指示器,指示器旋转时登陆界面会弹出来。过了一会儿,当交互完成后,你会看到控制台中出现NSLog消息。当要上传想image那种要花更长时间去传输的对象时,这是十分有用的。

           像之前那样,去到Data Browser界面你就会看到,在通过同步上传的对象的旁边出现了一个通过异步上传的对象。

     

    取得对象

           现在,是时候去获取对象了。为了实现这个目的,Parse有一个类PFQuery——它执行查询操作,具体可看PFQuery documentation

           你将会编写代码,去查询Score超过1000,Name为“John”的对象。在这之前,注释掉之前的代码,否则每次运行程序都会上传新的对象。加入以下代码:

     

    1. PFQuery *query = [PFQuery queryWithClassName:@"Player"]; //1  
    2. [query whereKey:@"Name" equalTo:@"John"];//2  
    3. [query whereKey:@"Score" greaterThan:[NSNumber numberWithInt:1000]]; //3  
    4. [query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {//4  
    5.     if (!error) {  
    6.         NSLog(@"Successfully retrieved: %@", objects);  
    7.     } else {  
    8.         NSString *errorString = [[error userInfo] objectForKey:@"error"];  
    9.         NSLog(@"Error: %@", errorString);  
    10.     }  
    11. }];  

           注释1:你创建了一个查询对象,“Player”是你想进行查询的表。

     

           注释2:你只想获取name为“John”的对象。。。

           注释3:。。。还有score要超过1000的

           注释4:发送查询,在代码块中打印结果。

           编译运行你的app!由于操作是异步的,你的UI界面不会卡住——这是让你的用户感到高兴的关键。在控制台中,你会看到符合查询条件的所有对象,如下图所示:

           

           在对基本的存储和查询操作有了简单探索后,你可以继续在项目中操作了。

           回到项目中,注释掉刚才的代码。

     

    用户注册

           你的用户使用你的app时的第一步就是在注册账号。

           在项目中打开RegisterViewController.m文件,添加以下Parse头文件:

     

    1. #import <Parse/Parse.h>  

           正如你所看到的,现在注册视图除了打开和关闭外,还没有添加任何功能。你的任务就是在用户点击“Sign Up”按钮时,可以进行注册操作。

     

           为了实现这个目的,你可以找到关联了这个按钮的IBAction:

     

    1. //Sign Up Button pressed  
    2. -(IBAction)signUpUserPressed:(id)sender  
    3. {  
    4.     //TODO  
    5.     //If signup sucessful:  
    6.     //[self performSegueWithIdentifier:@"SignupSuccesful" sender:self];  
    7. }  

          你需要在这里添加注册操作的代码,然后检查是否可以成功注册。

     

          用以下的代码替代上面signUpUserPressed方法中的内容:

     

    1. //Sign Up Button pressed  
    2. -(IBAction)signUpUserPressed:(id)sender  
    3. {  
    4.     //1  
    5.     PFUser *user = [PFUser user];  
    6.     //2  
    7.     user.username = self.userRegisterTextField.text;  
    8.     user.password = self.passwordRegisterTextField.text;  
    9.     //3  
    10.     [user signUpInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {  
    11.         if (!error) {  
    12.             //The registration was successful, go to the wall  
    13.             [self performSegueWithIdentifier:@"SignupSuccesful" sender:self];  
    14.    
    15.         } else {  
    16.             //Something bad has occurred  
    17.             NSString *errorString = [[error userInfo] objectForKey:@"error"];  
    18.             UIAlertView *errorAlertView = [[UIAlertView alloc] initWithTitle:@"Error" message:errorString delegate:nil cancelButtonTitle:@"Ok" otherButtonTitles:nil, nil];  
    19.             [errorAlertView show];  
    20.         }  
    21.     }];  
    22. }  

           在以上代码中,创建一个用户的步骤是:

     

           注释1:创建一个新的PFUser对象,这个类是用来登陆和注册的。它会保储已经通过验证的用户,你可以在你想要的时候访问这个用户的数据。你可以在这里找到关        于PFUser的文档。

           注释2:指定TextFields中的内容为用户名和密码。

           注释3:调用在后台注册用户的方法,在代码块中检查结果。结果有两种可能,一种是注册成功,新用户被创建,然后视图转到照片墙视图。或者是注册失败,产生错误信息,你可以对用户显示错误描述。

           编译运行你的app看是否有错误!

           为了检查用户注册操作,运行程序,在Log In界面按下Sign Up按钮,你会看到下图:

           

           输入用户名和密码,按下Sign Up按钮,如果顺利的话,app会转到照片墙视图。

           好极了!但你仍需要确认你的新用户是否已经保存了。打开Data Browser来确认新用户是否存在,如下图所示:

           

           恭喜!你第一个用户已经创建了!现在是时候让用户登陆并和后台交互了!

     

    用户登陆

           在这一节,你会学习怎样让你在上面创建的用户进行登陆。

           打开LoginviewController.m文件,加上头文件:

     

    1. #import <Parse/Parse.h>  

           然后看到以下代码:

    1. //Login button pressed  
    2. -(IBAction)logInPressed:(id)sender  
    3. {  
    4.     //If user logged succesful:  
    5.     //[self performSegueWithIdentifier:@"LoginSuccesful" sender:self];  
    6.    
    7. }  

           正如你所看到的,这一部分和注册部分的代码很相似!你会再次使用PFUser类,但这次你是用它来进行登陆操作的。用以下的代码替换掉loginPressed方法中的内容:

     

     

    1. //Login button pressed  
    2. -(IBAction)logInPressed:(id)sender  
    3. {  
    4.     [PFUser logInWithUsernameInBackground:self.userTextField.text password:self.passwordTextField.text block:^(PFUser *user, NSError *error) {  
    5.         if (user) {  
    6.             //Open the wall  
    7.              [self performSegueWithIdentifier:@"LoginSuccesful" sender:self];  
    8.         } else {  
    9.             //Something bad has ocurred  
    10.             NSString *errorString = [[error userInfo] objectForKey:@"error"];  
    11.             UIAlertView *errorAlertView = [[UIAlertView alloc] initWithTitle:@"Error" message:errorString delegate:nil cancelButtonTitle:@"Ok" otherButtonTitles:nil, nil];  
    12.             [errorAlertView show];  
    13.         }  
    14.     }];  
    15. }  

          代码和注册代码很相似。运行app,你会看到以下界面:

     

           

           尝试用你刚才创建的用户进行登陆,如果顺利的话,app应该会转到照片墙视图。

     

    照片墙

           刚才的操作(注册和登陆)都会使视图转到照片墙视图,在这个视图中,你可以看到所用的注册用户上传到后台服务器的带有评论的照片。

           但这在看到照片之前,也得先有照片上传上去啊!

           在Parse上传文件非常简单,先看一看UploadImageViewController.m文件,文件就是在这里进行上传的。

           一个已经登陆的用户可以点击在照片墙视图的Upload按钮,就是导航栏右边的按钮,上传文件的过程就在下面给出。

           用户点击Upload按钮时,就会触发selectPicturePressed方法。系统的照片库就会出现,让用户从中选择一张图片,如下所示:

     

    1. -(IBAction)selectPicturePressed:(id)sender  
    2. {  
    3.     //Open a UIImagePickerController to select the picture  
    4.     UIImagePickerController *imgPicker = [[UIImagePickerController alloc] init];  
    5.     imgPicker.delegate = self;  
    6.     imgPicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;  
    7.    
    8.     [self.navigationController presentModalViewController:imgPicker animated:YES];  
    9. }  

          选好图片后,图片就会出现在主界面的UIImageView中,如下所示:

     

     

    1. - (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingImage:(UIImage *)img editingInfo:(NSDictionary *)editInfo   
    2. {  
    3.     [picker dismissModalViewControllerAnimated:YES];  
    4.     //Place the image in the imageview  
    5.     self.imgToUpload.image = img;  
    6. }  

           用户可以在文本框中输入对照片的评论,也可以不输评论,这是可选的。

     

           这些都已经为你做好了!现在应该添加代码来实现sendPressed方法了。这个方法是导航栏上的按钮触发的,用来上传图片和评论到服务器。

           过程分开两个部分。首先,用PFFile对象上传图片;然后把对象附到PFObject上传到服务器。

           先在UploadImageViewController.m文件开头加上头文件:

     

    1. #import <Parse/Parse.h>  

           在-(IBAction)sendPressed:(id)sender方法中加入以下代码:

     

     

    1. //Upload a new picture  
    2.   //1  
    3.   PFFile *file = [PFFile fileWithName:@"img" data:pictureData];  
    4.   [file saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {  
    5.   
    6.       if (succeeded){  
    7.           //2  
    8.           //Add the image to the object, and add the comment and the user  
    9.           PFObject *imageObject = [PFObject objectWithClassName:@"WallImageObject"];  
    10.           [imageObject setObject:file forKey:@"image"];  
    11.           [imageObject setObject:[PFUser currentUser].username forKey:@"user"];  
    12.           [imageObject setObject:self.commentTextField.text forKey:@"comment"];  
    13.           //3  
    14.           [imageObject saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {  
    15.               //4  
    16.               if (succeeded){  
    17.                   //Go back to the wall  
    18.                   [self.navigationController popViewControllerAnimated:YES];  
    19.               }  
    20.               else{  
    21.                   NSString *errorString = [[error userInfo] objectForKey:@"error"];  
    22.                   UIAlertView *errorAlertView = [[UIAlertView alloc] initWithTitle:@"Error" message:errorString delegate:nil cancelButtonTitle:@"Ok" otherButtonTitles:nil, nil];  
    23.                   [errorAlertView show];  
    24.               }  
    25.           }];  
    26.       }  
    27.       else{  
    28.           //5  
    29.           NSString *errorString = [[error userInfo] objectForKey:@"error"];  
    30.           UIAlertView *errorAlertView = [[UIAlertView alloc] initWithTitle:@"Error" message:errorString delegate:nil cancelButtonTitle:@"Ok" otherButtonTitles:nil, nil];  
    31.           [errorAlertView show];  
    32.       }          
    33.   } progressBlock:^(int percentDone) {  
    34.       NSLog(@"Uploaded: %d %%", percentDone);  
    35.   }];  

           下面来解析一下以上代码:

     

           注释1:用图片创建PFFile对象,然后在后台保存它。在代码块的末尾你可以检查上传的进度。

           注释2:上传成功后,创建含有图片和数据的PFObject对象,对象中设置文件,用户名和评论。

           注释3:在后台中保存PFObject对象。

           注释4:如果成功了,就返回到照片墙视图。

           注释5:失败了就通知用户。

           编译运行你的app!用之前创建的用户名登陆,来到Upload界面,如下图所示:

           

           按下Select Picture在相册中选择一张图片,如果想的话,可以写上评论,在按下Send按钮。

           你可以在控制台中看到上传的进度。

           现在去到Data Browser界面看看,你会看到一个新的名为“WallImageObject”的表和里面的对象,但等等,在app中还没看到这些图片对象呢!!

           现在是时候获取这些图片了!

     

    在照片墙上贴上图片

           WallPicturesViewController.m文件用于展示用户已上传的照片。

           在WallPictureController.m文件开头加上头文件:

     

    1. #import <Parse/Parse.h>  

           getWallImage方法会在视图加载获取图片时调用,现在这个方法还是空的,在这个方法中加入以下代码:

     

     

    1. -(void)getWallImages  
    2. {  
    3.     //Prepare the query to get all the images in descending order  
    4.     //1  
    5.     PFQuery *query = [PFQuery queryWithClassName:@"WallImageObject"];  
    6. //2  
    7.     [query orderByDescending:@"createdAt"];  
    8.     [query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {  
    9.         //3   
    10.         if (!error) {  
    11.             //Everything was correct, put the new objects and load the wall  
    12.             self.wallObjectsArray = nil;  
    13.             self.wallObjectsArray = [[NSArray alloc] initWithArray:objects];  
    14.             [self loadWallViews];  
    15.    
    16.         } else {  
    17.    
    18.             //4  
    19.             NSString *errorString = [[error userInfo] objectForKey:@"error"];  
    20.             UIAlertView *errorAlertView = [[UIAlertView alloc] initWithTitle:@"Error" message:errorString delegate:nil cancelButtonTitle:@"Ok" otherButtonTitles:nil, nil];  
    21.             [errorAlertView show];  
    22.         }  
    23.     }];  
    24.    
    25. }  

           解释一下:

     

           注释1:用你想查询的表的名字创建一个查询对象。

           注释2:查询结果根据“createdAt”属性降序排列。

           注释3:找到符合条件的对象,把WallImageObject类型的对象展示出来。如果顺利的话,把下载到的对象替代wallObjectArray数组中的内容。

           注释4:出错了的话就告知用户。

           对象下载好后,就要在照片墙上展示它了!看到loadWallImage方法,加入以下代码:

     

    1. -(void)loadWallViews  
    2. {  
    3.     //Clean the scroll view  
    4.     for (id viewToRemove in [self.wallScroll subviews]){  
    5.    
    6.         if ([viewToRemove isMemberOfClass:[UIView class]])  
    7.             [viewToRemove removeFromSuperview];  
    8.     }  
    9.    
    10.     //For every wall element, put a view in the scroll  
    11.     int originY = 10;  
    12.    
    13.     for (PFObject *wallObject in self.wallObjectsArray){  
    14.    
    15.         //1  
    16.         //Build the view with the image and the comments  
    17.         UIView *wallImageView = [[UIView alloc] initWithFrame:CGRectMake(10, originY, self.view.frame.size.width - 20 , 300)];  
    18.    
    19.         //2  
    20.         //Add the image  
    21.         PFFile *image = (PFFile *)[wallObject objectForKey:@"image"];  
    22.         UIImageView *userImage = [[UIImageView alloc] initWithImage:[UIImage imageWithData:image.getData]];  
    23.         userImage.frame = CGRectMake(0, 0, wallImageView.frame.size.width, 200);  
    24.         [wallImageView addSubview:userImage];  
    25.    
    26.         //3  
    27.         //Add the info label (User and creation date)  
    28.         NSDate *creationDate = wallObject.createdAt;  
    29.         NSDateFormatter *df = [[NSDateFormatter alloc] init];  
    30.         [df setDateFormat:@"HH:mm dd/MM yyyy"];  
    31.         //4  
    32.         UILabel *infoLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 210, wallImageView.frame.size.width,15)];  
    33.         infoLabel.text = [NSString stringWithFormat:@"Uploaded by: %@, %@", [wallObject objectForKey:@"user"], [df stringFromDate:creationDate]];  
    34.         infoLabel.font = [UIFont fontWithName:@"Arial-ItalicMT" size:9];  
    35.         infoLabel.textColor = [UIColor whiteColor];  
    36.         infoLabel.backgroundColor = [UIColor clearColor];  
    37.         [wallImageView addSubview:infoLabel];  
    38.    
    39.         //5  
    40.         //Add the comment  
    41.         UILabel *commentLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 240, wallImageView.frame.size.width, 15)];  
    42.         commentLabel.text = [wallObject objectForKey:@"comment"];  
    43.         commentLabel.font = [UIFont fontWithName:@"ArialMT" size:13];  
    44.         commentLabel.textColor = [UIColor whiteColor];  
    45.         commentLabel.backgroundColor = [UIColor clearColor];  
    46.         [wallImageView addSubview:commentLabel];  
    47.    
    48.         //6  
    49.         [self.wallScroll addSubview:wallImageView];  
    50.    
    51.    
    52.         originY = originY + wallImageView.frame.size.width + 20;  
    53.    
    54.     }  
    55.    
    56.     //7  
    57.     //Set the bounds of the scroll  
    58.     self.wallScroll.contentSize = CGSizeMake(self.wallScroll.frame.size.width, originY);  
    59.    
    60. }  

           第一步就是清理scrollView中的东西,然后你遍历了数组中的内容。每个数组元素就是一个PFObject对象,对象包含了一个PFFile。

     

           对于数组中的每个对象:

           注释1:创建包含图片和评论的视图。

           注释2:取得图片对象数据(从PFFile中),然后用数据初始化一个UIImageView对象。

           注释3:取得对象的创建信息。

           注释4:取得上传图片的用户名,把它和创建数据放到一个label中。

           注释5:将评论放到另一个label中。

           注释6:将内容添加到scrollView中。

           当每个对象都被解析过后,就根据最后的视图的大小和位置来设置scrollview的边界。

           编译运行app!不出意外的话,你就会看到你之前上传的图片和评论了。花点时间上传更多的图片和评论,看看它们在照片墙上展示出来的效果吧。

           感觉很好吧?

     

    退出登陆

           这篇教程的最后一部分就是怎么让用户退出登陆。为此,看到WallPictureViewController.m文件中的logoutPressed方法,在这个方法中加入以下代码:

     

    1. -(IBAction)logoutPressed:(id)sender  
    2. {  
    3.     [PFUser logOut];  
    4.     [self.navigationController popViewControllerAnimated:YES];  
    5. }  

           运行项目,这就搞定了!

     

     

    教程来到这里也差不多结束了,希望这篇教程能给需要的人带来一点帮助。PS:翻译真的很累。。向那些默默为我们翻译各种外国好文章的大神们致敬!

    展开全文
  • 原文:Parse Tutorial: Getting Started with Web Backends 首先—创建你的后台服务  在开始编写你的app前,你首先要做的是创建你的Parse后台,每个开发人员和每个app都需要一个不同的标识,否则你...

    本文由CocoaChina翻译组成员leon(社区ID)翻译自raywenderlich
    原文:Parse Tutorial: Getting Started with Web Backends


    首先—创建你的后台服务

           在开始编写你的app前,你首先要做的是创建你的Parse后台,每个开发人员和每个app都需要一个不同的标识,否则你的数据和账号会和别人的混淆,虽然这会带来一些有趣的副作用,但是你应该使你的数据和别人的区别开来。

           第一步就是访问Parse.com,然后在右上角点击Sign Up创建一个新账号。

           账号创建好后,你会被要求创建你的第一个app,每个你想要使用后台服务的应用都要单独地注册。在这里,我们把这个应用命名为“tutorialApp”;在Parse中可能存在着很多同名的app,但是你注册的只有一个。

           你的app创建好后,来到Dashboard页面,在这里你可以查看你app的数据,这里有一系列的操作按钮,有点像UISegmentedControl,如以下截图:

           这里是对屏幕上方一些操作按钮的说明:

    • Overview:在这里你可以看到一些关于你app统计信息,如流量,推送信息,调用API的次数等。
    • Data Browser:这里你可以看到所有放到你后台里的数据。你也可以看到账号,你可以手动地操作数据,这里就像一个数据库编辑器。
    • Push Notifications:可以在这里向你的用户发送推送信息,或者向一个特定组发送推送信息。
    • Setting:你可以在这里设置你的app,管理它的安全性,和导出你的数据。

    Parse示例项目

           为了在这篇教程中创建一个后台服务,这里提供了一个简单的项目来使大家容易入手。你可以下载它并跟着本教程添加Parse服务。示例项目就放在github上。

           你可以在https://github.com/toniomg/TutorialBase上下载这个项目,也可以使用以下终端命令:

    [plain] view plaincopy
    1. git clone https://github.com/toniomg/TutorialBase  
           在Xcode中打开这个项目,编译运行!首先你会看到一个登陆界面,但目前为止,这个项目还没有加入后台服务,你很快就会完成这些功能。

           在继续学习之前,先打开MainStoryboard.storyboard来看一下程序的结构和流程。

           这个项目分为4个主要的视图,每个视图在storyboard中都有自己的视图控制器和视图

    • Log In:登陆页面有用户名和密码文本框,还有一个Sign Up按钮,在你想注册一个新账号的时候用来前往Sign Up页面。
    • Sign Up:在这个视图,用户输入用户名和密码,用来在后台服务中创建一个新账号。
    • Wall:这是这个app中的主要界面,这里用户可以看到其他用户上传的带有评论的图片。
    • Upload:在这里,用户可以上传带有评论的图片到照片墙上。

           注意segue线表示了这个app的流向,包括绕过了Sign Up界面的流向。如下图所示:

           

    准备Parse服务

           第一步自然是要配置你的项目使它可以加入Parse服务!

           在这个地址下载Parse框架:https://parse.com/downloads/ios/parse-library/latest

           下载完框架后,解压并把Parse.framework文件夹拖入你的Xcode项目的Framework文件夹内。记得勾选“Copy item...”和“Create groups...”。

           默认下Parse框架会加入到“tutorialBase”中,这也是我们期望的,然后添加其他的框架,完成后的框架列表如下:

           

           (怎么添加框架的步骤就不说了,网上一大把)

           下一步就是在app启动时注册后台服务,在AppDelegate.m文件中加入头文件:

    [plain] view plaincopy
    1. #import <Parse/Parse.h>  
           然后,在函数didFinishLaunchingWithOptions的开头,加入语句:
    [plain] view plaincopy
    1. [Parse setApplicationId:AppID clientKey:clientKey];  
           你会看到有错误出现了,Application ID和Client Key需要一个常量,但是它们现在还是空的——是时候改正了!

           为了找到需要的API keys,要去到Parse Dashboard(1),选择你的app(2),然后找到左侧栏,复制Application ID和Client Keys(3),如下图所示:

            

           (注意,我看到的界面与上图有的不同,我是在Settings——Application keys界面中找到所需的App ID和Client Key的)

           你可以直接把keys复制到setApplicationId方法中,它们只需使用一次。完成后,这个方法看起来和下面代码是相似的,只是keys有所不同:

    1. - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions  
    2. {  
    3.      // Register our parse app with the service  
    4.     [Parse setApplicationId:@"UXuHVmNRX44rcczbv1NIIHHbazteYfQU4GAJ8EOS"  
    5.               clientKey:@"cqFwq5Vpb19VKPKSe1dOZJrjsQbytPzKa2bEdakx"];  
    6.   
    7.      return YES;  
    8. }  

           编译运行你的app!确定没有任何错误。一切顺利的话,意味着你的app已经绑定Parse后台服务了。你即将开始使用后台服务!

           下一步就是创建一些示例对象!


    创建示例对象

           现在你的项目已经配置好了并连接上Parse,现在花一点时间来复习一下发送对象到后台和从后台获取对象的概念。

           你可以根据之前的步骤创建一个新的项目,或者在示例项目中交替地使用AppDelegate文件。

           在这个例子中,你会使用PFObject类,这是一个基本的类,提供一些基本的对象操作方法。对于PFObject类的详细详细,你可以参照这个文档:https://parse.com/docs/ios/api/Classes/PFObject.html

           在示例中,你会上传一个叫“Player”的对象,这个对象有“Name”和“Score”字段。在你的数据库中,你会有一个名为“Player”的表,和你上传的所有对象,下面来看看例子:

           找到didFinishLaunchingWithOptions方法,之后添加以下代码,连接到Parse后台服务:

    1. PFObject *player = [PFObject objectWithClassName:@"Player"];//1  
    2. [player setObject:@"John" forKey:@"Name"];  
    3. [player setObject:[NSNumber numberWithInt:1230] forKey:@"Score"];//2  
    4. [player save];//3  
           注释1:在这一行你创建了一个类名为“Player”的对象。

           注释2:在这里你对字段赋上值,name字段的值为“John”,score字段的值为“1230”。

           注释3:在这里你保存了对象,对象会同步发送到Parse服务器。

           这就可以了!最厉害的是你无须在浏览器上的Parse界面去创建一个表,这个表将根据你上传的对象自动创建。

           编译运行你的程序!如果你正确地在代码中设置了keys,还有你的app在上传对象前正确注册到了Parse服务器,那么一切都会很顺利。

           但上传的对象在哪?

           为了检查你的对象是否正确保存了,在浏览器中打开Parse dashboard界面,点击“Data Browser”,在这里你应该可以看到你上传的对象,如下图:

           

           这就是保存对象最简单的方法。恭喜你成功地和后台进行了交互!


    异步操作

           你可能已经注意到了,在控制带出现了警告信息,你的app会被阻塞直到你的对象完成上传,这是同步的网络操作!这样你不但不能检查调用的结果,你的用户也会被卡在调用API的等待上。

           你的应用可能会因此获得一星评分!当然,还是有解决的办法的。

           注释掉之前在didFinishLaunchingWithOptions方法添加的代码,否则你的app在每次运行时都会上传一个新的对象。再添加以下的代码:

    1.  PFObject *anotherPlayer = [PFObject objectWithClassName:@"Player"];  
    2. [anotherPlayer setObject:@"Jack" forKey:@"Name"];  
    3. [anotherPlayer setObject:[NSNumber numberWithInt:840] forKey:@"Score"];  
    4. [anotherPlayer saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {  
    5.   
    6.     if (succeeded){  
    7.         NSLog(@"Object Uploaded!");  
    8.     }  
    9.     else{  
    10.         NSString *errorString = [[error userInfo] objectForKey:@"error"];  
    11.         NSLog(@"Error: %@", errorString);  
    12.     }  
    13.   
    14. }];  
           正如你所看到,你使用了异步的方式上传了对象,还有在一个代码块中检查返回结果。随着代码块在iOS中越来越多的使用,你应该对代码块感到熟悉。每个简单的UIView动画目前都是在代码块中完成的。幸运的是,这里有一个教程让你更加熟悉代码块这种特性,链接为How To Use Block in iOS 5 Tutorial - Part 1(英文教程)。

           编译运行你的app吧!

           在Parse Dashboard中检查你是否正确上传了对象到服务器。不同的是这次你的app在上传对象时不会阻塞了。

           你应该会注意到你的设备(或模拟器)会出现一个网络活动指示器,指示器旋转时登陆界面会弹出来。过了一会儿,当交互完成后,你会看到控制台中出现NSLog消息。当要上传想image那种要花更长时间去传输的对象时,这是十分有用的。

           像之前那样,去到Data Browser界面你就会看到,在通过同步上传的对象的旁边出现了一个通过异步上传的对象。


    取得对象

           现在,是时候去获取对象了。为了实现这个目的,Parse有一个类PFQuery——它执行查询操作,具体可看PFQuery documentation

           你将会编写代码,去查询Score超过1000,Name为“John”的对象。在这之前,注释掉之前的代码,否则每次运行程序都会上传新的对象。加入以下代码:

    1. PFQuery *query = [PFQuery queryWithClassName:@"Player"]; //1  
    2. [query whereKey:@"Name" equalTo:@"John"];//2  
    3. [query whereKey:@"Score" greaterThan:[NSNumber numberWithInt:1000]]; //3  
    4. [query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {//4  
    5.     if (!error) {  
    6.         NSLog(@"Successfully retrieved: %@", objects);  
    7.     } else {  
    8.         NSString *errorString = [[error userInfo] objectForKey:@"error"];  
    9.         NSLog(@"Error: %@", errorString);  
    10.     }  
    11. }];  
           注释1:你创建了一个查询对象,“Player”是你想进行查询的表。

           注释2:你只想获取name为“John”的对象。。。

           注释3:。。。还有score要超过1000的

           注释4:发送查询,在代码块中打印结果。

           编译运行你的app!由于操作是异步的,你的UI界面不会卡住——这是让你的用户感到高兴的关键。在控制台中,你会看到符合查询条件的所有对象,如下图所示:

           

           在对基本的存储和查询操作有了简单探索后,你可以继续在项目中操作了。

           回到项目中,注释掉刚才的代码。


    用户注册

           你的用户使用你的app时的第一步就是在注册账号。

           在项目中打开RegisterViewController.m文件,添加以下Parse头文件:

    1. #import <Parse/Parse.h>  
           正如你所看到的,现在注册视图除了打开和关闭外,还没有添加任何功能。你的任务就是在用户点击“Sign Up”按钮时,可以进行注册操作。

           为了实现这个目的,你可以找到关联了这个按钮的IBAction:

    1. //Sign Up Button pressed  
    2. -(IBAction)signUpUserPressed:(id)sender  
    3. {  
    4.     //TODO  
    5.     //If signup sucessful:  
    6.     //[self performSegueWithIdentifier:@"SignupSuccesful" sender:self];  
    7. }  
          你需要在这里添加注册操作的代码,然后检查是否可以成功注册。

          用以下的代码替代上面signUpUserPressed方法中的内容:

    1. //Sign Up Button pressed  
    2. -(IBAction)signUpUserPressed:(id)sender  
    3. {  
    4.     //1  
    5.     PFUser *user = [PFUser user];  
    6.     //2  
    7.     user.username = self.userRegisterTextField.text;  
    8.     user.password = self.passwordRegisterTextField.text;  
    9.     //3  
    10.     [user signUpInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {  
    11.         if (!error) {  
    12.             //The registration was successful, go to the wall  
    13.             [self performSegueWithIdentifier:@"SignupSuccesful" sender:self];  
    14.    
    15.         } else {  
    16.             //Something bad has occurred  
    17.             NSString *errorString = [[error userInfo] objectForKey:@"error"];  
    18.             UIAlertView *errorAlertView = [[UIAlertView alloc] initWithTitle:@"Error" message:errorString delegate:nil cancelButtonTitle:@"Ok" otherButtonTitles:nil, nil];  
    19.             [errorAlertView show];  
    20.         }  
    21.     }];  
    22. }  
           在以上代码中,创建一个用户的步骤是:

           注释1:创建一个新的PFUser对象,这个类是用来登陆和注册的。它会保储已经通过验证的用户,你可以在你想要的时候访问这个用户的数据。你可以在这里找到关        于PFUser的文档。

           注释2:指定TextFields中的内容为用户名和密码。

           注释3:调用在后台注册用户的方法,在代码块中检查结果。结果有两种可能,一种是注册成功,新用户被创建,然后视图转到照片墙视图。或者是注册失败,产生错误信息,你可以对用户显示错误描述。

           编译运行你的app看是否有错误!

           为了检查用户注册操作,运行程序,在Log In界面按下Sign Up按钮,你会看到下图:

           

           输入用户名和密码,按下Sign Up按钮,如果顺利的话,app会转到照片墙视图。

           好极了!但你仍需要确认你的新用户是否已经保存了。打开Data Browser来确认新用户是否存在,如下图所示:

           

           恭喜!你第一个用户已经创建了!现在是时候让用户登陆并和后台交互了!


    用户登陆

           在这一节,你会学习怎样让你在上面创建的用户进行登陆。

           打开LoginviewController.m文件,加上头文件:

    1. #import <Parse/Parse.h>  
           然后看到以下代码:
    1. //Login button pressed  
    2. -(IBAction)logInPressed:(id)sender  
    3. {  
    4.     //If user logged succesful:  
    5.     //[self performSegueWithIdentifier:@"LoginSuccesful" sender:self];  
    6.    
    7. }  
           正如你所看到的,这一部分和注册部分的代码很相似!你会再次使用PFUser类,但这次你是用它来进行登陆操作的。用以下的代码替换掉loginPressed方法中的内容:

    1. //Login button pressed  
    2. -(IBAction)logInPressed:(id)sender  
    3. {  
    4.     [PFUser logInWithUsernameInBackground:self.userTextField.text password:self.passwordTextField.text block:^(PFUser *user, NSError *error) {  
    5.         if (user) {  
    6.             //Open the wall  
    7.              [self performSegueWithIdentifier:@"LoginSuccesful" sender:self];  
    8.         } else {  
    9.             //Something bad has ocurred  
    10.             NSString *errorString = [[error userInfo] objectForKey:@"error"];  
    11.             UIAlertView *errorAlertView = [[UIAlertView alloc] initWithTitle:@"Error" message:errorString delegate:nil cancelButtonTitle:@"Ok" otherButtonTitles:nil, nil];  
    12.             [errorAlertView show];  
    13.         }  
    14.     }];  
    15. }  
          代码和注册代码很相似。运行app,你会看到以下界面:

           

           尝试用你刚才创建的用户进行登陆,如果顺利的话,app应该会转到照片墙视图。


    照片墙

           刚才的操作(注册和登陆)都会使视图转到照片墙视图,在这个视图中,你可以看到所用的注册用户上传到后台服务器的带有评论的照片。

           但这在看到照片之前,也得先有照片上传上去啊!

           在Parse上传文件非常简单,先看一看UploadImageViewController.m文件,文件就是在这里进行上传的。

           一个已经登陆的用户可以点击在照片墙视图的Upload按钮,就是导航栏右边的按钮,上传文件的过程就在下面给出。

           用户点击Upload按钮时,就会触发selectPicturePressed方法。系统的照片库就会出现,让用户从中选择一张图片,如下所示:

    1. -(IBAction)selectPicturePressed:(id)sender  
    2. {  
    3.     //Open a UIImagePickerController to select the picture  
    4.     UIImagePickerController *imgPicker = [[UIImagePickerController alloc] init];  
    5.     imgPicker.delegate = self;  
    6.     imgPicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;  
    7.    
    8.     [self.navigationController presentModalViewController:imgPicker animated:YES];  
    9. }  
          选好图片后,图片就会出现在主界面的UIImageView中,如下所示:

    1. - (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingImage:(UIImage *)img editingInfo:(NSDictionary *)editInfo   
    2. {  
    3.     [picker dismissModalViewControllerAnimated:YES];  
    4.     //Place the image in the imageview  
    5.     self.imgToUpload.image = img;  
    6. }  
           用户可以在文本框中输入对照片的评论,也可以不输评论,这是可选的。

           这些都已经为你做好了!现在应该添加代码来实现sendPressed方法了。这个方法是导航栏上的按钮触发的,用来上传图片和评论到服务器。

           过程分开两个部分。首先,用PFFile对象上传图片;然后把对象附到PFObject上传到服务器。

           先在UploadImageViewController.m文件开头加上头文件:

    1. #import <Parse/Parse.h>  
           在-(IBAction)sendPressed:(id)sender方法中加入以下代码:

    1. //Upload a new picture  
    2.   //1  
    3.   PFFile *file = [PFFile fileWithName:@"img" data:pictureData];  
    4.   [file saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {  
    5.   
    6.       if (succeeded){  
    7.           //2  
    8.           //Add the image to the object, and add the comment and the user  
    9.           PFObject *imageObject = [PFObject objectWithClassName:@"WallImageObject"];  
    10.           [imageObject setObject:file forKey:@"image"];  
    11.           [imageObject setObject:[PFUser currentUser].username forKey:@"user"];  
    12.           [imageObject setObject:self.commentTextField.text forKey:@"comment"];  
    13.           //3  
    14.           [imageObject saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {  
    15.               //4  
    16.               if (succeeded){  
    17.                   //Go back to the wall  
    18.                   [self.navigationController popViewControllerAnimated:YES];  
    19.               }  
    20.               else{  
    21.                   NSString *errorString = [[error userInfo] objectForKey:@"error"];  
    22.                   UIAlertView *errorAlertView = [[UIAlertView alloc] initWithTitle:@"Error" message:errorString delegate:nil cancelButtonTitle:@"Ok" otherButtonTitles:nil, nil];  
    23.                   [errorAlertView show];  
    24.               }  
    25.           }];  
    26.       }  
    27.       else{  
    28.           //5  
    29.           NSString *errorString = [[error userInfo] objectForKey:@"error"];  
    30.           UIAlertView *errorAlertView = [[UIAlertView alloc] initWithTitle:@"Error" message:errorString delegate:nil cancelButtonTitle:@"Ok" otherButtonTitles:nil, nil];  
    31.           [errorAlertView show];  
    32.       }          
    33.   } progressBlock:^(int percentDone) {  
    34.       NSLog(@"Uploaded: %d %%", percentDone);  
    35.   }];  
           下面来解析一下以上代码:

           注释1:用图片创建PFFile对象,然后在后台保存它。在代码块的末尾你可以检查上传的进度。

           注释2:上传成功后,创建含有图片和数据的PFObject对象,对象中设置文件,用户名和评论。

           注释3:在后台中保存PFObject对象。

           注释4:如果成功了,就返回到照片墙视图。

           注释5:失败了就通知用户。

           编译运行你的app!用之前创建的用户名登陆,来到Upload界面,如下图所示:

           

           按下Select Picture在相册中选择一张图片,如果想的话,可以写上评论,在按下Send按钮。

           你可以在控制台中看到上传的进度。

           现在去到Data Browser界面看看,你会看到一个新的名为“WallImageObject”的表和里面的对象,但等等,在app中还没看到这些图片对象呢!!

           现在是时候获取这些图片了!


    在照片墙上贴上图片

           WallPicturesViewController.m文件用于展示用户已上传的照片。

           在WallPictureController.m文件开头加上头文件:

    1. #import <Parse/Parse.h>  
           getWallImage方法会在视图加载获取图片时调用,现在这个方法还是空的,在这个方法中加入以下代码:

    1. -(void)getWallImages  
    2. {  
    3.     //Prepare the query to get all the images in descending order  
    4.     //1  
    5.     PFQuery *query = [PFQuery queryWithClassName:@"WallImageObject"];  
    6. //2  
    7.     [query orderByDescending:@"createdAt"];  
    8.     [query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {  
    9.         //3   
    10.         if (!error) {  
    11.             //Everything was correct, put the new objects and load the wall  
    12.             self.wallObjectsArray = nil;  
    13.             self.wallObjectsArray = [[NSArray alloc] initWithArray:objects];  
    14.             [self loadWallViews];  
    15.    
    16.         } else {  
    17.    
    18.             //4  
    19.             NSString *errorString = [[error userInfo] objectForKey:@"error"];  
    20.             UIAlertView *errorAlertView = [[UIAlertView alloc] initWithTitle:@"Error" message:errorString delegate:nil cancelButtonTitle:@"Ok" otherButtonTitles:nil, nil];  
    21.             [errorAlertView show];  
    22.         }  
    23.     }];  
    24.    
    25. }  
           解释一下:

           注释1:用你想查询的表的名字创建一个查询对象。

           注释2:查询结果根据“createdAt”属性降序排列。

           注释3:找到符合条件的对象,把WallImageObject类型的对象展示出来。如果顺利的话,把下载到的对象替代wallObjectArray数组中的内容。

           注释4:出错了的话就告知用户。

           对象下载好后,就要在照片墙上展示它了!看到loadWallImage方法,加入以下代码:

    1. -(void)loadWallViews  
    2. {  
    3.     //Clean the scroll view  
    4.     for (id viewToRemove in [self.wallScroll subviews]){  
    5.    
    6.         if ([viewToRemove isMemberOfClass:[UIView class]])  
    7.             [viewToRemove removeFromSuperview];  
    8.     }  
    9.    
    10.     //For every wall element, put a view in the scroll  
    11.     int originY = 10;  
    12.    
    13.     for (PFObject *wallObject in self.wallObjectsArray){  
    14.    
    15.         //1  
    16.         //Build the view with the image and the comments  
    17.         UIView *wallImageView = [[UIView alloc] initWithFrame:CGRectMake(10, originY, self.view.frame.size.width - 20 , 300)];  
    18.    
    19.         //2  
    20.         //Add the image  
    21.         PFFile *image = (PFFile *)[wallObject objectForKey:@"image"];  
    22.         UIImageView *userImage = [[UIImageView alloc] initWithImage:[UIImage imageWithData:image.getData]];  
    23.         userImage.frame = CGRectMake(0, 0, wallImageView.frame.size.width, 200);  
    24.         [wallImageView addSubview:userImage];  
    25.    
    26.         //3  
    27.         //Add the info label (User and creation date)  
    28.         NSDate *creationDate = wallObject.createdAt;  
    29.         NSDateFormatter *df = [[NSDateFormatter alloc] init];  
    30.         [df setDateFormat:@"HH:mm dd/MM yyyy"];  
    31.         //4  
    32.         UILabel *infoLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 210, wallImageView.frame.size.width,15)];  
    33.         infoLabel.text = [NSString stringWithFormat:@"Uploaded by: %@, %@", [wallObject objectForKey:@"user"], [df stringFromDate:creationDate]];  
    34.         infoLabel.font = [UIFont fontWithName:@"Arial-ItalicMT" size:9];  
    35.         infoLabel.textColor = [UIColor whiteColor];  
    36.         infoLabel.backgroundColor = [UIColor clearColor];  
    37.         [wallImageView addSubview:infoLabel];  
    38.    
    39.         //5  
    40.         //Add the comment  
    41.         UILabel *commentLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 240, wallImageView.frame.size.width, 15)];  
    42.         commentLabel.text = [wallObject objectForKey:@"comment"];  
    43.         commentLabel.font = [UIFont fontWithName:@"ArialMT" size:13];  
    44.         commentLabel.textColor = [UIColor whiteColor];  
    45.         commentLabel.backgroundColor = [UIColor clearColor];  
    46.         [wallImageView addSubview:commentLabel];  
    47.    
    48.         //6  
    49.         [self.wallScroll addSubview:wallImageView];  
    50.    
    51.    
    52.         originY = originY + wallImageView.frame.size.width + 20;  
    53.    
    54.     }  
    55.    
    56.     //7  
    57.     //Set the bounds of the scroll  
    58.     self.wallScroll.contentSize = CGSizeMake(self.wallScroll.frame.size.width, originY);  
    59.    
    60. }  
           第一步就是清理scrollView中的东西,然后你遍历了数组中的内容。每个数组元素就是一个PFObject对象,对象包含了一个PFFile。

           对于数组中的每个对象:

           注释1:创建包含图片和评论的视图。

           注释2:取得图片对象数据(从PFFile中),然后用数据初始化一个UIImageView对象。

           注释3:取得对象的创建信息。

           注释4:取得上传图片的用户名,把它和创建数据放到一个label中。

           注释5:将评论放到另一个label中。

           注释6:将内容添加到scrollView中。

           当每个对象都被解析过后,就根据最后的视图的大小和位置来设置scrollview的边界。

           编译运行app!不出意外的话,你就会看到你之前上传的图片和评论了。花点时间上传更多的图片和评论,看看它们在照片墙上展示出来的效果吧。

           感觉很好吧?


    退出登陆

           这篇教程的最后一部分就是怎么让用户退出登陆。为此,看到WallPictureViewController.m文件中的logoutPressed方法,在这个方法中加入以下代码:

    1. -(IBAction)logoutPressed:(id)sender  
    2. {  
    3.     [PFUser logOut];  
    4.     [self.navigationController popViewControllerAnimated:YES];  
    5. }  
           运行项目,这就搞定了!
    展开全文
  • Parse--iOS Push(推送通知) Parse--iOS Push(推送通知) Parse官网:https://parse.com/docs/ios/guide Parse:不止推送功能,最大的功能是添加后台功能,开发云端应用详情: ...
  • 什么是Parse? 官网:https://docs.parseplatform.org/ Github:https://github.com/parse-community Parse是一个移动后端,最初由提供商Parse Inc开发。该公司于2013年被Facebook收购,并于2017年1月关闭。...
  • Parse SDK使用记录

    2019-06-27 17:50:44
    Parse是BaaS(Backend as a Service)的先驱, 它可以对多终端的资源进行管理, 发布通知等. 大大简化了后端的开发难度. 废话不多讲, 用过才知道,莽夫就是干! Server 服务端 安装Parse Server [scode type=“yellow”]...
  • Write By Monkeyfly 以下内容均为原创,如需转载请注明出处。 问题描述 广告位需要在生效时间内进行展示,这就需要将当前时间和广告位配置的...所以要将获取到的具体时间转化为毫秒数才能进行比较,故使用了Da...
  • 最近在学习Parse,但是Parse的中文教程比较少,看到这篇英文教程,把它翻译一下与大家共享,本人的英语水平不是很高,有的地方可能译得不好,望大神轻拍。。 原文地址...
  • XML文件解析常用的两种方式一种为苹果原生的NSXMLParser,另外一种为第三方GDataXML1.原生的NSXMLParser方式://*利用 NSXMLParser 方式 -(void)XMLParserWithData:(NSData *)data{ //1.创建NSXMLParser ...
  • Parse(解析)是一个很不错的BaaS(后端即服务),它有助于为你的移动应用尽可能快地建立后端基础设施。也许正是因为它的简洁性,很多开发者忘记了许多新的安全问题和其中存在的漏洞。
  • 可能很多人都用过...感谢的话嘛,不能说多,转入正题,如何利用七牛部署iOS应用:第一步:稍微观摩一下七牛的网站http://www.qiniu.com,看看它是什么,长啥样,在IT界大概是属于哪一个领域的公司,and so on!!
  • 发现一个布局新利器,用写前端的方式来写iOS页面,这里做一个使用总结。 1.xml文件中标签元素有几大属性,分别是:name,layout,attr,onPress,对它们的解释如下: name表示指定的元素,加载页面时需要进行元素的...
  • 在我们使用App的过程中,总是会收到很多的消息推送,今天我们就要来实现这个功能。...其实远程推送需要有服务器,但是我们自己暂时没有服务器,到时候后台使用Parse进行推送。实现步骤如下: (1)进入苹
  •  最近在学习Parse,但是Parse的中文教程比较少,看到这篇英文教程,把它翻译一下与大家共享,本人的英语水平不是很高,有的地方可能译得不好,望大神轻拍。。 原文地址...
  • 创建【apple-app-site-association】文件 >> 上传文件到自己的服务器>> app内配置 >> 打包安装到手机(真机) >> 使用Safari验证结果
  • ios Parse推送详解

    2013-07-04 18:16:34
    尊重劳动者果实,转载请写明: ... 很多人写教程都完全没有照顾到那些理解能力有限的人,我写这篇...当有新信息来的时候,如果程序在后台运行(好吧,ios没有多任务),有消息来时,就会在顶部出现提醒消息;如果应
  • iOS集成环信(二)

    2016-05-05 15:53:04
    iOS SDK介绍及导入环信SDK为用户开放IM相关的应用提供的一套完善的开发框架。 SDK_Core为核心的消息同步协议实现完成与服务器之间的信息交换。 SDK是基于核心协议实现的完整的IM功能,实现了不同类型消息的收发,...
1 2 3 4 5 ... 20
收藏数 5,750
精华内容 2,300
关键字:

parse配置ios 使用地址