Skip to content

Commit

Permalink
- Changed Config Manager to explicitly post notification when value c…
Browse files Browse the repository at this point in the history
…hanged

- Remove unused imports
- Fix unit tests
  • Loading branch information
khanhlvg committed Aug 24, 2023
1 parent dc277d8 commit e6cf223
Show file tree
Hide file tree
Showing 11 changed files with 63 additions and 129 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,14 @@

/* Begin PBXBuildFile section */
39A04804C8101D2C0D58D927 /* libPods-ObjectDetectorTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = BF80BB442A677B6C005E93B1 /* libPods-ObjectDetectorTests.a */; };
7F2ED5E52A97CEFD0044C53E /* coupleanddog.jpeg in Resources */ = {isa = PBXBuildFile; fileRef = BFCF18232A41476D00D64FA6 /* coupleanddog.jpeg */; };
7F7641A62A74803D00DDCE4E /* download_models.sh in Resources */ = {isa = PBXBuildFile; fileRef = 7F7641A52A74803D00DDCE4E /* download_models.sh */; };
9E41A7603AB8BE3B86C06DB9 /* Pods_ObjectDetector.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C3FBCABF9DABD56A270978F4 /* Pods_ObjectDetector.framework */; };
AAF981DB2A80D27500C7121A /* CameraViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAF981DA2A80D27500C7121A /* CameraViewController.swift */; };
AAF981DD2A80D28B00C7121A /* MediaLibraryViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAF981DC2A80D28B00C7121A /* MediaLibraryViewController.swift */; };
AAF981DF2A81330700C7121A /* InferenceConfigManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAF981DE2A81330700C7121A /* InferenceConfigManager.swift */; };
AAF981E52A85156500C7121A /* DefaultConstants.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAF981E42A85156500C7121A /* DefaultConstants.swift */; };
BF2B2D2F2A3C09E200589A11 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF2B2D2E2A3C09E200589A11 /* AppDelegate.swift */; };
BF2B2D312A3C09E200589A11 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF2B2D302A3C09E200589A11 /* SceneDelegate.swift */; };
BF2B2D332A3C09E200589A11 /* RootViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF2B2D322A3C09E200589A11 /* RootViewController.swift */; };
BF2B2D362A3C09E200589A11 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = BF2B2D342A3C09E200589A11 /* Main.storyboard */; };
BF2B2D382A3C09E300589A11 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = BF2B2D372A3C09E300589A11 /* Assets.xcassets */; };
Expand All @@ -27,7 +27,6 @@
BFCF181A2A405D3600D64FA6 /* OverlayView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFCF18192A405D3600D64FA6 /* OverlayView.swift */; };
BFCF18202A405F4300D64FA6 /* efficientdet_lite0.tflite in Resources */ = {isa = PBXBuildFile; fileRef = BFCF181E2A405F4300D64FA6 /* efficientdet_lite0.tflite */; };
BFCF18222A4066C900D64FA6 /* efficientdet_lite2.tflite in Resources */ = {isa = PBXBuildFile; fileRef = BFCF18212A40663700D64FA6 /* efficientdet_lite2.tflite */; };
BFCF18242A41476D00D64FA6 /* coupleanddog.jpeg in Resources */ = {isa = PBXBuildFile; fileRef = BFCF18232A41476D00D64FA6 /* coupleanddog.jpeg */; };
/* End PBXBuildFile section */

