iOS ISO-8583 message sending - ios

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];

Related

How to access raw data with CoreMotion

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.

Bullet points are not recognized in HTML String

I have a string:
NSString *str1 = #"\u2022 You were held in custody for a longer
period of time than may have been necessary.";
I am converting it into an HTML string using this code :
- (NSString *)HTMLString {
NSDictionary * const exportParams = #{NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType};
NSAttributedString *attributed = [[NSAttributedString alloc] initWithString:str1];
NSData *htmlData = [attributed dataFromRange:NSMakeRange(0, attributed.length) documentAttributes:exportParams error:nil];
return [[NSString alloc] initWithData:htmlData encoding:NSUTF8StringEncoding];
}
But bullet points are not showing in the HTML string. It's showing a ? instead of bullet point. Please tell me any solution.
Please try below code -
- (NSString *)HTMLString {
NSDictionary * const exportParams = #{NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType};
letterString = [letterString stringByReplacingOccurrencesOfString:#"\u2022" withString:#"•"];
NSAttributedString *attributed = [[NSAttributedString alloc] initWithString:letterString];
NSData *htmlData = [attributed dataFromRange:NSMakeRange(0, attributed.length) documentAttributes:exportParams error:nil];
return [[NSString alloc] initWithData:htmlData encoding:NSUTF8StringEncoding];
}

iOS - Converting UTF8 data from backend and displaying incorrectly

I am writing an iOS application that receives data from the backend. I parse the NSData object (objectNotation) as below.
Everything works fine until I receive a special character in the one entity, which is:
"Test já"
When I receive this and I debug parsedObject, it shows "type" to be "Test j\U00e1"
So this is obviously some Unicode/UTF8 issue. I then proceeded to look all over stack overflow, and found various potential solutions to this and tried them all, to no avail.
NSString *stringTest = [[NSString alloc] initWithData:objectNotation
encoding:NSUTF8StringEncoding]; --> does not work
NSString * test2 = [NSString
stringWithCString:[stringTest cStringUsingEncoding:NSUTF8StringEncoding]
encoding:NSASCIIStringEncoding]; --> does not work
I have tried every single encoding that Obj has to offer, and it either returns the character as \U00e1, or nil, or a bunch of garbage.
I have battled with this for hours so it is a good time to post now. I appreciate any assistance. Thank you.
Code is below:
NSDictionary *parsedObject = [NSJSONSerialization JSONObjectWithData:objectNotation options:0 error:&localError];
NSMutableArray *btms = [[NSMutableArray alloc] init];
NSArray *results = [parsedObject valueForKey:#"results"];
NSLog(#"Count %d", results.count);
NSLog(#"Count %d", parsedObject.count);
[parsedObject enumerateKeysAndObjectsUsingBlock:^(id key, id value, BOOL* stop) {
BTM *btm = [[BTM alloc] init];
NSLog(#"%# => %#", key, value);
btm.number = key;
btm.latitude = [value valueForKey:#"lat"];
btm.longitude = [value valueForKey:#"long"];
NSString* temp = [value valueForKey:#"type”];
}
Set "application/x-www-form-urlencoded; charset=UTF-8" as 'Content-Type' while receiving data from the backend.
[requestUrl setValue:#"application/x-www-form-urlencoded; charset=UTF-8" forHTTPHeaderField:#"Content-Type"];

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.

-[__NSArrayM insertObject:atIndex:]: object cannot be nil' [duplicate]

This question already has answers here:
__NSArrayM insertObject:atIndex:]; object cannot be nil
(2 answers)
Closed 8 years ago.
Here,
NSString *decryptedStr = [[NSString alloc] initWithData:decryptedData encoding:NSUTF8StringEncoding];
"decryptedStr" is getting "decryptedData" has been working fine in simulator.
but
it has not been working fine in iPhone devices. i got an error message is
-[__NSArrayM insertObject:atIndex:]: object cannot be nil'.
plz help me.
this is my code
NSString *stringIndex1 = [[NSString alloc]init];
NSMutableArray *arrAthigaaramList1 = [[NSMutableArray alloc] init];
dictDecryptList=[[NSMutableDictionary alloc]init];
for(int i=0;i<[arrD_Chapter count];i++)//50 Chapter wise
{
stringIndex1 = [arrD_Chapter objectAtIndex:i];
NSData *b64DecData = [Base64 decode:stringIndex1];
NSData *decryptedData = [[NSData alloc]init];
decryptedData= [b64DecData AESDecryptWithPassphrase:#"mypassword"];
NSString *decryptedStr = [[NSString alloc] initWithData:decryptedData encoding:NSUTF32StringEncoding];
if (decryptedStr) {
NSLog(#"Decryped Data Base 64 encoded = %#",decryptedStr);
[arrAthigaaramList1 addObject:decryptedStr];
} else {
NSLog(#"ERROR decrypting!!!");
}
}
change these lines:
NSData *decryptedData = [[NSData alloc]init];
decryptedData= [b64DecData AESDecryptWithPassphrase:#"mypassword"];
NSString *decryptedStr = [[NSString alloc] initWithData:decryptedData encoding:NSUTF32StringEncoding];
to this:
NSData *decryptedData= [b64DecData AESDecryptWithPassphrase:#"mypassword"];
if([decryptedData length] > 0)
{
NSString *decryptedStr = [[NSString alloc] initWithData:decryptedData
encoding:NSUTF32StringEncoding];
} else {
NSLog(#"Hmmm, why is decrypted data a zero byte object??");
}

Resources