XCText: query for text in navigation bar - ios

I've got a UITest that succeeds in iOS 10 (10.3):
let app = XCUIApplication()
let pageTitle = app.navigationBars["Module.ContainerView"].staticTexts["page title"]
XCTAssert(pageTitle.exists)
This however fails in iOS 11 (11.1). The app.navigationBars["Module.ContainerView"] exists, the staticTexts of that is an empty array.
Any ideas how to test for a title in the navigation bar in iOS 11?

You can find the exact type of title by using the recording feature.
As a solution you can try with the below code. Hope it will work.
let app = XCUIApplication()
let pageTitle =
app.navigationBars["Module.ContainerView"].otherElements["page title"]
XCTAssert(pageTitle.exists)

let app = XCUIApplication()
let navTitleIdentifier = "Community"
let navigationTitleElement = app.navigationBars.matching(identifier: navTitleIdentifier).firstMatch
XCTAssert(navigationTitleElement.exists)

Related

Copypaste doesn't work properly sometimes while XCUITest running. Why?

When the issue happens I see CoreSimulatorBridge pasted from CoreSimulatorBridge popup instead of my usual popup MyApp pasted from MyAppUITests-Runner. Any comments why it could happen?
code example:
UIPasteboard.general.string = "build 2882"
let app = XCUIApplication()
let textField = app.textFields["my text field"]
textField.tap()
let menuQuery = app.menuItems
let menuItem = menuQuery["Paste"]
menuItem.waitForExistence(timeout: 5)
menuItem.tap()
The rare result:

Sharing a story to Instagram with a background image and a sticker - IOS Swift

I'm trying to share a story with a background image a a sticker image via URL Scheme on my ios app, i am using the attached code and it dose not work.
When i'm trying to share just a background image or just a sticker it does work. But when im trying share both a background image and a sticker in top of it, it dose not work.
Any Ideas?
func shareToInstagram(deepLinkString : String){
let url = URL(string: "instagram-stories://share")!
if UIApplication.shared.canOpenURL(url){
let backgroundData = UIImageJPEGRepresentation(UIImage(named: "shop_placeholder")!, 1.0)!
let creditCardImage = UIImage(named: "share_instagram")!
let stickerData = UIImagePNGRepresentation(creditCardImage)!
let pasteBoardItems = [
["com.instagram.sharedSticker.backgroundImage" : backgroundData],
["com.instagram.sharedSticker.stickerImage" : stickerData],
]
if #available(iOS 10.0, *) {
UIPasteboard.general.setItems(pasteBoardItems, options: [.expirationDate: Date().addingTimeInterval(60 * 5)])
} else {
UIPasteboard.general.items = pasteBoardItems
}
UIApplication.shared.openURL(url)
}
I copy pasted OP's code for use in my own app (only substituting different UIImages) and found only 1 issue, pasteboard items should be contained in a single array otherwise instagram will render only the first item (in this case the background layer). To fix this, replace the declaration of pasteboard items with the following code
let pasteBoardItems = [
["com.instagram.sharedSticker.backgroundImage" : backgroundData,
"com.instagram.sharedSticker.stickerImage" : stickerData]
]
(basically just remove the close and open bracket separating the two items)
Also as a previous answer stated, make sure "instagram-stories" is included in LSApplicationQueriesSchemes in the info.plist file
I use this exact code in my app and it now works perfect
Everything is correct, my code is similar and it works for iOS 11+. I suggest you the following:
check the image data you pass to pasteboard (jpg can't be converted with
UIImagePNGRepresentation and vice versa)
check the info.plist. You should enable "instagram-stories" scheme in it (LSApplicationQueriesSchemes key)
Like Alec said, you need to put all of Instagram data in one list, not multiple lists. look at the example from the meta documents:
NSArray *pasteboardItems = #[#{#"com.instagram.sharedSticker.stickerImage" : stickerImage,
#"com.instagram.sharedSticker.backgroundTopColor" : backgroundTopColor,
#"com.instagram.sharedSticker.backgroundBottomColor" : backgroundBottomColor}];
2. For more recent readers, as of swift 4.2 and iOS 12 UIImageJPEGRepresentation is replaced by jpegData. change
let backgroundData = UIImageJPEGRepresentation(yourImage, 1.0)
with
let backgroundData = yourImage.jpegData(compressionQuality: 1.0)

How to enable camera in MFMessageComposeViewController?

