XCUITest detect UIView - xcode

So in XCUITest I use this code to get a button:
XCUIApplication *app = [[XCUIApplication alloc] init];
XCUIElement *button = app.buttons[#"button_identifier"];
getting a tableview using app.tables and image using app.images and so on.
But how can I get a view(UIView)?

Objective-C
XCUIApplication *app = [[XCUIApplication alloc] init];
XCUIElement *customView = app.otherElements[#"view_identifier"];
Swift
let app = XCUIApplication()
let customView = app.otherElements["view_identifier"]

For Swift 3 / 4 it would look like:
let app = XCUIApplication()
let custom_view = app.otherElements["view_identifier"]
Also what I like to do is to have a class variable, as I do reuse these views frequently for different tests:
lazy var custom_view: XCUIElement = { return XCUIApplication().otherElements["view_identifier"] }()

Related

App opens to specific ViewController inside Navigation Controller

I'm trying to have my app open to a specific ViewController that is deeply embedded in a Navigation Controller, but isn't the RootViewController. I have tried in the app delegate didFinishLaunchingWithOptions adding:
self.window = UIWindow(frame: UIScreen.mainScreen().bounds)
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let initialViewController = storyboard.instantiateViewControllerWithIdentifier("NavViewController")
self.window?.rootViewController = initialViewController
self.window?.makeKeyAndVisible()
But this goes to the root view controller. I tried changing this line to:
storyboard.instantiateViewControllerWithIdentifier("MainViewController")
and this does open to the correct viewcontroller but then there is no Navigation Bar on the top which is needed to navigate in the app.
To access the rootViewController from the AppDelegate then here is the code:
let rootViewController = application.windows[0].rootViewController as! UINavigationController
let mainStoryboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let notificationVC = mainStoryboard.instantiateViewControllerWithIdentifier("identifier") as! NotificationVC
rootViewController.pushViewController(notificationVC, animated: false)
Now, it will have the navigationBar. Let me know, if you still face the issue. thanks.
Here is the Objective-C version to open a specific UIViewController deeply embedded inside a UINavigationController (which is not the rootController).
If we take #bdc example in comments and we want to open UIViewController D:
A : rootViewController
N : navigationController
B, C, D : UIViewControllers embedded in N
A -> N[B C D]
Set storyboardId in InterfaceBuilder for every UIViewController or UINavigationController in the hierarchy through D.
In AppDelegate, the code is straight forward. You just have to instantiate everything, and use your UINavigationController to push every UIViewController in your hierarchy.
// Instanciate from storyboard with identifiers
UIStoryboard * storyboard = [UIStoryboard storyboardWithName:#"MyStoryboard" bundle:nil];
UINavigationController * N = (UINavigationController*) [storyboard instantiateViewControllerWithIdentifier:#"N"];
UIViewController* B = (UIViewController*) [storyboard instantiateViewControllerWithIdentifier:#"B"];
UIViewController* C = (UIViewController*) [storyboard instantiateViewControllerWithIdentifier:#"C"];
UIViewController* D = (UIViewController*) [storyboard instantiateViewControllerWithIdentifier:#"D"];
// Set up the views hierarchy
self.window.rootViewController = N;
[N pushViewController:B animated:NO];
[N pushViewController:C animated:NO];
[N pushViewController:D animated:YES];
[self.window makeKeyAndVisible];
Hope this will help.

How to set up an NSTextView programmatically with explicit NSLayoutManager, NSTextStorage, NSTextContainer?

Following the apple documentation I am trying to set up a simple NSTextView via its two constructor methods.
I am placing the below code inside the viewDidAppear method of the view controller of the content view. textView is an instance of NSTextView, frameRect is the frame of the content view.
The following Swift code works (gives me an editable textView with the text showing on the screen):
textView = NSTextView(frame: frameRect!)
self.view.addSubview(textView)
textView.textStorage?.appendAttributedString(NSAttributedString(string: "Hello"))
The following does NOT work (text view is not editable and no text shown on the screen):
var textStorage = NSTextStorage()
var layoutManager = NSLayoutManager()
textStorage.addLayoutManager(layoutManager)
var textContainer = NSTextContainer(containerSize: frameRect!.size)
layoutManager.addTextContainer(textContainer)
textView = NSTextView(frame: frameRect!, textContainer: textContainer)
textView.editable = true
textView.selectable = true
self.view.addSubview(textView)
textView.textStorage?.appendAttributedString(NSAttributedString(string: "Hello more complex"))
What am I doing wrong in the second example? I am trying to follow the example given in Apple's "Cocoa Text Architecture Guide" where they discuss setting up an NSTextView by explicitly instantiating its web of helper objects.
You need to keep a reference to the NSTextStorage variable you create. I'm not quite sure about the mechanics of it all, but it looks like the text view only keeps a weak reference to its text storage object. Once this object goes out of scope, it's no longer available to the text view. I guess this is in keeping with the MVC design pattern, where views (the NSTextView in this case) are meant to be independent of their models (the NSTextStorage object).
import Cocoa
#NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {
#IBOutlet weak var window: NSWindow!
var textView: NSTextView!
var textStorage: NSTextStorage! // STORE A REFERENCE
func applicationDidFinishLaunching(aNotification: NSNotification) {
var view = window.contentView as NSView
textStorage = NSTextStorage()
var layoutManager = NSLayoutManager()
textStorage.addLayoutManager(layoutManager)
var textContainer = NSTextContainer(containerSize: view.bounds.size)
layoutManager.addTextContainer(textContainer)
textView = NSTextView(frame: view.bounds, textContainer: textContainer)
textView.editable = true
textView.selectable = true
view.addSubview(textView)
textView.textStorage?.appendAttributedString(NSAttributedString(string: "Hello more complex"))
}
}
Tested under Xcode 12.4. in Playgrounds:
import Cocoa
import AppKit
let textViewFrame = CGRect(x: 0, y: 0, width: 250, height: 90)
let textStorage = NSTextStorage()
var layoutManager = NSLayoutManager()
textStorage.addLayoutManager(layoutManager)
var textContainer = NSTextContainer(containerSize: textViewFrame.size)
layoutManager.addTextContainer(textContainer)
let textView = NSTextView(frame: textViewFrame, textContainer: textContainer)
textView.isEditable = true
textView.isSelectable = true
textView.textColor = NSColor.red
textView.string = "Why is this so complicated..."
#import <Cocoa/Cocoa.h>
#interface TextViewController : NSObject {
NSLayoutManager *secondLayout;
IBOutlet NSSplitView *columnView;
IBOutlet NSTextView *bottomView;
}
- (IBAction) addColumn: (id)sender;
#end
#import "TextViewController.h"
#implementation TextViewController
- (void)awakeFromNib
{
NSTextStorage *storage = [bottomView textStorage];
secondLayout = [NSLayoutManager new];
[storage addLayoutManager: secondLayout];
[secondLayout release];
[self addColumn: nil];
[self addColumn: nil];
}
- (IBAction) addColumn: (id)sender
{
NSRect frame = [columnView frame];
NSTextContainer *container = [[NSTextContainer alloc]
initWithContainerSize: frame.size];
[container setHeightTracksTextView: YES];
[container setWidthTracksTextView: YES];
[secondLayout addTextContainer: container];
[container release];
NSTextView *newView = [[NSTextView alloc] initWithFrame: frame
textContainer: container];
[columnView addSubview: newView];
[newView release];
}
#end

how to integrate Admob Interstitial with Sprite Kit ?

This is my First Sprite game, and for some reason the only difficult I've been run to is the admob integration.
This is my ViewDidLoad
- (void)viewDidLoad
{
[super viewDidLoad];
// showing for the first time my AdMob Interstitial
[self showAdmobFullscreen];
// Configure the view.
SKView * skView = (SKView *)self.view;
SKScene *mc = [GameScene01 sceneWithSize:skView.bounds.size];
mc.scaleMode = SKSceneScaleModeAspectFill;
[skView presentScene:mc];
}
and this is my Admob Settings:
-(void)showAdmobFullscreen{
NSLog(#" showAdmoBFullScreenCalled");
// self.interstitial_ = [[GADInterstitial alloc] init];
// self.interstitial.delegate = self;
// self.interstitial.adUnitID = ADMOB_FULLSCREEN_ID;
// [self.interstitial loadRequest:[self adMobrequest]];
interstitial_ = [[GADInterstitial alloc]init];
interstitial_.delegate = self;
interstitial_.adUnitID = #"ca-app-pub-1032576214759203/773434443";
[interstitial_ loadRequest:[self adMobrequest]];
}
- (GADRequest *)adMobrequest {
NSLog(#"requestHasBeenCalled");
GADRequest *request = [GADRequest request];
request.testDevices = #[
// TODO: Add your device/simulator test identifiers here. Your device identifier is printed to
// the console when the app is launched.
//#"9481d65c607d68c867a51229a3c61340"
];
return request;
}
So Far So Good, The admob is fire when the game load. now I want to fire it every time when the user lose in the game.
Right now the whole game run into my Sprite files, and what I tried todo is to call the 'showAdmobFullscreen' every time there's a GameOver
So in my Sprite.m file, I have a method called GameOver, I've added those lines :
-(void)GameOver
{
//Trying to make Admob shows whenever User loses a game
MyMainViewController *spVc = [[MyMainViewController alloc]init];
[spVc showAdmobFullscreen];
I can see the logs of my Admob are being called but no ads are showing up.
any suggestion will be appreciated .
Instead of
MyMainViewController *spVc = [[MyMainViewController alloc]init];
[spVc showAdmobFullscreen];
Try this
[self showAdmobFullscreen];

How can I open a UIViewController from the storyboard with a button in another view programmatically?

I am trying open a view that is in storyboard from code and i don't know how open this. In objective c was
UIViewController *controller = [[UIViewController alloc]
initWithNibName:#"myXib" bundle:[NSBundle mainBundle]];
[self.storyboard instantiateViewControllerWithIdentifier:#"myView"];
But I don't know how to make this in Swift.
I have my code outlet declaration and I use this:
#IBOutlet var viewAboutUs : UIView = UIView()
UIView.animateWithDuration(0.2, animations: {
self.viewAboutUs.frame = CGRectMake(0, UIScreen.mainScreen().bounds.size.height, UIScreen.mainScreen().bounds.size.width, 260.0)
But with this code, my app crash. How can open this view from code??
Try something like this:
let controller1 = UIViewController(nibName: "myXib", bundle: nil);
let storyboard = UIStoryboard(name: "myStoryboard", bundle: nil)
let controller2 = storyboard.instantiateViewControllerWithIdentifier("myView") as UIViewController

MWPhotoBrowser used in button (Xcode)

Im trying to implement your implementation to my project as a button called 'Gallery" but receive an error when trying to run the project.
My implementation file looks like this.
-(IBAction) gallery{
NSMutableArray *photos = [[NSMutableArray alloc] init];
MWPhoto *photo;
{
photo = [MWPhoto photoWithFilePath:[[NSBundle mainBundle] pathForResource:#"fans1" ofType:#"jpg"]];
photo.caption = #"My fans 1";
[photos addObject:photo];
photo = [MWPhoto photoWithFilePath:[[NSBundle mainBundle] pathForResource:#"fans2" ofType:#"jpg"]];
photo.caption = #"My fans 2";
[photos addObject:photo];
photo = [MWPhoto photoWithFilePath:[[NSBundle mainBundle] pathForResource:#"fans3" ofType:#"jpg"]];
photo.caption = #"Fans3";
[photos addObject:photo];
photo = [MWPhoto photoWithFilePath:[[NSBundle mainBundle] pathForResource:#"fans4" ofType:#"jpg"]];
photo.caption = #"Fans4";
[photos addObject:photo];
}
self.photos = photos;
// Create browser
MWPhotoBrowser *browser = [[MWPhotoBrowser alloc] initWithDelegate:self];
browser.displayActionButton = YES;
//browser.wantsFullScreenLayout = NO;
//[browser setInitialPageIndex:2];
// Show
if (_segmentedControl.selectedSegmentIndex == 0) {
// Push
[self.navigationController pushViewController:browser animated:YES];
} else {
// Modal
UINavigationController *nc = [[UINavigationController alloc] initWithRootViewController:browser];
nc.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
[self presentModalViewController:nc animated:YES];
}
}
#pragma mark - MWPhotoBrowserDelegate
- (NSUInteger)numberOfPhotosInPhotoBrowser:(MWPhotoBrowser *)photoBrowser {
return _photos.count;
}
- (MWPhoto *)photoBrowser:(MWPhotoBrowser *)photoBrowser photoAtIndex: (NSUInteger)index {
if (index < _photos.count)
return [_photos objectAtIndex:index];
return nil;
}
When I run the project but the image gallery is not displayed. Im fairly new to ioS development.If you can please point me in the right direction i will deeply appreciate it. The main goal is to have the image gallery displayed when the user touches the Gallery button.
I copied and edited the code from the MWPhotoBrowser Demo Project File I don't receive any errors but I can't get the gallery to appear once button is touched. (BTW I assigned the IBACTION to the buttons). If there is another source code or alternative Framework I can use please advise. Thanks!
Some Ideas:
1) try using 'initWithPhotos'.
2) put a breakpoint at the place you are pushing, check that the push is called.
3) check that the navigationController is not null (0x0) in debugging.
4) remember to release 'browser'.

Resources