bridge: replace nsnotification by delegation

This patch takes care of replacing the NSNotification events fired
from the AccountConfigurationManagerAdaptator by a delegation pattern.

Indeed, we only want the AccountsService to be notified of callbacks
coming from the daemon. NSNotifications fired from the NSNotification
default center are broadcasted events. We want to avoid them as much
as possible.

In order to achieve this, a protocol is declared on the Swift part of
the application.
Then, the Ring-Swift.h generated file will take care of exposing it to
the objective-c source code (thanks to the @objc annotation).

We need the pch file to be present to resolve UIKit and Foundation in
the generated Ring-Swift file.

The accountsService now registers itself to the
AccountConfigurationManagerAdaptator as the reveiver of its callbacks.

Because notifications are not used anymore at this time, we remove
the related files factorizing the notifications names.

Tuleap: #1405
Change-Id: I25c906ef6bcfd019cfb331047768883b39755275
diff --git a/Ring/Ring.xcodeproj/project.pbxproj b/Ring/Ring.xcodeproj/project.pbxproj
index 675cbbc..b120f3e 100644
--- a/Ring/Ring.xcodeproj/project.pbxproj
+++ b/Ring/Ring.xcodeproj/project.pbxproj
@@ -14,6 +14,7 @@
 		024B61311DF7656A00C4F9DE /* FixtureFailInitDRingAdapter.mm in Sources */ = {isa = PBXBuildFile; fileRef = 024B612E1DF7656A00C4F9DE /* FixtureFailInitDRingAdapter.mm */; };
 		024B61321DF7656A00C4F9DE /* FixtureFailStartDRingAdapter.mm in Sources */ = {isa = PBXBuildFile; fileRef = 024B61301DF7656A00C4F9DE /* FixtureFailStartDRingAdapter.mm */; };
 		024B61331DF765CA00C4F9DE /* DaemonService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 02B22E081DF7585F000358C9 /* DaemonService.swift */; };
+		0273C2FF1E0C438F00CF00BA /* AccountAdapterDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0273C2FE1E0C438F00CF00BA /* AccountAdapterDelegate.swift */; };
 		02AED8191DD4C4B100F740BA /* librestbed.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 02AED8181DD4C4B100F740BA /* librestbed.a */; };
 		02B22DFC1DF755BB000358C9 /* AccountModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 02B22DFA1DF755BB000358C9 /* AccountModel.swift */; };
 		02B22DFD1DF755BB000358C9 /* AccountViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 02B22DFB1DF755BB000358C9 /* AccountViewModel.swift */; };
@@ -22,7 +23,6 @@
 		02B22E031DF755F7000358C9 /* WalkthroughStoryboard.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 02B22E021DF755F7000358C9 /* WalkthroughStoryboard.storyboard */; };
 		02B22E091DF7585F000358C9 /* DaemonService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 02B22E081DF7585F000358C9 /* DaemonService.swift */; };
 		02E1A0251DDE4ABA00D75B59 /* BoolStringExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 043866371D2304A700E06CE2 /* BoolStringExtension.swift */; };
-		02EFCAD11E0C3F6200FD8ED1 /* NotificationNames.mm in Sources */ = {isa = PBXBuildFile; fileRef = 02EFCAD01E0C3F6200FD8ED1 /* NotificationNames.mm */; };
 		043866211D218B1100E06CE2 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 043866201D218B1100E06CE2 /* AudioToolbox.framework */; };
 		043866331D22CE8C00E06CE2 /* MeViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 043866321D22CE8C00E06CE2 /* MeViewController.swift */; };
 		043866361D22D06500E06CE2 /* AccountTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 043866351D22D06500E06CE2 /* AccountTableViewCell.swift */; };
