提交 2c8ac3fa 编写于 作者: C Collin Jackson

Merge pull request #2265 from collinjackson/ios_value_child

Support for value and child events on Firebase iOS
......@@ -30,6 +30,10 @@ class FirebaseImpl : public ::firebase::Firebase {
void GetChild(
const mojo::String& path,
mojo::InterfaceRequest<Firebase> child) override;
void AddValueEventListener(
::firebase::ValueEventListenerPtr listener) override;
void AddChildEventListener(
::firebase::ChildEventListenerPtr listener) override;
void ObserveSingleEventOfType(
::firebase::EventType eventType,
const ObserveSingleEventOfTypeCallback& callback) override;
......@@ -41,6 +45,8 @@ class FirebaseImpl : public ::firebase::Firebase {
private:
mojo::StrongBinding<::firebase::Firebase> binding_;
::Firebase* client_;
std::vector<::firebase::ValueEventListenerPtr> value_event_listeners_;
std::vector<::firebase::ChildEventListenerPtr> child_event_listeners_;
DISALLOW_COPY_AND_ASSIGN(FirebaseImpl);
};
......
......@@ -12,6 +12,20 @@ namespace sky {
namespace services {
namespace firebase {
::firebase::DataSnapshotPtr toMojoSnapshot(FDataSnapshot* snapshot) {
::firebase::DataSnapshotPtr mojoSnapshot(::firebase::DataSnapshot::New());
mojoSnapshot->key = base::SysNSStringToUTF8(snapshot.key);
mojoSnapshot->value = base::SysNSStringToUTF8(snapshot.value);
return mojoSnapshot.Pass();
}
::firebase::ErrorPtr toMojoError(NSError* error) {
::firebase::ErrorPtr mojoError(::firebase::Error::New());
mojoError->code = error.code;
mojoError->message = base::SysNSStringToUTF8(error.description);
return mojoError.Pass();
}
FirebaseImpl::FirebaseImpl(mojo::InterfaceRequest<::firebase::Firebase> request)
: binding_(this, request.Pass()) {}
......@@ -35,6 +49,79 @@ void FirebaseImpl::GetChild(
child->client_ = [[client_ childByAppendingPath:@(path.data())] retain];
}
void FirebaseImpl::AddValueEventListener(::firebase::ValueEventListenerPtr ptr) {
::firebase::ValueEventListener *listener = ptr.get();
FirebaseHandle handle = [client_ observeEventType:FEventTypeValue
withBlock:^(FDataSnapshot *snapshot) {
listener->OnDataChange(toMojoSnapshot(snapshot));
} withCancelBlock:^(NSError *error) {
listener->OnCancelled(toMojoError(error));
}];
ptr.set_connection_error_handler([this, handle, listener]() {
[client_ removeObserverWithHandle:handle];
auto it = std::find_if(value_event_listeners_.begin(),
value_event_listeners_.end(),
[listener](const ::firebase::ValueEventListenerPtr& p) {
return (p.get() == listener);
});
DCHECK(it != value_event_listeners_.end());
value_event_listeners_.erase(it);
});
value_event_listeners_.emplace_back(ptr.Pass());
}
void FirebaseImpl::AddChildEventListener(::firebase::ChildEventListenerPtr ptr) {
::firebase::ChildEventListener *listener = ptr.get();
void (^cancelBlock)(NSError *) = ^(NSError *error) {
listener->OnCancelled(toMojoError(error));
};
void (^addedBlock)(FDataSnapshot *, NSString *) = ^(FDataSnapshot *snapshot, NSString *prevKey) {
listener->OnChildAdded(toMojoSnapshot(snapshot), base::SysNSStringToUTF8(prevKey));
};
FirebaseHandle addedHandle = [client_ observeEventType:FEventTypeChildAdded
andPreviousSiblingKeyWithBlock:addedBlock
withCancelBlock:cancelBlock];
void (^changedBlock)(FDataSnapshot *, NSString *) = ^(FDataSnapshot *snapshot, NSString *prevKey) {
listener->OnChildChanged(toMojoSnapshot(snapshot), base::SysNSStringToUTF8(prevKey));
};
FirebaseHandle changedHandle = [client_ observeEventType:FEventTypeChildChanged
andPreviousSiblingKeyWithBlock:changedBlock
withCancelBlock:cancelBlock];
void (^movedBlock)(FDataSnapshot *, NSString *) = ^(FDataSnapshot *snapshot, NSString *prevKey) {
listener->OnChildMoved(toMojoSnapshot(snapshot), base::SysNSStringToUTF8(prevKey));
};
FirebaseHandle movedHandle = [client_ observeEventType:FEventTypeChildMoved
andPreviousSiblingKeyWithBlock:movedBlock
withCancelBlock:cancelBlock];
void (^removedBlock)(FDataSnapshot *snapshot) = ^(FDataSnapshot *snapshot) {
listener->OnChildRemoved(toMojoSnapshot(snapshot));
};
FirebaseHandle removedHandle = [client_ observeEventType:FEventTypeChildRemoved
withBlock:removedBlock
withCancelBlock:cancelBlock];
ptr.set_connection_error_handler(
[this, addedHandle, changedHandle, movedHandle, removedHandle, listener]() {
[client_ removeObserverWithHandle:addedHandle];
[client_ removeObserverWithHandle:changedHandle];
[client_ removeObserverWithHandle:movedHandle];
[client_ removeObserverWithHandle:removedHandle];
auto it = std::find_if(child_event_listeners_.begin(),
child_event_listeners_.end(),
[listener](const ::firebase::ChildEventListenerPtr& p) {
return (p.get() == listener);
});
DCHECK(it != child_event_listeners_.end());
child_event_listeners_.erase(it);
}
);
child_event_listeners_.emplace_back(ptr.Pass());
}
void FirebaseImpl::ObserveSingleEventOfType(
::firebase::EventType eventType,
const ObserveSingleEventOfTypeCallback& callback) {
......@@ -42,10 +129,7 @@ void FirebaseImpl::ObserveSingleEventOfType(
new ObserveSingleEventOfTypeCallback(callback);
[client_ observeSingleEventOfType:static_cast<FEventType>(eventType)
withBlock:^(FDataSnapshot *snapshot) {
::firebase::DataSnapshotPtr mojoSnapshot(::firebase::DataSnapshot::New());
mojoSnapshot->key = base::SysNSStringToUTF8(snapshot.key);
mojoSnapshot->value = base::SysNSStringToUTF8(snapshot.value);
copyCallback->Run(mojoSnapshot.Pass());
copyCallback->Run(toMojoSnapshot(snapshot));
delete copyCallback;
}];
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册