如何正确地实现服务类到我的iOS应用程序? [英] How to properly implement a Services class into my iOS application?

查看:112
本文介绍了如何正确地实现服务类到我的iOS应用程序?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前的摸不到头脑:具体实施模型类服务调用我的Rails应用程序

My current head scratcher: implementing a model class specifically for service calls to my rails application.

下面是该方案:


  • 我有一个名为类的服务这是NSObject的一个子类。

  • 的实施文件有几个方法来定义......让我们来看看
    doSignUp

  • 我使用的 AFNetworking 与API进行通信。

  • 从我的 SignUpViewController ,我创建的一个实例我
    服务类并调用的 doSignUp

  • 的方法的作品,如预期,我从服务器接收正确的响应。

  • I have a class named Service that is a subclass of NSObject.
  • The implementation file has a few methods defined… lets look at doSignUp.
  • I am using AFNetworking to communicate with the api.
  • From my SignUpViewController, I create an instance of my Service class and call doSignUp
  • The method works, as expected and I receive the proper response from the server.

现在来了,我不完全了解的部分:

Now Comes the part I don't fully understand:


  • AFNetworking 利用其服务电话块。

  • 成功的块我打电话叫一个辅助方法的 handleSignUp 的(也是在服务类)。该方法主要解析JSON和我出它创建一个新的用户(NSObject的子类)。在 handSignUp 的方法,然后返回用户的对象。

  • AFNetworking utilizes blocks for its service calls.
  • Inside the success block I call a helper method called handleSignUp (also in Service class). This method essentially parses the JSON and I create a new User (NSObject subclass) out of it. The handSignUp method then returns the User object.

在这一点上我有一个新的用户对象,我需要那个对象送回到我的 SignUpViewController ...我怎么能这样做?

At this point I have a new User object and I need to send that object back to my SignUpViewController... How can I do that?


  • 我应该尝试给该对象添加到的AppDelegate 和访问
    SignUpViewController ?该解决方案可以工作访问
    各种全球性,但是当会在 SignUpViewController
    知道什么时候访问它?

  • 我应该尝试添加一个引用到 SignUpViewController
    服务类?这似乎适得其反......我还不如
    以及添加方法的 doSignUp 的和的 handSignUp 应用于
    SignUpViewController 。在我看来,像我的服务类不应该知道任何其他viewControllers的。

  • Should I try to add that object to the AppDelegate and access it from the SignUpViewController? This solution could work to access various global properties but when would the SignUpViewController know when to access it?
  • Should I try to add a reference to the SignUpViewController in the Service class? That seems counter productive... I might as well add the method doSignUp and handSignUp to the SignUpViewController. It seems to me like my Service class should not be aware of any other viewControllers.

请参阅以下我的code例子:

See below for my code examples:

Service.h

Service.h

//Service.h
#import <UIKit/UIKit.h>
#import "AFNetworking.h"
@interface Services : NSObject
- (void) doSignUp:(NSMutableDictionary*)params;
@end

Service.m

Service.m

// Service.m
 #import "Services.h"
 #import "Config.h"
 @implementation Services

 - (void) doSignUp:(NSMutableDictionary*)params {
     NSURL *url = [NSURL URLWithString:@"http://MYURL.COM"];
     AFHTTPClient *httpClient = [[AFHTTPClient alloc] initWithBaseURL:url];
     NSURLRequest *request = [httpClient requestWithMethod:@"POST" path:@"signup.json" parameters:params];
     AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request
                                    success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) {
         [self handleSignUp:JSON];
     } failure:nil];
     [operation start];
 }

 - (User*) handleSignUp:(NSMutableArray*)json {
     User * user = nil;
     if ([[json valueForKey:@"success"] isEqualToString:@"true"]) {
           // create user here ...
     }
     return user;
 }

SignUpViewController.h

SignUpViewController.h

#import "Service.h"
 @interface SignUpViewController : UIViewController {
     Service * service;
 }

 @property (nonatomic, strong) Service * service;

SignUpViewController.m

SignUpViewController.m

#import "SignUpViewController.h"
 @interface SignUpViewController ()
 @end

 @implementation SignUpViewController

 @synthesize service = __service;
 - (IBAction) initSignUp:(id)sender {
      // create params...
      [self.service doSignUp:params];
 }

同样,这一切code做的事情是应该做的......我只需要知道应该如何沟通的所有。我怎样才能提醒 SignUpViewController handleSignUp 的已经调用了一个新的用户对象可用?

Again, all this code does what it is supposed to do... I just need to know how it should all communicate. How can I alert the SignUpViewController the handleSignUp has been called and a new User object is available?

感谢您的时间,
安德烈

Thanks for your time, Andre

推荐答案

至于我能看到你没有意识到这一过程的异步性:实际上因为网络或者IO操作需要很长的时间才能完成,我们往往preFER异步访问,我的意思是:主叫方(查看控制器)呼吁通过服务的Web API的消息,然后停止等待响应。实际上网络处理可以在不同的进程或线程或者处理器核心来完成。