@@ -117,6 +117,8 @@
 		024B612E1DF7656A00C4F9DE /* FixtureFailInitDRingAdapter.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = FixtureFailInitDRingAdapter.mm; path = Fixtures/DRingAdaptor/FixtureFailInitDRingAdapter.mm; sourceTree = "<group>"; };
 		024B612F1DF7656A00C4F9DE /* FixtureFailStartDRingAdapter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FixtureFailStartDRingAdapter.h; path = Fixtures/DRingAdaptor/FixtureFailStartDRingAdapter.h; sourceTree = "<group>"; };
 		024B61301DF7656A00C4F9DE /* FixtureFailStartDRingAdapter.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = FixtureFailStartDRingAdapter.mm; path = Fixtures/DRingAdaptor/FixtureFailStartDRingAdapter.mm; sourceTree = "<group>"; };
+		0273C2FE1E0C438F00CF00BA /* AccountAdapterDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = AccountAdapterDelegate.swift; path = Services/AccountAdapterDelegate.swift; sourceTree = "<group>"; };
+		0273C3001E0C445200CF00BA /* RingPrefixHeader.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = RingPrefixHeader.pch; path = Ring/RingPrefixHeader.pch; sourceTree = "<group>"; };
 		028568301DF610A9003A8D8D /* RingTests-Bridging-Header.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "RingTests-Bridging-Header.h"; sourceTree = "<group>"; };
 		02AED8181DD4C4B100F740BA /* librestbed.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = librestbed.a; path = ../DEPS/x86_64/lib/librestbed.a; sourceTree = "<group>"; };
 		02B22DFA1DF755BB000358C9 /* AccountModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = AccountModel.swift; path = Account/AccountModel.swift; sourceTree = "<group>"; };
@@ -125,8 +127,6 @@
 		02B22E001DF755E5000358C9 /* MainTabBarViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = MainTabBarViewController.swift; path = MainTabBar/MainTabBarViewController.swift; sourceTree = "<group>"; };
 		02B22E021DF755F7000358C9 /* WalkthroughStoryboard.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = WalkthroughStoryboard.storyboard; path = Walkthrough/WalkthroughStoryboard.storyboard; sourceTree = "<group>"; };
 		02B22E081DF7585F000358C9 /* DaemonService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = DaemonService.swift; path = Services/DaemonService.swift; sourceTree = "<group>"; };
-		02EFCAD01E0C3F6200FD8ED1 /* NotificationNames.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = NotificationNames.mm; path = Bridging/NotificationNames.mm; sourceTree = "<group>"; };
-		02EFCAD21E0C3F8200FD8ED1 /* NotificationNames.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = NotificationNames.h; path = Bridging/NotificationNames.h; sourceTree = "<group>"; };
 		043866201D218B1100E06CE2 /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = System/Library/Frameworks/AudioToolbox.framework; sourceTree = SDKROOT; };
 		043866321D22CE8C00E06CE2 /* MeViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MeViewController.swift; sourceTree = "<group>"; };
 		043866351D22D06500E06CE2 /* AccountTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AccountTableViewCell.swift; sourceTree = "<group>"; };
@@ -329,6 +329,7 @@
 			children = (
 				02B22E081DF7585F000358C9 /* DaemonService.swift */,
 				02B22DFE1DF755DB000358C9 /* AccountsService.swift */,
+				0273C2FE1E0C438F00CF00BA /* AccountAdapterDelegate.swift */,
 			);
 			name = Services;
 			sourceTree = "<group>";
@@ -352,8 +353,6 @@
 				04399AA81D1C304300E99CD9 /* DRingAdapter.mm */,
 				04399AAA1D1C304300E99CD9 /* Utils.h */,
 				04399AAB1D1C304300E99CD9 /* Utils.mm */,
-				02EFCAD01E0C3F6200FD8ED1 /* NotificationNames.mm */,
-				02EFCAD21E0C3F8200FD8ED1 /* NotificationNames.h */,
 			);
 			name = Bridging;
 			sourceTree = "<group>";
