I am making some changes to an existing library which uses the "addTimeInterval:" function which was deprecated in OS X v10.6. I would like to supress the warning using a preprocessor directive to check which SDK version the current build is using. Something like this:
NSDate *newDate= nil;
#if OS X v10.6 (or newer)
newDate= [someOtherDate dateByAddingTimeInterval:60];
#else
newDate= [someOtherDate addTimeInterval:60];
#endif
Is this at all possible using Xcode 4?
How about +[NSDate dateWithTimeIntervalSinceNow:] that's been around since 10.0?
Maybe instead of doing a compile-time check, you could do a runtime check:
if ([[NSDate class] instancesRespondToSelector:#selector(dateByAddingTimeInterval:)]) {
newDate = [someOtherDate dateByAddingTimeInterval:60];
} else {
newDate = [someOtherDate addTimeInterval:60];
}
#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6)
newDate = [someOtherDate dateByAddingTimeInterval:60];
#else
newDate = [someOtherDate addTimeInterval:60];
#endif
But it won't work with 10.5 if you build it with 10.6 SDK. need a runtime check as #Dave said.
You can use the exact same technique I described in CLLocation getDistanceFrom: vs distanceFromLocation:
Juste replace CLLocation with NSDate, getDistanceFrom: with addTimeInterval: and distanceFromLocation: with dateByAddingTimeInterval: in the instructions and you'll be able to always use dateByAddingTimeInterval: no matter what SDK you are using and no matter what OS version you are running.
Related
According to the documentation for
SDL_bool SDL_GetWindowWMInfo(SDL_Window* window,
SDL_SysWMinfo* info)
SDL_SysWMinfo* info's SDL_Version version member must be defined by the SDL_VERSION macro at compile time before it is passed.
Why does SDL_GetWindowWMInfo require the SDL version the calling code was compiled against? What would happen if SDL_GetWindowWMInfo did not check the SDL version?
It's pretty much like keltar said. This is from SDL_windowswindow.c:
SDL_bool
WIN_GetWindowWMInfo(_THIS, SDL_Window * window, SDL_SysWMinfo * info)
{
const SDL_WindowData *data = (const SDL_WindowData *) window->driverdata;
if (info->version.major <= SDL_MAJOR_VERSION) {
info->subsystem = SDL_SYSWM_WINDOWS;
info->info.win.window = data->hwnd;
info->info.win.hdc = data->hdc;
return SDL_TRUE;
} else {
SDL_SetError("Application not compiled with SDL %d.%d\n",
SDL_MAJOR_VERSION, SDL_MINOR_VERSION);
return SDL_FALSE;
}
}
This function fills in a user-provided struct. The danger is that this struct is liable to change as the platform support in SDL changes (as opposed to actual feature/API changes that are more apparent in a new version number).
If that struct definition has changed between versions of SDL (say, you use updated headers but old dll), this requirement allows SDL to detect the problem before it stomps your program's memory.
I am using xcode 7 , swift 2.0
I am getting voice text to Speech working in Simulator but not in real iphone6 plus device, iOS 9. I have properly imported AVFOUNDATION and its Framework.
I tried...
#IBAction func SpeakTheList(sender: AnyObject) {
let mySpeechUtterance = AVSpeechUtterance(string: speakString)
//let voice = AVSpeechSynthesisVoice(language: "en-US")
// mySpeechUtterance.voice = voice
let voices = AVSpeechSynthesisVoice.speechVoices()
for voice in voices {
if "en-US" == voice.language {
mySpeechUtterance.voice = voice
print(voice.language)
break;
}
}
mySpeechSynthesizer.speakUtterance(mySpeechUtterance)
}
I get the following error :
Building MacinTalk voice for asset: (null)
Is there anything I ned to do settings in my iphone6plus iOS 9 , or I have to download something.
I have found a suggestion here Why I'm getting "Building MacinTalk voice for asset: (null)" in iOS device test
saying that..
" since iOS9, possibly a log event turned on during development that they forgot to turn off"
Just want to add to this (and by extension, the linked discussion in the original post):
I have two devices: an iPad2 and an iPad Air. They are running exactly the same version of iOS (9.2, 13C75). I have the following objective-C++ function for generating speech from Qt using Xcode 7.2 (7C68) on Yosemite:
void iOSTTSClient::speakSpeedGender(const QString &msg, const float speechRateModifier, const QString &gender, const bool cutOff) {
QString noHTML(msg);
noHTML.remove(QRegularExpression("<[^<]*?>"));
AVSpeechUtterance *utterance = [[AVSpeechUtterance alloc] initWithString:noHTML.toNSString()];
/* See https://forums.developer.apple.com/thread/18178 */
const float baseSpeechRate = (m_iOSVersion < 9.0) ? 0.15 : AVSpeechUtteranceDefaultSpeechRate;
utterance.rate = baseSpeechRate * speechRateModifier;
NSString *locale;
if (gender.compare("male", Qt::CaseInsensitive) == 0)
locale = #"en-GB"; // "Daniel" by default
else if (gender.compare("female", Qt::CaseInsensitive) == 0)
locale = #"en-US"; // "Samantha" by default
else
locale = [AVSpeechSynthesisVoice currentLanguageCode];
AVSpeechSynthesisVoice *voice = [AVSpeechSynthesisVoice voiceWithLanguage:locale];
const QString errMsg = QString("Null pointer to AVSpeechSynthesisVoice (could not fetch voice for locale '%1')!").arg(QString::fromNSString(locale));
Q_ASSERT_X(voice, "speakSpeedGender", errMsg.toLatin1().data());
utterance.voice = voice;
static const AVSpeechSynthesizer *synthesizer = [[AVSpeechSynthesizer alloc] init];
if (synthesizer.speaking && cutOff) {
const bool stopped = [synthesizer stopSpeakingAtBoundary:AVSpeechBoundaryImmediate];
Q_ASSERT_X(stopped, "speakSpeedGender", "Could not stop previous utterance!");
}
[synthesizer speakUtterance:utterance];
}
On the iPad Air, everything works beautifully:
Building MacinTalk voice for asset:
file:///private/var/mobile/Library/Assets/com_apple_MobileAsset_MacinTalkVoiceAssets/db2bf75d6d3dbf8d4825a3ea16b1a879ac31466b.asset/AssetData/
But on the iPad2, I hear nothing and get the following:
Building MacinTalk voice for asset: (null)
Out of curiosity, I fired up the iPad2 simulator and ran my app there. I got yet another console message:
AXSpeechAssetDownloader|error| ASAssetQuery error fetching results
(for com.apple.MobileAsset.MacinTalkVoiceAssets) Error Domain=ASError
Code=21 "Unable to copy asset information"
UserInfo={NSDescription=Unable to copy asset information}
However, I heard speech! And I realized I was wearing headphones. Sure enough, when I plugged ear buds into the iPad2, I heard speech there too. So now I'm searching for information about that. The following link is recent and has the usual assortment of this-worked-for-me voodoo (none of it helped me, but maybe will help others with this problem):
https://forums.developer.apple.com/thread/18444
In summary: TTS "works" but is not necessarily audible without headphones/ear buds. It appears to be a hardware settings issue with iOS 9.2. The console messages may or may not be relevant.
Final update: in the interests of full, if sheepish, disclosure, I figured I'd share how I finally solved the issue. The iPad2 in question had the "Use side switch to:" option set to "Mute". I left that alone but went ahead and toggled the switch itself. Wham! Everything worked without ear buds. So if you are unable to hear text-to-speech, try ear-buds. If that works, check whether your device is set to mute!
Do not use pauseSpeakingAtBoundary(). Instead, use stopSpeakingAtBoundary and continueSpeaking. This works for me.
Finally Found that there was a bug in iOS9, soon after XCODE new release 7.2 update, and iOS 9.2 Update release,
I tested same above code, text to speech started working.
I have this piece of code running on OS X 10.7:
NSLog(#"Start");
if (NSAccessibilityPriorityKey != NULL) {
NSLog(#"%p", NSAccessibilityPriorityKey);
}
NSLog(#"End");
The code crashes (SIGSEGV) after the Start marker and before it gets to the End marker. According to the headers, the NSAccessibilityPriorityKey symbol was introduced in 10.9:
APPKIT_EXTERN NSString *const NSAccessibilityPriorityKey NS_AVAILABLE_MAC(10_9);
My deployment target is set to 10.6, so I thought the code should run, just the symbol might be NULL. What am I doing wrong?
It looks like I have to use the & operator when checking for weakly linked strings:
if (&NSAccessibilityPriorityKey != NULL) { … }
See this related question.
I just went to use libcrypto on Lion and it looks like the entire api has been deprecated. The man pages haven't been updated since 10.6.6.
Does anybody know what the replacement for libcrypto is on Lion?
libcrypto is part of OpenSSL, which hasn't changed much. It's not going away, but Apple recommends that developers use their CDSA (Common Data Security Architecture) library rather than using OpenSSL directly.
In case you know what you're doing and you just want to get rid of these warnings, one way is to add
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
to the relevant headers – in my case /usr/include/openssl/crypto.h and /usr/include/openssl/md5.h.
Ok, answering my own question here.
10.7 introduced Transforms into Security.framework, which is tied closely to SecKey. Transforms let you do lots of things, including encoding (eg. base64), digests, signing/verifying, and encryption.
Here's an example of how to sign some data. All of the transforms follow the same basic pattern; if you look in the Headers for Security.framework you'll see a header for each type of transform. These are from SecTransformReadTransform.h and SecSignVerifyTransform.h. I'm omitting any error checking or cleanup code here for simplicity.
NSData *dataToBeSigned = ;// Get this from somewhere. We set sha1 attributes down below, so this should be a sha1 digest
SecKeyRef *key = ;// Get this from somewhere; keychain or SecItemImport
SecGroupTransformRef group = SecTransformCreateGroupTransform();
CFReadStreamRef readStream = NULL;
SecTransformRef readTransform = NULL;
SecTransformRef signingTransform = NULL;
// Setup our input stream as well as an input transform
readStream = CFReadStreamCreateWithBytesNoCopy(kCFAllocatorDefault,
[dataToBeSigned bytes],
[dataToBeSigned length],
kCFAllocatorNull); // Pass Null allocator so it doesn't free NSData's bytes
readTransform = SecTransformCreateReadTransformWithReadStream(readStream);
// Setup a signing transform
signingTransform = SecSignTransformCreate(key, NULL);
SecTransformSetAttribute(signingTransform, kSecInputIsDigest, kCFBooleanTrue, NULL);
SecTransformSetAttribute(signingTransform, kSecDigestTypeAttribute, kSecDigestSHA1, NULL);
// Connect read and signing transform; Have read pass its data to the signer
SecTransformConnectTransforms(readTransform, kSecTransformOutputAttributeName,
self.signingTransformRef, kSecTransformInputAttributeName,
group, NULL);
// Execute the sequence of transforms (group)
// The last one in the connected sequence is the return value
NSData *signature = SecTransformExecute(group, NULL);
I want to get the OS X system version, such as: 10.5.4, 10.4.8, etc. I want to get it in my app, how do I do this? Thanks!
You can read the property list at "/System/Library/CoreServices/SystemVersion.plist and extract the "ProductVersion" key, this is how the OS X installer application does it. Here's an example:
NSString *versionString;
NSDictionary * sv = [NSDictionary dictionaryWithContentsOfFile:#"/System/Library/CoreServices/SystemVersion.plist"];
versionString = [sv objectForKey:#"ProductVersion"];
Alternatively, the command swvers -productVersion will do the same.
You can use Gestalt:
SInt32 version = 0;
Gestalt( gestaltSystemVersion, &version );
BOOL leopard = ( version >= 0x1050 );
if ( leopard )
{
//draw it this way
}
else
{
//draw it that way
}
Keep in mind if you're checking if a method is available or not, it's better to test that directly using respondsToSelector:.
NSString *osver()
{
SInt32 versionMajor=0, versionMinor=0, versionBugFix=0;
Gestalt(gestaltSystemVersionMajor, &versionMajor);
Gestalt(gestaltSystemVersionMinor, &versionMinor);
Gestalt(gestaltSystemVersionBugFix, &versionBugFix);
return [NSString stringWithFormat:#"%d.%d.%d", versionMajor, versionMinor, versionBugFix];
}
-[NSProcessInfo operatingSystemVersionString] is human readable and localized. Appropriate for displaying to user or using in bug emails and such, but not appropriate for parsing.
Again, you can use Gestalt. Look at the documentation for more information; specifically, you'll want to pass the gestaltSystemVersionMajor, gestaltSystemVersionMinor, and gestaltSystemVersionBugFix constants in the "System Version Constants" portion of the Gestalt Manager Reference documentation
After 10_10, 8_0 were presented the better & simplest way would be
[NSProcessInfo processInfo].operatingSystemVersion
which will return
NSOperatingSystemVersion struct
with all 3 numbers.
There's also a Cocoa wrapper around the Gestalt calls others have mentioned in the Google Toolbox for Mac:
http://code.google.com/p/google-toolbox-for-mac/source/browse/trunk/Foundation/GTMSystemVersion.h
use this method it will return Mac OS X version
+(SInt32) OSVersion;
{
SInt32 osxMinorVersion;
Gestalt(gestaltSystemVersionMinor, &osxMinorVersion);
return osxMinorVersion;
}