Chr*_*ris 2 cocoa objective-c nsstring
NSString当参数计数变量时,用最简单的方法构建查询是什么?
假设我有一个Web服务,它返回按参数列表过滤的国家/地区列表.例如:
NSString *continent = @"europe";
NSString *language = @"german";
NSString *timeZone = @"UTC+1";
// to be continued
Run Code Online (Sandbox Code Playgroud)
因此我的查询字符串将是:
[NSString stringWithFormat:@"/getCountries?continent=%@&language=%@&timezone=%@",
continent, language, timeZone];
Run Code Online (Sandbox Code Playgroud)
我的回复将包含
奥地利,德国和瑞士
因为它们匹配所有三个参数.
现在我正在寻找最聪明的方法(例如,不是ifs 的意大利面条代码)来构建这个查询,当0:n这些参数可能是零.(例如,当*timeZone是nil时,URL不应包含timezone=nil)的结果应是一个NSString.
我会做一个做这件事并且做得对的对象.
您必须注意的一件事是确保正确地逃避所有名称和值.例如,如果传入"fred&wilma"值,则不应在URL中显示为"members = fred&wilma" - 您需要转义&(转义%26).
您可以在装订时简单地转义每个字符串,但忘记这样做太容易了.代码中重复的任何内容都很容易被遗漏.
这是我为此制作一个对象的主要原因.该对象不仅会将字符串拼接在一起,还会适当地逃避它们.
我假设您以后不需要查找键的值.您只想构建一个URL.
首先,对象应该私有地保存NSMutableString(不是公共 - @property私有@property或实例变量).它应该在初始化中创建它并在其整个生命中保持它.
对象的指定初始化程序应该是这样的initWithResourceURLString:.此方法向字符串发送mutableCopy消息,并将结果分配给实例变量或私有属性.init应抛出异常(最容易通过断言false).
该对象还应具有单个实例变量unichar.initWithResourceURLString:应该把它设置为'?'.
对象应该响应诸如的消息setQueryParameterWithName:toValue:.每个参数都应该是一个字符串.如果是任一字符串nil,则该方法只返回.
该方法向每个字符串发送一条stringByAddingPercentEscapesUsingEncoding:消息,然后向可变字符串发送一条appendFormat:消息,格式如下:
%C%@=%@
Run Code Online (Sandbox Code Playgroud)
参数是unichar实例变量中的字符,转义参数名称和转义值.然后它将字符变量设置为&.
该对象应该响应一条消息,例如constructedURLString通过返回可变字符串的副本(如果您正在使用MRC自动释放).
然后你会像这样使用那个对象:
builder = [[MyURLBuilder alloc] initWithResourceURLString:@"http://example.com/getCountries"]; //Add autorelease under MRC
[builder setQueryParameterName:@"continent" toValue:continent];
[builder setQueryParameterName:@"language" toValue:language];
[builder setQueryParameterName:@"timeZone" toValue:timeZone];
NSURL *finishedURL = [NSURL URLWithString:[builder constructedURLString]];
Run Code Online (Sandbox Code Playgroud)
好处:
nil正确处理(忽略).所有其他代码不应该担心它.nil任何或仅一些参数的支持.您对该类所做的任何更改都可立即用于您可能拥有的任何其他URL构建作业.