Pass method to run on NSURLConnection's connectionDidFinishLoading - xcode

I'm creating an app where i call my API through this function:
func serverCallAPI(function:String,
success:((result:NSDictionary) -> Void)?) -> Void {
//code here to set up request to send with NSURLConnection
let connection:NSURLConnection = NSURLConnection(request: request,
delegate: self,
startImmediately: true)!
//I WANT TO RUN THE PASSED ON SUCCESS FUNCTION WHEN connectionDidFinishLoading IS CALLED.
}
I need to use NSURLConnection to update my UI when fetching the data
I might have a queue with serverCallAPIs waiting in line to be run, every single now with their own success function. The final function needs to be able to do that
It needs to cancel if the connection fails. Perhaps something with a dispatch or NSOperation? I'm lost on this one... :(
My problem is that I cannot think of a way to call the passed on success function when connectionDidFinishLoading is done processing. How can you do that?

Related

How to call $this->emitSelf() multiple times on function

I have the following example function:
public function backupService()
{
$job = Job::find($this->job_id);
sleep(5);
$job->status = 'in_progress';
$job->update();
$this->emitSelf('refreshComponent');
sleep(10);
$job->status = 'finished';
$job->update();
$this->emitSelf('refreshComponent');
}
When I change the status to 'in_progress' it changes in my database but doesn't update the component. Apparently it is only issuing $this->emitSelf() when the backupService() function finishes, ie the status will never appear as 'in_progress', only as 'finished'.
I don't want to use the wire:poll directive because I don't want to keep updating the page all the time, only when I specifically call it. How can I resolve this?
The event will be emitted once the entire method backupService() is finished with its execution, when the response from that method is sent back to the browser. Livewire-events are actually sent to the browser with the response, and any components listening for those events will be triggering actions on the client, making secondary-requests.
This means that the refresh-event that you emit, will trigger after everything is completed.
If you don't want to use polling, then another alternative is websockets. But this too can be a bit much for such a simple task, so a third alternative is to restructure your method into two methods, one that starts the process, and have events going from there. Something like this, where the first method is only responsible for setting the new status and emitting a new event that will be starting the job, and the second method is responsible for execution.
protected $listeners = [
'refreshComponent' => '$refresh',
'runJob'
];
public function backupService()
{
$job = Job::find($this->job_id);
$job->status = 'in_progress';
$job->update();
$this->emitSelf('runJob', $job);
}
public function runJob(Job $job)
{
sleep(10);
$job->status = 'finished';
$job->update();
$this->emitSelf('refreshComponent');
}

How to handle sse connection closed?

I have an endpoint streamed as in the sample code block. When streaming, I call an async method through streamHelper.getStreamSuspendCount(). I am stopping this async method in changing state. But I can not access this async method when the browser is closed and the session is terminated. I am stopping the async method in session scope when changing state. But I can not access this async method when the browser is closed and the session is terminated. How can I access this scope when Session is closed?
#RequestMapping(value = "/stream/{columnId}/suspendCount", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
#ResponseBody
public Flux<Integer> suspendCount(#PathVariable String columnId) {
ColumnObject columnObject = streamHelper.findColumnObjectInListById(columnId);
return streamHelper.getStreamSuspendCount(columnObject);
}
getStreamSuspendCount(ColumnObject columnObject) {
...
//async flux
Flux<?> newFlux = beSubscribeFlow.get(i);
Disposable disposable = newFlux.subscribe();
beDisposeFlow.add(disposable); // my session scope variable. if change state, i will kill disposable (dispose()).
...
return Flux.fromStream(Stream.generate(() -> columnObject.getPendingObject().size())).distinctUntilChanged()
.doOnNext(i -> {
System.out.println(i);
}));
}
I think part of the problem is that you are attempting to get a Disposable that you want to call at the end of the session. But in doing so, you are subscribing to the sequence yourself. Spring Framework will also subscribe to the Flux returned by getStreamSuspendCount, and it is THAT subscription that needs to be cancelled for the SSE client to get notified.
Now how to achieve this? What you need is a sort of "valve" that will cancel its source upon receiving an external signal. This is what takeUntilOther(Publisher<?>) does.
So now you need a Publisher<?> that you can tie to the session lifecycle (more specifically the session close event): as soon as it emits, takeUntilOther will cancel its source.
2 options there:
the session close event is exposed in a listener-like API: use Mono.create
you really need to manually trigger the cancel: use MonoProcessor.create() and when the time comes, push any value through it
Here are simplified examples with made up APIs to clarify:
Create
return theFluxForSSE.takeUntilOther(Mono.create(sink ->
sessionEvent.registerListenerForClose(closeEvent -> sink.success(closeEvent))
));
MonoProcessor
MonoProcessor<String> processor = MonoProcessor.create();
beDisposeFlow.add(processor); // make it available to your session scope?
return theFluxForSSE.takeUntilOther(processor); //Spring will subscribe to this
Let's simulate the session close with a scheduled task:
Executors.newSingleThreadScheduledExecutor().schedule(() ->
processor.onNext("STOP") // that's the key part: manually sending data through the processor to signal takeUntilOther
, 2, TimeUnit.SECONDS);
Here is a simulated unit test example that you can run to better understand what happens:
#Test
public void simulation() {
Flux<Long> theFluxForSSE = Flux.interval(Duration.ofMillis(100));
MonoProcessor<String> processor = MonoProcessor.create();
Executors.newSingleThreadScheduledExecutor().schedule(() -> processor.onNext("STOP"), 2, TimeUnit.SECONDS);
theFluxForSSE.takeUntilOther(processor.log())
.log()
.blockLast();
}