As far as i can see you are not realizing the asynchronous nature of this process: actually since network or IO operations take a long time to complete we tend to prefer asynchronous access, i mean: the caller (View Controller) calls a message on the web API through the service and then STOPS WAITING FOR A RESPONSE. Actually the network processing could be done on a different process or thread or processor's core.

现在那么,如何才能调用者可以通过当操作完成服务通知找到?
为了做到这一点,我们必须使用绑定代表团的两个对象:
我们创建一个协议(这只是一个对象将响应消息的声明),我们在我们的视图控制器,这样,谁就将使用它肯定知道消息是可实现它。

Now then, how can the caller BE NOTIFIED by the service when the operation completes? For this to happen we must bind the two objects using Delegation: we create a protocol (it's just a declaration of messages that an object will be responding to) and we implement it in our View Controller, that way whoever will be using it will know for sure what messages are available.

然后,我们会宣布我们的服务类型ID一旦操作将完成,将调用的委托。

Then we will declare a delegate of type id in our service that will be called once the operations will be completed.

这几乎就像在服务类导入您ViewController.h,并给予服务一个指向视图控制器,而是在正确的方式(不包括循环引用,尊重SOLID原则)

It's almost like importing your ViewController.h in the service class and giving the service a pointer to the view controller, but done in the right way (without circular references and respecting SOLID principles)

现在一些code:

//service.h
@protocol RemoteApiProtocol <NSObject>
@required
-(void) UserLoggingIn;
-(void) UserLoggedIn:(User*)user;
-(void) UserLoginError:(NSError *)error;
@end

该协议就像一个小的接口,它的两个类/对象之间的合同。
然后在你的服务,你可以声明场和放大器;属性的协议:

The protocol works like a small interface, it's a contract between two classes/objects. Then in your service you can declare field & property for the protocol:

//Service.h
#import <UIKit/UIKit.h>
#import "AFNetworking.h"
@interface Services : NSObject{
      __weak id<RemoteApiProtocol> delegate;
}

@property (nonatomic, assign) id<RemoteApiProtocol> delegate;

- (void) doSignUp:(NSMutableDictionary*)params;

@end

在这一点上你实现你的视图控制器的协议,你只是建立在合同整合。这样,服务器就知道该委托将始终能够以协议的消息作出回应。

At this point you implement the protocol in your view controller, integrating the contract you just build. This way the server will know that the delegate will always be able to respond to the protocol messages.

//SignUpViewController.h
#import "Service.h"
 @interface SignUpViewController : UIViewController <RemoteApiProtocol> {
     Service * service;
 }

 @property (nonatomic, strong) Service * service;

实施该协议后,您可以将您的视图控制器为代表的服务器,这样一来,服务器,调用的API将能够调用委托的调用的结果之后。为了做到这一点,你执行将由该服务被称为协议的消息:

After implementing the protocol you can assign your view controller as delegate for the server, this way the server, after calling the apis will be able to call the delegate with the result of the call. For this to happen you implement the protocols messages that will be called by the service:

//SignUpViewController.m
#import "SignUpViewController.h"

 @implementation SignUpViewController

 @synthesize service = __service;
 - (IBAction) initSignUp:(id)sender {
      //create the service with params
      //...

      //assign self as the delegate
      self.service.delegate = self;
      [self.service doSignUp:params];
 }

#pragma mark - RemoteApiProtocol
-(void) UserLoggingIn
{
      //login started, 
      //you can show a spinner or animation here
}
-(void) UserLoggedIn:(User*)user
{
      //user logged in , do your stuff here
}
-(void) UserLoginError:(NSError *)error
{
      NSLog(@"error: %@",error);
}

@end

最后,你所说的消息在服务中,调用这些API的成功和错误块之后:

And finally you call the messages in your service, after calling the apis in the success and error block:

// Service.m
 #import "Services.h"
 #import "Config.h"
 @implementation Services

 - (void) doSignUp:(NSMutableDictionary*)params {
     NSURL *url = [NSURL URLWithString:@"http://MYURL.COM"];
     AFHTTPClient *httpClient = [[AFHTTPClient alloc] initWithBaseURL:url];
     NSURLRequest *request = [httpClient requestWithMethod:@"POST" path:@"signup.json" parameters:params];
     AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request
                                    success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) {
         [self handleSignUp:JSON];
     } failure:nil];


     //Signaling the start of the signup operation to the delegate
     if(self.delegate){
          [self.delegate UserLoggingIn];
     }

     [operation start];
 }

 - (User*) handleSignUp:(NSMutableArray*)json {
     User * user = nil;
     if ([[json valueForKey:@"success"] isEqualToString:@"true"]) {
           // create user here ...
           //call the delegate (view controller) passing the user
           if(self.delegate){
               [self.delegate UserLoggedIn:user];
           }
     }else{
           //error handling
           if(self.delegate){
               //NSError *error = ...
               //[self.delegate UserLoginError:error];
           }
     }


     //return user;
 }
@end

这篇关于如何正确地实现服务类到我的iOS应用程序?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