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

Add iOS linter & report issues on PR #634

Merged
merged 3 commits into from
Apr 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
name: Build
run-name: ⚙️ Build examples on ${{ github.event_name == 'pull_request' && 'PR' || '🌱' }} ${{ github.event_name == 'pull_request' && github.event.number || github.ref_name }}

on:
pull_request:
types: [opened, reopened]
push:
branches:
- main
pull_request:
types: [opened, synchronize, reopened]

jobs:
build-example-ios:
name: build-example-ios
Expand Down
35 changes: 33 additions & 2 deletions .github/workflows/linter.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
name: Linter
run-name: 🩺 Code checks on ${{ github.event_name == 'pull_request' && 'PR' || '🌱' }} ${{ github.event_name == 'pull_request' && github.event.number || github.ref_name }}

on:
pull_request:
types: [opened, reopened]
push:
branches:
- main
pull_request:
types: [opened, synchronize, reopened]

jobs:
eslint:
name: ESLint
Expand All @@ -16,3 +21,29 @@ jobs:
run: yarn bootstrap-linux
- name: Lint
run: yarn lint

ios:
name: Lint iOS
runs-on: macos-latest

steps:
- name: Checkout
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Install dependencies
run: brew bundle
- name: Run swiftlint
run: |
if [[ "${{ github.event_name }}" == "pull_request" ]]; then
updatedFiles=$(git --no-pager diff --name-only --diff-filter=ACMRT ${{ github.event.pull_request.base.sha }} ${{ github.event.pull_request.head.sha }} -- '*.swift')

if [[ -z "$updatedFiles" ]]; then
echo "No Swift files changed, skipping linting"
exit 0
fi

swiftlint --reporter github-actions-logging -- $updatedFiles
else
swiftlint
fi
21 changes: 21 additions & 0 deletions .swiftlint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
included:
- ios
- example/ios

excluded:
- ios/Pods
- example/ios/Pods

disabled_rules:
- todo

line_length: 160
type_body_length: 400
function_body_length: 50

identifier_name:
excluded:
- on
- x
- y
- at
2 changes: 2 additions & 0 deletions Brewfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
brew 'swiftlint'

62 changes: 62 additions & 0 deletions Brewfile.lock.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
{
"entries": {
"brew": {
"swiftlint": {
"version": "0.53.0",
"bottle": {
"rebuild": 0,
"root_url": "https://ghcr.io/v2/homebrew/core",
"files": {
"arm64_sonoma": {
"cellar": ":any_skip_relocation",
"url": "https://ghcr.io/v2/homebrew/core/swiftlint/blobs/sha256:240ccda9de55d948d0c635798079074099bfcb73ffda41428900fdc748aeea7b",
"sha256": "240ccda9de55d948d0c635798079074099bfcb73ffda41428900fdc748aeea7b"
},
"arm64_ventura": {
"cellar": ":any_skip_relocation",
"url": "https://ghcr.io/v2/homebrew/core/swiftlint/blobs/sha256:7b7ceb7896c6833965cc4eac9001255d8adde6c5432045d5a8ab6aea8a9e81d9",
"sha256": "7b7ceb7896c6833965cc4eac9001255d8adde6c5432045d5a8ab6aea8a9e81d9"
},
"arm64_monterey": {
"cellar": ":any_skip_relocation",
"url": "https://ghcr.io/v2/homebrew/core/swiftlint/blobs/sha256:78c2a4c3f4a2f6847b484527b0f0f916da71e3ee29e49890fd44b63fe7b38e26",
"sha256": "78c2a4c3f4a2f6847b484527b0f0f916da71e3ee29e49890fd44b63fe7b38e26"
},
"sonoma": {
"cellar": ":any_skip_relocation",
"url": "https://ghcr.io/v2/homebrew/core/swiftlint/blobs/sha256:abdca78dd8a8bd268053b3be195fe891bb74aef5502ab3a6b871ae0c6bb04540",
"sha256": "abdca78dd8a8bd268053b3be195fe891bb74aef5502ab3a6b871ae0c6bb04540"
},
"ventura": {
"cellar": ":any_skip_relocation",
"url": "https://ghcr.io/v2/homebrew/core/swiftlint/blobs/sha256:be711c707bf3b49fa0dd6e2ae576b309aad620f9b56a2c6e7b1ac5cf35cf652a",
"sha256": "be711c707bf3b49fa0dd6e2ae576b309aad620f9b56a2c6e7b1ac5cf35cf652a"
},
"monterey": {
"cellar": ":any_skip_relocation",
"url": "https://ghcr.io/v2/homebrew/core/swiftlint/blobs/sha256:13487d68a971dbe035019364e19d70641af2a18c06e52925d238685b384a7979",
"sha256": "13487d68a971dbe035019364e19d70641af2a18c06e52925d238685b384a7979"
},
"x86_64_linux": {
"cellar": "/home/linuxbrew/.linuxbrew/Cellar",
"url": "https://ghcr.io/v2/homebrew/core/swiftlint/blobs/sha256:fbbc56fccfcfcd34564feb7325567e2ff3638d3c609396a5c4aa13311c7b26e0",
"sha256": "fbbc56fccfcfcd34564feb7325567e2ff3638d3c609396a5c4aa13311c7b26e0"
}
}
}
}
}
},
"system": {
"macos": {
"sonoma": {
"HOMEBREW_VERSION": "4.2.0-54-g0b804d4",
"HOMEBREW_PREFIX": "/opt/homebrew",
"Homebrew/homebrew-core": "api",
"CLT": "15.1.0.0.1.1700200546",
"Xcode": "15.0",
"macOS": "14.1"
}
}
}
}
7 changes: 3 additions & 4 deletions ios/ReactNativeCameraKit/CameraManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,11 @@ import Foundation
resolve: @escaping RCTPromiseResolveBlock,
reject: @escaping RCTPromiseRejectBlock) {
guard let cam = self.camera else {
reject("capture_error", "CKCamera capture() was called but camera view is nil", nil)
reject("capture_error", "CKCamera capture() was called but camera view is nil", nil)
return
}
cam.capture(options as! [String: Any],
onSuccess: { resolve($0) },
onError: { reject("capture_error", $0, nil) })
cam.capture(onSuccess: { resolve($0) },
onError: { reject("capture_error", $0, nil) })
}

