2009-05-27 21 views
8

Tôi đang cố gắng để gửi nội dung của UITextView hoặc UITextField như tham số cho một file phpgian Encoding trong UITextView/UITextField sang định dạng URL

NSString *urlstr = [[NSString alloc] initWithFormat:@"http://server.com/file.php?name=%@&tags=%@&entry=%@",nameField.text, tagsField.text, dreamEntry.text]; 

Khi tôi đăng nhập urlstr, định dạng url là ok giống như dài vì UITextView hoặc UITextField không chứa dấu cách. Làm thế nào tôi sẽ đi về chuyển đổi không gian để% 20?

chỉnh sửa

đây là mã hiện tại, không chỉ treo mà không mã hóa url đúng cách.

name = John Doe & tags = tái phát cơn ác mộng & entry = kiểm tra thử nghiệm kiểm tra

được chuyển thành

name = John -1844684964oe & tags = recurringightmare & entry = Testing -1.992836e 4.214929e-307sting + 00sting

- (IBAction)sendButtonPressed:(id)sender 
{ 

    NSString *urlString = [[NSString alloc] initWithFormat:@"http://server.com/file.php?name=%@&tags=%@&entry=%@", nameField.text, tagsField.text, dreamEntry.text]; 

    NSString *encodedString = [urlString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; 

    NSURL *url = [[NSURL alloc] initWithString:encodedString]; 

    NSLog(encodedString); 

    NSLog(urlString); 

    [urlString release]; 
    [url release]; 
    [encodedString release]; 


} 

Trả lời

14

Bạn không được phép thoát URL khỏi toàn bộ chuỗi, bạn phải chạy thoát khỏi các thành phần động. Hãy thử

NSString *urlStr = [NSString stringWithFormat:@"http://server.com/file.php?name=%@&tags=%@&entry=%@", 
         [nameField.text stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding], 
         [tagsField.text stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding], 
         [dreamEntry.text stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding], 
         nil]; 
NSURL *url = [NSURL URLWithString:urlStr]; 

Vấn đề thứ hai với mã của bạn (và chắc chắn lý do in lẻ) là bạn đang chuyển chuỗi trực tiếp tới NSLog, vì vậy nó được coi là chuỗi định dạng. Bạn cần phải sử dụng

NSLog(@"%@", encodedString); 

để thay thế. Điều đó sẽ làm cho nó in như mong đợi.

Chỉnh sửa: Vấn đề thứ ba với mã của bạn là bạn đang trộn các đối tượng được tự động phát hành và sở hữu, sau đó phát hành tất cả chúng ở cuối. Đi xem 3 đối tượng bạn tạo và sau đó bạn phát hành sau đó. Một trong số họ không nên được phát hành sau này bởi vì nó đã được sản xuất bởi một phương pháp mà không bắt đầu với các từ phân bổ, sao chép, hoặc mới. Xác định đối tượng được đề cập là một bài tập được để lại cho người đọc.

+0

điểm hehe. cảm ơn! – bcsantos

0

bạn có thể lấy URL và sử dụng của bạn:

01.
NSString *urlStr = [[NSString alloc] initWithFormat:@"http://server.com/file.php?name=%@&tags=%@&entry=%@",nameField.text, tagsField.text, dreamEntry.text]; 

NSString *encStr = [urlStr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; 
+0

cảm ơn con trỏ :) – bcsantos

+0

NP ... câu trả lời ở trên thực sự chính xác hơn. Thx ... –

20

Trên thực tế, tất cả các câu trả lời trước chứa ít nhất một số không chính xác, mà đối với nhiều giá trị chung của người sử dụng được cung cấp văn bản trong Trường văn bản sẽ không giao tiếp chính xác với máy chủ

stringByAddingPercentEscapesUsingEncoding: trăm thoát tất cả các ký tự không phải là URL hợp lệ nhân vật. Phương pháp này sẽ áp dụng một lần cho toàn bộ URL.

Câu trả lời trước cho rằng stringByAddingPercentEscapesUsingEncoding: hoạt động giống như các lớp xây dựng URL bằng nhiều ngôn ngữ kịch bản, nơi bạn không nên áp dụng nó cho toàn bộ chuỗi URL, nhưng không. Bất kỳ ai cũng có thể dễ dàng xác minh điều này bằng cách kiểm tra kết quả đầu ra của nó cho các ảnh chưa được thoát & s và ? s. Vì vậy, nó là tốt để áp dụng cho toàn bộ chuỗi, nhưng nó là không đủ để áp dụng cho nội dung url 'động' của bạn.

Câu trả lời trước là đúng trong đó bạn phải thực hiện thêm một số công việc cho tên và giá trị đi vào chuỗi truy vấn CGI của bạn. Vì CGI được chỉ định bởi RFC3875, điều này thường được gọi là RFC3875 phần trăm thoát.Nó làm cho chắc chắn rằng tên và giá trị của bạn không chứa các ký tự có ký tự URL hợp lệ nhưng đó là quan trọng trong các bộ phận khác của URL (;, ?, :, @, &, =, $, +, {, }, < , >,)

Tuy nhiên, điều rất quan trọng cũng là hoàn thành bằng cách làm phần trăm URL thoát trên chuỗi đầy đủ để đảm bảo rằng tất cả ký tự trong chuỗi là các ký tự URL hợp lệ. Mặc dù bạn không có trong ví dụ của mình, nói chung có thể có các ký tự trong phần 'tĩnh' của chuỗi không phải là các ký tự URL hợp lệ, do đó bạn cũng cần phải thoát khỏi các ký tự đó.

Thật không may, NSString không cung cấp cho chúng tôi sức mạnh để thoát khỏi RFC3875 nhân vật quan trọng vì vậy chúng tôi phải nhúng xuống thành CFString để làm như vậy. Rõ ràng sử dụng CFString là một nỗi đau vì vậy tôi thường thêm một Category vào NSString như vậy:

@interface NSString (RFC3875) 
- (NSString *)stringByAddingRFC3875PercentEscapesUsingEncoding:(NSStringEncoding)encoding; 
@end 

@implementation NSString (RFC3875) 
- (NSString *)stringByAddingRFC3875PercentEscapesUsingEncoding:(NSStringEncoding)encoding { 
    CFStringEncoding cfEncoding = CFStringConvertNSStringEncodingToEncoding(encoding); 
    NSString *rfcEscaped = (NSString *)CFURLCreateStringByAddingPercentEscapes(
               NULL, 
               (CFStringRef)self, 
               NULL, 
               (CFStringRef)@";/?:@&=$+{}<>,", 
               cfEncoding); 
    return [rfcEscaped autorelease]; 
} 
@end 

Với Category này tại chỗ, vấn đề gốc có thể được giải quyết một cách chính xác như sau:

NSString *urlEscapedBase = [@"http://server.com/file.php" stringByAddingPercentEscapesUsingEncoding: 
              NSUTF8StringEncoding]; 
NSString *rfcEscapedName = [nameField.text stringByAddingRFC3875PercentEscapesUsingEncoding: 
               NSUTF8StringEncoding]; 
NSString *rfcEscapedTags = [tagsField.text stringByAddingRFC3875PercentEscapesUsingEncoding: 
               NSUTF8StringEncoding]; 
NSString *rfcEscapedEntry = [dreamEntry.text stringByAddingRFC3875PercentEscapesUsingEncoding: 
               NSUTF8StringEncoding]; 

NSString *urlStr = [NSString stringWithFormat:@"%@?name=%@&tags=%@&entry=%@", 
           urlEscapedBase, 
           rfcEscapedName, 
           rfcEscapedTags, 
           rfcEscapedEntry]; 

NSURL *url = [NSURL URLWithString:urlStr]; 

này một chút biến nặng chỉ rõ ràng hơn. Cũng lưu ý rằng danh sách biến được cung cấp cho stringWithFormat: không được là nil bị chấm dứt. Chuỗi định dạng mô tả số lượng biến chính xác cần theo dõi. Ngoài ra, về mặt kỹ thuật, các chuỗi cho các tên chuỗi truy vấn (tên, thẻ, mục nhập, ..) phải được chạy thông qua stringByAddingPercentEscapesUsingEncoding: như một vấn đề, nhưng trong ví dụ nhỏ này, chúng ta có thể dễ dàng thấy rằng chúng không chứa các ký tự URL không hợp lệ.

Để xem lý do tại sao các giải pháp trước đó không chính xác, hãy tưởng tượng văn bản nhập của người dùng trong dreamEntry.text có chứa &, điều này không có khả năng xảy ra. Với các giải pháp trước đó, tất cả văn bản theo sau ký tự đó sẽ bị mất khi máy chủ nhận được văn bản đó, vì ký tự không thoát và sẽ được máy chủ giải thích là kết thúc phần giá trị của cặp chuỗi truy vấn đó.

+1

kudo. Câu trả lời "đúng" hiện tại là tất cả chúng ta có thể thấy hơi quá sai. * Tuy nhiên * khi sử dụng tính năng này để thoát khỏi các giá trị tham số được gửi tới ứng dụng twitter, kết quả bị cắt xén (thực ra chỉ là một nhóm gồm% ký tự). Nếu đây là một vấn đề với giải mã trên danh nghĩa của khách hàng Twitter hay không, tôi không biết. Nó hoạt động với một giải pháp khác bằng cách sử dụng CFURLCreateStringByAddingPercentEscapes(). Tôi nhận giải pháp đó từ đây: http://wiki.akosma.com/IPhone_URL_Schemes#Note_about_URL_Encoding_in_Objective-C – Jonny

+0

Việc triển khai Danh mục mà tôi đã cung cấp hầu như giống với giải pháp bạn liên kết đến (nó cũng sử dụng CFURLCreateStringByAddingPercentEscapes() cho hạng nặng nâng lên. Sự khác biệt chính là giải pháp không được bao bọc gọn gàng). Nếu bạn có vấn đề với Danh mục ở trên, tôi nghi ngờ bạn đã áp dụng cả hai chuỗiByAddingRFC3875PercentEscapesUsingEncoding() và chuỗi NSString bình thườngByAddingPercentEscapesUsingEncoding() vào cùng một chuỗi, điều này là xấu, vì thoát URL không phải là idempotent, vì vậy bạn bắt đầu thoát khỏi thoát (ví dụ:% 20 trở thành% 2520). – barrycburton

+0

Thực ra, giải pháp này là * gần như * chính xác. Cụ thể, lệnh gọi đến [self stringByAddingPercentEscapesUsingEncoding: encoding] là không cần thiết, vì CFURLCreateStringByAddingPercentEscapes() sẽ thực hiện điều đó cho bạn.Vì vậy, phương pháp trở thành: - (NSString *) stringByAddingRFC3875PercentEscapesSử dụng Mã hóa: (NSStringEncoding) mã hóa { CFStringEncoding cfEncoding = CFStringConvertNSStringEncodingToEncoding (encoding); NSString * rfcEscaped = (NSString *) CFURLCreateStringByAddingPercentEscapes (NULL, (CFStringRef) tự, NULL, (CFStringRef) @ "; /?: @ & = $ + {} <>,", CfEncoding); trả lại [rfcEscaped autorelease]; } – lensovet

Các vấn đề liên quan