2012-11-08 3 views
2

Twitter의 검색 API에서 RubyMotion 클래스를 읽어서 아래와 같이 Tweet 개체를 만듭니다.RubyMotion을 사용하여 JSON 구문 분석

(main)> 2012-11-08 17:01:32.634 Hello[39940:c07] -[__NSCFString bytes]: unrecognized selector sent to instance 0xea1f800 
2012-11-08 17:01:32.685 Hello[39940:c07] json.rb:20:in `parse:': NSInvalidArgumentException: -[__NSCFString bytes]: unrecognized selector sent to instance 0xea1f800 (RuntimeError) 
    from tweets_controller.rb:11:in `create_tweets' 
    from tweets_controller.rb:7:in `tweets' 
    from twitter_view_controller.rb:21:in `tableView:numberOfRowsInSection:' 
    from app_delegate.rb:10:in `application:didFinishLaunchingWithOptions:' 
2012-11-08 17:01:32.686 Hello[39940:c07] *** Terminating app due to uncaught exception 'RuntimeError', reason: 'json.rb:20:in `parse:': NSInvalidArgumentException: -[__NSCFString bytes]: unrecognized selector sent to instance 0xea1f800 (RuntimeError) 
    from tweets_controller.rb:11:in `create_tweets' 
    from tweets_controller.rb:7:in `tweets' 
    from twitter_view_controller.rb:21:in `tableView:numberOfRowsInSection:' 
    from app_delegate.rb:10:in `application:didFinishLaunchingWithOptions:' 

가 어떻게이 JSON을 구문 분석해야합니다

은 내가이 오류를 언제 실행?

class TweetsController 
    def initialize 
    @twitter_accounts = %w(dhh google) 
    end 

    def tweets 
    @tweets ||= create_tweets 
    end 

    def create_tweets 
    BW::JSON.parse(twitter_search_results)["results"].each do |result| 
     @tweets << Tweet.new(result) 
    end 
    @tweets 
    end 

    def twitter_search_results 
    query = @twitter_accounts.map{ |account| "from:#{account}" }.join(" OR ") 
    url_string = "http://search.twitter.com/search.json?q=#{query}" 
    url_string_escaped = url_string.stringByAddingPercentEscapesUsingEncoding(NSUTF8StringEncoding) 
    url = NSURL.URLWithString(url_string_escaped) 
    request = NSURLRequest.requestWithURL(url) 
    response = nil 
    error = nil 
    data = NSURLConnection.sendSynchronousRequest(request, returningResponse: response, error: error) 
    ##raise "BOOM!" unless (data.length > 0 && error.nil?) 
    json = NSString.alloc.initWithData(data, encoding: NSUTF8StringEncoding) 
    end 
end 

class Tweet 
    attr_reader :created_at, :from_user, :text 
    def initialize(tweet_result) 
    @created_at = tweet_result["created_at"] 
    @from_user = tweet_result["from_user"] 
    @text = tweet_result["text"] 
    end 
end 

답변

1

짧은 답변 : 뽁뽁이를 사용하여 건너 여기에 두 개의 다른 구현이다.

이에 대한
def create_tweets 
    json_string = twitter_search_results.dataUsingEncoding(NSUTF8StringEncoding) 
    e = Pointer.new(:object) 
    json_hash = NSJSONSerialization.JSONObjectWithData(json_string, options:0, error: e) 
    json_hash["results"].each do |result| 
     @tweets << Tweet.new(result) 
    end 
    end 
+0

내 질문에 가장 간결하게 답변하므로 직접 답변을 수락했습니다. 스티브 로스 (Steve Ross)의 대답과 블로그 게시물은 훌륭하고 읽기에도 가치가 있습니다. http://sxross-blog.herokuapp.com/2012/11/11/how-to-build-a-twitter-search-client-in-ruby -운동/ – Mike

3

이 문제를 해결하는 몇 가지 CocoaPod가 있습니다. 특히 JSONKit.

편집 : 버블 랩 버그가 아닙니다. 그것은 트위터로부터의 응답을 해석하는 문제입니다. 나는 이것을 bubblewrap과 JSONKit 모두에서 수행하는 샘플을 가지고있다. 나는 GitHub에 곧 올릴 것이다. 짧은 요약, 트위터 배열의 배열을 반환합니다. 첫 번째 요소는 해당 그룹에 있으며 두 번째 요소는 실제 데이터입니다. 가장 바깥 쪽 배열을 반복하여 첫 번째 요소가 결과 인 배열을 찾고 두 번째 요소를 사용하여 응답 데이터를 가져 오려고합니다.

def create_tweets_using_bubblewrap 
    @twitter_accounts = %w(dhh google) 
    query = @twitter_accounts.map{ |account| "from:#{account}" }.join(" OR ") 
    url_string = "http://search.twitter.com/search.json?q=#{query}" 

    BW::HTTP.get(url_string) do |response| 
    parsed = BW::JSON.parse response.body.to_str 
    parsed.each do |item| 
     next if item[0] != 'results' 
     @feed = [] 
     item[1].each do |tweet| 
     @feed << {:from => tweet['from_user'], :text => tweet['text']} 
     end 
    end 
    end 
    @feed 
end 

def create_tweets_using_jsonkit 
    @twitter_accounts = %w(dhh google) 
    query = @twitter_accounts.map{ |account| "from:#{account}" }.join(" OR ") 
    url_string = "http://search.twitter.com/search.json?q=#{query}" 

    error_ptr = Pointer.new(:object) 
    BW::HTTP.get(url_string) do |response| 
    parsed = response.body.to_str.objectFromJSONStringWithParseOptions JKParseOptionValidFlags, error: error_ptr 
    if parsed.nil? 
     error = error_ptr[0] 
     puts error.userInfo[NSLocalizedDescriptionKey] 
     @timer.setValid false 
    else 
     parsed.each do |item| 
     next if item[0] != 'results' 
     @feed = [] 
     item[1].each do |tweet| 
      @feed << {:from => tweet['from_user'], :text => tweet['text']} 
     end 
     end 
    end 
    end 
    @feed 
end 

http://developer.apple.com/library/ios/#documentation/Foundation/Reference/NSJSONSerialization_Class/Reference/Reference.html

+0

감사 http://sxross-blog.herokuapp.com/2012/11/11/how-to-build-a-twitter-search-client-in-ruby-에서 당신의 쓰기까지 모션/ – Mike