@objc func checkDeviceCameraAuthorizationStatus(_ resolve: @escaping RCTPromiseResolveBlock,
Expand Down
4 changes: 2 additions & 2 deletions ios/ReactNativeCameraKit/CameraProtocol.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,6 @@ protocol CameraProtocol: AnyObject, FocusInterfaceViewDelegate {
func update(scannerFrameSize: CGRect?)

func capturePicture(onWillCapture: @escaping () -> Void,
onSuccess: @escaping (_ imageData: Data, _ thumbnailData: Data?, _ dimensions: CMVideoDimensions) -> (),
onError: @escaping (_ message: String) -> ())
onSuccess: @escaping (_ imageData: Data, _ thumbnailData: Data?, _ dimensions: CMVideoDimensions) -> Void,
onError: @escaping (_ message: String) -> Void)
}
29 changes: 14 additions & 15 deletions ios/ReactNativeCameraKit/CameraView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ class CameraView: UIView {
}

private func setupCamera() {
if (hasPropBeenSetup && hasPermissionBeenGranted && !hasCameraBeenSetup) {
if hasPropBeenSetup && hasPermissionBeenGranted && !hasCameraBeenSetup {
hasCameraBeenSetup = true
camera.setup(cameraType: cameraType, supportedBarcodeType: scanBarcode && onReadCode != nil ? supportedBarcodeType : [])
}
Expand Down Expand Up @@ -141,6 +141,7 @@ class CameraView: UIView {
}

// Called once when all props have been set, then every time one is updated
// swiftlint:disable:next cyclomatic_complexity function_body_length
override func didSetProps(_ changedProps: [String]) {
hasPropBeenSetup = true

Expand All @@ -154,11 +155,11 @@ class CameraView: UIView {
if changedProps.contains("cameraType") || changedProps.contains("torchMode") {
camera.update(torchMode: torchMode)
}

if changedProps.contains("onOrientationChange") {
camera.update(onOrientationChange: onOrientationChange)
}

if changedProps.contains("onZoom") {
camera.update(onZoom: onZoom)
}
Expand Down Expand Up @@ -219,21 +220,20 @@ class CameraView: UIView {
if changedProps.contains("zoomMode") {
self.update(zoomMode: zoomMode)
}

if changedProps.contains("zoom") {
camera.update(zoom: zoom?.doubleValue)
}

if changedProps.contains("maxZoom") {
camera.update(maxZoom: maxZoom?.doubleValue)
}
}

// MARK: Public

func capture(_ options: [String: Any],
onSuccess: @escaping (_ imageObject: [String: Any]) -> (),
onError: @escaping (_ error: String) -> ()) {
func capture(onSuccess: @escaping (_ imageObject: [String: Any]) -> Void,
onError: @escaping (_ error: String) -> Void) {
camera.capturePicture(onWillCapture: { [weak self] in
// Flash/dim preview to indicate shutter action
DispatchQueue.main.async {
Expand All @@ -254,12 +254,12 @@ class CameraView: UIView {
}
}, onError: onError)
}

// MARK: - Private Helper

private func update(zoomMode: ZoomMode) {
if zoomMode == .on {
if (zoomGestureRecognizer == nil) {
if zoomGestureRecognizer == nil {
let pinchGesture = UIPinchGestureRecognizer(target: self, action: #selector(handlePinchToZoomRecognizer(_:)))
addGestureRecognizer(pinchGesture)
zoomGestureRecognizer = pinchGesture
Expand All @@ -271,13 +271,12 @@ class CameraView: UIView {
}
}
}

private func handleCameraPermission() {
switch AVCaptureDevice.authorizationStatus(for: .video) {
case .authorized:
// The user has previously granted access to the camera.
hasPermissionBeenGranted = true
break
case .notDetermined:
// The user has not yet been presented with the option to grant video access.
AVCaptureDevice.requestAccess(for: .video) { [weak self] granted in
Expand All @@ -294,11 +293,11 @@ class CameraView: UIView {
private func writeCaptured(imageData: Data,
thumbnailData: Data?,
dimensions: CMVideoDimensions,
onSuccess: @escaping (_ imageObject: [String: Any]) -> (),
onError: @escaping (_ error: String) -> ()) {
onSuccess: @escaping (_ imageObject: [String: Any]) -> Void,
onError: @escaping (_ error: String) -> Void) {
do {
let temporaryImageFileURL = try saveToTmpFolder(imageData)

onSuccess([
"size": imageData.count,
"uri": temporaryImageFileURL.description,
Expand Down
14 changes: 7 additions & 7 deletions ios/ReactNativeCameraKit/FocusInterfaceView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ class FocusInterfaceView: UIView {

func update(focusMode: FocusMode) {
if focusMode == .on {
if (focusGestureRecognizer == nil) {
if focusGestureRecognizer == nil {
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(focusAndExposeTap(_:)))
addGestureRecognizer(tapGesture)
focusGestureRecognizer = tapGesture
Expand Down Expand Up @@ -157,17 +157,17 @@ class FocusInterfaceView: UIView {
UIView.animate(withDuration: 0.2, animations: {
self.focusView.frame = focusViewFrame
self.focusView.alpha = 1
}) { _ in
}, completion: { _ in
self.hideFocusViewTimer?.invalidate()
self.hideFocusViewTimer = Timer.scheduledTimer(withTimeInterval: 2, repeats: false) { [weak self] _ in
self.hideFocusViewTimer = Timer.scheduledTimer(withTimeInterval: 2, repeats: false, block: { [weak self] _ in
guard let self else { return }
UIView.animate(withDuration: 0.2, animations: {
self.focusView.alpha = 0
}) { _ in
}, completion: { _ in
self.focusView.isHidden = true
}
}
}
})
})
})
}
}

Expand Down
2 changes: 1 addition & 1 deletion ios/ReactNativeCameraKit/PhotoCaptureDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ class PhotoCaptureDelegate: NSObject, AVCapturePhotoCaptureDelegate {
return
}

var thumbnailData: Data? = nil
var thumbnailData: Data?
if let previewPixelBuffer = photo.previewPixelBuffer {
let ciImage = CIImage(cvPixelBuffer: previewPixelBuffer)
let uiImage = UIImage(ciImage: ciImage)
Expand Down
1 change: 1 addition & 0 deletions ios/ReactNativeCameraKit/RatioOverlayView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ class RatioOverlayView: UIView {

// MARK: - Private

// swiftlint:disable:next function_body_length
private func setOverlayParts() {
guard let ratioData, ratioData.ratio != 0 else {
isHidden = true
Expand Down
Loading
Loading