Skip to content

Commit

Permalink
Release 2.0.0
Browse files Browse the repository at this point in the history
* Release 2.0.0

* update umbrella import

* update example project code & switch release version to branch while we re-work the release process

* add background uploading capability and streamline some of the Example app code

* update readme, as we no longer should need any netrc stuff for using the SDK

---------

Co-authored-by: Anka <[email protected]>
  • Loading branch information
alrikai and Anka authored Nov 1, 2024
1 parent 99605c4 commit fd47190
Show file tree
Hide file tree
Showing 39 changed files with 619 additions and 490 deletions.
8 changes: 6 additions & 2 deletions Example/Example.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
/* End PBXBuildFile section */

/* Begin PBXFileReference section */
0A878E652CD4A4E4008FAE00 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = Info.plist; sourceTree = "<group>"; };
B4C6AE8F2AF546B200A68766 /* Example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Example.app; sourceTree = BUILT_PRODUCTS_DIR; };
B4C6AE922AF546B200A68766 /* ExampleApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExampleApp.swift; sourceTree = "<group>"; };
B4C6AE942AF546B200A68766 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -57,6 +58,7 @@
B4C6AE912AF546B200A68766 /* Example */ = {
isa = PBXGroup;
children = (
0A878E652CD4A4E4008FAE00 /* Info.plist */,
B4C6AE922AF546B200A68766 /* ExampleApp.swift */,
B4C6AE942AF546B200A68766 /* ContentView.swift */,
B4C6AE962AF546B300A68766 /* Assets.xcassets */,
Expand Down Expand Up @@ -293,6 +295,7 @@
ENABLE_HARDENED_RUNTIME = YES;
ENABLE_PREVIEWS = YES;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = Example/Info.plist;
INFOPLIST_KEY_NSCameraUsageDescription = "To capture photos of your property";
"INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphoneos*]" = YES;
"INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphonesimulator*]" = YES;
Expand Down Expand Up @@ -332,6 +335,7 @@
ENABLE_HARDENED_RUNTIME = YES;
ENABLE_PREVIEWS = YES;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = Example/Info.plist;
INFOPLIST_KEY_NSCameraUsageDescription = "To capture photos of your property";
"INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphoneos*]" = YES;
"INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphonesimulator*]" = YES;
Expand Down Expand Up @@ -386,8 +390,8 @@
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/hoverinc/hover-capture-ios.git";
requirement = {
kind = upToNextMajorVersion;
minimumVersion = 0.1.1;
branch = release/2.0.0;
kind = branch;
};
};
/* End XCRemoteSwiftPackageReference section */
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
{
"originHash" : "c8f3ebc6a23f3c1e8a73f3e85b85901f9db883bb57585cf587f6108a424a2640",
"pins" : [
{
"identity" : "hover-capture-ios",
"kind" : "remoteSourceControl",
"location" : "https://github.com/hoverinc/hover-capture-ios.git",
"state" : {
"revision" : "a2fd119de617dc69d93af4f4ddcff95d74763583",
"version" : "0.1.1"
"branch" : "release/2.0.0",
"revision" : "4b0a5942180f6f9e50a409001f5352fff5985055"
}
}
],
"version" : 2
"version" : 3
}
33 changes: 20 additions & 13 deletions Example/Example/ContentView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,21 +13,28 @@ struct ContentView: View {
VStack {
Button("Start Flow") {
Task {
try await HVCameraExterior.sharedInstance.startCaptureSession(
settings: HVCameraSettings(),
info: CaptureJobInformation(
firstTimeUser: true,
jobID: 12345,
clientIdentifier: "DEADBEEF_DEAD_BEEF_DEAD_BEEFDEADBEEF",
uploadSecret: "DEADBEEF_DEAD_BEEF_DEAD_BEEFDEADBEEF"
)
)
let jobInfo = CaptureJobInformation(
firstTimeUser: true,
identifier: JobIdentifier(
jobID: 123
),
uploadSecret: "DEADBEEF_DEAD_BEEF_DEAD_BEEFDEADBEEF")
let sessionSettings = HVCameraSettings()

do {
_ = try await HVPartnerSDK.sharedInstance.startCaptureSession(
settings: sessionSettings,
info: jobInfo)
try await HVPartnerSDK.sharedInstance.startCaptureFlow()
} catch let error as HVSessionError {
print("Known capture flow error: \(error.localizedDescription)")
} catch {
print("Unknown Capture Flow Error: \(error.localizedDescription)")

}
}
}
}
.padding()
.onAppear {
HVCameraExterior.sharedInstance.initialize()
.padding()
}
}
}
Expand Down
48 changes: 48 additions & 0 deletions Example/Example/ExampleApp.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,60 @@
//

