在 JSON 中,我在 "title" 中得到以下格式的数据,如何才能得到实际数据?
in JSON I getting following format of data in "title" , how Can get actual data?
这是我的 JSON 数据,
{
"total": 60,
"per_page": 10,
"current_page": 1,
"last_page": 6,
"next_page_url": "http://www.ladybirdweb.com/support/api/v1/helpdesk/inbox?page=2",
"prev_page_url": null,
"from": 1,
"to": 10,
"data": [
{
"updated_at": "2017-07-18 07:17:25",
"user_name": "eugene@smartitfirm.com",
"first_name": "Eugene",
"last_name": "Dunayev",
"email": "eugene@smartitfirm.com",
"profile_pic": "https://secure.gravatar.com/avatar/841369e30f04310b23750abbb670c65c?s=80&r=g&d=identicon",
"ticket_number": "AAAA-0000-745",
"id": 4395,
"title": "Demo",
"created_at": "2017-07-12 04:15:15",
"department_name": "Support",
"priotity_name": "Low",
"priority_color": "#00a65a",
"sla_plan_name": "Low",
"help_topic_name": "Support query",
"ticket_status_name": "Open",
"department_id": "3",
"user_dpt": null,
"attachment": "23",
"overdue_date": "2017-07-12 12:15:15"
},
{
"updated_at": "2017-07-18 07:15:40",
"user_name": "rmuller@idagroup.net",
"first_name": "Robin",
"last_name": "W.",
"email": "rmuller@idagroup.net",
"profile_pic": "https://secure.gravatar.com/avatar/90efb0e570dfc699f78c414449cb46d9?s=80&r=g&d=identicon",
"ticket_number": "AAAA-0000-776",
"id": 4426,
"title": "=?UTF-8?Q?Re:_Robin_-_Implementing_Faveo_H?= =?UTF-8?Q?elp_Desk._Let=E2=80=99s_get_you_started.?=",
"created_at": "2017-07-14 16:15:17",
"department_name": "Support",
"priotity_name": "Low",
"priority_color": "#00a65a",
"sla_plan_name": "Low",
"help_topic_name": "Support query",
"ticket_status_name": "Open",
"department_id": "3",
"user_dpt": null,
"attachment": "3",
"overdue_date": "2017-07-17 12:00:00"
}
]
}
在这本特定的词典中,只有我从 at 得到这个。其他显示正确数据的词典。
所以,我希望得到这样的回应,
"title: Re: Robin - Implementing Faveo Help Desk. Let’s get you started."
如果没问题,我正在获取这种格式,那么是否有任何解决方案可以获取实际数据,以便我在视图控制器中打印。
代码是,
我在这里发送请求,
-(void)reload
{
NSString *url=[NSString stringWithFormat:@"%@helpdesk/inbox?api_key=%@&ip=%@&token=%@",[userDefaults objectForKey:@"companyURL"],API_KEY,IP,[userDefaults objectForKey:@"token"]];
MyWebservices *webservices=[MyWebservices sharedInstance];
[webservices httpResponseGET:url parameter:@"" callbackHandler:^(NSError *error,id json,NSString* msg) {
if (error || [msg containsString:@"Error"]) {
[refresh endRefreshing];
[[AppDelegate sharedAppdelegate] hideProgressView];
if (msg) {
[utils showAlertWithMessage:[NSString stringWithFormat:@"Error-%@",msg] sendViewController:self];
}else if(error) {
[utils showAlertWithMessage:[NSString stringWithFormat:@"Error-%@",error.localizedDescription] sendViewController:self];
NSLog(@"Thread-NO4-getInbox-Refresh-error == %@",error.localizedDescription);
}
return ;
}
if ([msg isEqualToString:@"tokenRefreshed"]) {
[self reload];
NSLog(@"Thread--NO4-call-getInbox");
return;
}
if (json) {
//NSError *error;
NSLog(@"Thread-NO4--getInboxAPI--%@",json);
_mutableArray = [json objectForKey:@"data"];
_nextPageUrl =[json objectForKey:@"next_page_url"];
_currentPage=[[json objectForKey:@"current_page"] integerValue];
_totalTickets=[[json objectForKey:@"total"] integerValue];
_totalPages=[[json objectForKey:@"last_page"] integerValue];
NSLog(@"Thread-NO4.1getInbox-dic--%@", _mutableArray);
dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{
dispatch_async(dispatch_get_main_queue(), ^{
[[AppDelegate sharedAppdelegate] hideProgressView];
[refresh endRefreshing];
[self.tableView reloadData];
});
});
}
NSLog(@"Thread-NO5-getInbox-closed");
}];
}
}
这里是 cellForRowAtIndexPath 方法,
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
if (indexPath.row == [_mutableArray count]) {
LoadingTableViewCell *cell=[tableView dequeueReusableCellWithIdentifier:@"LoadingCellID"];
if (cell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"LoadingTableViewCell" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
UIActivityIndicatorView *activityIndicator = (UIActivityIndicatorView *)[cell.contentView viewWithTag:1];
[activityIndicator startAnimating];
return cell;
}else{
TicketTableViewCell *cell=[tableView dequeueReusableCellWithIdentifier:@"TableViewCellID"];
if (cell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"TicketTableViewCell" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
NSDictionary *finaldic=[_mutableArray objectAtIndex:indexPath.row];
cell.ticketIdLabel.text=[finaldic objectForKey:@"ticket_number"];
NSString *fname= [finaldic objectForKey:@"first_name"];
NSString *lname= [finaldic objectForKey:@"last_name"];
NSString *userName= [finaldic objectForKey:@"user_name"];
[Utils isEmpty:fname];
[Utils isEmpty:lname];
if (![Utils isEmpty:fname] && ![Utils isEmpty:lname])
{
cell.mailIdLabel.text=[NSString stringWithFormat:@"%@ %@",[finaldic objectForKey:@"first_name"],[finaldic objectForKey:@"last_name"]];
}
else
{ if(![Utils isEmpty:userName])
{
cell.mailIdLabel.text=[finaldic objectForKey:@"user_name"];
}
else
{
cell.mailIdLabel.text=[finaldic objectForKey:@"email"];
}
}
NSString *title1= [finaldic objectForKey:@"title"];
[Utils isEmpty:title1];
if ([Utils isEmpty:title1]){
cell.ticketSubLabel.text=@"No Title";
}
else
{
cell.ticketSubLabel.text=[finaldic objectForKey:@"title"];
}
return cell;
}
}
我的网络服务 class 方法是,
-(void)httpResponseGET:(NSString *)urlString
parameter:(id)parameter
callbackHandler:(callbackHandler)block{
NSError *error;
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:urlString]];
//[request addValue:@"text/html" forHTTPHeaderField:@"Accept"];
[request addValue:@"application/json" forHTTPHeaderField:@"Accept"];
[request addValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
[request setTimeoutInterval:45.0];
NSData *postData = nil;
if ([parameter isKindOfClass:[NSString class]]) {
postData = [((NSString *)parameter) dataUsingEncoding:NSUTF8StringEncoding];
} else {
postData = [NSJSONSerialization dataWithJSONObject:parameter options:0 error:&error];
}
[request setHTTPBody:postData];
[request setHTTPMethod:@"GET"];
NSLog(@"Thread--httpResponseGET--Request : %@", urlString);
NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] ];
[[session dataTaskWithRequest:request completionHandler:^(NSData * data, NSURLResponse * response, NSError * error) {
NSLog(@"Response is required : %@",(NSHTTPURLResponse *) response);
if (error) {
dispatch_async(dispatch_get_main_queue(), ^{
block(error,nil,nil);
});
NSLog(@"Thread--httpResponseGET--dataTaskWithRequest error: %@", [error localizedDescription]);
}else if ([response isKindOfClass:[NSHTTPURLResponse class]]) {
NSInteger statusCode = [(NSHTTPURLResponse *)response statusCode];
if (statusCode != 200) {
NSLog(@"dataTaskWithRequest HTTP status code: %ld", (long)statusCode);
if (statusCode==400) {
if ([[self refreshToken] isEqualToString:@"tokenRefreshed"]) {
dispatch_async(dispatch_get_main_queue(), ^{
block(nil,nil,@"tokenRefreshed");
});
NSLog(@"Thread--httpResponsePOST--tokenRefreshed");
}else {
dispatch_async(dispatch_get_main_queue(), ^{
block(nil,nil,@"tokenNotRefreshed");
});
NSLog(@"Thread--httpResponsePOST--tokenNotRefreshed");
}
}else
dispatch_async(dispatch_get_main_queue(), ^{
block(nil, nil,[NSString stringWithFormat:@"Error-%ld",(long)statusCode]);
});
return ;
}
NSString *replyStr = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
if ([replyStr containsString:@"token_expired"]) {
NSLog(@"Thread--httpResponseGET--token_expired");
if ([[self refreshToken] isEqualToString:@"tokenRefreshed"]) {
dispatch_async(dispatch_get_main_queue(), ^{
block(nil,nil,@"tokenRefreshed");
});
NSLog(@"Thread--httpResponseGET--tokenRefreshed");
}else {
dispatch_async(dispatch_get_main_queue(), ^{
block(nil,nil,@"tokenNotRefreshed");
});
NSLog(@"Thread--httpResponseGET--tokenNotRefreshed");
}
return;
}
NSError *jsonerror = nil;
id responseData = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:&jsonerror];
dispatch_async(dispatch_get_main_queue(), ^{
block(jsonerror,responseData,nil);
});
}
}] resume];
}
好的,首先字符串是 Q-encode 并且是来自电子邮件的 MIME Header。
The "Q" encoding is similar to the "Quoted-Printable" content- transfer-encoding defined in RFC 1521. It is designed to allow text containing mostly ASCII characters to be decipherable on an ASCII terminal without decoding.
Any 8-bit value may be represented by a "=" followed by two hexadecimal digits. For example, if the character set in use were ISO-8859-1, the "=" character would thus be encoded as "=3D", and a SPACE by "=20". (Upper case should be used for hexadecimal digits "A" through "F".)
The 8-bit hexadecimal value 20 (e.g., ISO-8859-1 SPACE) may be
represented as "" (underscore, ASCII 95.). (This character may not
pass through some internetwork mail gateways, but its use will greatly
enhance readability of "Q" encoded data with mail readers that do not
support this encoding.) Note that the "" always represents
hexadecimal 20, even if the SPACE character occupies a different code
position in the character set in use.
8-bit values which correspond to printable ASCII characters other than
"=", "?", "_" (underscore), and SPACE may be represented as those
characters. (But see section 5 for restrictions.)
来源http://www.freesoft.org/CIE/RFC/1522/6.htm
此问题已在其他 Whosebug 中得到解决 post:
在上面的 post 中显示了一段代码,用于替换 Q-coded 支持 base 64 的字符串并将其转换为有效的 NSString 格式:
@implementation NSString (MimeEncodedWord)
- (BOOL) isMimeEncodedWord
{
return [self hasPrefix:@"=?"] && [self hasSuffix:@"?="];
}
+ (NSString*) stringWithMimeEncodedWord:(NSString*)word
{ // Example: =?iso-8859-1?Q?=A1Hola,_se=F1or!?=
NSArray *components = [word componentsSeparatedByString:@"?"];
if (components.count < 5) return nil;
NSString *charset = [components objectAtIndex:1];
NSStringEncoding encoding = CFStringConvertEncodingToNSStringEncoding(CFStringConvertIANACharSetNameToEncoding((CFStringRef)charset)); // TODO: What happens if the encoding is invalid?
NSString *encodingType = [components objectAtIndex:2];
NSString *encodedText = [components objectAtIndex:3];
if ([encodingType isEqualToString:@"Q"])
{ // quoted-printable
encodedText = [encodedText stringByReplacingOccurrencesOfString:@"_" withString:@" "];
encodedText = [encodedText stringByReplacingOccurrencesOfString:@"=" withString:@"%"];
NSString *decoded = [encodedText stringByReplacingPercentEscapesUsingEncoding:encoding];
return decoded;
} else if ([encodingType isEqualToString:@"B"])
{ // base64
NSData *data = [QSStrings decodeBase64WithString:encodedText];
NSString *decoded = [[NSString alloc] initWithData:data encoding:encoding];
return decoded;
} else {
NSLog(@"%@ is not a valid encoding (must be Q or B)", encodingType);
return nil;
}
}
@end
此代码也作为 NSString class 类别在 Github post 中找到
这里:https://github.com/hpique/NSString-MimeEncodedWord
希望对您有所帮助
检查下面的代码,我希望它能工作。我根据你的代码创建了..!此代码取自@Sophy Swicz。
NSString *encodedString =[finaldic objectForKey:@"title"];
[Utils isEmpty:encodedString];
if ([Utils isEmpty:encodedString]){
cell.ticketSubLabel.text=@"No Title";
}
else
{
NSMutableString *decodedString = [[NSMutableString alloc] init];
if ([encodedString hasPrefix:@"=?UTF-8?Q?"] || [encodedString hasSuffix:@"?="])
{
NSScanner *scanner = [NSScanner scannerWithString:encodedString];
NSString *buf = nil;
// NSMutableString *decodedString = [[NSMutableString alloc] init];
while ([scanner scanString:@"=?UTF-8?Q?" intoString:NULL]
|| ([scanner scanUpToString:@"=?UTF-8?Q?" intoString:&buf] && [scanner scanString:@"=?UTF-8?Q?" intoString:NULL])) {
if (buf != nil) {
[decodedString appendString:buf];
}
buf = nil;
NSString *encodedRange;
if (![scanner scanUpToString:@"?=" intoString:&encodedRange]) {
break; // Invalid encoding
}
[scanner scanString:@"?=" intoString:NULL]; // Skip the terminating "?="
// Decode the encoded portion (naively using UTF-8 and assuming it really is Q encoded)
// I'm doing this really naively, but it should work
// Firstly I'm encoding % signs so I can cheat and turn this into a URL-encoded string, which NSString can decode
encodedRange = [encodedRange stringByReplacingOccurrencesOfString:@"%" withString:@"=25"];
// Turn this into a URL-encoded string
encodedRange = [encodedRange stringByReplacingOccurrencesOfString:@"=" withString:@"%"];
// Remove the underscores
encodedRange = [encodedRange stringByReplacingOccurrencesOfString:@"_" withString:@" "];
// [decodedString appendString:[encodedRange stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
NSString *str1= [encodedRange stringByRemovingPercentEncoding];
[decodedString appendString:str1];
}
NSLog(@"Decoded string = %@", decodedString);
cell.ticketSubLabel.text= decodedString;
}
else{
cell.ticketSubLabel.text= encodedString;
}
}
这是我的 JSON 数据,
{
"total": 60,
"per_page": 10,
"current_page": 1,
"last_page": 6,
"next_page_url": "http://www.ladybirdweb.com/support/api/v1/helpdesk/inbox?page=2",
"prev_page_url": null,
"from": 1,
"to": 10,
"data": [
{
"updated_at": "2017-07-18 07:17:25",
"user_name": "eugene@smartitfirm.com",
"first_name": "Eugene",
"last_name": "Dunayev",
"email": "eugene@smartitfirm.com",
"profile_pic": "https://secure.gravatar.com/avatar/841369e30f04310b23750abbb670c65c?s=80&r=g&d=identicon",
"ticket_number": "AAAA-0000-745",
"id": 4395,
"title": "Demo",
"created_at": "2017-07-12 04:15:15",
"department_name": "Support",
"priotity_name": "Low",
"priority_color": "#00a65a",
"sla_plan_name": "Low",
"help_topic_name": "Support query",
"ticket_status_name": "Open",
"department_id": "3",
"user_dpt": null,
"attachment": "23",
"overdue_date": "2017-07-12 12:15:15"
},
{
"updated_at": "2017-07-18 07:15:40",
"user_name": "rmuller@idagroup.net",
"first_name": "Robin",
"last_name": "W.",
"email": "rmuller@idagroup.net",
"profile_pic": "https://secure.gravatar.com/avatar/90efb0e570dfc699f78c414449cb46d9?s=80&r=g&d=identicon",
"ticket_number": "AAAA-0000-776",
"id": 4426,
"title": "=?UTF-8?Q?Re:_Robin_-_Implementing_Faveo_H?= =?UTF-8?Q?elp_Desk._Let=E2=80=99s_get_you_started.?=",
"created_at": "2017-07-14 16:15:17",
"department_name": "Support",
"priotity_name": "Low",
"priority_color": "#00a65a",
"sla_plan_name": "Low",
"help_topic_name": "Support query",
"ticket_status_name": "Open",
"department_id": "3",
"user_dpt": null,
"attachment": "3",
"overdue_date": "2017-07-17 12:00:00"
}
]
}
在这本特定的词典中,只有我从 at 得到这个。其他显示正确数据的词典。 所以,我希望得到这样的回应,
"title: Re: Robin - Implementing Faveo Help Desk. Let’s get you started."
如果没问题,我正在获取这种格式,那么是否有任何解决方案可以获取实际数据,以便我在视图控制器中打印。
代码是,
我在这里发送请求,
-(void)reload
{
NSString *url=[NSString stringWithFormat:@"%@helpdesk/inbox?api_key=%@&ip=%@&token=%@",[userDefaults objectForKey:@"companyURL"],API_KEY,IP,[userDefaults objectForKey:@"token"]];
MyWebservices *webservices=[MyWebservices sharedInstance];
[webservices httpResponseGET:url parameter:@"" callbackHandler:^(NSError *error,id json,NSString* msg) {
if (error || [msg containsString:@"Error"]) {
[refresh endRefreshing];
[[AppDelegate sharedAppdelegate] hideProgressView];
if (msg) {
[utils showAlertWithMessage:[NSString stringWithFormat:@"Error-%@",msg] sendViewController:self];
}else if(error) {
[utils showAlertWithMessage:[NSString stringWithFormat:@"Error-%@",error.localizedDescription] sendViewController:self];
NSLog(@"Thread-NO4-getInbox-Refresh-error == %@",error.localizedDescription);
}
return ;
}
if ([msg isEqualToString:@"tokenRefreshed"]) {
[self reload];
NSLog(@"Thread--NO4-call-getInbox");
return;
}
if (json) {
//NSError *error;
NSLog(@"Thread-NO4--getInboxAPI--%@",json);
_mutableArray = [json objectForKey:@"data"];
_nextPageUrl =[json objectForKey:@"next_page_url"];
_currentPage=[[json objectForKey:@"current_page"] integerValue];
_totalTickets=[[json objectForKey:@"total"] integerValue];
_totalPages=[[json objectForKey:@"last_page"] integerValue];
NSLog(@"Thread-NO4.1getInbox-dic--%@", _mutableArray);
dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{
dispatch_async(dispatch_get_main_queue(), ^{
[[AppDelegate sharedAppdelegate] hideProgressView];
[refresh endRefreshing];
[self.tableView reloadData];
});
});
}
NSLog(@"Thread-NO5-getInbox-closed");
}];
}
}
这里是 cellForRowAtIndexPath 方法,
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
if (indexPath.row == [_mutableArray count]) {
LoadingTableViewCell *cell=[tableView dequeueReusableCellWithIdentifier:@"LoadingCellID"];
if (cell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"LoadingTableViewCell" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
UIActivityIndicatorView *activityIndicator = (UIActivityIndicatorView *)[cell.contentView viewWithTag:1];
[activityIndicator startAnimating];
return cell;
}else{
TicketTableViewCell *cell=[tableView dequeueReusableCellWithIdentifier:@"TableViewCellID"];
if (cell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"TicketTableViewCell" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
NSDictionary *finaldic=[_mutableArray objectAtIndex:indexPath.row];
cell.ticketIdLabel.text=[finaldic objectForKey:@"ticket_number"];
NSString *fname= [finaldic objectForKey:@"first_name"];
NSString *lname= [finaldic objectForKey:@"last_name"];
NSString *userName= [finaldic objectForKey:@"user_name"];
[Utils isEmpty:fname];
[Utils isEmpty:lname];
if (![Utils isEmpty:fname] && ![Utils isEmpty:lname])
{
cell.mailIdLabel.text=[NSString stringWithFormat:@"%@ %@",[finaldic objectForKey:@"first_name"],[finaldic objectForKey:@"last_name"]];
}
else
{ if(![Utils isEmpty:userName])
{
cell.mailIdLabel.text=[finaldic objectForKey:@"user_name"];
}
else
{
cell.mailIdLabel.text=[finaldic objectForKey:@"email"];
}
}
NSString *title1= [finaldic objectForKey:@"title"];
[Utils isEmpty:title1];
if ([Utils isEmpty:title1]){
cell.ticketSubLabel.text=@"No Title";
}
else
{
cell.ticketSubLabel.text=[finaldic objectForKey:@"title"];
}
return cell;
}
}
我的网络服务 class 方法是,
-(void)httpResponseGET:(NSString *)urlString
parameter:(id)parameter
callbackHandler:(callbackHandler)block{
NSError *error;
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:urlString]];
//[request addValue:@"text/html" forHTTPHeaderField:@"Accept"];
[request addValue:@"application/json" forHTTPHeaderField:@"Accept"];
[request addValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
[request setTimeoutInterval:45.0];
NSData *postData = nil;
if ([parameter isKindOfClass:[NSString class]]) {
postData = [((NSString *)parameter) dataUsingEncoding:NSUTF8StringEncoding];
} else {
postData = [NSJSONSerialization dataWithJSONObject:parameter options:0 error:&error];
}
[request setHTTPBody:postData];
[request setHTTPMethod:@"GET"];
NSLog(@"Thread--httpResponseGET--Request : %@", urlString);
NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] ];
[[session dataTaskWithRequest:request completionHandler:^(NSData * data, NSURLResponse * response, NSError * error) {
NSLog(@"Response is required : %@",(NSHTTPURLResponse *) response);
if (error) {
dispatch_async(dispatch_get_main_queue(), ^{
block(error,nil,nil);
});
NSLog(@"Thread--httpResponseGET--dataTaskWithRequest error: %@", [error localizedDescription]);
}else if ([response isKindOfClass:[NSHTTPURLResponse class]]) {
NSInteger statusCode = [(NSHTTPURLResponse *)response statusCode];
if (statusCode != 200) {
NSLog(@"dataTaskWithRequest HTTP status code: %ld", (long)statusCode);
if (statusCode==400) {
if ([[self refreshToken] isEqualToString:@"tokenRefreshed"]) {
dispatch_async(dispatch_get_main_queue(), ^{
block(nil,nil,@"tokenRefreshed");
});
NSLog(@"Thread--httpResponsePOST--tokenRefreshed");
}else {
dispatch_async(dispatch_get_main_queue(), ^{
block(nil,nil,@"tokenNotRefreshed");
});
NSLog(@"Thread--httpResponsePOST--tokenNotRefreshed");
}
}else
dispatch_async(dispatch_get_main_queue(), ^{
block(nil, nil,[NSString stringWithFormat:@"Error-%ld",(long)statusCode]);
});
return ;
}
NSString *replyStr = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
if ([replyStr containsString:@"token_expired"]) {
NSLog(@"Thread--httpResponseGET--token_expired");
if ([[self refreshToken] isEqualToString:@"tokenRefreshed"]) {
dispatch_async(dispatch_get_main_queue(), ^{
block(nil,nil,@"tokenRefreshed");
});
NSLog(@"Thread--httpResponseGET--tokenRefreshed");
}else {
dispatch_async(dispatch_get_main_queue(), ^{
block(nil,nil,@"tokenNotRefreshed");
});
NSLog(@"Thread--httpResponseGET--tokenNotRefreshed");
}
return;
}
NSError *jsonerror = nil;
id responseData = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:&jsonerror];
dispatch_async(dispatch_get_main_queue(), ^{
block(jsonerror,responseData,nil);
});
}
}] resume];
}
好的,首先字符串是 Q-encode 并且是来自电子邮件的 MIME Header。
The "Q" encoding is similar to the "Quoted-Printable" content- transfer-encoding defined in RFC 1521. It is designed to allow text containing mostly ASCII characters to be decipherable on an ASCII terminal without decoding.
Any 8-bit value may be represented by a "=" followed by two hexadecimal digits. For example, if the character set in use were ISO-8859-1, the "=" character would thus be encoded as "=3D", and a SPACE by "=20". (Upper case should be used for hexadecimal digits "A" through "F".)
The 8-bit hexadecimal value 20 (e.g., ISO-8859-1 SPACE) may be represented as "" (underscore, ASCII 95.). (This character may not pass through some internetwork mail gateways, but its use will greatly enhance readability of "Q" encoded data with mail readers that do not support this encoding.) Note that the "" always represents hexadecimal 20, even if the SPACE character occupies a different code position in the character set in use.
8-bit values which correspond to printable ASCII characters other than "=", "?", "_" (underscore), and SPACE may be represented as those characters. (But see section 5 for restrictions.)
来源http://www.freesoft.org/CIE/RFC/1522/6.htm
此问题已在其他 Whosebug 中得到解决 post:
在上面的 post 中显示了一段代码,用于替换 Q-coded 支持 base 64 的字符串并将其转换为有效的 NSString 格式:
@implementation NSString (MimeEncodedWord)
- (BOOL) isMimeEncodedWord
{
return [self hasPrefix:@"=?"] && [self hasSuffix:@"?="];
}
+ (NSString*) stringWithMimeEncodedWord:(NSString*)word
{ // Example: =?iso-8859-1?Q?=A1Hola,_se=F1or!?=
NSArray *components = [word componentsSeparatedByString:@"?"];
if (components.count < 5) return nil;
NSString *charset = [components objectAtIndex:1];
NSStringEncoding encoding = CFStringConvertEncodingToNSStringEncoding(CFStringConvertIANACharSetNameToEncoding((CFStringRef)charset)); // TODO: What happens if the encoding is invalid?
NSString *encodingType = [components objectAtIndex:2];
NSString *encodedText = [components objectAtIndex:3];
if ([encodingType isEqualToString:@"Q"])
{ // quoted-printable
encodedText = [encodedText stringByReplacingOccurrencesOfString:@"_" withString:@" "];
encodedText = [encodedText stringByReplacingOccurrencesOfString:@"=" withString:@"%"];
NSString *decoded = [encodedText stringByReplacingPercentEscapesUsingEncoding:encoding];
return decoded;
} else if ([encodingType isEqualToString:@"B"])
{ // base64
NSData *data = [QSStrings decodeBase64WithString:encodedText];
NSString *decoded = [[NSString alloc] initWithData:data encoding:encoding];
return decoded;
} else {
NSLog(@"%@ is not a valid encoding (must be Q or B)", encodingType);
return nil;
}
}
@end
此代码也作为 NSString class 类别在 Github post 中找到 这里:https://github.com/hpique/NSString-MimeEncodedWord
希望对您有所帮助
检查下面的代码,我希望它能工作。我根据你的代码创建了..!此代码取自@Sophy Swicz。
NSString *encodedString =[finaldic objectForKey:@"title"];
[Utils isEmpty:encodedString];
if ([Utils isEmpty:encodedString]){
cell.ticketSubLabel.text=@"No Title";
}
else
{
NSMutableString *decodedString = [[NSMutableString alloc] init];
if ([encodedString hasPrefix:@"=?UTF-8?Q?"] || [encodedString hasSuffix:@"?="])
{
NSScanner *scanner = [NSScanner scannerWithString:encodedString];
NSString *buf = nil;
// NSMutableString *decodedString = [[NSMutableString alloc] init];
while ([scanner scanString:@"=?UTF-8?Q?" intoString:NULL]
|| ([scanner scanUpToString:@"=?UTF-8?Q?" intoString:&buf] && [scanner scanString:@"=?UTF-8?Q?" intoString:NULL])) {
if (buf != nil) {
[decodedString appendString:buf];
}
buf = nil;
NSString *encodedRange;
if (![scanner scanUpToString:@"?=" intoString:&encodedRange]) {
break; // Invalid encoding
}
[scanner scanString:@"?=" intoString:NULL]; // Skip the terminating "?="
// Decode the encoded portion (naively using UTF-8 and assuming it really is Q encoded)
// I'm doing this really naively, but it should work
// Firstly I'm encoding % signs so I can cheat and turn this into a URL-encoded string, which NSString can decode
encodedRange = [encodedRange stringByReplacingOccurrencesOfString:@"%" withString:@"=25"];
// Turn this into a URL-encoded string
encodedRange = [encodedRange stringByReplacingOccurrencesOfString:@"=" withString:@"%"];
// Remove the underscores
encodedRange = [encodedRange stringByReplacingOccurrencesOfString:@"_" withString:@" "];
// [decodedString appendString:[encodedRange stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
NSString *str1= [encodedRange stringByRemovingPercentEncoding];
[decodedString appendString:str1];
}
NSLog(@"Decoded string = %@", decodedString);
cell.ticketSubLabel.text= decodedString;
}
else{
cell.ticketSubLabel.text= encodedString;
}
}