It is stated in http://playcontrol.net/opensource/LuaCocoa/other-luaobjective-c-bridge.html that LuaCocoa supports Mac implementation. Thus, the available framework, luacocoa.framework is compiled for Mac platform.
However, I wanted to try to compile it on iOS platform to see if it works. So, I downloaded LuaCocoa source code and tried to compile it on iOS platform. Obviously, there are errors. I have this:
"target specifies product type 'com.apple.product-type.framework', but there's no such
product type for the 'iphonesimulator' platform"
I believe that is due to iOS unable to run dynamic library.
So my question is: anyone successfully compile luacocoa on iOS platform and is there any chance luacocoa able to be used on iOS platform.
If there are better suggestion to bridge ObjC-Lua, do let me know as well.
Have you tried Wax
It is an Lua - Obj-C bridge for iOS that has been around for a long time.
Here is a nice article about it.
Related
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.
In order to be able to submit again to the app store (for a published game) we had to make things work for IPv6. So we updated Unity to the version 5.3.5p2 (latest patched version available)
We went through reworking all our networking interfaces (we used to use classic http requests for backend server com and socket connections for asset download) we swapped everything with UnityWebRequest, DownloadHandler and UploadHandler from UnityEngine.Experimental.Networking
Everything works fine on Editor and android but for iOS it just ... crashes.
We are using : Unity 5.3.5p2
xCode 7.2
and iPad2 with iOS 9.3.2
Build settings :
IL2CPP
Universal Architecture (min iOS 7.1)
API Level .Net 2.0
Strip Engine code set to OFF
AOT-Compile options set to : mint-trampoline 512 (we were using this for mono scripting backend)
On Xcode :
Bitcode is disabled
optimisation level set to (for release and debug) : None[-O0]
Here is the error we get on console when the game runs :
Unable to find method GetProgress in
[UnityEngine.dll]UnityEngine.Experimental.Networking.DownloadHandler
.
.
Unable to find method ReceiveContentLength in
[UnityEngine.dll]UnityEngine.Experimental.Networking.DownloadHandler
.
.
[project name] was compiled with optimization - stepping may behave
oddly; variables may not be available.
(we very simply implemented the DownloadHandlerScript with a managed static buffer)
When we build with mono as scripting backend things work fine. But IL2CPP is mandatory for us.
Thank you for your help.
When we build with mono as scripting backend things work fine. But
IL2CPP is mandatory for us.
It is very likely that a function you are calling from UnityWebRequest is not yet implemented in the IL2CPP side or that is a plain bug.
Notice that you are using UnityWebRequest from UnityEngine.Experimental namespace which is clearly an experimental version of UnityWebRequest that is not yet mature. You need to download the latest version of Unity which is Unity 5.4. In 5.4, UnityWebRequest is moved to UnityEngine.Networking namespace and more bugs were fixed in that new release. Download Unity's 5.4.0b21 here.
If that doesn't work, use the Unity WWW API instead of UnityWebRequest. It is IPv6 safe in >= 5.3 versions. Also file for bug report if UnityWebRequest didn't work after updating Unity to 5.4.
This is likely an issue with managed code stripping. I've posted a possible work around on the Unity forums here:
http://forum.unity3d.com/threads/unity-ios-and-ipv6-support.404938/#post-2670944
IIRC runtime compilation and linkage to JIT-ed native code is not allowed on iOS. I was wondering does it affect native code that was not compiled on the client machine but a remote build server and deployed and linked to internally. Is the problem "native code generated on the fly" or "native code that has not passed Apple's review process"?
As I know, there's no correct way to dynamic linking in iOS - it's prohibited by Apple.
Also look here please: Can you build dynamic libraries for iOS and load them at runtime?
For debugging purposes I am looking for a way that a iOS app (whose source code I have access to) can communicate with a separate OSX app, e.g. via sockets.
Since an iOS app running in the Simulator runs natively on the Mac, by using specially designed iOS simulator frameworks that route I/O through OSX frameworks, there must be a way that I can achieve that with my own code as well.
Simply adding standard OSX frameworks to the project and using them from within the iOS app does not work:
If I try to load a OSX framework that exists already as a iOS framework, the iOS framework will always be preferred, meaning if a framework function is only available on OSX but not in iOS, I can't get to it. If the framework doesn't exist yet, like Carbon.framework, then I can get the linker tries to load it. For instance, if I'd try to get to SysBeep(), which is part of Carbon.framework, the linker then fails with an error msg when it wants to resolve external symbols that point to other libs that are already loaded as a iOS-only lib.
I've also tried loading a OSX specific framework using dlopen(), but that fails just the same.
In other words:
How can my iOS code get access to the OSX-specific libs additionally?
That's a lot of questions at once. Let's go step by step:
For debugging purposes I am looking for a way that a iOS app (whose
source code I have access to) can communicate with a separate OSX app,
e.g. via sockets.
It's definitely possible to use OS X facilities from within the iOS app process running in the simulator. Using plain sockets would be very simple as the BSD library is identical in both iOS and Mac OS. You can simply compile your C code and it would use the underlying OS transparently.
If you wanted to use an Objective-C API like NSURLConnection you can do this as well. In the simulator your app uses the Mac OS version of Foundation and Core Foundation. In most cases you would not recognize this as the API is very similar.
[...] the linker will have trouble keeping things apart due to name space
collisions [...]
It's not really clear what you are trying yo achieve here. As I explained, the simulator process uses proper Mac OS lower level frameworks directly. It does not make sense to link to higher level frameworks like AppKit since the app does not make use of Cocoa desktop components. That's why there is no NSApplication symbol and the app does not instantiate one. Instead it uses the UIApplication class from the simulator's specially crafted UIKit framework located in
/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator5.1.sdk/System/Library/Frameworks/UIKit.framework
[...] Building the above then leads to a linker error [...]
That's because the linker is directed to only look into the iPhoneSimulator SDK where no AppKit is present (using a linker flag like -isysroot <path-to-SDK>).
But at this point it's probably worth asking yourself why you want to link to AppKit in the first place. You can set up you interprocess communication without AppKit.
Oh, and to prove that it must be possible somehow, take a look at RubyMotion [...]
In the simulator event handling is done in the "iOS-Simulator.app" process (which is a Mac OS application). To get at these events from within your simulator process you could probably use Quartz Event Services.
Is there a way to have Xcode tell me when I'm calling a method that isn't available in the SDK of the minimum supported target?
For example, the method [NSURLConnection sendAsynchronousRequest:queue:completionHandler:]. This method is available on iOS5 and up. But my application's minimum target is iOS4.
If I use that method (sendAsync), I'd like Xcode to tell me that that method isn't available for the minimum target I'm trying to support.
I've tried putting __IPHONE_OS_VERSION_MAX_ALLOWED=40000 in the preprocessor settings, but that just triggers a bunch of Apple SDK errors that aren't helpful. (Probably because my active SDK is iOS5.1)
Is the only solution to get ahold of old SDKs and install them in Xcode?
Are there any easier solutions?
There is unfortunately no standard way of doing this. By setting the target OS to a lower number than the base SDK, Xcode will weakly link the libraries and frameworks. When doing that Xcode will not warn you for using methods that may not be available on the target OS.
You could temporarily set the base SDK lower, but that might not always work. Since you want to ignore most of the errors and warnings produced (because they are only called conditionally in your code path), and many warnings and errors are dependant on other error that you may need to resolve before the compiler will give any meaningful output.
I do not think there exist any static analysis tools for this, neither from Apple nor third party.
After doing some research, reading the Apple Doc about it, and trying a number of things. The solution is downloading an old Xcode DMG from Apple, grab the .pkg file for the same SDK as your deployment target and install it in your version of Xcode. Here's how:
Download older Xcode.dmg from Apple
Open the DMG
In Terminal, go into packages: "cd /Volumes/[DMG]/Packages; open ."
Find the SDK you want, something like iPhoneSDK_4.0.pkg
Install that package, but change the install directory to /Applications/Xcode/Contents/Developer
Restart Xcode if it was open.
Now that you have the same SDK as your deployment target, set your BaseSDK to the same. When you build you'll get warnings about missing methods. Your project may or may not successfully build with an older BaseSDK in a new version of Xcode, but that doesn't matter - you've just found the method calls you need to wrap in a feature check with respondsToSelector:.
As of Xcode 7.3, the compiler can now generate these warnings for you. All you need to do is set the -Wpartial-availability warning flag in the Build Settings, as described in this answer.