Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix KVO that breaks if a target object overrides 'isEqual' and 'hash' #361

Open
wants to merge 12 commits into
base: master
Choose a base branch
from
8 changes: 7 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
language: objective-c
before_install:
- (ruby --version)
- sudo chown -R travis ~/Library/RubyMotion
- mkdir -p ~/Library/RubyMotion/build
- sudo motion update
script: ./travis.sh
script:
- bundle install
- bundle exec rake clean
- bundle exec rake spec
- bundle exec rake clean
- bundle exec rake spec osx=true
4 changes: 3 additions & 1 deletion Gemfile.lock
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
PATH
remote: .
specs:
bubble-wrap (1.5.0)
bubble-wrap (1.6.0.rc1)
bubble-wrap-http (= 1.6.0.rc1)

GEM
remote: https://rubygems.org/
specs:
bacon (1.1.0)
bubble-wrap-http (1.6.0.rc1)
metaclass (0.0.1)
mocha (0.11.4)
metaclass (~> 0.0.1)
Expand Down
9 changes: 6 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ A collection of (tested) helpers and wrappers used to wrap Cocoa Touch and AppKi
[BubbleWrap mailing list](https://groups.google.com/forum/#!forum/bubblewrap)

[![Code Climate](https://codeclimate.com/github/rubymotion/BubbleWrap.png)](https://codeclimate.com/github/rubymotion/BubbleWrap)
[![Build Status](https://travis-ci.org/rubymotion/BubbleWrap.png?branch=master)](https://travis-ci.org/rubymotion/BubbleWrap)
[![Build Status](https://travis-ci.org/rubymotion/BubbleWrap.svg?branch=master)](https://travis-ci.org/rubymotion/BubbleWrap)
[![Dependency Status](https://gemnasium.com/rubymotion/BubbleWrap.png)](https://gemnasium.com/rubymotion/BubbleWrap)

## Installation
Expand Down Expand Up @@ -186,7 +186,10 @@ A module with useful methods related to the running application
> App.run_after(0.5) { p "It's #{Time.now}" }
# Runs the block after 0.5 seconds.
> App.open_url("http://matt.aimonetti.net")
# Opens the url using the device's browser. (accepts a string url or an instance of `NSURL`.
> App.open_url("tel://123456789")
# Opens the url using the device's browser. Can also open custom URL schemas (accepts a string url or an instance of `NSURL`.)
> App.can_open_url("tel://")
# Returns whether the app can open a given URL resource.
> App::Persistence['channels'] # application specific persistence storage
# ['NBC', 'ABC', 'Fox', 'CBS', 'PBS']
> App::Persistence['channels'] = ['TF1', 'France 2', 'France 3']
Expand Down Expand Up @@ -767,7 +770,7 @@ class HttpClient
BW::HTTP.get(user_url(user_id)) do |response|
# ..
end
end
end
end
```

Expand Down
1 change: 1 addition & 0 deletions bubble-wrap.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ Gem::Specification.new do |gem|

gem.extra_rdoc_files = gem.files.grep(%r{motion})

gem.add_dependency 'bubble-wrap-http', BubbleWrap::VERSION
gem.add_development_dependency 'mocha', '0.11.4'
gem.add_development_dependency 'mocha-on-bacon'
gem.add_development_dependency 'bacon'
Expand Down
9 changes: 4 additions & 5 deletions lib/bubble-wrap/http.rb
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
require 'bubble-wrap/version' unless defined?(BubbleWrap::VERSION)
require 'bubble-wrap/loader'
require 'bubble-wrap/network-indicator'
BubbleWrap.require('motion/core/ns_url_request.rb')
BubbleWrap.require('motion/core.rb')
BubbleWrap.require('motion/http.rb')
BubbleWrap.require('motion/http/query.rb')
BubbleWrap.require('motion/http/response.rb')
require 'bubble-wrap-http'
Motion::Project::App.warn "BubbleWrap::HTTP is deprecated and will be removed, see https://github.com/rubymotion/BubbleWrap/issues/308"
Motion::Project::App.warn "Switch to a different networking library soon - consider AFNetworking: http://afnetworking.com/"
Motion::Project::App.warn "You can use the 'bubble-wrap-http' gem if you need compatibility: https://github.com/rubymotion/BubbleWrap-HTTP"
1 change: 1 addition & 0 deletions lib/bubble-wrap/ui.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
require 'bubble-wrap/loader'

BubbleWrap.require_ios("ui") do
BubbleWrap.require('motion/util/constants.rb')
BubbleWrap.require('motion/ui/**/*.rb') do
file('motion/ui/pollute.rb').depends_on %w(
motion/ui/ui_control_wrapper.rb
Expand Down
2 changes: 1 addition & 1 deletion lib/bubble-wrap/version.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
module BubbleWrap
VERSION = '1.5.0' unless defined?(BubbleWrap::VERSION)
VERSION = '1.6.0.rc1' unless defined?(BubbleWrap::VERSION)
MIN_MOTION_VERSION = '2.17'
end
16 changes: 14 additions & 2 deletions motion/core/ios/app.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,28 @@ module App
module_function

# Opens an url (string or instance of `NSURL`)
# in the device's web browser.
# in the device's web browser or in the correspondent app for custom schemas
# Usage Example:
# App.open_url("http://matt.aimonetti.net")
# App.open_url("fb://profile")
def open_url(url)
unless url.is_a?(NSURL)
url = NSURL.URLWithString(url)
end
UIApplication.sharedApplication.openURL(url)
end

# Returns whether an app can open a given URL resource (string or instance of `NSURL`)
# Useful to check if certain apps are installed before calling to their custom schemas.
# Usage Example:
# App.open_url("fb://profile") if App.can_open_url("fb://")
def can_open_url(url)
unless url.is_a?(NSURL)
url = NSURL.URLWithString(url)
end
UIApplication.sharedApplication.canOpenURL(url)
end

# Displays a UIAlertView.
#
# title - The title as a String.
Expand Down Expand Up @@ -80,4 +92,4 @@ def window
key_window || normal_windows.first
end
end
end
end
23 changes: 16 additions & 7 deletions motion/core/kvo.rb
Original file line number Diff line number Diff line change
Expand Up @@ -62,25 +62,34 @@ def unobserve_all

private
def registered?(target, key_path)
!@targets.nil? && !@targets[target].nil? && @targets[target].has_key?(key_path.to_s)
target_id = target.object_id
!@targets.nil? && !@targets[target_id].nil? && @targets[target_id].has_key?(key_path.to_s)
end

def add_observer_block(target, key_path, &block)
return if target.nil? || key_path.nil? || block.nil?

block.weak! if BubbleWrap.use_weak_callbacks?

target_id = target.object_id

@targets ||= {}
@targets[target] ||= {}
@targets[target][key_path.to_s] ||= []
@targets[target][key_path.to_s] << block
@targets[target_id] ||= {}
@targets[target_id][key_path.to_s] ||= []
@targets[target_id][key_path.to_s] << block
end

def remove_observer_block(target, key_path)
return if @targets.nil? || target.nil? || key_path.nil?

key_paths = @targets[target]
target_id = target.object_id

key_paths = @targets[target_id]
key_paths.delete(key_path.to_s) if !key_paths.nil?

if key_paths.size == 0
@targets.delete target_id
end
end

def remove_all_observer_blocks
Expand All @@ -90,8 +99,9 @@ def remove_all_observer_blocks
# NSKeyValueObserving Protocol

def observeValueForKeyPath(key_path, ofObject: target, change: change, context: context)
key_paths = @targets[target] || {}
key_paths = @targets[target.object_id] || {}
blocks = key_paths[key_path] || []

blocks.each do |block|
args = [change[NSKeyValueChangeOldKey], change[NSKeyValueChangeNewKey]]
args << change[NSKeyValueChangeIndexesKey] if collection?(change)
Expand All @@ -102,6 +112,5 @@ def observeValueForKeyPath(key_path, ofObject: target, change: change, context:
def collection?(change)
COLLECTION_OPERATIONS.include?(change[NSKeyValueChangeKindKey])
end

end
end
34 changes: 0 additions & 34 deletions motion/http.rb

This file was deleted.

Loading