I am trying to port one of my iOS applications to Mac OS X, and I am struggling to find the UIDevice-like object for OS X. I am interested in getting the name of the device, such as "MacBookAir".
EDIT/ANSWER
As Josh Caswell pointed out, you can use SCDynamicStoreCopyComputerName key.
Here is the code:
+ (NSString *)computerName {
return [(id)SCDynamicStoreCopyComputerName(NULL, NULL) autorelease];
}
Swift 4.0 OSX
Here is what I needed for a similar value to UIDevice name
iOS (swift 3.2)
let deviceName = UIDevice.current.name
OSX (swift 4.0)
let deviceName = Host.current().name
The Net Services Programming Guide says:
In Mac OS X on the desktop, calling the SCDynamicStore function from the System Configuration framework returns the computer name so you can manipulate it like any other string. In iOS, you can obtain the same information from the name property of the UIDevice class.
There doesn't seem to be a single function called SCDynamicStore (doc bug), but you probably want SCDynamicStoreCopyValue. Looks like you get the key you need using SCDynamicStoreKeyCreateComputerName.
EDIT: Or, even better, as you found, use the SCDynamicStoreCopyComputerName function, found in SCDynamicStoreCopySpecific.h
NSHost *host = [NSHost currentHost];
NSLog(#"hostName %#",[host localizedName]);
you can see the mac name
You can try NSHost. Heres the class documentation
With the deprecation of Host, you might consider ProcessInfo.hostName as an alternative. In my case it returned:
ExampleHostName.local
Related
After upgrading from XCode 10.0 to 11
I am getting the error 'name' is unavailable: not available on iOS
This is during Build for Swift 4.2 on XCode 11.0 and 11.1 , I can still build using XCode 10
This is happening in the code of one of the Objective C external libraries we have been using through Cocopods.
return [(NSNumber *)[table[state] objectForKey:[rule name]] unsignedIntegerValue];
I can work around the issue by renaming the variable name to ruleName , but I would rather not do this.
Why is Xcode objecting to a variable name of name? Is this an Xcode but or is it something I can fix in the build settings
Edit
The specific pod is NUI 0.5.5
In module NUIPShiftReduceGotoTable.m
- (NSUInteger)gotoForState:(NSUInteger)state rule:(NUIPRule *)rule
{
return [(NSNumber *)[table[state] objectForKey:[rule name]] unsignedIntegerValue];
}
Apple made a change that can break previously compiling code in Xcode 11.0/11.1. Previously the compiler would be fine with passing the 'name' message to an object that it didn't know the type of. This can happen for many reasons in the weakly typed Objective-C world.
Currently in Xcode 11.1 you can do.
id x = nil;
[x name];
And this will compile, no problem. But:
NSObject *x = nil
[x name];
won't compile due to the compiler identifying the most likely selector being the API_UNAVAILABLE one in NSLayoutAnchor.h (maybe).
If the compiler had more information it can map the correct selector. This might be as simple as including the header for whatever has name property in the .m file that is failing.
My guess is something like in NUIPShiftReduceGotoTable.m you add a line
#import"NUIPRule.h"
Is it possible to mark a function/computed variable as available on OS X and unavailable on iOS (and vice versa)? Something such as #available(OSX 10.0, iOS unavailable).
I know about the #if OSX statement, however, I'm trying to achieve something that Apple has done for the NSURLThumbnailKey - it's marked as NS_AVAILABLE_MAC(10_10); in ObjC and the compiler will complain that the symbol is unavailable rather than that the compiler cannot resolve the symbol.
Also, I've found that the #if statements in Swift are buggy, for example, defining func myFunc(_, arg1:) and func myFunc(_, somethingElse:) within the #if scope will result in an error saying that myFunc has already been defined. Which is why I'm trying to avoid using #if.
You should be able to do something like:
#available(OS X 10.10, *)
To force it for OS X 10.10 higher only, or:
if #available(OS X 10.10, *)
There's some more information available on Hacking With Swift.
Multiple specification:
#available(iOS, unavailable, message="nope")
#available(OS X 10.10, *)
func someFunc()
Unlike the author of this previous question, I'm having the opposite problem. I'm attempting to make use of a component written in C++ in my iPad application that uses setlocale() from the standard C library. When running via the simulator (either i386 or x86_64), I'm able to set a locale successfully and get an expected return value:
(lldb) p (const char *)setlocale(2, "ja_JP")
(const char *) $1 = 0x000000010e776bd0 "ja_JP"
However, when running on a device (on either iOS8 or iOS9, on both armv7 and arm64 devices), this call always seems to fail and return null.
(lldb) p (const char *)setlocale(2, "ja_JP")
(const char *) $0 = 0x00000000
Actually setting the region and language on the iOS device doens't seem to make a difference either.
Is this an example of something like iOS9 preventing the use of sysctl(), or am I missing something bigger here?
This was actually answered on the Apple Dev Forums recently, sharing it here as well:
The problem here is not setlocale per se, but rather in reading the
locale in the first place. Notably, newlocale also returns NULL when
you call it with similar parameters. This fails because no C-style
locales are available to you on iOS. On the simulator this works
because the locale code picks up the locale data from OS X (in
/usr/share/locale). I’m not sure if this directory is populated on
iOS (I suspect not) but that doesn’t matter because the sandbox won’t
let your process get to it.
I am developing an app using SDK 8.1, Apple LLVM 6.0 and Xcode 6.1.1. The deployment target is 6.0. I'm using NSOperationQueue and I want to use QoS whenever it's available.
The code I'm using is:
if ([self.operationQueue respondsToSelector:#selector(setQualityOfService:)]
&& (&NSOperationQualityOfServiceUserInitiated)) {
[self.operationQueue performSelector:#selector(setQualityOfService:) withObject: NSOperationQualityOfServiceUserInitiated];
} else {
//Other stuff not related to the scope of this question
}
The error I get is:
Use of undeclared identifier 'NSOperationQualityOfServiceUserInitiated'
I added the if (&NSOperationQualityOfServiceUserInitiated) part to check if this constant exists. This code worked with older versions of Xcode/Obj-C Compiler.
I am able to use selectors with performSelectorWithIdentifier but what about constants that do not have a defined value in the docs? The value of this constant is set by NSQualityOfServiceUserInitiated but there is no definition for this value that can be hardcoded.
How do I fix that?
There are several things wrong with the code.
NSOperationQualityOfServiceUserInitiated is a native type (NSInteger) so you can't use it the way that you are in either line.
The qualityOfService is a property of type NSQualityOfService. Your attempt to pass an argument to the qualityOfService method (getter method) makes no sense. If you are trying to set the quality of service, you need to call the setter but you can't use performSelector.
You want:
if ([self.operationQueue respondsToSelector:#selector(qualityOfService)]) {
self.operationQueue.qualityOfService = NSOperationQualityOfServiceUserInitiated;
} else {
//Other stuff not related to the scope of this question
}
This code will compile fine as long as your Base SDK is iOS 8.0 or later. The Deployment Target doesn't matter.
If you also want to build this code with Xcode 5 or earlier (a Base SDK of iOS 7 or earlier) then you need to wrap the code with the proper compiler directives to check for the Base SDK.
I'm using a dictionary to evaluate an expression, when the expression has variables and the dictionary is actually used by NSExpression, something happens and I get EXC_BAD_ACCESS when trying to update the dictionary, this only happens when debugging in an iPhone6, not in the simulator and not in an iPhone 4S.
let strExpression = "a+b+20"
let exp = NSExpression(format:strExpression)
self.dictionary = ["a":10.0, "b":15.0, "c":25.0]
let value:AnyObject = exp.expressionValueWithObject(self.dictionary, context: nil)
let doubleValue = value as Double
self.dictionary.updateValue(doubleValue, forKey: "c")
Something really weird is that if i add this line just after creating the dictionary, then it woks fine:
let newDic = self.dictionary
I,m using iOS 8.1. Thanks in advance!
With #bensarz comment, I thought it might be helpful for others searching for answers if I put the response into an actual answer instead of a comment.
Per #LeeWhitney's response on a similar post:
Looks like a compiler bug.
Have you tried switching between Release and Debug then rebuilding? If debug works but not release it can be an indication of a compiler/optimizer bug.
Does it happen in the simulator also?
Your code works for me on iOS 8.1 with XCode 6.1.
Solution:
The issue seems to be solved by changing the 'Optimization Level' under the 'Swift Compiler - Code Generation' to 'None'. The issue seems to be with the 'Fastest' Compiler optimization level.
Also, a work around that I've found original before the compiler change:
If you use a let statement prior to assigning values in the dictionary, it seems to alleviate the issue. More information found at link below:
EXC_BAD_ACCESS on iOS 8.1 with Dictionary