Nativescript addSubview - nativescript

I'm trying to implement the OpenTok SDK into Nativescript and I've run into an issue that I can't seem to wrap my head around.
Per their documentation (https://tokbox.com/developer/guides/publish-stream/ios/#create_publisher) once you create a publisher object you call:
[self.view addSubview:publisher.view];
I can't figure out how I would tie this into Nativescript, if it's even possible.
My first thought is that I would want a UIView or View element on my page in the XML, then I would call .addView(publisher.view); on that element.
There is a similar question here (Inject pure Java / Obj-C code in NativeScript App) but nothing came of it, the one answer does't provide much help.
I cloned one of OpenTok's sample projects and added their implementation of this call into a gist here: https://gist.github.com/bondydaa/2db355ed45b7e50e4071
You can see at line 117 how they implemented this call. This code raises another question for me in that I'm not sure where _publisherView comes from.
Any help would be greatly appreciated!

In Nativescript you can try calling the 'ios' property of the container you are trying to add the component to. This will return the native object.
For example if you have a StackLayout, you can:
var stackLayout = args.object.getViewById("theIdOfTheStackLayout");
stackLayout.ios.addSubview(publisher.view);

Related

NativeScript: use custom objective-c imported class into Xcode project in NativeScript

basically I have some Objective-c class already existing and I want to use them in my NativeScript projet. Currently I have added those files to the Xcode project target and I want to be able to call my objective-c code from nativeScript js. I've read the doc but I don't understand it. It seems so complicated. basically currently all I want to do is be able to present my custom view controller by calling probably something along
const vc = MyCustomViewController.alloc.initWithNibName("xib file")
page.frame.ios.controller.present(vc,true, nil)
Am I obligated to create a plugin for that? Am I obligated to use my objective-c class to build a framework in Xcode and then import the framework?
So I found out.
Actually what you need to do is first to compile your native iOS code into a framework. As per the documentation all your classes must inherit NSObject and all your function must be marked with #objc to be exposed to the objective-c Nativescript side if you write in swift. You will notice as well that in a framework your bundle is not the main bundle. In this example you can see how you can retrieve the bundle from the framework and load a xib from it.
Then you need to add your framework file to a Nativescript plugin. For that, you want to add the framework to the plugin's iOS folder yourPlugin/platform/iOS/yourFramework.framework.
then, you need to add your plugin to your app. You can add your local plugin by using the next command line. Notice the path end with the /src folder.
tns plugin add /path/to/yourplugin/src
Now, you can then call your native functions and classes without even importing them. Of course this works only on iOS. If you run your app on android, calling those methods will crash.
To show this viewController on your Nativescript side you will need to call the following code. By the way You can find documentation elsewhere to get a reference to the current page or frame object.
const controller = page.frame.ios.controller
const vc = IOMediaViewController.create()
vc.modalPresentationStyle = UIModalPresentationFullScreen
controller.presentViewControllerAnimatedCompletion(vc,true,null)

NativeScript importing iOS framework classes and downcast

I have a custom Swift framework in a Cocoapod, wrapped in a NativeScript plugin. My NativeScript TypeScript code can do everything it needs to access classes and methods in the classes in the framework. That in itself was a lot of work to figure out all the nuances. Now I'm at the last part, which is to downcast a custom viewController in the framework from UIViewController. The following code is working, in that NativeScript actually loads my storyboard and controller:
var podBundle = NSBundle.bundleForClass(CustomViewController)
var bundleUrl = podBundle.URLForResourceWithExtension("MyFramework", "bundle")
var bundle = NSBundle.bundleWithURL(bundleUrl)
var storyboard = UIStoryboard.storyboardWithNameBundle("Main", bundle)
var viewController = storyboard.instantiateViewControllerWithIdentifier("CustomViewControllerID")
console.log(viewController)
console.log(viewController instanceof CustomViewController)
application.ios.rootController.presentViewControllerAnimatedCompletion(viewController, true, null)
The first console.log actually logs the full class, as in MyFramework.CustomViewController: hexcodehere
The second console.log logs true as well, meaning it knows the type of the viewController variable is indeed CustomViewController.
The problem is, I need to call a function in CustomViewController, so I need to downcast:
storyboard.instantiateViewControllerWithIdentifier("CustomViewControllerID") as CustomViewController
But the compiler says "Cannot find name" to CustomViewController. If I try MyFramework.CustomViewController, it says "Cannot find name" to MyFramework. Notice NSBundle.bundleForClass(CustomViewController) works. So that means CustomViewController is known to the compiler.
If I import the plugin at the top of the file:
import { CustomViewController } from "myplugin", it says "cannot find module" to myplugin. Mind you I can actually access all the classes in this plugin. So the plugin is definitely properly installed. It is installed from a local file path, not git.
It seems I'm missing something devilishly simple. But I can't figure it out for the life of me.
I'm happy to help others who want to use native iOS storyboard and Swift classes, etc.
Attesting to the brain's ability to work on a problem in the background, it suddenly came to me. Since the runtime is aware of the type, all I have to do is to cast to "any" to get around the compiler issue:
var viewController = storyboard.instantiateViewControllerWithIdentifier("CustomViewControllerID") as any
Then the compiler allows me to call whatever function on my CustomViewController viewcontroller instance without a complaint, and runtime is fine too. To be extra safe, wrap the calls to subclass methods in a if instanceof block.

protractor dragAndDrop not working on Mac

I am executing my protractor code on MAC OS system and using Chrome. Everything works but not drag and drop event.
The code is working fine if I put my actual mouse position on the target of drop. But if the actual mouse position is not at the target location, its not performing the action.
The code I am using is as:
browser.actions().dragAndDrop(source,target).perform();
I have also tried this :
browser.actions().mouseDown(source).mouseMove(target).mouseUp().perform();
Use html-dnd NPM module.
Link:https://www.npmjs.com/package/html-dnd
code snippet:
var dragAndDrop = require('html-dnd').code;
var draggable = driver.findElement(By.id('draggable'));
var droppable = driver.findElement(By.id('droppable'));
driver.executeScript(dragAndDrop, draggable, droppable);
for this :
browser.actions().dragAndDrop(source,target).perform();
try this :
browser.actions().mouseMove(source).mouseDown().mouseMove(target).mouseUp().perform();
Note that dragAndDrop is nothing but mouseMove + mouseDown + mouseMove + mouseUp
Chances are you're in a long line of people who have problems with the drag and drop functionality implemented with html5. This has been a problem area to work around using Selenium webdriver.
Please see that the issue might be due to an age old bug that was filed for ChromeDriver.
The bug has a lot of discussion that may be helpful in understanding the real issue and there are also a lot of solutions mentioned in the comments below - however there has not been a fool-proof or 100% working solution to this problem.
This bug has been mentioned in Protractor github issues a lot of times like here, here, here,and here and in Selenium GitHub in the archived issues here.
One of the solutions you can try is this helper method that was created here. However this is not a guaranteed solution, but I would suggest you to give it a try. The original issue mentioned for Protractor here also has many other solutions mentioned which you can try. You can also try this helper method.
Also, please see that the same question has been posted multiple times here, here, here, here.

How to get iOS alert text in appium 1.6

Before upgrading to XCode 8 and subsequently Appium 1.6 and IOS 10 for some appium tests, I used to be able to use the below XPath to capture the main text in an alert.
#iOSFindBy(xpath = "//UIAAlert/UIAScrollView/UIAStaticText[2]")
private MobileElement alertText;
However something has changed and this no longer works. I would still like to be able to assert on the alert text and don't want to use the IOSMobileCapabilityType.AUTO_DISMISS_ALERTS capability.
Has anyone found a way to get at the alert text?
Bonus question: Where is all this XPath documented? I found it on some random forum, but I can't find any official documentation or figure out how it relates to a captured View Hierarchy in XCode.
Answering my own question in case it helps anyone else.
Due to the appium inspector not working with XCode8, the best way to print the screen layout XML is just to do a System.out.println(driver.getPageSource());
Then you can follow the structure and do something like
#iOSFindBy(xpath = "//XCUIElementTypeAlert//XCUIElementTypeStaticText[2]")
private MobileElement alertText;
I got that from this question: Finding elements by xpath in Appium using XCUITEST driver

ModalViewController in iOS8

I am upgrading old code to latest iOS8, I see lots of this:
if (controller.modalViewController
&& controller.modalViewController.parentViewController == controller)
if(tabcontroller.modalViewController) ....
I see lots of documentation about how to present a modalViewController, but not for when its a property like above code. What's the equivalent of above code in iOS8?
THanks
If you look at the documentation, it says:
modalViewController (iOS 6.0) The controller for the active presented
view'that is, the view that is temporarily displayed on top of the
view managed by the receiver. (read-only)
Deprecation Statement Use presentedViewController instead.
That's probably a good place to start.

Resources