2009-05-22 25 views
10

tôi cần phải vượt qua một dấu thời gian với một múi giờ bù đắp trong một yêu cầu GET, ví dụ:Thực hiện một NSURL với một mã hóa cộng (% 2B)

2009-05-04T11: 22: 00 + 01: 00

Điều này trông giống như hai đối số "2009-05-04T11: 22: 00" và "01:00" đối với tập lệnh PHP nhận (mà tôi không kiểm soát được).

NSURL không mã hóa dấu cộng, nhưng nếu tôi làm cho một NSURL bằng cách sử dụng chuỗi

2009-05-04T11: 22: 00% 2B01: 00

url tôi kết thúc lên bằng bao gồm:

2009-05-04T11: 22: 00% 252B01: 00

Bất kỳ ý tưởng nào về cách tôi có thể giữ lại dấu cộng được mã hóa của mình hoặc chỉ đơn giản là ngăn NSURL mã hóa bất kỳ thứ gì?

Trả lời

13

gì làm việc đối với tôi là làm việc chuyển đổi UTF8, sau đó thay thế vào dấu + với% 2B:

NSString *urlString = 
    [NSString stringWithFormat:@"%@/iphone/push/create?pn[token]=%@&pn[send_at]=%@", 
    kHTTPURL, appDelegate.deviceAPNToken, [dateTimeToUse description]]; 

urlString = 
    [[urlString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding] 
    stringByReplacingOccurrencesOfString:@"+" withString:@"%2B"]; 
+0

Tôi không hiểu câu trả lời đúng như thế nào. Các câu hỏi sẽ hỏi cách tạo một đối tượng NSURL thích hợp. Nếu chuỗi này được sử dụng để tạo đối tượng NSURL, dấu% sẽ lại được mã hóa dưới dạng% 25. Vui lòng làm rõ. –

+1

Điều này giải quyết được vấn đề. Tuy nhiên nó không phải là giải pháp đúng vì nó chỉ đề cập đến '+' chứ không phải các ký tự khác cần được mã hóa. –

+0

Điều này không hiệu quả đối với tôi. Thay vào đó, tôi mã hóa dấu thời gian bằng câu trả lời của Ric Santos TRƯỚC KHI tạo urlString. Theo kinh nghiệm của tôi, tôi chưa từng thấy ai cần mã hóa tên tham số, lược đồ, tên miền hoặc các phần khác của url. Vì vậy, luôn luôn tốt nhất để mã hóa các giá trị tham số riêng biệt. Tuy nhiên, sẽ rất tuyệt khi có một chức năng có thể phá vỡ một url, mã hóa nó một cách chính xác, sau đó đặt nó lại với nhau. Tôi giả định rằng stringByAddingPercentEscapesUsingEncoding đã làm điều này, nhưng dường như nó không thành công cho các trường hợp như + dấu hiệu. – Brainware

2

Sử dụng phương pháp NSString 's stringByAddingPercentEscapesUsingEncoding: trên văn bản bạn muốn bao gồm làm đối số.

Như tên gọi của nó, phương thức sẽ chuyển đổi trả về chuỗi tự động phát hành có chứa phiên bản an toàn url của người nhận.

+0

Tôi đã thử điều đó - nó chuyển đổi '+' thành '% 2B'. NSURL sau đó mã hóa '%' để bạn kết thúc bằng '% 252B' – edoloughlin

+0

Có thể, bạn đang làm gì đó sai với URL rồi. Bạn cần sử dụng 'URLWithString:' của NSURL. –

+0

Và chắc chắn rằng bạn không gọi phương thức đó hai lần trên cùng một chuỗi, nếu không thì sẽ gọi nó mã hóa chuỗi kết quả của bạn hai lần, do đó mã hóa% thành% 25. Ngoài ra hãy chắc chắn rằng bạn đang sử dụng NSUTF8Encoding ở khắp mọi nơi. –

2

Nghĩ rằng tôi cũng có thể cung cấp cách giải quyết của tôi như một câu trả lời, vì tôi không nghĩ rằng có một giải pháp tốt cho vấn đề ban đầu.

Dấu cộng (+) hoàn toàn hợp lệ trong URL, vì vậy giải pháp của tôi là chuyển đổi thời gian thành GMT và loại bỏ chênh lệch múi giờ/DST khỏi chuỗi. Tôi sẽ để nó như một bài tập để người đọc xác định giá trị của giâyFromGMT dưới đây, trong trường hợp của tôi, nó luôn luôn giống nhau vì tôi chỉ quan tâm đến dấu thời gian được tạo bởi một máy chủ web.

