Skip to content

Commit

Permalink
Don't use NSInvoke to get task attributes.
Browse files Browse the repository at this point in the history
I've experimented, on iOS 14.0.1, that `invocation.getReturnValue(ret)` raises:
     [NSInvocation getArgument:atIndex:]: NULL address argument

However, using invocations seems no more needed since the properties we're
fetching are directly available from the task object.
  • Loading branch information
boutier committed Oct 5, 2020
1 parent cc507cc commit 4d28dfa
Showing 1 changed file with 6 additions and 34 deletions.
40 changes: 6 additions & 34 deletions packages/background-http/index.ios.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Observable, knownFolders } from "@nativescript/core";
import { ProgressEventData, ErrorEventData, ResultEventData, Session as ISession, Task as ITask, Request as IRequest, CompleteEventData } from ".";
import { knownFolders, Observable } from "@nativescript/core";
import { CompleteEventData, ErrorEventData, ProgressEventData, Request as IRequest, ResultEventData } from ".";

const main_queue = dispatch_get_current_queue();
let zonedOnProgress = null;
Expand Down Expand Up @@ -230,36 +230,8 @@ class Session implements Session {
}
}

class NativePropertyReader {
private _invocationCache = new Map<string, NSInvocation>();

private getInvocationObject(object: NSObject, selector: string): NSInvocation {
let invocation = this._invocationCache.get(selector);
if (!invocation) {
const sig = object.methodSignatureForSelector(selector);
invocation = NSInvocation.invocationWithMethodSignature(sig);
invocation.selector = selector;

this._invocationCache[selector] = invocation;
}

return invocation;
}

public readProp<T>(object: NSObject, prop: string, type: interop.Type<T>): T {
const invocation = this.getInvocationObject(object, prop);
invocation.invokeWithTarget(object);

const ret = new interop.Reference<T>(type, new interop.Pointer());
invocation.getReturnValue(ret);

return ret.value;
}
}

class Task extends Observable {
public static _tasks = new Map<NSURLSessionTask, Task>();
public static tasksReader = new NativePropertyReader();
private static is64BitArchitecture = interop.sizeof(interop.types.id) === 8;
public static NSIntegerType = Task.is64BitArchitecture ? interop.types.int64 : interop.types.int32;

Expand All @@ -282,19 +254,19 @@ class Task extends Observable {
}

get upload(): number {
return Task.tasksReader.readProp(this._task, "countOfBytesSent", interop.types.int64);
return this._task.countOfBytesSent;
}

get totalUpload(): number {
return Task.tasksReader.readProp(this._task, "countOfBytesExpectedToSend", interop.types.int64);
return this._task.countOfBytesExpectedToSend;
}

get status(): string {
if (Task.tasksReader.readProp(this._task, "error", Task.NSIntegerType)) {
if (this._task.error) {
return "error";
}
// NSURLSessionTaskState : NSInteger, so we should pass number format here
switch (Task.tasksReader.readProp(this._task, "state", Task.NSIntegerType) as NSURLSessionTaskState) {
switch (this._task.state) {
case NSURLSessionTaskState.Running: return "uploading";
case NSURLSessionTaskState.Completed: return "complete";
case NSURLSessionTaskState.Canceling: return "error";
Expand Down

0 comments on commit 4d28dfa

Please sign in to comment.