stringWithFormat中的变量参数列表用于查询字符串

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这些参数可能是零.(例如,当*timeZonenil时,URL不应包含timezone=nil)的结果应是一个NSString.

Pet*_*sey 5

我会做一个做这件事并且做得对的对象.

您必须注意的一件事是确保正确地逃避所有名称和值.例如,如果传入"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正确处理(忽略).所有其他代码不应该担心它.
  • 订单保留.字典可以改变参数的顺序.这应该无关紧要(服务器不应该关心),但如果确实如此,那么您需要一个保留订单的解决方案.
  • 为这个对象编写单元测试很容易.
  • 如果需要,可以在多个方向上修改此对象.例如,您可以添加对重置构造的查询URL的支持,而无需修改或不必单独记住基本URL,从而使您可以将此对象重用于多个查询.您还可以添加对空字符串替换nil任何或仅一些参数的支持.您对该类所做的任何更改都可立即用于您可能拥有的任何其他URL构建作业.