NSString *gmtWhen = [[self descriptionWithCalendarFormat:nil 
          timeZone:[NSTimeZone 
          timeZoneForSecondsFromGMT:secondsFromGMT 
        ] locale:nil] stringByReplacingOccurrencesOfString:@" +0000" withString:@""]; 
3

Chuỗi nên được URL mã hóa.

Dưới đây là một phạm trù cho NSString sẽ giúp:

NSString + Additions.h

@interface NSString (Additions) 

- (NSString *)stringByURLEncoding; 

NSString + bổ sung.m

#import "NSString+Additions.h" 

@implementation NSString (Additions) 

- (NSString *)stringByURLEncoding { 
    return (__bridge NSString *)CFURLCreateStringByAddingPercentEscapes(NULL, 
                  (CFStringRef)self, 
                  NULL, 
                  (CFStringRef)@"!*'\"();:@&=+$,/?%#[]% ", 
                  CFStringConvertNSStringEncodingToEncoding(NSUTF8StringEncoding)); 
} 
0

encode bạn chuỗi bằng cách sử dụng mã dưới đây

NSString * result = (NSString *) CFURLCreateStringByAddingPercentEscapes (NULL, (CFStringRef) tự, NULL, (CFStringRef) @ "+", kCFStringEncodingUTF8) ;

này sẽ mã hóa + của bạn chuỗi đó sẽ ngăn chặn thay thế + bởi% 2b khi đăng dữ liệu trong bài phương pháp

0

Để mã hóa cộng (% 2B) (Nó hoạt động với tất cả charcters) sử dụng CFURLCreateStringByAddingPercentEscapes như

/** 
get parameterized url from url and query parameters. 
*/ 
+(NSString *)getParameterizedUrl:(NSString *)url withParameters:(NSDictionary *)queryDictionary 
{ 
    NSMutableArray *mutablePairs = [NSMutableArray array]; 
    for (NSString *key in queryDictionary) { 
     [mutablePairs addObject:[NSString stringWithFormat:@"%@=%@", CTPercentEscapedQueryStringKeyFromStringWithEncoding(key, NSUTF8StringEncoding), CTPercentEscapedQueryStringValueFromStringWithEncoding(queryDictionary[key], NSUTF8StringEncoding)]]; 
    } 

    return [[NSString alloc]initWithFormat:@"%@?%@",url,[mutablePairs componentsJoinedByString:@"&"]]; 
} 

static NSString * const kCharactersToBeEscapedInQueryString = @":/?&=;[email protected]#$()',*"; 

static NSString * CTPercentEscapedQueryStringKeyFromStringWithEncoding(NSString *string, NSStringEncoding encoding) { 
    static NSString * const kCharactersToLeaveUnescapedInQueryStringPairKey = @"[]."; 

    return (__bridge_transfer NSString *)CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, (__bridge CFStringRef)string, (__bridge CFStringRef)kCharactersToLeaveUnescapedInQueryStringPairKey, (__bridge CFStringRef)kCharactersToBeEscapedInQueryString, CFStringConvertNSStringEncodingToEncoding(encoding)); 
} 

static NSString * CTPercentEscapedQueryStringValueFromStringWithEncoding(NSString *string, NSStringEncoding encoding) { 
    return (__bridge_transfer NSString *)CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, (__bridge CFStringRef)string, NULL, (__bridge CFStringRef)kCharactersToBeEscapedInQueryString, CFStringConvertNSStringEncodingToEncoding(encoding)); 
} 

Và sử dụng trong mã của bạn như

NSMutableDictionary *params = [[NSMutableDictionary alloc]init]; 
[params setObject:@"2009-05-04T11:22:00+01:00" forKey:@"timestamp"]; 

NSString *urlString = [self getParameterizedUrl:@"http://www.example.com" withParameters:params]; 
NSURL *url = [NSURL URLWithString:[urlString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]]; 
0

giải pháp khi sử dụng URLComponents (Swift 3):

var params = ["email": "[email protected]", "name": "John Brown"] 
var components = URLComponents(string: "http://www.example.com")! 
components.path = "/login" 
components.queryItems = params.map { URLQueryItem(name: $0, value: $1) } 

let url_NoFix = components.url! 
// http://www.example.com/login?name=John%20Brown&[email protected] 

let cs = CharacterSet(charactersIn: "+").inverted 
let q = components.percentEncodedQuery?.addingPercentEncoding(withAllowedCharacters: cs) 
components.percentEncodedQuery = q 

let url_Fixed = components.url! 
// http://www.example.com/login?name=John%20Brown&email=user%[email protected] 
Các vấn đề liên quan