@@ -394,6 +393,7 @@
 		043999EA1D1C2D9D00E99CD9 = {
 			isa = PBXGroup;
 			children = (
+				0273C3001E0C445200CF00BA /* RingPrefixHeader.pch */,
 				04399A991D1C2F6400E99CD9 /* SYS_DEPS */,
 				04399A921D1C2E3600E99CD9 /* RING_DEPS */,
 				043999F51D1C2D9D00E99CD9 /* Ring */,
@@ -670,11 +670,11 @@
 				043866331D22CE8C00E06CE2 /* MeViewController.swift in Sources */,
 				04399AAE1D1C304300E99CD9 /* Utils.mm in Sources */,
 				02B22DFD1DF755BB000358C9 /* AccountViewModel.swift in Sources */,
-				02EFCAD11E0C3F6200FD8ED1 /* NotificationNames.mm in Sources */,
 				043999FA1D1C2D9D00E99CD9 /* Ring.xcdatamodeld in Sources */,
 				0438663B1D2313B700E06CE2 /* AccountDetailsViewController.swift in Sources */,
 				043866361D22D06500E06CE2 /* AccountTableViewCell.swift in Sources */,
 				04399AAD1D1C304300E99CD9 /* DRingAdapter.mm in Sources */,
+				0273C2FF1E0C438F00CF00BA /* AccountAdapterDelegate.swift in Sources */,
 				02B22DFF1DF755DB000358C9 /* AccountsService.swift in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
@@ -828,6 +828,8 @@
 				CODE_SIGN_IDENTITY = "iPhone Developer";
 				"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
 				DEVELOPMENT_TEAM = KM95526DS8;
+				GCC_PRECOMPILE_PREFIX_HEADER = YES;
+				GCC_PREFIX_HEADER = Ring/RingPrefixHeader.pch;
 				HEADER_SEARCH_PATHS = "$(SRCROOT)/../fat/include";
 				INFOPLIST_FILE = Ring/Info.plist;
 				IPHONEOS_DEPLOYMENT_TARGET = 9.3;
@@ -851,6 +853,8 @@
 				CODE_SIGN_IDENTITY = "iPhone Developer";
 				"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
 				DEVELOPMENT_TEAM = KM95526DS8;
+				GCC_PRECOMPILE_PREFIX_HEADER = YES;
+				GCC_PREFIX_HEADER = Ring/RingPrefixHeader.pch;
 				HEADER_SEARCH_PATHS = "$(SRCROOT)/../fat/include";
 				INFOPLIST_FILE = Ring/Info.plist;
 				IPHONEOS_DEPLOYMENT_TARGET = 9.3;
diff --git a/Ring/Ring/Bridging/AccountAdapter.h b/Ring/Ring/Bridging/AccountAdapter.h
index 75288c1..8bb44cd 100644
--- a/Ring/Ring/Bridging/AccountAdapter.h
+++ b/Ring/Ring/Bridging/AccountAdapter.h
@@ -21,11 +21,29 @@
 
 #import <Foundation/Foundation.h>
 
+/**
+ Forward declaration of the Swift delegate.
+ We have to do this because the Ring-Swift.h generated file can't be imported from a .h file.
+ The plain import is done in the .mm file.
+ */
+@protocol AccountAdapterDelegate;
+
+/**
+ Class making the bridge between the Ring Daemon and the application.
+ It only concerns "Accounts related" features.
+ Its responsabilities:
+ - register to daemon callbacks,
+ - forward callbacks to the application thanks to the integrated delegation pattern,
+ - forward instructions coming from the app to the daemon
+ */
 @interface AccountAdapter : NSObject
 
-+ (id)sharedManager;
+/**
+ Delegate where all the accounts events will be forwarded.
+ */
+@property (nonatomic, weak) id <AccountAdapterDelegate> delegate;
 
-- (void)registerConfigurationHandler;
++ (instancetype)sharedManager;
 
 - (NSDictionary *)getAccountDetails:(NSString *)accountID;
 
diff --git a/Ring/Ring/Bridging/AccountAdapter.mm b/Ring/Ring/Bridging/AccountAdapter.mm
index c229723..996635b 100644
--- a/Ring/Ring/Bridging/AccountAdapter.mm
+++ b/Ring/Ring/Bridging/AccountAdapter.mm
@@ -19,9 +19,10 @@
  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.
  */
 
+#import "Ring-Swift.h"
+
 #import "AccountAdapter.h"
 #import "Utils.h"
-#import "NotificationNames.h"
 
 #import "dring/configurationmanager_interface.h"
 
@@ -30,7 +31,7 @@
 using namespace DRing;
 
 #pragma mark Singleton Methods
-+ (id)sharedManager {
++ (instancetype)sharedManager {
     static AccountAdapter* sharedMyManager = nil;
     static dispatch_once_t onceToken;
     dispatch_once(&onceToken, ^{
@@ -47,13 +48,14 @@
 }
 #pragma mark -
 
-#pragma mark Callbacks
+#pragma mark Callbacks registration
 - (void)registerConfigurationHandler {
     std::map<std::string, std::shared_ptr<CallbackWrapperBase>> confHandlers;
     confHandlers.insert(exportable_callback<ConfigurationSignal::AccountsChanged>([&]() {
-        NSNotificationCenter* nc = [NSNotificationCenter defaultCenter];
-        [nc postNotificationName:kNotificationAccountsChanged
-                          object:[AccountAdapter sharedManager]];
+        //~ Using sharedManager to avoid as possible to retain self in the block.
+        if ([[AccountAdapter sharedManager] delegate]) {
+            [[[AccountAdapter sharedManager] delegate] accountsChanged];
+        }
     }));
     registerConfHandlers(confHandlers);
 }
diff --git a/Ring/Ring/Bridging/NotificationNames.h b/Ring/Ring/Bridging/NotificationNames.h
deleted file mode 100644
index 5228271..0000000
--- a/Ring/Ring/Bridging/NotificationNames.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- *  Copyright (C) 2016 Savoir-faire Linux Inc.
- *
- *  Author: Romain Bertozzi <romain.bertozzi@savoirfairelinux.com>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.
- */
-
-#ifndef NotificationNames_hpp
-#define NotificationNames_hpp
-
-#import <Foundation/Foundation.h>
-
-extern NSString * const kNotificationAccountsChanged;
-
-#endif /* NotificationNames_hpp */
diff --git a/Ring/Ring/Bridging/Ring-Bridging-Header.h b/Ring/Ring/Bridging/Ring-Bridging-Header.h
index 8f86a0a..834ccd1 100644
--- a/Ring/Ring/Bridging/Ring-Bridging-Header.h
+++ b/Ring/Ring/Bridging/Ring-Bridging-Header.h
@@ -24,4 +24,3 @@
  */
 #import "AccountAdapter.h"
 #import "DRingAdapter.h"
-#import "NotificationNames.h"
diff --git a/Ring/Ring/Bridging/NotificationNames.mm b/Ring/Ring/RingPrefixHeader.pch
similarity index 86%
copy from Ring/Ring/Bridging/NotificationNames.mm
copy to Ring/Ring/RingPrefixHeader.pch
index 1b5958a..016b63b 100644
--- a/Ring/Ring/Bridging/NotificationNames.mm
+++ b/Ring/Ring/RingPrefixHeader.pch
@@ -18,6 +18,10 @@
  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.
  */
 
-#include "NotificationNames.h"
+#ifndef RingPrefixHeader_pch
+#define RingPrefixHeader_pch
 
-NSString * const kNotificationAccountsChanged = @"AccountsChanged";
+#import <UIKit/UIKit.h>
+#import <Foundation/Foundation.h>
+
+#endif
diff --git a/Ring/Ring/Bridging/NotificationNames.mm b/Ring/Ring/Services/AccountAdapterDelegate.swift
similarity index 88%
rename from Ring/Ring/Bridging/NotificationNames.mm
rename to Ring/Ring/Services/AccountAdapterDelegate.swift
index 1b5958a..4e3905b 100644
--- a/Ring/Ring/Bridging/NotificationNames.mm
+++ b/Ring/Ring/Services/AccountAdapterDelegate.swift
@@ -18,6 +18,8 @@
  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.
  */
 
-#include "NotificationNames.h"
+@objc protocol AccountAdapterDelegate {
 
-NSString * const kNotificationAccountsChanged = @"AccountsChanged";
+    func accountsChanged()
+    
+}
diff --git a/Ring/Ring/Services/AccountsService.swift b/Ring/Ring/Services/AccountsService.swift
index 7c4122b..6dfd1f3 100644
--- a/Ring/Ring/Services/AccountsService.swift
+++ b/Ring/Ring/Services/AccountsService.swift
@@ -19,20 +19,27 @@
  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.
  */
 
-class AccountsService {
-    // MARK: - Properties
-    fileprivate let confAdapter = AccountAdapter.sharedManager() as AnyObject
+class AccountsService: AccountAdapterDelegate {
+    // MARK: Private members
+    /**
+     AccountConfigurationManagerAdaptator instance.
+     Used to register the service to daemon events.
+     */
+    fileprivate let confAdapter = AccountAdapter.sharedManager() as AccountAdapter
 
-    /// Fileprivate Accounts list.
-    ///
-    /// Can be used for all the operations, but won't be accessed from outside this file.
-    ///
-    /// - SeeAlso: `accounts`
+    /**
+     Fileprivate Accounts list.
+     Can be used for all the operations, but won't be accessed from outside this file.
+
+     - SeeAlso: `accounts`
+     */
     fileprivate var accountList: Array<AccountModel>
 
-    /// Accounts list public interface
-    ///
-    /// Can be used to access by constant the list of accounts.
+    // MARK: - Public members
+    /**
+     Accounts list public interface.
+     Can be used to access by constant the list of accounts.
+     */
     fileprivate(set) var accounts: Array<AccountModel> {
         set {
             accountList = newValue
@@ -49,12 +56,9 @@
     fileprivate init() {
         accountList = []
 
-        NotificationCenter.default.addObserver(forName: NSNotification.Name(rawValue: kNotificationAccountsChanged),
-                                               object: nil,
-                                               queue: nil,
-                                               using: { _ in
-                                                self.reload()
-        })
+        //~ Registering to the AccountConfigurationManagerAdaptator with self as delegate in order
+        //~ to receive delegation callbacks.
+        confAdapter.delegate = self
     }
 
     // MARK: - Methods
@@ -89,4 +93,9 @@
             confAdapter.removeAccount(accountList[row].id)
         }
     }
+
+    // MARK: - AccountAdapterDelegate
+    func accountsChanged() {
+        print("Accounts changed.")
+    }
 }