According to Apple's documentaion, I should be able to launch an app based on its bundle ID using the code below.
// Open safariapp
let safariApp = XCUIApplication(bundleIdentifier: "com.apple.mobilesafari")
// Launch safari app
safariApp.launch()
Unfortunately, this code will not compile because Xcode claims that XCUIApplication can not take any initialization arguments. This is my error:
Argument passed to call that takes no arguments
This functionality is available starting with the Xcode 9 SDK, so you'll need to update your Xcode version and migrate to Swift 3.2 or 4.
Source: https://developer.apple.com/documentation/xctest/xcuiapplication/2879415-init
Related
Until I upload myapp to appstore
I have this issue:
Please correct the following issues, then upload again.
ITMS-90842: Invalid SDK usage - App clip
'Runner.app/AppClips/RunnerAppClip.app' uses the SDK selector
'requestAlwaysAuthorization', which is not supported. Ensure your app clip is
using supported SDK features.
I am used location permission but how exclude specific location from AppClip
You can include/exclude specific lines of code from your App Clip target using a Swift Compilation Flag.
To do this you can open the Build Settings of your App Clip target and add some custom flag like APPCLIP.
Then in your code...
#if !APPCLIP
//Location code that uses `requestAlwaysAuthorization`
#endif
There's a similar question that works on Objective-C, but I tried the same code in Swift and it never executes, neither in the main app, nor in the action extension.
My situation is similar to the one in the question above, that is, when running from the main app I want to use UIApplication.shared.open to open a link in Safari, but I want to ignore this part of the code on the App Extension.
The problem isn't finding out whether the app is running from an App Extension or not, but ignoring the code when building for the App Extension, so that the compiler does not give me the following error on build:
You could introduce a new Custom Flag (similar to the DEBUG flag) for the extension target. In your Build Settings look for the Custom Flags and add a new one (e.g. "EXTENSION"). Like here in the screenshot, but also do it for release.
In your Code you could then do something like
#if EXTENSION
// here goes code that is only compiled in the extension
#else
// here goes code that is only compiled outside the extension
#endif
Update: Please read the Apple provided documentation on App Extensions:
Some APIs Are Unavailable to App Extensions
Because of its focused role in the system, an app extension is ineligible to participate in certain activities. An app extension cannot:
Access a Application.shared object, and so cannot use any of the methods on that object
- Apple, App Extension Programming Guide
To programmatically find if the it the running extension via code it's really simple, just do this:
let bundleUrl: URL = Bundle.main.bundleURL
let bundlePathExtension: String = bundleUrl.pathExtension
let isAppex: Bool = bundlePathExtension == "appex"
// `true` when invoked inside the `Extension process`
// `false` when invoked inside the `Main process`
This is as straightforward as is sounds; when I try to use session.transferCurrentComplicationUserInfo(_:), I get the error message written in the title, word for word.
Looking at the documentation (transferCurrentComplicationUserInfo, WCSession) there's no indication that it's been deprecated... plus, if something is deprecated it says so in the error message and will still show up in Xcode's intellisense (albeight with strikethrough). For me, neither is happening.
So why Xcode saying it's unavailable?
This is my barebones code that causes the error message:
let userInfo: [String:Any] = [:]
let _ = session?.transferCurrentComplicationUserInfo(userInfo)
For some background, I'm using Xcode 10.1 and Swift 4.2. My app's deployment target is iOS 9.3 and my watch extension's is watchOS 4.0.
Probably, you are trying to call it from the Watch Extension, where it appears as unavailable.
The function transferCurrentComplicationUserInfo can only be called from the iOS app.
I am using github.com/apple/swift-protobuf tag 0.9.904 and github.com/grpc/grpc-swift tag 0.1.12 with Xcode in my iOS app. I am also using the same versions with protoc to compile my .proto file.
The app works fine in the iOS simulator but when I try to run the app on my device I get compile errors on the following bit of generated code in myapp.pb.swift:
// If the compiler emits an error on this type, it is because this file
// was generated by a version of the `protoc` Swift plug-in that is
// incompatible with the version of SwiftProtobuf to which you are linking.
// Please ensure that your are building against the same version of the API
// that was used to generate this file.
fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAPIVersionCheck {
struct _2: SwiftProtobuf.ProtobufAPIVersion_2 {}
typealias Version = _2
}
The errors are
No type named 'ProtobufAPIVersion_2' in module 'SwiftProtobuf'
and
Type '_GeneratedWithProtocGenSwiftVersion' does not conform to protocol 'ProtobufAPIVersionCheck'
The comment on the piece of code causing the errors speaks for itself. However, if this is true, why does the app compile and run fine in the simulator? How can I get it to compile and run on my device as well?
If this is still a problem for you, please file a GitHub issue on the swift-protobuf project.
I've got 3 iPhone 5, 2 iPhone SE, 2 iPhone 6, an iPhone 6+ and an iPhone 7.
I've found that my app which uses a call directory extension won't work on any of the three iPhone 5 devices but there's no problem with it working on the other 6 assorted devices.
In case there is some problem with my app, I created a new app with a call extension which was created entirely using the XCode project templates (the Xcode call directory target template creates a lot of boilerplate code which is fully functional and will run and work without further change).
I got the same results - the template app also does not run on any of the iPhone 5 but it does run on the other 6 devices.
The conclusion from this would appear to be that for some reason call extensions don't work on an iPhone 5, however this is not a correct assumption because I downloaded an app from the app store (Hiya) which uses call extensions onto an iPhone 5 and there were no similar problems with its call extension.
So it is a mystery to me why both my app and the Xcode template app both do not work on any of my iPhone 5 but they are fine on every other device.
And that therefore is my question - has anybody encountered a similar situation or has any speculation why they don't work on iPhone 5?
(Was there an architecture change after iPhone5 and the build settings of the call extension might need changing to get it to work on the iPhone 5 for example?)
The way my app and the Xcode template app fails on the iPhone 5 is the same
1) the extension does not appear in Setting | Phone | Call Blocking & Identification. This implies it may not have installed/registered with the OS properly, however I don't see any problems being logged by the OS in the console when looking at the OS logging.
2) The status of the extension cannot be queried on an iPhone 5:
let theExtension = CXCallDirectoryManager.sharedInstance
theExtension.getEnabledStatusForExtension(withIdentifier: "com.redacted.redacted.CallDirectoryApp.TheCallExtension") {(enabledStatus, error) -> Void in
if let err = error as? NSError
{
print ("\(err.code) \(err.localizedDescription) \(err.localizedFailureReason)")
}
}
The error is err NSError domain: "com.apple.CallKit.error.calldirectorymanager" - code: 1
Again this might indicate the problem is related to the extension not installing.
(The problem is independent of the version of iOS 10 used on the iPhone 5, its the same result with a few versions of both beta and non beta versions. All devices are registered on the provisioning portal)
The iPhone 5 is 32 bit and everything else is 64 bit. I changed Xcode's default settings for the extension to the following and it now works: