Skip to content

Native properties provided by internal classes are not available #1149

@mbektchiev

Description

@mbektchiev

Environment

  • iOS Runtime: 5.3.0+

Describe the bug
There are cases in the iOS SDK where the public headers information (which is the source of NativeScript's metadata) and the actual internal classes which comprise the APIs are different. E.g. Let's consider the inconsistencies of downloadTaskWithURL:completionHandler: method of NSURLSession:

  • The instance that it actually returns is of some internal interface type __NSCFLocalDownloadTask (tested on iOS 12.1)
  • This interface doesn't even inherit from the class advertised as the type of the method's return value -- NSURLSessionDownloadTask. Its base class hierarchy is: __NSCFLocalDownloadTask -> __NSCFLocalSessionTask -> __NSCFURLSessionTask -> NSURLSessionTask -> NSObject
  • NSURLSessionDownloadTask doesn't implement the response selector

=> As a result, the iOS runtime hides this property (along with several others) and reports them as undefined.

To Reproduce

Execute the following JavaScript:

const url = NSURL.URLWithString("http://upload.wikimedia.org/wikipedia/commons/7/7f/Williams_River-27527.jpg");

const downloadPhotoTask = NSURLSession.sharedSession.downloadTaskWithURLCompletionHandler(url, () => {
          console.log("response1: ", downloadPhotoTask.performSelector("response"));
          console.log("response2: ", downloadPhotoTask.response);
});
downloadPhotoTask.resume();

=> The first log correctly prints the response object. While the second one prints undefined.

Expected behavior
Both logs should be identical.

Additional context
The issue has been introduced with the additional filtering implemented with #1086.

Discovered with NativeScript/nativescript-background-http#214

Workaround
As a workaround, such methods, property getters or setters can be invoked dynamically via performSelector, performSelector:withObject: or performSelector:withObject:withObject:

When the return value is not an Objective-C object the above methods will not work correctly. In such cases, NSInvocation should be used like it's done here: https://github.com/NativeScript/nativescript-background-http/pull/222/files#diff-4d82b00cf4fca680654c7e489bc635b2R235

Metadata

Metadata

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions