How do you set up a block property that takes as an argument another block property so that auto-complete supplies all of the required parameters for both blocks?
To explain further, I'll demonstrate how auto-complete works with just one block property.
In AppDelegate.h
, create a convenient way to reference the AppDelegate class for all classes that require access to the block property:
#define AppServices ((AppDelegate *)[[UIApplication sharedApplication] delegate])
Then, define the block:
typedef void (^LogEvent)(NSString *context, NSString *entry, LogTextAttributes logTextAttributes, dispatch_block_t block);
Then, designate the block as a property:
@property (copy, nonatomic, readwrite) LogEvent logEvent;
In the AppDelegate.m, write a method that returns ???n (I don't know exactly what I'm returning; I just know that it works—is it a block that :
- (LogEvent)logEvent
{
return ^(NSString *context, NSString *entry, LogTextAttributes logTextAttributes, dispatch_block_t block) {
...task A...
block();
};
}
In another class file, import the header containing the block property:
#import "AppDelegate.h"
Then, begin typing the name of the LogEvent
block property (logEvent
), and let auto-complete fill in the required parameters:
AppServices.logEvent(<#NSString *context#>, <#NSString *entry#>, <#LogTextAttributes logTextAttributes#>, <#^(void)block#>)
To use that, you have to substitute the placeholders for real values, and you have to replace block with:
^{ ...block... }
Here's an example of what that looks like in a real-world scenario:
AppServices.logEvent([NSString stringWithFormat:@"%s", __PRETTY_FUNCTION__], @"Starting network service browser...", LogTextAttributes_Operation, ^(){
...task B...
});
What this will do is perform task A, and then perform task B. What I want to do is define two blocks, designate both as properties, and then add one to the other as a parameter; then, when I type the name of the block that accepts the other as a parameter, I want Xcode to auto-complete the required parameters for both of them. For example:
For a block property named RunTask
that takes, as a parameter, a dispatch_block_t
named block
, I would expect, with the same setup, that typing RunTask
would produce this:
RunTask(<#^(void)block#>)
So, if the dispatch_block_t block
parameter of the LogEvent
type definition was replaced by RunTask
:
void (^LogEvent)(..., RunTask runTask);
Then, Xcode would auto-complete LogEvent
like this:
AppServices.logEvent(..., ^{ ...task B... });
By the way, how would you make it so that, with the original dispatch_block_t parameter of LogEvent, auto-complete would do the same thing as then block parameter of, say, dispatch_async:
dispatch_async(<#dispatch_queue_t _Nonnull queue#>, <#^(void)block#>)
When you type dispatch_async, Xcode provides placeholders for the two required parameters. If you hit tab twice, the block (last) parameter is highlighted in blue; if you press Return, this happens:
dispatch_async(<#dispatch_queue_t _Nonnull queue#>, ^{
<#code#>
})
The block-statement placeholder turns into a block statement with a code placeholder inside the block. I want to know how to do that...
The following code shows you how to set up blocks-within-a-block so that Xcode will auto-complete both the parameters and return values when you use the block:
In the header file:
In the implementation file:
In the implementation file of any class granted access to the Task property, being typing the path to the property, as well as the property name itself, until Xcode auto-completes the rest:
Press the tab key to advance to the first parameter (
condition
), and then press Return; repeat for the remaining two parameters (success
andfailure
):Replace
code
with your code, making sure to return the appropriate value for any block that returns a non-void type )(condition
returnsBOOL
):In this example, the Task block executes either the
Success
orFailure
block depending on the return value of the conditional specified in theCondition
block.My intended use is far more complex and pragmatic than this example; but, as far as "how to do it" goes, it will do.