2014-02-27 57 views
0

我有一个iOS应用程序下载并解析Twitter JSON供稿,然后在UITableView中呈现该供稿。这一切都很好,但我有一个问题:检查JSON值是否存在 - iOS

当用户点击一个UITableView单元格时,应用程序将查看数组“tweets_links”,看看该特定的tweet是否有附加的URL,如果它然后在网络视图会出现。

因为不是所有的微博有网站网址,我添加了一个简单的尝试catch语句(如在C++),它可以告诉我,如果有试图访问阵列的一部分时异常。

我的问题是:这是做得好还是坏做法?

这里是我的代码:

int storyIndex = indexPath.row; 
int url_test = 1; 
NSString *url; 

@try { 
    url = [[tweets_links[storyIndex] valueForKey:@"url"] objectAtIndex:0]; 
} 

@catch (NSException *problem) { 
    // There is NO URL to access for this Tweet. Therefore we get the out of bounds error. 
    // We will NOT take the user to the web browser page. 
    // Uncomment the line below if you wish to see the out of bounds exception. 
    // NSLog(@"%@", problem); 
    url_test = 0; 
} 

if (url_test == 1) { 
    WebBrowser *screen = [[WebBrowser alloc] initWithNibName:nil bundle:nil]; 
    self.seconddata = screen; 
    seconddata.web_url = url; 
    screen.modalTransitionStyle = UIModalTransitionStyleCoverVertical; 
    [self presentViewController:screen animated:YES completion:nil]; 
} 

else if (url_test == 0) { 
    UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Info" message:@"There is no URL attatched to this Tweet." delegate:self cancelButtonTitle:@"Dismiss" otherButtonTitles:nil]; 
    [alertView show]; 

    [tweetTableView deselectRowAtIndexPath:indexPath animated:YES]; 
} 

有没有的努力实现我在做什么更好的办法???

谢谢,丹。

+1

应该没有必要尝试赶上。当你向NSDictionary询问一个不存在的条目时,它返回'nil',你可以很容易地测试它。 (事实上​​,你必须努力获得一个例外。) –

+4

并且不要使用'valueForKey:',使用'objectForKey:'。 – rmaddy

+0

因为valueForKey:是一个非常复杂的方法,它可以处理各种不同对象的各种关键路径,因此必须仔细检查路径是什么,方法发送到哪种对象等等。 objectForKey仅用于查找字典中的内容。可能运行速度快十倍。 – gnasher729

回答

5

使用try和catch是Objective-C中不鼓励有其他的方法检查和处理错误

// firstObject will return the first object in the array or nil if the array is empty. 
url = [[tweets_links[storyIndex][@"url"]] firstObject]; 

if (!url) { 
    // handle the case for no url 
} else { 
    // do something with url 
} 

由于发送消息到nil在Objective-C安全返回nil它的安全链调用。例如如果字典没有该密钥的对象,则它将返回nil并发送firstObjectnil返回nil

+0

当你不知道自己在做什么时,连锁呼叫并不明智。使调试更加困难。 –

+0

@HotLicks这是非常真实的。但是,如果您处理的是可能包含或可能不包含数据的JSON响应,并且您可以理智地处理那些不存在的数据,那么只需尝试它并处理零响应即可__arguably__。我从Haskell和'Maybe' monad中学到了一些东西。 – Abizern

+0

非常感谢您的先生:) – Supertecnoboff

0

我不知道一吨关于Twitter的饲料,但你也许可以检查一个nil值从objectForKey:回来,像这样

if ([tweets_links[storyIndex] objectForKey:@"url"] != nil) { /* process the URL */ } 

你的代码假设值总是数组至少size = 1,在假设它是一个数组之前检查@“url”键的值会更安全。

0

在Objective-C中使用异常被抛弃。例外是为编程错误保留的。你不抓住它们,你修复代码。使用JSON文档,您从未得到任何保证,因此请小心。

NSString* url = nil; 
NSArray* linksArray = nil; 
NSDictionary* linkDict = nil; 
NSArray* urlArray = nil; 

if ([tweet_links isKindOfClass:[NSArray class]]) 
    linksArray = tweet_links; 

if (storyIndex >= 0 && storyIndex < linksArray.count) 
    linkDict = linksArray [storyIndex]; 

urlArray = linkDict [@"url"]; 
if ([urlArray isKindOfClass:[NSArray class]] && urlArray.count > 0) 
    url = urlArray [0]; 

if ([url isKindOfClass:[NSString class]]) 
{ 
    // Code handling the URL 
} 
else 
{ 
    // Code handling there is no URL 
} 

请注意,发送消息给nil对象总是返回0/NO/nil。

并请进入正确的变量命名的习惯。你写了“int url_test = 1;”。 url_test意味着什么?我读了变量名,我不知道它的含义。我需要了解所有的代码。使它“int”意味着它可以是0,1,2,20000或其他。如果您改为写“BOOL urlValid = YES;”很明显:这意味着你有一个有效的URL。

0

由于url值是一个NSString值,因此可以使用length来检查它是否为零,如果没有,是否有任何值(非空字符串)。你可以检查这个NSString是否是一个有效的url。

- (BOOL) validateUrl: (NSString *) candidate { 
     NSString *urlRegEx = @"(http|https)://((\\w)*|([0-9]*)|([-|_])*)+([\\.|/]((\\w)*|([0-9]*)|([-|_])*))+"; 
     NSPredicate *urlTest = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", urlRegEx]; 
     return [urlTest evaluateWithObject:candidate]; 
    } 

.... -

NSString *url = [[tweets_links[storyIndex][@"url"]] firstObject]; 

if ([url length] && [self validateUrl: url]) { 
// Has a valid URL 
} 
+0

非空字符串无效。尝试使用URL并处理任何错误,而不是采取这种简单的方法可能会更好。 – Abizern

+0

那么,在这种情况下,你可以使用验证方法来检查url字符串。看到编辑的答案! :) –

1

无论是使用,如果因为TRY CATCH来捕捉编程错误 和使用objectForKey 下面的方法将被罚款:的 代替 valueForKey

if ([tweets_links[storyIndex] objectForKey:@"url"] != nil) 

OR

if ([url isKindOfClass:[NSString class]]) 
{ 
// Code handling the URL 
} 
else 
{ 
// Code handling there is no URL 
}