How to access raw data with CoreMotion - ios

I'm going to develop an iPhone application based on CoreMotion and Pedestrian Dead Reckoning Algorithm.
I'm experiencing a little strange behaviour reading gyroscope and acceleration data (device: iPhone 5s).
Here is my code:
motionManager = [[CMMotionManager alloc] init];
motionManager.deviceMotionUpdateInterval=0.008;
[motionManager startDeviceMotionUpdatesToQueue:[NSOperationQueue mainQueue] withHandler:^(CMDeviceMotion * motion, NSError *error)
{
NSString *Acc_x = [[NSString alloc] initWithFormat:#"%f ",motion.userAcceleration.x];
NSString *Acc_y = [[NSString alloc] initWithFormat:#"%f ",motion.userAcceleration.y];
NSString *Acc_z = [[NSString alloc] initWithFormat:#"%f ",motion.userAcceleration.z];
NSData *AccData_x = [Acc_x dataUsingEncoding:NSUTF8StringEncoding];
NSData *AccData_y = [Acc_y dataUsingEncoding:NSUTF8StringEncoding];
NSData *AccData_z = [Acc_z dataUsingEncoding:NSUTF8StringEncoding];
NSString *Gyro_x = [[NSString alloc] initWithFormat:#"%f ",motion.rotationRate.x];
NSString *Gyro_y = [[NSString alloc] initWithFormat:#"%f ",motion.rotationRate.y];
NSString *Gyro_z = [[NSString alloc] initWithFormat:#"%f ",motion.rotationRate.z];
NSData *GyroData_x = [Gyro_x dataUsingEncoding:NSUTF8StringEncoding];
NSData *GyroData_y = [Gyro_y dataUsingEncoding:NSUTF8StringEncoding];
NSData *GyroData_z = [Gyro_z dataUsingEncoding:NSUTF8StringEncoding];
[HandleAcc seekToEndOfFile];
[HandleAcc writeData:AccData_x];
[HandleAcc writeData:AccData_y];
[HandleAcc writeData:AccData_z];
[HandleAcc writeData:GyroData_x];
[HandleAcc writeData:GyroData_y];
[HandleAcc writeData:GyroData_z];
NSDate *DataOra = [NSDate date];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"HH:mm:ss\r\n"];
NSString *dataString = [dateFormatter stringFromDate:DataOra];
NSData *data = [dataString dataUsingEncoding:NSUTF8StringEncoding];
[HandleAcc writeData:data];
}
];
And here is my log:
acc_x acc_y acc_z gyro_x gyro_y gyro_z time
0.006040 0.003147 -0.011406 0.001642 0.002079 -0.000864 01:04:40
0.006472 0.000715 -0.008345 -0.003239 -0.001569 -0.000839 01:04:40
After, I tried to compare iPhone's IMU data with other from an Adafruit's 10DOF IMU and I obtain this log:
acc_x acc_y acc_z gyro_x gyro_y gyro_z time
-4.773060 -1.769106 8.427839 -0.030030 0.022133 0.002239 0.008333
-4.789249 -1.741337 8.442565 -0.028949 0.009581 0.000027 0.016667
What am I doing wrong?? Are iPhone data biased? If so, should I acces unbiased data?
Hope someone will help. Thank you, Giacomo.

CMMotionManager has many different things it can measure. I think all but the one you are using are unbiased.
After creating an instance of CMMotionManager, an app can use it to receive four types of motion: raw accelerometer data, raw gyroscope data, raw magnetometer data, and processed device-motion data (which includes accelerometer, rotation-rate, and attitude measurements).
If you want unbiased data, either combine gravity and userAcceleration as documented or measure acceleration directly.

Related

Song title by stream wrong Encoding

I'm working on a simple radio stream app for ios. I'm retriving song title with a KVO Observation of:
if ([keyPath isEqualToString:#"timedMetadata"])
{
for (AVMetadataItem* metadata in playerItem.timedMetadata)
{
if([metadata.commonKey isEqualToString:#"title"]){
}
}
}
With this code i can get the title. Anyway whe there are some characthers i have this result:
deep grounder feat virÃ;g
instead of
deep grounder feat viràg
So i'm trying any solution to print the correct result in the screen. I have also tried:
NSString *StringaPassata=[NSString stringWithFormat:#"%#",#"deep grounder feat virÃ;g"];
NSData *data = [stringFromUTFString dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:YES]; NSString *newStr = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
The string remain the same... I have not control on the server that output the stream. To test the conversion i store in a NSString the string that cause the problem when it is downloaded from the server.
How i can convert to the string to the correct "à" ?
Try This Snippet I Have tried it
NSString *strYourKey = #"deep grounder feat viràg";
NSData *data = [strYourKey dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
NSString *dataToString = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding];
NSLog(#"Your Converted Text is : %#", dataToString);
Output
[12134:168898] Your Converted Text is : deep grounder feat virag

Saving NSAttributedString to Parse.com

Parse doesn't support direct saving of NSAttributedStrings. Converting to HTML isn't the most straightforward. Anyone have a friendly method for storing NSAttributedStrings (font & superscript) to Parse.com?
Thanks guys, decided to go with saving an rtf string onto Parse, based off #Wain's comment.
// convert NSAttributedString to RTFString and save to Parse
PFObject *note = [PFObject objectWithClassName:#"Note"];
NSAttributedString *noteAttributedText = self.noteTextView.attributedText;
NSDictionary *documentAttributes = [NSDictionary dictionaryWithObjectsAndKeys:NSRTFTextDocumentType,NSDocumentTypeDocumentAttribute, nil];
NSData *rtfData = [noteAttributedText dataFromRange:NSMakeRange(0, noteAttributedText.length) documentAttributes:documentAttributes error:NULL];
NSString *rtfString = [[NSString alloc] initWithData:rtfData encoding:NSUTF8StringEncoding];
note[#"noteTextAsRTFString"] = rtfString;
// convert RTFString to NSAttributedString after pulling from Parse
NSString *rtfString = [pfObject objectForKey:#"noteTextAsRTFString"];
NSData *data = [rtfString dataUsingEncoding:NSUTF8StringEncoding];
NSAttributedString *noteAttributedText = [[NSAttributedString alloc] initWithData:data options:#{NSDocumentTypeDocumentAttribute:NSRTFTextDocumentType} documentAttributes:nil error:nil];

iOS ISO-8583 message sending

I'm an iOS developer. I need to send a message in ISO-8583 standard, via socket server.
I have established connection with server, and it is working well.
The server works this way : when message comes to it in correct format (but with incorrect data, eg. wrong PIN), it responds with proper error code. When message comes in wrong format, the server doesn't respond at all ;)
So, knowing that my connection works fine (tested), I have following problem :
I need to send ISO8583 message to server. The message must have those fields :
SI (2 bytes - size of whole message)
TPDU (it must be 12345 - documetation says)
Detail (more info below)
EOT (specification - sign "0D")
In below example, we are using :
MTI - 0200
Account number - 6019 5300 0601 9592
Code - 700000
Terminal ID - 35959551
PIN - 880088 (needs to have two SPACES appedned to the end (docs says))
Here are documentation specifications :
Field 2 - Card number, length - 19 (3 length + 16 number), format
LLVAR
Field 3 - Processing code, length - 6, format NUMBER
Field 12 - Time (hhmmss), length - 6, format NUMBER
Field 13 - Date (mmdd), length - 4, format NUMBER
Field 41 - Terminal ID, length - 8, format ALPHANUMERICAL
Field 52 - PIN, length - 16, format HEX
So, fields 2,3,12,13,41 and 52 must be set.
I used two methods :
1) using external library : https://github.com/mordoskull/Objective-ISO8583 - using many different combinations of data, it doesn't work. My usage :
ISOMessage *isoMessage1 = [[ISOMessage alloc] init];
NSString *tpdu = #"0102030405";
[isoMessage1 setMTI:#"0200"];
isoMessage1.bitmap = [[ISOBitmap alloc] initWithGivenDataElements:#[#"DE02", #"DE03", #"DE12", #"DE13", #"DE41", #"DE52"] configFileName:nil];
[isoMessage1 addDataElement:#"DE02" withValue:cardNumber configFileName:nil];
[isoMessage1 addDataElement:#"DE03" withValue:#"700000" configFileName:nil];
[isoMessage1 addDataElement:#"DE12" withValue:transactionTime configFileName:nil];
[isoMessage1 addDataElement:#"DE13" withValue:transactionDate configFileName:nil];
[isoMessage1 addDataElement:#"DE41" withValue:#"35959551" configFileName:nil]; //TID - 35959551
[isoMessage1 addDataElement:#"DE52" withValue:#"880088" configFileName:nil];
2) manually setting all fields like this :
//CARD NUMBER
NSData *card = [cardNumber dataUsingEncoding:NSUTF8StringEncoding];
//TPDU
NSMutableData *TPDU = [[NSMutableData alloc] init];
[TPDU appendBytes:"\x01\x02\x03\x04\x05" length:5];
//TRANSACTION CODE
NSData *transactionCode = [[NSString stringWithFormat:#"%x",700000] dataUsingEncoding:NSUTF8StringEncoding];
//TIME AND DATE
NSData *time = [[NSString stringWithFormat:#"%x",[transactionTime intValue]] dataUsingEncoding:NSUTF8StringEncoding];
NSData *date = [[NSString stringWithFormat:#"%x",[transactionDate intValue]] dataUsingEncoding:NSUTF8StringEncoding];
//PIN
NSData *PIN = [[NSString stringWithFormat:#"%# ",self.pinField.text] dataUsingEncoding:NSASCIIStringEncoding];
//TID
NSData *TID = [#"35959551" dataUsingEncoding:NSASCIIStringEncoding];
//MTI
NSMutableData *MTI = [[NSMutableData alloc] init];
[MTI appendBytes:"\x02\x00" length:2];
//BITMAP
NSArray* fields = [NSArray arrayWithObjects:#2, #3,
#12, #13, #41, #52, nil];
NSMutableArray* binary = [NSMutableArray new];
for(int i=0 ; i<64 ; ++i) {
binary[i] = #"0";
}
for(int j = 0; j<[fields count]; ++j)
{
binary[[fields[j] intValue]-1] = #"1";
}
NSMutableString * bitmap = [[NSMutableString alloc] init];
for (NSObject * obj in binary)
{
[bitmap appendString:[obj description]];
}
NSData *bitmapByte = [bitmap dataUsingEncoding:NSUTF8StringEncoding];
NSMutableData *request = [[NSMutableData alloc] init];
[request appendData:TPDU];
[request appendData:MTI];
[request appendData:bitmapByte];
[request appendData:card];
[request appendData:transactionCode];
[request appendData:time];
[request appendData:date];
[request appendData:TID];
[request appendData:PIN];
NSData *SI = [[NSString stringWithFormat:#"00%lu",(unsigned long)[request length]] dataUsingEncoding:NSUTF8StringEncoding];
NSMutableData* fullRequest = [[NSMutableData alloc] init];
[fullRequest appendData:SI];
[fullRequest appendData:request];
I know that Card Number field must have three-digit length appended in front of it, and I know every other specs about ISO8583.
I managed to get NSData that looks like this in Log :
Printing description of fullRequest:
<30303131 39010203 04050200 30313130 30303030 30303031 31303030 30303030 30303030 30303030 30303030 30303030 30303030 31303030 30303030 30303031 30303030 30303030 30303030 30313636 30313935 33303030 36303139 35393261 61653630 31393232 37346231 33353935 39353531 38383030 38382020>
The same message, not converted to NSData, looks like this :
009001020304050200601800000080100001660195300060195927000001131041201359595513838303038382020
And server doesn't respond at all, so I must be sending wrong formatted message.
Can somebody help me how to correctly format the message?
Finally managed to do it myslef. Here is a code for setting the parameters (in case somebody needs it) :
NSDate *currentTime = [NSDate date];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
//get current Time
[dateFormatter setDateFormat:#"hhmmss"];
NSString *transactionTime = [dateFormatter stringFromDate: currentTime];
transactionTime = [transactionTime stringByReplacingOccurrencesOfString:#":" withString:#""];
//get current Date
[dateFormatter setDateFormat:#"MMdd"];
NSString *transactionDate = [dateFormatter stringFromDate:currentTime];
NSString* cardNumber = [[NSUserDefaults standardUserDefaults] objectForKey:#"cardNumber"];
//TID
NSData *TID = [#"35959551" dataUsingEncoding:NSASCIIStringEncoding];
//PIN
NSData *PIN = [[NSString stringWithFormat:#"%#",self.pinField.text] dataUsingEncoding:NSASCIIStringEncoding];
//TPDU
NSMutableData *TPDU = [[NSMutableData alloc] init];
[TPDU appendBytes:"\x01\x02\x03\x04\x05" length:5];
//MTI
NSMutableData *MTI = [[NSMutableData alloc] init];
[MTI appendBytes:"\x02\x00" length:2];
//TRANSACTION CODE
NSString *transactionCode = #"700000";
NSData *trCode = [self convertToData:transactionCode];
//CARD NUMBER
NSString *cardWithLength = [#"16" stringByAppendingString:cardNumber];
NSData *card = [self convertToData:cardWithLength];
//TIME AND DATE
NSData *time = [self convertToData:transactionTime];
NSData *date = [self convertToData:transactionDate];
//BITMAP
NSString *mapa = #"6018000000801000";
NSData *mapaData = [self convertToData:mapa];
NSMutableData *request = [[NSMutableData alloc] init];
[request appendData:TPDU];
[request appendData:MTI];
[request appendData:mapaData];
[request appendData:card];
[request appendData:trCode];
[request appendData:time];
[request appendData:date];
[request appendData:TID];
[request appendData:PIN];
NSString *SI = [NSString stringWithFormat:#"00%lu",(unsigned long)[request length]];
NSData *SIData = [self convertToData:SI];
NSMutableData* fullRequest = [[NSMutableData alloc] init];
[fullRequest appendData:SIData];
[fullRequest appendData:request];

NSString iOS Russian encoding

I'm using code below:
AVMetadataItem *item = [self.player.metaData objectAtIndex:0];
NSLog("%#", item.stringValue);
Its works good with any english song title.
But, when i'm getting russian song title from AVMetadataItem:
ÐÐÐÐРÐЯ - ÐРСÐРÐÐÐТÐÐУ // СÐУШÐЮТ: 1585
How can i get something like:
Тратата - мы везем с собой кота.
Any help appreciated.
Try this:
NSData *test = [item.stringValue dataUsingEncoding:NSISOLatin1StringEncoding allowLossyConversion:YES];
NSString *dataString = [[NSString alloc] initWithData:test encoding:NSUTF8StringEncoding];
We get meta from audio in UTF8 and don't know in what NSStringEncoding it's converted so i use:
for (i = 0; i < 15; i++) {
NSData *test = [item.stringValue dataUsingEncoding:i allowLossyConversion:YES];
NSString *dataString = [[NSString alloc] initWithData:test encoding:NSUTF8StringEncoding];
}
Looks like iOS encoding Cyrillic(UTF8) in ISOLatin.

iOS html/xml parsing google shopping results with TFHpple

is there any way to parsing google shopping results using TFHpple without using google API (deprecated) but simple using url like for example this: https://www.google.com/search?hl=en&tbm=shop&q=AudiR8 ?
I've tried many types of tags:
...
myCar = #"Audi R8";
myURL = [NSString stringWithFormat:#"https://www.google.com/search?hl=en&tbm=shop&q=%#",myCar];
NSData *htmlData = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:myURL]];
TFHpple *xpath = [[TFHpple alloc] initWithHTMLData:htmlData];
//use xpath to search element
NSArray *elements = [NSArray new];
elements = [xpath searchWithXPathQuery:#"//html//body"]; // <-- tags
...
but nothing to do, always the same output console message: UNABLE TO PARSE.
I've found various problem and finally i've solved all.
First of all it's necessary to encoding URL adding:
myURL = [myURL stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
Then, inside original (and actual) TFHPPLE code (for exactly XPathQuery.m) parsing phase going to crash 'cause any time nodeContent and Raw are NIL.
So, to solve this crash I've changed
[resultForNode setObject:currentNodeContent forKey:#"nodeContent"];
with (ATTENTION FOR BOTH ROWS [resultForNode...:
if (currentNodeContent != nil)
[resultForNode setObject:currentNodeContent forKey:#"nodeContent"];
and:
[resultForNode setObject:rawContent forKey:#"raw"];
with:
if (rawContent != nil)
[resultForNode setObject:rawContent forKey:#"raw"];
I want to remember that, 'cause the harder html code used by google, i decide to use these xpathqueries:
...
NSArray *elementsImages = [NSArray new];
NSArray *elementsPrices = [NSArray new];
elementsImages = [xpath searchWithXPathQuery:#"//html//*[#class=\"psliimg\"]"];
elementsPrices = [xpath searchWithXPathQuery:#"//html//*[#class=\"psliprice\"]"];
...
Another inconvenience is when you decide to use a for or while cycle to retrieve various html pages, in fact if you use:
NSData *htmlData = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:myURL]];
initWithContenctsOfURL many times during the cycle cannot get correctly page (and debug console write the famous UNABLE TO PARSE )so I've decide to change it with:
// Send a synchronous request
NSURLRequest * urlRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:myURL]];
NSURLResponse * response = nil;
NSError * error = nil;
NSData * data = [NSURLConnection sendSynchronousRequest:urlRequest
returningResponse:&response
error:&error];
if (error == nil)
{
// Parse data here
}
And if you don't want to waiting this cycle 'cause it's maded by syncronous NSURLRequests try to call parent method with (and your viewcontroller don't freeze waiting for parser):
_dispatch_queue_t *queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async( _queue, // now i call my google shopping parser cycle
^{
[self GShoppingParser];
});
Can you try changing the below line
NSData *htmlData = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:myURL]];
to
NSData *Data = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:myURL]];
and also the below line
TFHpple *xpath = [[TFHpple alloc] initWithHTMLData:htmlData];
to
TFHpple *xpathParser = [[TFHpple alloc] initWithHTMLData:data];
Let me know if this helps else there is one more line that you may need to change in your code.
happy coding!

Resources