/* Begin PBXContainerItemProxy section */
Expand All @@ -51,7 +50,6 @@
AAF981E42A85156500C7121A /* DefaultConstants.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DefaultConstants.swift; sourceTree = "<group>"; };
BF2B2D2B2A3C09E200589A11 /* ObjectDetector.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ObjectDetector.app; sourceTree = BUILT_PRODUCTS_DIR; };
BF2B2D2E2A3C09E200589A11 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
BF2B2D302A3C09E200589A11 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = "<group>"; };
BF2B2D322A3C09E200589A11 /* RootViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RootViewController.swift; sourceTree = "<group>"; };
BF2B2D352A3C09E200589A11 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
BF2B2D372A3C09E300589A11 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
Expand Down Expand Up @@ -181,11 +179,9 @@
BF2B2D672A3C0C3F00589A11 /* ViewControllers */,
7F7641A42A74803D00DDCE4E /* RunScripts */,
BF2B2D2E2A3C09E200589A11 /* AppDelegate.swift */,
BF2B2D302A3C09E200589A11 /* SceneDelegate.swift */,
BF2B2D342A3C09E200589A11 /* Main.storyboard */,
BF2B2D372A3C09E300589A11 /* Assets.xcassets */,
BF2B2D392A3C09E300589A11 /* LaunchScreen.storyboard */,
BFCF18232A41476D00D64FA6 /* coupleanddog.jpeg */,
BF2B2D3C2A3C09E300589A11 /* Info.plist */,
BFCF181E2A405F4300D64FA6 /* efficientdet_lite0.tflite */,
BFCF18212A40663700D64FA6 /* efficientdet_lite2.tflite */,
Expand All @@ -196,6 +192,7 @@
BF2B2D442A3C09E300589A11 /* ObjectDetectorTests */ = {
isa = PBXGroup;
children = (
BFCF18232A41476D00D64FA6 /* coupleanddog.jpeg */,
BF2B2D452A3C09E300589A11 /* ObjectDetectorTests.swift */,
);
path = ObjectDetectorTests;
Expand Down Expand Up @@ -309,7 +306,6 @@
BF2B2D3B2A3C09E300589A11 /* LaunchScreen.storyboard in Resources */,
BF2B2D382A3C09E300589A11 /* Assets.xcassets in Resources */,
BF2B2D362A3C09E200589A11 /* Main.storyboard in Resources */,
BFCF18242A41476D00D64FA6 /* coupleanddog.jpeg in Resources */,
7F7641A62A74803D00DDCE4E /* download_models.sh in Resources */,
BFCF18202A405F4300D64FA6 /* efficientdet_lite0.tflite in Resources */,
);
Expand All @@ -319,6 +315,7 @@
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
7F2ED5E52A97CEFD0044C53E /* coupleanddog.jpeg in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down Expand Up @@ -349,6 +346,7 @@
};
7F7641A12A747F5D00DDCE4E /* Download models */ = {
isa = PBXShellScriptBuildPhase;
alwaysOutOfDate = 1;
buildActionMask = 2147483647;
files = (
);
Expand Down Expand Up @@ -403,7 +401,6 @@
BF2B2D2F2A3C09E200589A11 /* AppDelegate.swift in Sources */,
BF2B2D6D2A3C0EF900589A11 /* ObjectDetectorService.swift in Sources */,
AAF981DD2A80D28B00C7121A /* MediaLibraryViewController.swift in Sources */,
BF2B2D312A3C09E200589A11 /* SceneDelegate.swift in Sources */,
AAF981DB2A80D27500C7121A /* CameraViewController.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,6 @@ import UIKit
@main
class AppDelegate: UIResponder, UIApplicationDelegate {



func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
return true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ struct DefaultConstants {
}

// MARK: Model
@objc enum Model: Int, CaseIterable {
enum Model: Int, CaseIterable {
case efficientdetLite0
case efficientdetLite2

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,28 @@ import Foundation

/**
* Singleton storing the configs needed to initialize an MediaPipe Tasks object and run inference.
* Properties are key value observable. Controllers simply need to observe these properties for any changes made by the user.
* Controllers can observe the `InferenceConfigManager.notificationName` for any changes made by the user.
*/
@objc class InferenceConfigManager: NSObject {
@objc dynamic var model: Model = DefaultConstants.model
class InferenceConfigManager: NSObject {
var model: Model = DefaultConstants.model {
didSet { postConfigChangedNotification() }
}

@objc dynamic var maxResults: Int = DefaultConstants.maxResults
var maxResults: Int = DefaultConstants.maxResults {
didSet { postConfigChangedNotification() }
}

@objc dynamic var scoreThreshold: Float = DefaultConstants.scoreThreshold
var scoreThreshold: Float = DefaultConstants.scoreThreshold {
didSet { postConfigChangedNotification() }
}

static let sharedInstance = InferenceConfigManager()

private override init() {

static let notificationName = Notification.Name.init(rawValue: "com.google.mediapipe.inferenceConfigChanged")

private func postConfigChangedNotification() {
NotificationCenter.default
.post(name: InferenceConfigManager.notificationName, object: nil)
}

}
59 changes: 0 additions & 59 deletions examples/object_detection/ios/ObjectDetector/SceneDelegate.swift

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
// limitations under the License.

import UIKit
import MediaPipeTasksVision

protocol InferenceViewControllerDelegate: AnyObject {
/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,9 @@
// See the License for the specific language governing permissions and
// limitations under the License.

import UIKit
import AVFoundation
import CoreMedia

import MediaPipeTasksVision
import UIKit

/**
* The view controller is responsible for performing detection on incoming frames from the live camera and presenting the frames with the
Expand All @@ -36,7 +34,7 @@ class CameraViewController: UIViewController {
@IBOutlet weak var overlayView: OverlayView!

private var isSessionRunning = false
private var isObserver = false
private var isObserving = false
private let backgroundQueue = DispatchQueue(label: "com.google.mediapipe.cameraController.backgroundQueue")

// MARK: Controllers that manage functionality
Expand Down Expand Up @@ -152,10 +150,10 @@ class CameraViewController: UIViewController {

private func initializeObjectDetectorServiceOnSessionResumption() {
clearAndInitializeObjectDetectorService()
addConfigManagerKeyValueObservers()
startObserveConfigChanges()
}

private func clearAndInitializeObjectDetectorService() {
@objc private func clearAndInitializeObjectDetectorService() {
objectDetectorService = nil
objectDetectorService = ObjectDetectorService
.liveStreamDetectorService(
Expand All @@ -166,36 +164,27 @@ class CameraViewController: UIViewController {
}

private func clearObjectDetectorServiceOnSessionInterruption() {
removeConfigManagerKeyValueObservers()
stopObserveConfigChanges()
objectDetectorService = nil
}

private func addConfigManagerKeyValueObservers() {
InferenceConfigManager.sharedInstance.addObserver(
self,
forKeyPath: (#keyPath(InferenceConfigManager.maxResults)),
options: [.new],
context: nil)
InferenceConfigManager.sharedInstance.addObserver(
self,
forKeyPath: (#keyPath(InferenceConfigManager.scoreThreshold)),
options: [.new],
context: nil)
InferenceConfigManager.sharedInstance.addObserver(
self,
forKeyPath: (#keyPath(InferenceConfigManager.model)),
options: [.new],
context: nil)
isObserver = true
private func startObserveConfigChanges() {
NotificationCenter.default
.addObserver(self,
selector: #selector(clearAndInitializeObjectDetectorService),
name: InferenceConfigManager.notificationName,
object: nil)
isObserving = true
}

private func removeConfigManagerKeyValueObservers() {
if isObserver {
InferenceConfigManager.sharedInstance.removeObserver(self, forKeyPath: #keyPath(InferenceConfigManager.maxResults))
InferenceConfigManager.sharedInstance.removeObserver(self, forKeyPath: #keyPath(InferenceConfigManager.scoreThreshold))
InferenceConfigManager.sharedInstance.removeObserver(self, forKeyPath: #keyPath(InferenceConfigManager.model))
private func stopObserveConfigChanges() {
if isObserving {
NotificationCenter.default
.removeObserver(self,
name:InferenceConfigManager.notificationName,
object: nil)
}
isObserver = false
isObserving = false
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,9 @@
// See the License for the specific language governing permissions and
// limitations under the License.

import UIKit
import UniformTypeIdentifiers
import AVKit
import MediaPipeTasksVision
import UIKit

/**
* The view controller is responsible for performing detection on videos or images selected by the user from the device media library and
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,6 @@
// limitations under the License.

import UIKit
import MediaPipeTasksVision
import UniformTypeIdentifiers
import AVKit


protocol InferenceResultDeliveryDelegate: AnyObject {
func didPerformInference(result: ResultBundle?)
Expand Down
Loading

0 comments on commit e6cf223

Please sign in to comment.