Objective C generated interface header file Not found in WatchKit - ios

I am currently working to add Apple Watch app in my current App. I added the required profiles and got it to working without any issues.
Now, I want to use some of the class files from iphone app in my apple watch app. I did add the .m file in the target membership to the watchkit extension target.
Since the file which I want to use is in Objective C class, I went ahead and created the bridging header file for apple watch extension target.
Each time when I run the application; I get $(SWIFT_MODULE_NAME)-Swift.h file not found. I did try to follow steps from this link but to no avail. I did clean build folder; removed the derived data but it still gives me the same error.
Am I missing anything in particular which others have tried and can share with me ?
I am using Xcode 8 and Swift 3.

So I figured out the answer and thought of posting it here.
There are couple of ways in which you can fix this but it depends on what you want to do.
1) Using #IF TARGET_OS_IOS will allow you to use the class from iphone to watch.
2) You can also use WatchConnectivity framework to send and/or receive messages, send data also. This is the new framework Apple has recommended to use for connectivity between the devices.
Hope this will help someone else trying to figure out this problem.

Related

AVFAudio Framework not present on macOS causes warning for iOS app (app should also be available on AS Macs)

My iOS app uses the AVFAudio framework to provide spoken feedback to the user while running. I would like this app to also run on Apple Silicon Macs (where the spoken feedback is not really necessary).
However, just importing the framework results in the following warning email after I upload to App Store Connect:
We identified one or more issues with a recent delivery for your app,
"App Name" 7.0 (24). Your delivery was successful, but you may wish to
correct the following issues in your next delivery:
ITMS-90863: Apple silicon Macs support issue - The app links with
libraries that are not present on Mac:
/System/Library/Frameworks/AVFAudio.framework/AVFAudio
I guess that this means the app will not be able to run on Macs.
How should I get this app to use the AVFAudio framework for iOS and still be available to run on macOS (AS Macs) with or without the framework on macOS?
Relevant code is:
import AVFoundation
class Speaker {
var speechSynth: AVSpeechSynthesizer
class func establishAudioSession() {
do {
try AVAudioSession.sharedInstance().setCategory(.playback, options: [.interruptSpokenAudioAndMixWithOthers, .duckOthers])
try AVAudioSession.sharedInstance().setMode(.voicePrompt)
try AVAudioSession.sharedInstance().setActive(true, options: [])
UPDATE / CLARIFICATION:
Note that my project does not include multiple targets. With multiple targets, this would be fairly straightforward. I am wondering if there is a way to achieve this by taking advantage of the newer AS Macs’ ability to run apps built for iOS without a separate target.
Is this possible when using this framework?
UPDATE 2:
I have submitted a support request to Apple for this now and their first suggestion was replacing
import AVFoundation
with
import AVFAudio
and then re-uploaded to App Store Connect, but after trying this, I get the same warning email back again. Will post an update (or hopefully an answer) when I hear back from them again.
I suppose your project has multiple targets defines (i.e. one for iOS and one for macOS). In the "General" tag of your target settings you can select which frameworks should be included under "Frameworks, Libraries and Embedded Content". Add your library for iOS, remove it for macOS.
If you share the same code you between apps you can also conditionally exclude some of it for macOS.
#if os(iOS)
// iOS only code
#endif
However, just importing the framework results in the following warning email after I upload to App Store Connect:
The problem probably isn't importing, but (as the message you got indicates), linking to AVFAudio, that's the problem. So solve that, you should select your app target in the Xcode project and go to the Build Phases tab. Look at the Link Binary with Libraries line and hit the disclosure button at the beginning of the line to reveal all the libraries that are linked into your app. Find AVFAudio and change the setting (there's a popup on the right side of the line) from Required to Optional. That'll let your app link to the framework if it's there, but still run if it's not.
But wait, you're not done yet... What do you think will happen if your app tries to actually use a framework that's not linked in (because it doesn't exist on the machine)? You'll get a crash, of course. To avoid that unhappy fate, you'll need to check for the existence of the framework before you use it. For example, you could do something like:
if NSClassFromString("AVAudioPlayer") != nil {
// do your AVFAudio stuff here
}
Further follow up from Apple support suggested the following:
Change back to import AVFoundation
Reduce the deployment targets from the latest and greatest back down to something less recent.
So I did both of these, changing the deployment targets from iOS 14.5 and macOS 11.3 to iOS 14.1 and macOS 11.0.
This has resolved (or worked around!) the issue.
I do want to deploy to the latest and greatest target for this particular app, so I don't consider it to be a complete solution as yet, but it will do as a work around for now. (I actually want to deploy to 15.0 when it's available to make use of the promised improvements to OSLogStore.)
So this sounds like a bug to me, and I have queried Apple for some further information on the issue, in particular, the ability to target more recent OS versions.

How to use Swift Pod in Unity exported iOS App

I have reach experience in iOS native app development, My company have a unity app. Unity app developer exported the app for iOS and shared with me. I wanted to use my own created cocoa-pod library (which I have already using in my another iOS App) into Unity iOS project.
So Unity developer exported by File -> Build Settings, choose iOS and click Build, and now I am trying integrated pod (which is written in Swift 4.2) into Unity exported of iOS project.
I have taken medium post and many more reference, I have implemented the same as conclusive direction. Please look the attached screenshot below.
Reference - https://medium.com/ios-os-x-development/swift-and-objective-c-interoperability-2add8e6d6887
Please look the below screenshot for autogenerated file
Now when I am going to import this autogenerated header file to make connection between Objective C to Swift, then it is showing error as attached screenshot below
Please help me to resolve this issue. Thanks in advance.
One thing that has hung me up on this in the past is if you get an error during the initial build, then sometimes it doesn't create the -swift.h file and then subsequent builds also get an error that it's missing. Make sure you've deleted your derived data and cleaned the build folder to reset so everything gets built from the beginning.

How to connect Realm with watchOS and iOS app at the same time?

So, there simple instructions on Realm website:
Installation (Swift 2.1.1):
...
2) Go to your Xcode project’s “General”
settings. Drag RealmSwift.framework and Realm.framework from the
ios/swift-2.1.1/, watchos/, tvos/ or osx/swift-2.1.1/ directory to the
“Embedded Binaries” section. Make sure Copy items if needed is
selected and click Finish.
Basically, stating that we need to use different Realm libraries for developing apps for Watch and for iPhone.
Problem here, is that if I want to create watchOS app I need to import library specific to it. When at the same time I'm trying to import library for iOS, I get error from xCode (version 7.2.1):
Multiple errors occurred while copying the files
Making it impossible to add both libraries at the same time.
My goal is to share data between Watch and iPhone like instructed in this article, but even there author is missing information on how to setup 2 different libraries.
Appreciate any help or advice. Thank you.
The problem you are having adding both the iOS Frameworks and the WatchKit's frameworks is the exact same one I had
I solved this by copying both folders [iOS] [watchkit] into my Xcode project's folder, then adding the respective libraries to their target's Embedded Binaries section.
In this way, you will not be literally copying the same-named items to the same location and it will not throw the error!

Framework CFBundleIdentifier Collision

I've made a custom SDK using Cocoa Touch Framework (followed these instructions to make it https://kodmunki.wordpress.com/2015/03/04/cocoa-touch-frameworks-for-ios8-remix/) .
One app, that is using this SDK is already uploaded to app store and is reviewed by apple and all is well.
Now I'm trying to submit second app to App store. All is well on the xCode, it shows that upload was completed successfully, but few minutes after uploading I get a letter that says:
CFBundleIdentifier Collision - The Info.plist CFBundleIdentifier value
'com.company.MySDK' of 'myApp.app/Frameworks/MySDK.framework' is
already in use by another application.
I don’t understand why apple even checks the app framework's bundleidentifier. Looks like there are lot of similar issues with using different bundles, but I haven not found a fix that would work for this issue.
Would be really thankful for help, thanks!
For me it was caused by framework's .plist keyword CFBundlePackageType that was using the default value APPL but had to be changed to FMWK (https://developer.apple.com/library/ios/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html#//apple_ref/doc/uid/20001431-111321).
if you are using Nested frameworks use "Do Not Embed" in the general tab-> framework and libraries
for example:
your project uses framework A and
and framework A uses frameworks B, C, ... Do not Embed these frameworks

How can I reference a Swift class in my WatchKit extension from the core iOS code?

I am trying to make my iOS application send the WatchKit Extension a set of data each time that data is updated from the server.
This is what the code in my iOS app looks like (names changed)
[WatchKitDataModel loadDataFromSource: currentData]
However, the iOS application does not recognize the WatchKitDataModel.
The error is "use of undeclared modifier."
Please help me make my apps talk to one another!
Ensure that your offending class is added to both the App target and the WatchKit target in the Document panel
The picture shows a TodayExtension but the principle is the same.
To share code between your WatchKit Extension and its containing app, create an embedded Framework in your app. Frameworks are the recommended tool by Apple to share code, within an app, and between apps.
To create an embedded Framework in Xcode 6, select your project and go to File > New > Target... Then in the dialog that opens select iOS > Framework & Library > Cocoa Touch Framework. Click Next. Give it a name, SomethingKit, similar to what Apple uses, e.g. UIKit, HealthKit, WatchKit. Now create your new classes and other common code in files inside your new Framework. When you want to use it in any of your other targets, i.e. the WatchKit Extension or its containing app, don't forget to import SomethingKit.
Ah, and don't forget to give public access level to the public-facing classes and functions in your Framework.
For more information about Frameworks to share code, for example, what sort of things cannot be included in Frameworks, see Apple's article: Using an Embedded Framework to Share Code.
There is also an interesting WWDC 2014 session video about this: Building Modern Frameworks.

Resources