I am developing an iOS application with a button to report an issue using SMS/iMessage. I am using MFMessageComposeViewController to present the message composition interface using the following code (Swift 3):
if(MFMessageComposeViewController.canSendText()){
let controller = MFMessageComposeViewController()
controller.messageComposeDelegate = self
controller.body = "Example Message"
controller.recipients = ["2345678901"]
self.present(controller, animated: true, completion: nil)
}
I have also implemented the MFMessageComposeViewControllerDelegate function to dismiss properly. A standard text message / iMessage sends successfully, but the user does not have the option to attach an image. The buttons for camera, iMessage Apps, etc. are there, but they are disabled and cannot be pressed. How can I enable these buttons (camera, specifically) to allow my users to attach images to messages composed with the app?
The Buttons in Question:
EDIT:
Thanks Abdelahad for the suggestion. I've modified his response to allow multiple recipients and to include a message body. I also updated it to remove the deprecated addingPercentEscapes(using: ) method.
Here is a solution using a url to open the Messages app. NOTE: This takes users out of the app.
let recipients = "2345678901,3456789012" //Phone Numbers
let messageBody = "This is a test"
let sms: String = "sms://open?addresses=\(recipients)&body=\(messageBody)"
let smsEncoded = sms.addingPercentEncoding(withAllowedCharacters: .urlFragmentAllowed)
let url = URL(string: smsEncoded!)
UIApplication.shared.openURL(url!)
But still I would like a solution that does not take the user out of the app. Is this possible? Why would the MFMessageComposeViewController show the buttons without enabling them?
Don't use MFMessageComposeViewController use UIApplication.shared.openURL(url!) but this will takes the user out of the app
var phoneToCall: String = "sms: +201016588557"
var phoneToCallEncoded = phoneToCall.addingPercentEscapes(using: String.Encoding.ascii)
var url = URL(string: phoneToCallEncoded)
UIApplication.shared.openURL(url!)

Issue with Xmartlabs Eureka form builder on iOS in Swift

I am having a bit of trouble with a part of the Eureka framework for Swift in iOS. It works fine, except for when I try to clear out a form programatically which is already on the screen all the fields seem to clear out fine, except for the DecimalRow type field.
(form.rowBy(tag: "name") as? TextRow)?.value = ""
**(form.rowBy(tag: "amount") as? DecimalRow)?.value = Double(0.0)**
(form.rowBy(tag: "date") as? DateRow)?.value = Date()
(form.rowBy(tag: "reimb") as? SwitchRow)?.value = false
The DecimalRow type field stays whatever value was in it and does not respond to the line above in bold (asterisk-ed).
Any insight appreciated. Many thanks.
Have you reloaded the row?
This worked fine on my code.
(self.form.rowBy(tag: "user_weight") as? DecimalRow)?.value = Double(0.0)
(self.form.rowBy(tag: "user_weight")?.reload()
Where
<<< DecimalRow("user_weight")
And if I run
self.form.values() I get:
"user_weight": Optional(0.0)
So its cleared
You can also clear the form in this way
self.form.setValues(["user_weight": 0])
An example made by them
form.setValues(["IntRowTag": 8, "TextRowTag": "Hello world!", "PushRowTag": Company(name:"Xmartlabs")])
https://github.com/xmartlabs/Eureka#how-to-set-the-form-values-using-a-dictionary

How to detect First launch of app on every new version upgrade?

I have a requirement of detecting the first launch of app after the user upgrades the app to a newer version. I need to perform certain task only on first launch of app after the user upgrades the app to a new version. Many links available online but none answer clearly to my query. How to achieve this in Swift 2 , iOS 9.
Most of the answers available says to maintain a key in NSUserDefaults and set its value to false and after first launch make it true. But the problem is after I upgrade my app the variable still will be true and thus my scenario fails on app upgrade. Any help would be much appreciated. Thanks!
Try this:
let existingVersion = NSUserDefaults.standardUserDefaults().objectForKey("CurrentVersionNumber") as? String
let appVersionNumber = NSBundle.mainBundle().objectForInfoDictionaryKey("CFBundleShortVersionString") as! String
if existingVersion != appVersionNumber {
NSUserDefaults.standardUserDefaults().setObject(appVersionNumber, forKey: "CurrentVersionNumber")
NSUserDefaults.standardUserDefaults().synchronize()
//You can handle your code here
}
updating Yogesh's perfect, yet simple solution to swift 4
let existingVersion = UserDefaults.standard.object(forKey: "CurrentVersionNumber") as? String
let appVersionNumber = Bundle.main.object(forInfoDictionaryKey: "CFBundleShortVersionString") as! String
if existingVersion != appVersionNumber {
print("existingVersion = \(String(describing: existingVersion))")
UserDefaults.standard.set(appVersionNumber, forKey: "CurrentVersionNumber")
// run code here.
}

Resources