erikdoe / ocmock

Mock objects for Objective-C
http://ocmock.org
Apache License 2.0
2.16k stars 606 forks source link

OCMock 3.8 does not compile in Xcode 11 #472

Closed madsolar8582 closed 3 years ago

madsolar8582 commented 3 years ago

Introduced in ee79b169e2199f3d4d0911fcc9a4a74813d89f66, OCMock 3.8 does not compile anymore in Xcode 11 as the code being used is only available in Xcode 12 or newer. This was not called out in the release notes nor was a major revision made, so I would consider this non-passive. This can be resolved by placing the code in compile checks, or if this is intended, this should be reverted and 3.8.1 released to restore compatibility with Xcode 11 and then the change remade and re-released as OCMock 4.0.

https://github.com/erikdoe/ocmock/blob/7438b18c4e0c3d40665c66b4b81f8ecbdd245462/Source/OCMock/OCMFunctions.m#L466-L476

erikdoe commented 3 years ago

Apologies, it looks like I missed the availability note in the documentation. It's curious, though, because I could have sworn that the deprecation warning for the older API appeared before Xcode 12, so I didn't expect that the replacement would require Xcode 12. Well, that teaches me to respond to Apple's deprecating warnings in a timely manner.

(Minor rant: of course I'm aware of Apple's tendency to push for the latest and greatest quite aggressively, but I also feel this is getting worse these days. The other day I tried to use a new feature of Swift UI and it suddenly required Big Sur as a minimum deployment target...)

Do you happen to know how to do compile time checks for the Xcode version? If that's not possible, I guess, I could always look up the classes by their name.

madsolar8582 commented 3 years ago

No worries Erik. If we're talking about Apple being Apple we can also rant about their missing documentation 🙃.

To fix this, you can pull in the Availability header (<Availability.h>) and use the __IPHONE_X_Y definition (or macOS/tvOS; your choice) in an #ifdef. So if we need to check for Xcode 12+, that would look something like:

#ifdef __IPHONE_14_0
if (newThing) {
  // Do new thing
}
else {
  // Do old thing
}
#else
 // Do old thing
#endif

It unfortunately leads to a bit of code duplication, but it makes things backwards compatible. Luckily XCTest is shipped in Xcode itself and not the SDKs, otherwise you'd have to wrap things in the @available check too.

erikdoe commented 3 years ago

I think I fixed it.