I'm trying to use schedule(deadline:repeating:leeway:) on an iOS project. In a counterpart macOS project it works fine, but in the iOS project I get an error:
'schedule(deadline:repeating:leeway:)' is unavailable
Here is a part of the code:
var timeoutTimer : DispatchSourceTimer?
func startUpdateTimer(){
let delay : DispatchTime = .now() + .seconds(3)
if timeoutTimer == nil {
timeoutTimer = DispatchSource.makeTimerSource()
timeoutTimer!.schedule(deadline: delay, repeating: 0) // Error: 'schedule(deadline:repeating:leeway:)' is unavailable
...
Doc 1:
https://developer.apple.com/documentation/dispatch/dispatchsourcetimer/2920395-schedule
I would like to understand if I'm doing something wrong, could someone tell me if this code should work on iOS?
PS
Using scheduleRepeating(deadline:interval:leeway:) which is deprecated instead of schedule(deadline:repeating:leeway:) seems to work. At the moment unfortunately I do not have enough knowledge to understand how the two statements differ.
timeoutTimer!.scheduleRepeating(deadline: delay, interval: 0)
Doc 2: https://developer.apple.com/documentation/dispatch/dispatchsourcetimer/2016072-schedulerepeating
scheduleRepeating(deadline:interval:leeway:) was introduced in iOS 7/macOS 10.9 and has been deprecated in iOS 11/macOS 10.13.
Initially Apple offered scheduleRepeating and scheduleOneshot variants but this made no sense as if a timer is repeating or oneshot can be deducted solely by arguments passed to the function. Now they only offer schedule(deadline:repeating:leeway:), and if called with a non-zero value for repeating, the timer is repeating, otherwise it is oneshot.
However, please note that in fact GCD timers are not real objects, neither Swift objects nor Objective-C objects, in fact they are C structures represented as opaque pointers. If you create such a GCD object in C or Obj-C, the code is like this:
dispatch_source_t ds = dispatch_source_create(
DISPATCH_SOURCE_TYPE_TIMER, 0, 0, someQueue
);
dispatch_source_set_timer(ds, startTime, interval, leeway);
Making GCD Objects appear as Swift objects is actually some "magic" built into Xcode and the Swift SDK. schedule(deadline:repeating:leeway:) is only available if you use Xcode 9+ and Swift 4. If you use Xcode 8.x or if you use Swift 3 in Xcode 9+, then only the deprecated scheduleRepeating(deadline:interval:leeway:) is available.
Unlike with other API, that's not a question of the iOS/macOS SDK version you build for, as this magic is not provided by the iOS/macOS SDK, it depends on the Swift SDK version you build for and this version is independent of the target operating system, as the SDK is embedded into your app and thus shipped together with your app.
That's why you can use schedule(deadline:repeating:leeway:) in Swift 4 in Xcode 9+ and still deploy all the way down to iOS 7.0/macOS 10.9, since only for your Swift code the call has changed, internally it uses the same GCD API calls that the deprecated methods were using before, so the compiled code runs just fine even on these old OS versions.
To answer your question on how the statements differ: Well, they have different names and the arguments have different names, other than that the argument types are identically and they also work identically.
Related
I have an app with Firebase integration to connect analytics using cocoapods. It was working well without any yellow warnings for iOS 13, but when I installed the new cocoa pods for target iOS 14 and build the app I get 6 yellow warning messages
"XXXPods/GoogleUtilities/GoogleUtilities/Logger/GULLogger.m:130:20: This old-style function definition is not preceded by a prototype"
When I was looking for answers online, there are only few and pointing to Flutter. I don't have Flutter for this app and I don't think I will be needing one. Does anyone else have the same issue? How can this be silenced for iOS 14 please?
I can downgrade the pods to iOS 13 but the whole point was to update the version.
Thank you for any help/direction
So this is a new warning in Xcode 12.5 (I believe) for old C style functions declared in those SDKs or any old style code using that syntax.
What does it mean?
do-not-leave-the-parameter-list-of-a-function-blank---use-void
if a function declaration does not include arguments, as in
double atof();, that too is taken to mean that nothing is to be assumed about the arguments of atof; all parameter checking is turned off. This special meaning of the empty argument list is intended to permit older C programs to compile with new compilers. But it's a bad idea to use it with new programs. If the function takes arguments, declare them; if it takes no arguments, use void.
So this is how your function prototype should look:
int foo(void);
And this is how the function definition should be:
int foo(void)
{
...
<statements>
...
return 1;
}
One advantage of using the above, over int foo() type of declaration (ie. without using the keyword void), is that the compiler can detect the error if you call your function using an erroneous statement like foo(42). This kind of a function call statement would not cause any errors if you leave the parameter list blank. The error would pass silently, undetected and the code would still execute.
What can we do?
May be raise a ticket for Firebase SDK to address (if there is not one already).
How big of a problem is this?
Depends on the implementation details. Could be as simple as replacing () with (void) for all of these functions. Could be a little more involved as explained above otherwise.
Firebase team maintains the SDKs regularly and we should see a fix for this in an upcoming release soon.
Run pod update
Firebase fixed this issue in February after Xcode 12.5 was introduced github.com/google/GoogleUtilities/pull/8/files.
What is the min iOS which works well with Swift 5.1 or incoming Swift 5.2?
Are there any references to check this?
A similar question has been asked before, when Swift 4 came out. You can find the question and answer here.
Having that said, the swift.org site and the release notes only specify the compatibility with previous Swift versions, the operating systems and the toolchain (Xcode). So, a straight forward answer can't be given to this question.
Since Swift 5.1 is compatible with Swift 4, you can safely assume the code will run iOS 11 and probably iOS 10 as well. There are, however, some incompatibilities between Swift 5.1 and Swift 4, see for the details this link. I think you should also be aware of the fact that as of iOS 11 32 bit is not being supported anymore.
The next issue you will definitely run into are the deprecated functions in iOS. You have to build your code in the productive version of Xcode and that tool will throw errors and warnings for deprecated functions or variables being changed. For instance, the key "[UIImagePickerControllerOriginalImage" has been changed to "UIImagePickerController.InfoKey.originalImage". at the moment Xcode 11.3 doesn't let you specify below 12.1, so you will run into these problems when updating source code written in an older version.
I'm creating a simple App in which TimePickers are used to capture the hour and the minute. I use code to do this like the following:
end.AddHours(view.FindViewById<TimePicker>(Resource.Id.endPicker).Hour);
end.AddMinutes(view.FindViewById<TimePicker>(Resource.Id.endPicker).Minute);
The problem is with the Hourand the Minute properties, while end is a DateTime.
On KitKat API lvl 19, Visual Studio gives me the following error:
On MarshMallow API lvl 23, however, the App runs very well. So the problem must be that the Java getCurrentMinute/Hour methods were exchanged in later APIs for the getMinute/Hour methods as it is written here. Is there a way to use the earlier methods in earlier APIs and use the most recent methods on later ones? Can I code this into my Xamarin.Android App? In Native Android I would of course check the SDK version and use Java methods accordingly, but I don't know if I can force the underlying Java code to behave this way.
UPDATE
Following the suggestion of Janmejoy , I created an if statement to check the Android version in problematic cases like this one and used deprecated code:
if(((int)Android.OS.Build.VERSION.SdkInt) < 23)
{
start = new DateTime(1, 1, 1, (int)view.FindViewById<TimePicker>(Resource.Id.startPicker).CurrentHour,
(int)view.FindViewById<TimePicker>(Resource.Id.startPicker).CurrentMinute, 0);
end = new DateTime(1, 1, 1, (int)view.FindViewById<TimePicker>(Resource.Id.endPicker).CurrentHour,
(int)view.FindViewById<TimePicker>(Resource.Id.endPicker).CurrentMinute, 0);
}
This seemed to work, however, my App was extremely slow on the emulated KitKat device (it runs flawlessly on a 1 GB Marsh, but it appears to be buggy on an earlier device with 762 MB RAM). What is worse, the App now looks the same on both Marsh and KitKat exhibiting the same buggy behavior. I deleted the App from both devices, commented out the deprecated code and done a RebuildAll, but this strange behavior still persists. Has anyone seen any similar? What might be the problem?
In Native Android I would of course check the SDK version and use
Java methods accordingly,
Yes You are right ! You can try like this in Xamarin also
if (((int)Android.OS.Build.VERSION.SdkInt) >= 23){
//
}
else{//}
#see https://developer.xamarin.com/api/property/Android.OS.Build+VERSION.SdkInt/
http://thenextweb.com/apple/2016/05/09/swift-3-0-developer-previews-wwdc/#gref
Does this mean anything? Will I have to completely rebuild my apps or merely convert 2.2 syntax to 3.0?
Swift 3.0 will not be compatible with 2.2. Here is the list of the current proposals, it also details what has been implemented already, and what will be :
https://github.com/apple/swift-evolution
You will not have to entirely rebuild your App, but you will have to adapt your code.
I'd say no. Every Swift app comes with its own runtime and standard libraries of whatever Xcode version you used to build it. Some of my Swift 1.0 app still runs on the latest version of El Capitan.
Source incompatibility means you can't take valid code written in Swift 2, feed it to the Swift 3 compiler and expect everything to go smoothly. There will be errors and deprecation warnings, much of which you already see today with Swift 2.3.
You also can't take a compiled application written in Swift 2 and make it run without modification on a Swift 3 runtime either. Swift is lacking a stable Application Binary Interface (ABI) at the moment. That's why every Swift app must carry its own runtime. OS X and iOS don't provide those at the system level. Hence Swift app tends be larger in size, more of a problem on iOS than OS X.
With Swift 3, Apple is trying to establish a stable ABI so your compiled Swift 3 can run without modification on the Swift 4 runtime, whenever that comes.
What about source code compatibility? No one knows what Chris Lattner has in mind or what he considers archaic. Removing the ++ and -- operator in Swift 3 seem superfluous to me. And why kill C-style for loop too?
I'm currently adapting all my code to the present state of Swift 3. The existing code is certainly not compatible; most methods have been renamed, case names have been lowercased, and so on. To what extent Apple will assist by providing a migration tool is unknown, as that's in the future.
#CodeDifferent provided a great answer, but I'd like to extend on it.
AFAIK, if your Swift 2 app is compiled with its own runtime linked in (i.e., not relying on the system runtime), then your app will run fine & there's no need to rebuild on a Swift 3 machine to run on a Swift 3 machine. But if there's no runtime compiled into the app, then your app won't run on a machine with a Swift 3 ABI.
Of course, if you are going to compile with application with Swift 3, then you will have to re-build.
I have to make apps for that work on both iOS 4 and iOS 5. The iOS 5.0 SDK has nice features like ARC, storyboard etc, which are not available in iOS 4.
My question is: In order to make an app optimized for iOS 4 and 5 what should do? Should I develop an app in a classic way without ARC, storyboard etc?
For instance, how can I switch off automatic garbage collection for iOS 4? If I do, of course iOS 5 will not benefit from having ARC. Also, if you mark reference as weak/string - that will not compile for iOS4, won't it?
As Andrey indicates in his comments, while automatic reference counting was introduced with the LLVM Compiler 3.0 that came with Xcode 4.2 and the iOS 5.0 SDK, you can use it in applications that target back to iOS 4.0. There's no good reason not to use it for applications that will run on iOS 4.0+. Also, it's different from garbage collection, as I explain in this answer.
__weak pointers are only available for applications that use ARC and target iOS 5.0 and greater. For iOS 4.0, you'll need to fall back to using __unsafe_unretained as a pointer type when you want to avoid retain cycles.
However, storyboarding is not available for applications targeting anything earlier than iOS 5.0. It's a nice convenience, but I don't personally use it for anything. Jonathan Wight has, and he has some complaints about its current implementation, so you might not be missing much if you gave that feature a pass.