GWT RPC - Parallel asynchronous calls

I have a list of promises that needs to be executed in parallel and in an asynchronous manner.Say,i have,
List<Promise<X>> list;
Once all the parallel request completes, i need to make another request say "Y". Here is my GWT code,
GQuery.when(list).done(...).fail(..)
But the above doesn seem to work!.How can i pass a list of promises to GQuery?.Is the above synctax valid?.
If you create a sample GWT project in Eclipse, a simple asynchronous RPC call is created. You can take that as a template to change it the way you need. With the callback of the request is it possible to display your "Y".
// Set up the callback object.
AsyncCallback<List<Promise<X>>> callback = new AsyncCallback<List<Promise<X>>>() {
public void onFailure(Throwable caught) {
// TODO: Do something with errors.
}
public void onSuccess(List<Promise<X>> result) {
// TODO: DO something with the result.
}
};
You should also read the documentations, at least...
http://www.gwtproject.org/doc/latest/tutorial/RPC.html

RestKit Best practices with the sendSynchronously method

I am trying to load objects synchronously with RestKit and to do that I am using [anObjectLoader sendSynchronously] on a background thread. Then in the RKObjectLoader didFinishLoad: the application is currently stopping at the first line: NSAssert([NSThread isMainThread], #"RKObjectLoaderDelegate callbacks must occur on the main thread");
Looking at the documentation, the sendSynchronously method from the RKRequest class says that the request will be synchronously requested and a hydrated response object will be returned.
This is a snapshot of my code:
RKObjectLoader *anObjectLoader = [self.objectManager loaderWithResourcePath:resourcePath];
NSLog(#"Response: %#", [anObjectLoader sendSynchronously]);
On console:
*** Assertion failure in -[RKManagedObjectLoader didFinishLoad:], ...RestKit/Code/ObjectMapping/RKObjectLoader.m:423
Is it Ok to use RestKit with synchronous calls?
Are there better ways to send synchronous requests?
Am I missing something?
You should never make synchronous calls. Use the send method and catch the response using either delegates or block callbacks. Among other things, this method is optimized for network bandwidth usage and also handles threading correctly.
As an aside, the reason RKObjectLoader requires the main thread is because that is where your main object context is.
I recently had this same question. I figured out how to send a synchronous call using blocks and it's actually quite nice. Basically you do whatever restkit call you were intending to do, but instead of setting the delegate to self, you use usingBlock. Then, within that block you can handle the various responses from your API call.
Block Example (APIUser is class I wrote that represents the current user):
[[RKObjectManager sharedManager] loadObjectsAtResourcePath:[#"/api/users/" stringByAppendingString:userName] usingBlock:^(RKObjectLoader* loader) {
loader.onDidLoadResponse = ^(RKResponse *response) {
NSLog(#"Response: \n%#", [response bodyAsString]);
};
loader.onDidLoadObjects = ^(NSArray *objects) {
APIUser *apiUser = [objects objectAtIndex:0];
};
loader.onDidFailWithError = ^(NSError *error) {
NSLog(#"Response: \n%#", [response bodyAsString]);
};
}];
My original question and answer can be found here.

why doesn't ajax fn() follow the code sequence

I just wanted to understand the coding flow of ajax function. let me give one simple example,
function test() { alert("Hello"); alert("World"); }
if you run this function, the first dialog would be Hello and the second would be World, Right? But why in ajax the coding structure doesn't go through in same fashion.
ajaxRequest.open("POST", "pos/write", true);
ajaxRequest.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
ajaxRequest.send("user=Ram"); /* this line can be written anywhere */
ajaxRequest.onreadystatechange = function() {
if(ajaxRequest.readyState == 4 && ajaxRequest.status == 200){
alert("done"); }
// ajaxRequest.send("user=Ram");
as you can see, .send('user=Ram') written above & below the .readyState, but it runs successfully in both case. This is what i want to understand, why doesn't ajax fn() follow the code sequence
You have to keep in mind that .send() is asynchronous. Immediately after .send() is called, you're wiring up the onreadystatechange handler on the same object that will eventually receive the response from pos/write. Even though it appears after the request was initiated, there will always be time for it to run and wire that handler up before the response comes back, the XHR object changes its readyState to 4, and your onreadystatechange event handler is executed.

Resources