Writing Your Own Lock Method

I am trying to follow examples from others as well as from Apple. I'm lost.

I have a singleton class that I use to handle my login (causing problems with the web server, etc.).

I want to create a block that I can call, pass username / password. The block will make web service calls, and then return if it was successful or not.

Here is what I have managed so far to work:

My singleton class is as follows:

.h

typedef void (^AMLoginBlock)(NSString *userName, NSString *password); @interface AuthManager : NSObject + (id)sharedManager; + (bool)loginUserWithBlock:(AMLoginBlock)block; @end 

wow

 @implementation AuthManager + (id)sharedManager { static dispatch_once_t pred = 0; __strong static id _sharedObject = nil; dispatch_once(&pred, ^{ _sharedObject = [[self alloc] init]; // or some other init method }); return _sharedObject; } + (bool)loginUserWithBlock:(AMLoginBlock)block { NSLog(@"im printing from AM"); return true; } @end 

Then I call the method as follows:

 bool rtn = [AuthManager loginUserWithBlock:^(NSString *userName, NSString *password) { NSLog(@"im here in the block LVC."); }]; 

My question has three parts:

  • How to write a completion handler for a block similar to a UIView animation... block.

  • Is it good to make these web service calls from a block implementation?

  • Should I declare a block method as follows:

    - (bool)loginUserWithBlock:(AMLoginBlock)block;

instead of using +(bool)loginUser.. since it is in a singleton class. Not sure if this will lead to multiple instances of the singleton.

My goal is to be able to call this block, as you call [UIView animation..] . So I can just do:

 [AuthManager loginUserWithUsername:foo password:bar1 completion:^(BOOL finished) { if (finished) //push new view controller. else //spit out error }]; 
+6
source share
1 answer

Completion handler

You will want to copy the completion block into the iVar class:

 @property (nonatomic, copy) void (^completionHandler)(bool *); 

Since you are saving the block, you need the non-class method to accept the block (see how to do this without breaking your singleton). An example of your method might be:

 - (void)loginUserWithUsername:(NSString *)username password:(NSString *)password completion:(void(^)(bool *finished))completionBlock { // Copy the blocks to use later self.completionHandler = completionBlock; // Run code [self doOtherThings]; } 

Then, when your login code finishes its work, you can call the block - here I pass self.error, a bool to the block:

 - (void)finishThingsUp { // We are done with all that hard work. Lets call the block! self.completionHandler(self.error); // Clean up the blocks self.completionHandler = nil; } 

A good idea

Well, this is a philosophical question, but I will say this: Blocks in Objective-C allow you to write code that performs one task and easily integrate it into many programs. If you decide not to use the completion handler in your login code, you will need a login code:

  • Require classes using it to implement the protocol (as in LoginDelegate )
  • Use a different reporting system for your code, such as Monitoring Key Values ​​or Notifications
  • Hard code only works with one type of calling class

Any of the above approaches are fine, I believe the block-based callback system is the simplest and most flexible. It allows you to simply use your class without worrying about additional infrastructure (setting up notifications, protocol compliance, etc.), but it allows you to reuse it in other classes or programs.

Singelton

Methods starting with + in Objective-C are class methods. You cannot use class methods to control iVars, since who will own this data?

What you can do is to have a class method that always returns the same instance of that class, allowing you to have an object that can own the data, but avoid having more than one of them.

This great answer contains sample code .

Good luck

+6
source

Source: https://habr.com/ru/post/925272/


All Articles