import SwiftUI
import HVCaptureSDK
import BackgroundTasks

@main
struct ExampleApp: App {

let uploadTaskIdentifier = "to.hover.uploads"

init() {
// NOTE: to allow the SDK to handle its own background uploads, uncomment this line
// and comment out the `registerBackgroundTask` line.
//HVPartnerSDK.sharedInstance.registerForBackgroundJobs()
HVPartnerSDK.sharedInstance.initialize()

registerBackgroundTask()
}

var body: some Scene {
WindowGroup {
ContentView()
}
}
}

extension ExampleApp {
/// Example of how we can manually trigger the SDK to perform background uploads
func registerBackgroundTask() {
// set up background tasks for scheduling HVCaptureSDK uploads, if applicable
BGTaskScheduler.shared.register(forTaskWithIdentifier: uploadTaskIdentifier, using: nil) { task in
self.uploadCaptureDataInBackground(task: task as! BGProcessingTask)
}

// schedule the background task to be executed
let request = BGProcessingTaskRequest(identifier: uploadTaskIdentifier)
request.requiresNetworkConnectivity = true
request.requiresExternalPower = false
try? BGTaskScheduler.shared.submit(request)
}

func uploadCaptureDataInBackground(task: BGProcessingTask) {
let processingTask = Task {
do {
// set up HVPartnerSDK for background uploading (on wifi only)
// NOTE: can configure whether to upload on wifi only (`true`) vs. wifi + cellular (`false`)
try await HVPartnerSDK.sharedInstance.initializeForBackground(parameters: .init(
uploadOnWiFiOnly: true))
task.setTaskCompleted(success: true)
} catch {
task.setTaskCompleted(success: false)
}
}

task.expirationHandler = {
processingTask.cancel()
}
}
}
30 changes: 15 additions & 15 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ let package = Package(
name: "HVCaptureSDK",
dependencies: [
"ObjcExceptionBridging",
"_HoverSDK",
"_HVAVCamera",
"_HVCameraExterior",
"_HVCore",
"_HVCVPixelBufferHelper",
"_XCGLogger",
Expand All @@ -32,33 +32,33 @@ let package = Package(

.binaryTarget(
name: "ObjcExceptionBridging",
url: "https://api.github.com/repos/hoverinc/hover-capture-ios/releases/assets/179081155.zip",
checksum: "9a7b6d95fb1c5a2fcbe812dfec2dacdac564cc5eb035fed849994b7ae7798ebd"
url: "https://api.github.com/repos/hoverinc/hover-capture-ios/releases/assets/203311933.zip",
checksum: "5fa8986aa63f860c681eefece027e919ccdf02e80f4da4a66e701a561cad4e73"
),
.binaryTarget(
name: "_HVAVCamera",
url: "https://api.github.com/repos/hoverinc/hover-capture-ios/releases/assets/179081156.zip",
checksum: "fcbcd6a0359bb95ce70ebd6ed151c7b9fef86bc115f68770d061c570d6ec26f9"
name: "_HoverSDK",
url: "https://api.github.com/repos/hoverinc/hover-capture-ios/releases/assets/203311994.zip",
checksum: "c4ae23a5ebb048c40b346f41d5757ba24b50980f017b8a1ff27f35902ef4ef40"
),
.binaryTarget(
name: "_HVCameraExterior",
url: "https://api.github.com/repos/hoverinc/hover-capture-ios/releases/assets/179081164.zip",
checksum: "391966af56f124238dd8aaab383f2ce286a3821ef264636cf37c9545c3d0c586"
name: "_HVAVCamera",
url: "https://api.github.com/repos/hoverinc/hover-capture-ios/releases/assets/203311934.zip",
checksum: "2355881d8b1b50a0cec6d7480f3a10db5994abaef5bca0a4c6a52bc56b586660"
),
.binaryTarget(
name: "_HVCore",
url: "https://api.github.com/repos/hoverinc/hover-capture-ios/releases/assets/179081167.zip",
checksum: "096e8fdb1a1ecf01c6fd0a2133a7bc5516043dc670bdc8a81af66e9e7a0855c3"
url: "https://api.github.com/repos/hoverinc/hover-capture-ios/releases/assets/203311990.zip",
checksum: "44152baf504ab9872a357f298ef3e38f0c482de19d11a0effcfcf9f11ca96093"
),
.binaryTarget(
name: "_HVCVPixelBufferHelper",
url: "https://api.github.com/repos/hoverinc/hover-capture-ios/releases/assets/179081161.zip",
checksum: "59d089565ef612213ac325fd2ae7e0dad2a3a010be7613bba24a7a86ad435e7b"
url: "https://api.github.com/repos/hoverinc/hover-capture-ios/releases/assets/203311987.zip",
checksum: "838cfb39bbd2bdc66e5298e1dfa6b624fb7275ce1d7c5fc94bb717cf35efab1b"
),
.binaryTarget(
name: "_XCGLogger",
url: "https://api.github.com/repos/hoverinc/hover-capture-ios/releases/assets/179081168.zip",
checksum: "95110df7e425f8a770cf5b7192605917b1ed352dee0c5166ba3df7f3406f9d72"
url: "https://api.github.com/repos/hoverinc/hover-capture-ios/releases/assets/203311996.zip",
checksum: "2b774d6d83aa1ee5205fd169a22d5fd6e5340b050e06c52227a503b3298e1a5f"
),
]
)
59 changes: 9 additions & 50 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,54 +17,49 @@ The HOVER Capture iOS SDK provides a user flow for capturing and submitting 3D s

The HOVER Capture iOS SDK is distributed using Swift Package Manager. You may integrate it using Xcode or a `Package.swift` file.

> [!TIP]
> Swift Package Manager requires a properly configured `.netrc` file to download binary assets from the private repository. Please see [Authenticating with .netrc](#authenticating-with-netrc) below for instructions on how to properly configure this.
<details>
<summary>Xcode</summary>

To integrate the SDK using Xcode, perform the following steps:

1. In the Xcode Project Navigator pane (on the left side), select your project.
2. Select your project under the PROJECT heading on the left-side panel
3. Select the Package Dependencies tab on the top
4. Click the + button under the Packages list.
5. In the "Search or Enter Package URL" search bar, enter the repository url (`https://github.com/hoverinc/hover-capture-ios.git`)
- We recommend using https to mitigate some bumps with github authentication.
6. Click "Add Package"
7. Select a target to add the `HVCaptureSDK` library.

</details>

<details>
<summary>Package.swift</summary>

To integrate the SDK into a Swift package, add the following line to your `dependencies` array in your `Package.swift` manifest:

```swift
.package(url: "https://github.com/hoverinc/hover-capture-ios.git", from: "0.1.1")
.package(url: "https://github.com/hoverinc/hover-capture-ios.git", from: "2.0.0")
```

</details>

## Usage

> [!CAUTION]
> APIs are non-final and considered unstable.
The `Example` app in the repository provides a minimal example of how to integrate the SDK into an application. Additionally, the [Getting Stated](https://hoverinc.github.io/hover-capture-ios/documentation/hvcapturesdk/gettingstarted) guide and [Tutorials](https://hoverinc.github.io/hover-capture-ios/tutorials/tutorials/) have more comprehensive and up-to-date documentation regartding SDK usage, customization and integration.

### Initializing the SDK

The SDK should be initialized as early as possible in the app lifecycle. This is because the SDK does some background work to set up required structures and upload any remaining captured data from past jobs that have yet to complete.
As such, the SDK should (ideally) be initialized in host application’s `applicationDidFinishLaunching` method, so that the SDK can continue uploading any files that remain to be uploaded. This helps expedite 3D model generation, as we need all the captured images and metadata to begin the 3D reconstruction process.

```swift
import HVCamera
import HVCaptureSDK
class AppDelegate: UIResponder, UIApplicationDelegate {
// ...

@MainActor
private func applicationDidFinishLaunching(_ notification: Notification) {
HVCameraExterior.sharedInstance.initialize()
HVPartnerSDK.sharedInstance.initialize()
}
}
```
Expand All @@ -74,7 +69,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
The host app can launch the SDK in any way it sees fit, as long as there is an active ViewController somewhere in the app. Here is one example using SwiftUI of launching the SDK capture flow on a button click:

```swift
import HVCamera
import HVCaptureSDK
import SwiftUI

struct FooView: View {
Expand All @@ -87,7 +82,7 @@ struct FooView: View {
Button("Start Capture") {
let captureTask = Task {
do {
try await HVCameraExterior.sharedInstance.startCaptureSession(settings: sessionSettings, info: jobInfo)
try await HVPartnerSDK.sharedInstance.startCaptureSession(settings: sessionSettings, info: jobInfo)
} catch let error as HVSessionError {
// maybe handle our known errors here
switch error.kind {
Expand Down Expand Up @@ -127,7 +122,7 @@ Since we execute asynchronously, within a Swift ``Task``, we also honor its canc
```swift
let captureTask = Task {
do {
try await HVCameraExterior.sharedInstance.startCaptureSession(settings: sessionSettings, info: jobInfo)
try await HVPartnerSDK.sharedInstance.startCaptureSession(settings: sessionSettings, info: jobInfo)
} catch let error as HVSessionError {
switch error.kind {
case .UserCancelled:
Expand All @@ -141,39 +136,3 @@ DispatchQueue.main.asyncAfter(deadline: .now() + 10, execute: {
captureTask.cancel()
})
```

## Troubleshooting

### Authenticating with `.netrc`

The SDK wraps a number of sub-frameworks into one tidy package to simplify distribution and integration. However, to avoid checking these binaries into the repository, we host them as artifacts within the associated Github Release. To meet Swift Package Manager's security requirements, we must use Github's API to download these binary assets, and thus authenticate with the Github API using `netrc` to authorize the download.

Your `netrc` file should look something like this:

```
machine api.github.com
login schrismartin
password ghp_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
```

- `machine` – This will be `api.github.com`, as SPM will attempt to download the binary frameworks via Github's API
- `login` – This will be your Github username, omitting any `@domain.com` suffix.
- `password` – This will be a [Github Personal Access Token](#github-personal-access-token)

After making any modifications to this file, you will want to restart Xcode for the changes to take effect. You may need to reset package caches if you continue to see errors.

> [!NOTE]
> An incorrect configuration of this file will result in an `badResponseStatusCode(404)` error when attempting to download a framework binary. While a 404 typically indicates that a resources doesn't exist, in this case, it means it doesn't exist _for you_. If your `.netrc` file is correctly configured and you're still seeing this issue, please review the scopes for your configured Github PAT.
### Github Personal Access Tokens:

Both Xcode and the `.netrc` file will need access to Github in order to seamlessly download the requirements to build & run the SDK. The associated Github Personal Access Token (PAT) will need to be configured as below.

1. Make sure you’re signed into Github for the account that you need to authenticate
2. Navigate to Settings → Developer Settings → Personal Access Tokens
3. Click “Generate new token” → “Generate new token (classic)”
4. Generate a new token that contains at least the following scopes
- `admin:public_key`
- `write:discussion`
- `repo`
- `user`
2 changes: 1 addition & 1 deletion Sources/HVCaptureSDK/HVCaptureSDK.docc/CaptureSDK.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# ``_HVCameraExterior``
# ``_HoverSDK``

The HOVER capture experience

Expand Down
Loading

0 comments on commit fd47190

Please sign in to comment.