2012-11-07 2 views
0

RubyMotion (처음으로!)을 사용하여 일부 사용자의 최근 트윗을 검색하기 위해 트위터의 검색 API를 사용하고자합니다.HTTP 응답 본문을 문자열로 가져 오기 (RubyMotion 용 BubbleWrap)

tweets의 값은 항상 빈 배열입니다. 나는 BW::HTTP.get(url)이 문제를 일으키는 자체 스레드를 생성한다고 의심합니다.

정말로, 단지 twitter_search_resultsresponse.body.to_str으로 되 돌리고 싶습니다. 그러나 어떻게해야할지 모르겠습니다.

RubyMotion (또는 BubbleWrap)을 사용하여 Tweet 개체를 UIViewController에 어떻게 배치합니까?

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

    def tweets 
    twitter_search_results 
    puts @tweets.count 
    @tweets 
    end 

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

    def twitter_search_results 
    query = @twitter_accounts.map{ |account| "from:#{account}" }.join(" OR ") 
    url = "http://search.twitter.com/search.json?q=#{query}" 
    BW::HTTP.get(url) do |response| 
     create_tweets(response.body.to_str) 
    end 
    end 
end 

class TwitterViewController < UIViewController 
    def viewDidLoad 
    super 
    self.view.backgroundColor = UIColor.blueColor 
    @table = UITableView.alloc.initWithFrame(self.view.bounds) 
    self.view.addSubview @table 
    @table.dataSource = self 
    @tweets_controller = TweetsController.new 
    end 

    def initWithNibName(name, bundle: bundle) 
    super 
    self.tabBarItem = UITabBarItem.alloc.initWithTitle(
     "Twitter", 
     image: UIImage.imageNamed('twitter.png'), 
     tag: 1) 
    self 
    end 

    def tableView(tableView, numberOfRowsInSection: section) 
    @tweets_controller.tweets.length 
    end 

    def tableView(tableView, cellForRowAtIndexPath: indexPath) 
    @reuse_id = "Tweet" 
    cell = UITableViewCell.alloc.initWithStyle(UITableViewCellStyleDefault, reuseIdentifier:@reuse_id) 
    cell.textLabel.text = @tweets_controller.tweets[indexPath.row].text 
    return cell 
    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 

답변

0

아래의 전체 컨트롤러 코드. 나는 또한 넣었습니다 project on GitHub

class TweetsController 
    def initialize 
    @twitter_accounts = %w(dhh google) 
    @tweets = [] 
    create_tweets 
    end 

    def tweets 
    @tweets 
    end 

    def create_tweets 
    json_data = twitter_search_results.dataUsingEncoding(NSUTF8StringEncoding) 
    e = Pointer.new(:object) 
    dict = NSJSONSerialization.JSONObjectWithData(json_data, options:0, error: e) 
    dict["results"].each do |result| 
     p result.class 
     p result 
     @tweets << Tweet.new(result) 
    end 
    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 
0

여기에 문제는 비 동시성이다. 당신은 거의 다 왔다고 생각하지만 create_tweets 메서드는 puts @tweets 전에 호출되지 않습니다. 나는 그들이 ;-)

TweetsReady = 'TweetsReady' # constants are nice 
NSNotificationCenter.defaultCenter.postNotificationName(TweetsReady, object:@tweets) 

In your controller, register for this notification in `viewWillAppear` and unregister in `viewWillDisappear` 

NSNotificationCenter.defaultCenter.addObserver(self, selector: 'tweets_ready:', name: TweetsReady, object:nil) # object:nil means 'register for all events, not just ones associated with 'object' 
# ... 
NSNotificationCenter.defaultCenter.removeObserver(self, name:TweetsReady, object:nil) 

좋은 생각이 tweets_ready 방법은 당신의 UI 변경을 구현해야하기 때문에이 경우에, 나는 알림을 사용하는 것이 좋습니다 것입니다.

def tweets_ready(notification) 
    @table.reloadData 
end 
+0

#rubymotion으로 멈추고 걸쇠를 치면 저를 때려주세요. :-) – colinta

+0

솔루션이 BW :: HTTP를 사용하지 않는 것이 흥미 롭습니다. HTTP 요청 차단이 누락되어 @colinta의보기에 버그가 있습니까? – user94154

+0

나는 나의 대답을 고쳤다. 마이크는 NSWRLRequest와 family에 찬성하여 BW :: HTTP를 사용하지 않았다. 나는 Notifications의 사용을 추천했고 나의 원래 답은 위에있다. 나는 마이크가 내 대답에 대해 만든 매우 정교한 편집에 동의하지 않는다. – colinta

관련 문제