I'm looking at using openUDID inside my app for registration purposes.
However its still using the UDID number apple issues and so I was just reading though the .m file and came across this:
// One day, this may no longer be allowed in iOS. When that is, just comment this line out.
//
#if TARGET_OS_IPHONE
if([UIDevice instancesRespondToSelector:#selector(uniqueIdentifier)]){
_openUDID = [[UIDevice currentDevice] uniqueIdentifier];
}
#endif
// Take this opportunity to give the simulator a proper UDID (i.e. nullify UDID and create an OpenUDID)
//
#if TARGET_IPHONE_SIMULATOR
_openUDID = nil;
#endif
// Next we try to use an alternative method which uses the host name, process ID, and a time stamp
// We then hash it with md5 to get 32 bytes, and then add 4 extra random bytes
// Collision is possible of course, but unlikely and suitable for most industry needs (e.g.. aggregate tracking)
//
However I'm not sure exactly what line to comment out so that it used the alternative method which uses the host name, process ID, and a time stamp
You would comment out the 3 lines of code in the TARGET_OS_IPHONE block
You can "comment" out the line with uniqueIdentifier in it by prefixing that line using double slash comment.... or you can change the #if TARGET_OS_IPHONE line to #if 0, which means that block of code will never get called at all.
And then the alternative code will get used instead.
The way the code is currently written, it seems pretty safe to me to just leave it as is. Once Apple does completely do away with the uniqueIdentifier method, the instancesRespondToSelector call will properly fail and the alternative code will get used automatically.
Related
I am changing the name of my app based on the device it is running on through configuration files, i.e. I put in an _iPhone, _iPad or _Universal in the display name accordingly.
To do this I am using xcconfig files as follows:
TARGETED_DEVICE_FAMILY = 1,2
APP_NAME1 = Something_iPhone
APP_NAME2 = Something_iPad
APP_NAME1,2 = Something_Universal //1,2 The "," causes a problem here.
The problem is that the comma character is causing a problem:
*Build setting 'APP_NAME1,2' does not have a valid base name.*
Any ideas?
No apps will be approved for app store with using the trade marked names such as iPhone or iPad try using something else. I have had that even in the binary and not in the display and they rejected it in review. If you want to create a set of codes for universal porpose the take a look at this code snippet. I use this a lot in my universal apps.
`if __IPHONE_OS_VERSION_MAX_ALLOWED >= 30200
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
NSLog(#"iPad Idiom");
else
#else
NSLog(#"iPhone Idiom");
#endif
Adrian
I have not been able to find this information anywhere. How long can a string be send with the TTL version of the redpark cable?
The following delegate method is called twice when I print something thorough serial from my Arduino, an example of a string is this: 144;480,42;532,40;20e
- (void) readBytesAvailable:(UInt32)length{
When I use the new function methods of retrieving available data [getStringFromBytesAvailable] I will only get 144;480,42;532,40; and then the whole function is called again and the string now contains the rest of the string: 20e
The following method is working for appending the two strings, but only if the rate of data transmission is 'slow' (1 time a second, I would prefer minimum 10 times a second).
-
(void) readBytesAvailable:(UInt32)length{
if(string && [string rangeOfString:#"e"].location == NSNotFound){
string = [string stringByAppendingString:[rscMgr getStringFromBytesAvailable]];
NSLog(string);
finishedReading = YES;
}
else{
string = [rscMgr getStringFromBytesAvailable];
}
if (finishedReading == YES)
{
//do stuff
}
finishedReading = NO;
string = nil;
}
}
But can you tell my why the methods is called twice if I write a "long" string, and how to avoid this issue?
Since your program fragment runs faster then the time it takes to send a string, you need to capture the bytes and append them to a string.
If the serial data is terminated with a carriage return you can test for it to know when you have received the entire string.
Then you can allow your Arduino to send 10 times a second.
That is just how serial ports work. You can't and don't need to avoid those issues. There is no attempt at any level of the SW/HW to keep your serial data stream intact, so making any assumptions about that in your code is just wrong. Serial data is just a stream of bytes, with no concept of packetization. So you have to deal with the fact that you might have to read partial data and read the rest later.
The serialPortConfig within the redparkSerial header file provided by RedPark does, in fact, give you more configuration control than you may realize. The readBytesAvailable:length method is abstracted, and is only called when one of two conditions is met: rxForwardingTimeout value is exceeded with data in the primary buffer (default set to 100 ms) or rxForwardCount is reached (default set to 16 characters).
So, in your case it looks like you've still got data in your buffer after your initial read, which means that the readBytesAvailable:length method will be called again (from the main run loop) to retrieve the remaining data. I would propose playing around with the rxForwardingTimeout and rxForwardCount until it performs as you'd expect.
As already mentioned, though, I'd recommend adding a flag (doesn't have to be carriage return) to at least the end of your packet, for identification.
Also, some good advice here: How do you design a serial command protocol for an embedded system?
Good luck!
Good morning,
I am retrieving a stream of bytes from a serial device that connects to the iPad. Once connected the supplied SDK will call a delegate method with the bytes that have been forwarded.
The readings forwarded by the serial device via the SDK are in the following format:
!X1:000.0;
Once connected to the serial device the delegated methods will start receiving data immediately - this could be in various states of completion i.e.
:000.00;
What I need to do is establish a concrete way of splitting the readings returned from the serial device so that I can manipulate the data.
Some of the tried options are:
Simply concatenate the received strings for a fixed period and then split the NSString on the ";" character. This is a little inefficient though and does not allow me to manipulate the data dynamically
-(void)receivingDelegateMethod:(NSString *)aString {
if(counter < 60){
[self.PropertyString stringByAppendingString:aString];
}else{
NSArray *readings = [self.PropertyString componentsSeparatedByString: #";"];
}
}
Determine a starting point by looking for the "!" character and then appending the resulting substring to a NSString property. All previous calls to the delegated method will append to this property and then remove the first 10 characters.
I know there are further options such as NSScanners and RegEx but I wanted to get the opinion of the community before wasting more time of different methods.
Thanks
Make a BOOL flag that indicates that the stream has been initialized, and set it to false. When you receive the next chunk of data, check the flag first. If it is not set, skip all characters until you see an exclamation point '!'. Once you see it, discard everything in front of it, and copy the rest of the string into the buffer. If the "is initialized" flag is set, append the entire string to the buffer without skipping characters.
Once you finish the append, scan the buffer for ! and ; delimited sections. For each occurrence of that pattern, call a designated method with a complete portion of the pattern. You can get fancy, and define your own "secondary" delegate for processing pre-validated strings.
You may need to detect disconnections, and set the "is initialized" flag back to NO.
I have a simple question. How do I get iPhone's battery level?
[UIDevice currentDevice] batteryLevel]
Simple enough? However there is a little catch - I can't use UIKit. Here is what I wrote so far, but I don't think it works:
// notification port
IONotificationPortRef nport = IONotificationPortCreate(kIOMasterPortDefault);
CFRunLoopAddSource(CFRunLoopGetCurrent(), IONotificationPortGetRunLoopSource(nport), kCFRunLoopDefaultMode);
CFMutableDictionaryRef matching = IOServiceMatching("IOPMPowerSource");
kern_return_t kr = IOServiceAddMatchingNotification(nport, kIOFirstMatchNotification, matching, (IOServiceMatchingCallback)power, self, &powerIterator);
NSLog(#"Kernel said %d",kr);
power((void*)nport,powerIterator);
I'm still pretty sure you have to rely on IOKit in order to retrieve battery level. My application does not use UIKit as it is a low-level application in which UIKit cannot be used. Here are the frameworks I am using :
alt text http://img837.imageshack.us/img837/1829/screenshot20100718at211.png
A while ago I wrote a program called iox that is similar to ioreg, except it makes it easier for me to translate back to IOKit calls. When I run that on my laptop, I see the following with a battery level.
AppleSmartBattery - IOService:/AppleACPIPlatformExpert/SMB0/AppleECSMBusController/AppleSmartBatteryManager/AppleSmartBattery
CurrentCapacity = 11678
FullyCharged = YES
DesignCapacity = 13000
MaxCapacity = 11910
...
In code, that is
IOServiceNameMatching( "AppleSmartBattery" );
I have no idea if the name would be the same on iOS, but I would try either finding a program like ioreg that you can run on the iPhone, or writing something simple to log the equivalent.
ioreg is part of IOKitTools and it should just compile on iPhone.
Edit:
CFMutableDictionaryRef matching , properties = NULL;
io_registry_entry_t entry = 0;
matching = IOServiceMatching( "IOPMPowerSource" );
//matching = IOServiceNameMatching( "AppleSmartBattery" );
entry = IOServiceGetMatchingService( kIOMasterPortDefault , matching );
IORegistryEntryCreateCFProperties( entry , &properties , NULL , 0 );
NSLog( #"%#" , properties );
CFRelease( properties );
IOObjectRelease( entry );
Add some safety checks. Once you figure out the specific properties you want, you can get them directly instead of using IORegistryEntryCreateCFProperties to get them all at once.
IOKit represents everything as a big tree. IOPMPowerSource may not directly have the attributes you want, in which case you would need to iterate through the children. Using something like ioreg can tell you what you are looking for before you start coding.
I don't have any experience with jailbroken development, but this guide might be helpful.
I'm going to go for the big one: Why?
AS you probably know, you can't really not use UIKit on the iPhone, so I'm not quite sure what you're on about.
This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
Do I need to disable NSLog before release Application?
I wonder if someone could help me setup a number of NSLog statements so they print to console when executing in "Debug Mode" but don't print in "Release Mode". I understand I need to add something like DEBUG = 1 to the debug config in Xcode but I can't find where. Also how do I utilise this in my code?
NSLog(#"Print Always");
if(DEBUG) NSLog(#"Print only in debug");
Is there a simple way of doing this?
EDIT_001:
I tried following this but the keys now seem to be only listed under "All Settings", and are presenting as nice names. The one I should be using is GCC_PREPROCESSOR_DEFINITIONS, so I needed to find "Preprocessor Macros", select edit and add DEBUG=1
When you come to use this its simply a case of adding (see below) or some marco to remove the messy #ifdef / #endif tags.
NSLog(#"You always see me?");
#ifdef DEBUG
NSLog(#"Only in DEBUG");
#endif
This is a popular solution:
http://iphoneincubator.com/blog/debugging/the-evolution-of-a-replacement-for-nslog
See comments about using either -DDEBUG=1 or DEBUG=1.
The best solution is not to use NSLog in the first place but instead rely on the debugger.
You can set breakpoints that execute debugger commands to print out anything and you can set the breakpoints to execute the debugger commands but not to stop execution. In practice this works just like NSLog.
By using the debugger to do the logging, you don't have to worry about removing the log statements.
Please have a look at the answers of How to print out the method name and line number and conditionally disable NSLog?. There are some nice macros in there that can be very useful.
I use this:
-(void)debugWinLog
{
NSUserDefaults * defaultsDebug = [NSUserDefaults standardUserDefaults];
theDebugWin = [defaultsDebug boolForKey:#"logger"];
}
Which is called in the awakeFromNib.
It checks the apps plist file for a 1 or 0 for the BOOL entry "logger"
The normal state if off, but when debugging you can then turn it on or off at will in terminal. with the normal defaults write.
The NSlog statments look like:
if ( theDebugWin) {NSLog (#"%#", windowState );}