I'm doing UI testing in Swift and the app I'm testing shows many update/progress messages using the pod SVProgressHud. I want to be able to verify whether the correct message is being displayed. How can I capture the SVProgress HUD and get its text?
SVProgressHud is accessibility-ready (at least the version 1.1.3 that I'm using), so it's as simple as:
let message = app.otherElements["Your update/progress message"]
If you're also looking for string localization in UI tests target, please refer to this answer:
https://stackoverflow.com/a/44014704/1104337
Hide SVProgressHUD in Swift 4
func stopLoader(){
DispatchQueue.main.async {
SVProgressHUD.dismiss()
}
}
Thanks!
Show SVProgressHUD with text and setting ring thickness in Swift 4
func startLoader(){
DispatchQueue.main.async {
SVProgressHUD.show(withStatus: "Loading...")
SVProgressHUD.setDefaultStyle(SVProgressHUDStyle.dark)
SVProgressHUD.setRingThickness(3.0)
SVProgressHUD.setMinimumDismissTimeInterval(2.0)
}
}
Thanks!
Related
I’m currently creating a text entry that allows the user to enter some texts and use it as some kind of title. Then I had this idea of making a preview for this text entry, but I don’t know how to update the preview content as the user is editing the text entry.
For example, once the user type something into the text entry, the preview label automatically and immediately respond to display the text written by the user. (the user doesn’t have to do anything)
I’ve seen a lot of tutorials online about “how to live check a NSTextField?”, but I’ve tried their ways, it didn’t work.
I’m using Xcode 10.0 with Swift 4.2, is there any way to achieve this?
I figured out how to do this:
extension ViewController: NSTextFieldDelegate {
func controlTextDidChange(_ obj: Notification) {
guard let textView = obj.object as? NSTextField else {
return
}
// codes
}
}
I am working on accepting a CKShare in a macOS app in Swift 4. I've already done all the following:
Create the CKShare and save it with its rootRecord to CloudKit
Add a participant (CKShare.Participant)
I've confirmed that the CKShare is on the CloudKit server and that the person I invited has access to it. Here's a screenshot: https://d.pr/i/0sMFQq
When I click the share link associated with the CKShare, it opens my app, but nothing happens and userDidAcceptCloudKitShareWith doesn't fire.
func application(_ application: NSApplication, userDidAcceptCloudKitShareWith metadata: CKShareMetadata) {
print("Made it!") //<-- This never gets logged :(
let shareOperation = CKAcceptSharesOperation(shareMetadatas: [metadata])
shareOperation.qualityOfService = .userInteractive
shareOperation.perShareCompletionBlock = {meta, share, error in
print("meta \(meta)\nshare \(share)\nerror \(error)")
}
shareOperation.acceptSharesCompletionBlock = { error in
if let error = error{
print("error in accept share completion \(error)")
}else{
//Send your user to where they need to go in your app
print("successful share:\n\(metadata)")
}
}
CKContainer.default().add(shareOperation)
}
Is there some kind of URL scheme I have to include in my info.plist? Or perhaps a protocol I need to conform to in my NSApplicationDelegate delegate? I can't, for the life of me, figure out what to do. Thanks in advance!
Update
I've tried a few more things on this. When I open the share link in a web browser, I see this:
Clicking OK makes the screen fade away to this:
Not particularly helpful. :) After doing this, the participant's status in CloudKit is still Invited, so the share still hasn't been accepted.
When I click on a share link within Messages, I am shown a popup like this:
After I click open, a new copy of my app shows up in the dock, then the app suddenly closes. The crash log states:
Terminating app due to uncaught exception 'CKException', reason: 'The application is missing required entitlement com.apple.developer.icloud-services'
I've tried turning iCloud off and on again in the Capabilities section of Xcode, but nothing changes. I know this exception can't be right because I can start my app normally and use CloudKit all day long. Only the CKShare causes this crash.
This is a mess. Save me, Obi-wan Kenobi, you're my only hope.
Yes,
You need to add this to your info.plist.
<key>CKSharingSupported</key>
<true/>
** EDITED ANSWER **
I use this code to share, I don't do it manually... not sure if this is an option under OS X I must confess. I am using iOS.
let share = CKShare(rootRecord: record2S!)
share[CKShareTitleKey] = "My Next Share" as CKRecordValue
share.publicPermission = .none
let sharingController = UICloudSharingController(preparationHandler: {(UICloudSharingController, handler:
#escaping (CKShare?, CKContainer?, Error?) -> Void) in
let modifyOp = CKModifyRecordsOperation(recordsToSave:
[record2S!, share], recordIDsToDelete: nil)
modifyOp.savePolicy = .allKeys
modifyOp.modifyRecordsCompletionBlock = { (record, recordID,
error) in
handler(share, CKContainer.default(), error)
}
CKContainer.default().privateCloudDatabase.add(modifyOp)
})
sharingController.availablePermissions = [.allowReadWrite,
.allowPrivate]
sharingController.delegate = self
sharingController.popoverPresentationController?.sourceView = self.view
DispatchQueue.main.async {
self.present(sharingController, animated:true, completion:nil)
}
This presents an activity controller in which you can choose say email and then send a link. You might also want to watch this video, focus on cloudKit JS right at the beginning.
Watch this WWDC video too https://developer.apple.com/videos/play/wwdc2015/710/
It talks about the cloudkit JSON API, using it you can query what has and what hasn't been shared in a terminal window/simple script perhaps. I did the same when using dropbox API a few years back. Hey you can even use the cloudkit JSON API within your code in place of the native calls.
I finally got it to work! I did all of the following:
Deleted my app from ~/Library/Developer/Excode/DerivedData
Made sure I had no other copies of my app archived anywhere on my machine.
Said a prayer.
Rebooted.
Sheesh, that was rough. :)
If your app is a Mac Catalyst app running on any version of macOS Catalina at least up to and including 10.15.4 Beta 1, a UIApplicationDelegate userDidAcceptCloudKitShareWith method will never be invoked.
After some significant debugging, we discovered that the MacCatalyst UIKit doesn’t even have an implementation for userDidAcceptCloudKitShareWithMetadata in its UIApplication delegate. It’s not broken, it’s just not there. So, at least temporarily, our workaround is the following, which seems to work, even if it’s very inelegant:
// Add CloudKit sharing acceptance handling to UINSApplicationDelegate, which is missing it.
#if targetEnvironment(macCatalyst)
extension NSObject {
#objc func application(_ application: NSObject, userDidAcceptCloudKitShareWithMetadata cloudKitShareMetadata: CKShare.Metadata) {
YourClass.acceptCloudKitShare(cloudKitShareMetadata: cloudKitShareMetadata)
}
}
#endif
If you are using a SceneDelegate, implement the delegate callback there, instead of on AppDelegate.
func windowScene(_ windowScene: UIWindowScene, userDidAcceptCloudKitShareWith cloudKitShareMetadata: CKShare.Metadata) {
// ...
}
You need to create the app delegate for your SwiftUI app using #NSApplicationDelegateAdaptor:
#main
struct Sharing_ServiceApp: App
{
#NSApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
var body: some Scene
{
WindowGroup
{
ContentView()
.environment(\.managedObjectContext, persistenceController.container.viewContext)
}
}
}
I put that line in and my code instantly started receiving the share requests.
I'm new at Swift 3 and I try to make a print("Test") in a Widget extension.
I tried the same code in ViewController.swift and It works ok. I don't know why it works there but it doesn't on TodayViewController.swift. I can't access to objects too.
func loadData() {
let query = PFQuery(className: "Noticias")
query.whereKey("titulo", equalTo:"Es Navidad")
query.findObjectsInBackground(block: { (objects : [PFObject]?, error: Error?) -> Void in
if error == nil {
// The find succeeded.
print("Successfully retrieved \(objects!.count) scores.")
// Do something with the found objects
if let objects = objects {
for object in objects {
print(object.objectId!)
}
}
} else {
// Log details of the failure
print("bad day homie")
print(error!)
}
})
}
I attach I picture to see it clearly. If I try to print on the file marked as Work, it works. But if I try it on the file marked ad NO, it doesn't.
It is extremely difficult to retrieve print messages from an extension. The problem is that it's an extension! It isn't running in your app, so it doesn't arrive at your console. Sometimes I find you can solve this problem by switching the debugged process in the Debug Bar at the top of the debug area (at the bottom of the screen, not shown in your screen shot), but at other times this doesn't work.
I'll illustrate a possible technique that seems to be pretty reliable. Look at this screen shot:
"Expand" is an action extension. But my containing app is called "bk2ch13...". So how will I ever manage to pause at the breakpoint shown at the right, which is in the action extension? This is what I do.
First, with the screen as shown above, I build and run my containing app.
Then, I switch the target to the action extension:
Now I build and run again. But now I am trying to run an action extension, which you can't do, so Xcode asks me what app to run:
So I choose "bk2ch13...". So now we are running my host app again, but we are debugging the extension. So I use my host app to exercise the extension, and sure enough, we pause at the breakpoints and print statements arrive into the console.
Note, in that screen shot, how the debug bar clearly shows that we are talking to the extension, not the host app.
Using Xcode 7.3, writing Swift program; searched for this topic but could not find an answer. Apologies, in advance. Last program language was COBOL.
Application background:
It is a single view application, User keys in data and at some point the User 'wins' - at that point, two buttons are available: 'Quit?' and 'Play Again?'
For the 'Quit?' button I have:
// MARK: C.This IBAction used to quit the game
#IBAction func quitIt(sender: AnyObject)
{
exit(0)
}
Hopefully, the above is the most efficient way.
What I need help on is the 'Play Again?' button:
// TODO: B. This IBAction used to play another game
#IBAction func Playagain(sender: AnyObject)
{
}
What code do I put in?
Move the startup code for your game to it's own func(tion).
Call that function both from [wherever you moved it from] and also in PlayAgain().
I hope this is for OS X rather than iOS - Apple will probably reject your iOS app if it exits. They consider that "crashing".
https://developer.apple.com/library/ios/qa/qa1561/_index.html
**I have read the RevMob instructions for Swift and I have read an answer to an Swift-RevMob question on here, but it didn't resolve my particular issue. **
I am currently trying to get a fullscreen ad to show.
This is my GameViewController.swift:
verride func viewDidLoad() {
super.viewDidLoad()
//Start RevMob code
let completionBlock: () -> Void = {
// do something when it successfully starts the session
RevMobAds.session().showFullscreen();
}
let errorBlock: (NSError!) -> Void = {error in
// check the error
println(error);
}
RevMobAds.startSessionWithAppID("55770fcc17dd7840727aa5e8",
withSuccessHandler: completionBlock, andFailHandler: errorBlock);
//End of RevMob Code
I have defined the modules in my package as "Yes":
This is my Bridge-Header:
// Use this file to import your target's public headers that you would like to expose to Swift.
#import <RevMobAds/RevMobAds.h>
Lastly, this is the error that I am currently getting when I try to build my code:
Thanks if you can help!
CLBeaconRegion is part of Core Location from iOS 7 on, so you need to make sure the framework is linked in your project.
Note: in my experience, CLBeaconRegion is picked up by Apple as part of app review and they often want to know how you're using beacons – even if the code is just sitting there and you're not planning to use it.
Twice now I have been asked by app review to provide a video of my app detecting a beacon so they can see how it works, so either be prepared to explain your usage or see if there's a library version without it built in.
In addition to the required frameworks, you have to add CoreLocation.framework
I had the same issue. With CoreLocation.framework, also add AVFoundation.framework. Hope that helps