Skip to content

Commit

Permalink
24 - Post: Camera, Galeria e Permissões #21
Browse files Browse the repository at this point in the history
Este módulo foca no desenvolvimento da funcionalidade de publicação de fotos, abordando desde a integração com o backend até desafios em arquitetura, uso de bibliotecas para recursos nativos e gerenciamento de permissões em Android e iOS.

Você vai aprender a acessar a galeria de fotos do dispositivo e criar um componente de câmera dentro do app. Além disso, o módulo oferece uma visão sobre arquiteturas de software, com práticas de implementação variadas para cada plataforma.

Exploraremos o Xcode para habilitar testes do aplicativo em dispositivos físicos iPhone.
  • Loading branch information
LucasGarcez authored Feb 22, 2024
2 parents a288790 + 95316d5 commit b5d46c0
Show file tree
Hide file tree
Showing 57 changed files with 3,257 additions and 111 deletions.
2 changes: 1 addition & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true
"source.fixAll.eslint": "explicit"
},
"cSpell.words": ["MMKV", "Zustand"]
}
9 changes: 9 additions & 0 deletions __mocks__/react-native-vision-camera/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import React from 'react';
import {View} from 'react-native';

export function Camera() {
return <View />;
}

export const useCameraDevice = jest.fn();
export const useCameraFormat = jest.fn();
4 changes: 4 additions & 0 deletions android/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android">

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="32" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

<application
android:name=".MainApplication"
Expand Down
5 changes: 3 additions & 2 deletions android/app/src/main/java/com/nubbleapp/MainActivity.java
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
package com.nubbleapp;
import expo.modules.ReactActivityDelegateWrapper;

import com.facebook.react.ReactActivity;
import com.facebook.react.ReactActivityDelegate;
Expand Down Expand Up @@ -30,13 +31,13 @@ protected String getMainComponentName() {
*/
@Override
protected ReactActivityDelegate createReactActivityDelegate() {
return new DefaultReactActivityDelegate(
return new ReactActivityDelegateWrapper(this, BuildConfig.IS_NEW_ARCHITECTURE_ENABLED, new DefaultReactActivityDelegate(
this,
getMainComponentName(),
// If you opted-in for the New Architecture, we enable the Fabric Renderer.
DefaultNewArchitectureEntryPoint.getFabricEnabled(), // fabricEnabled
// If you opted-in for the New Architecture, we enable Concurrent React (i.e. React 18).
DefaultNewArchitectureEntryPoint.getConcurrentReactEnabled() // concurrentRootEnabled
);
));
}
}
14 changes: 12 additions & 2 deletions android/app/src/main/java/com/nubbleapp/MainApplication.java
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
package com.nubbleapp;
import android.content.res.Configuration;
import expo.modules.ApplicationLifecycleDispatcher;
import expo.modules.ReactNativeHostWrapper;

import android.app.Application;
import com.facebook.react.PackageList;
Expand All @@ -13,7 +16,7 @@
public class MainApplication extends Application implements ReactApplication {

private final ReactNativeHost mReactNativeHost =
new DefaultReactNativeHost(this) {
new ReactNativeHostWrapper(this, new DefaultReactNativeHost(this) {
@Override
public boolean getUseDeveloperSupport() {
return BuildConfig.DEBUG;
Expand Down Expand Up @@ -42,7 +45,7 @@ protected boolean isNewArchEnabled() {
protected Boolean isHermesEnabled() {
return BuildConfig.IS_HERMES_ENABLED;
}
};
});

@Override
public ReactNativeHost getReactNativeHost() {
Expand All @@ -58,5 +61,12 @@ public void onCreate() {
DefaultNewArchitectureEntryPoint.load();
}
ReactNativeFlipper.initializeFlipper(this, getReactNativeHost().getReactInstanceManager());
ApplicationLifecycleDispatcher.onApplicationCreate(this);
}

@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
ApplicationLifecycleDispatcher.onConfigurationChanged(this, newConfig);
}
}
2 changes: 1 addition & 1 deletion android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ buildscript {
mavenCentral()
}
dependencies {
classpath("com.android.tools.build:gradle:7.3.1")
classpath("com.android.tools.build:gradle:7.4.1")
classpath("com.facebook.react:react-native-gradle-plugin")
}
}
3 changes: 3 additions & 0 deletions android/settings.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,6 @@ rootProject.name = 'NubbleApp'
apply from: file("../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesSettingsGradle(settings)
include ':app'
includeBuild('../node_modules/react-native-gradle-plugin')

apply from: new File(["node", "--print", "require.resolve('expo/package.json')"].execute(null, rootDir).text.trim(), "../scripts/autolinking.gradle")
useExpoModules()
1 change: 1 addition & 0 deletions babel.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ module.exports = {
'@infra': './src/infra',
'@services': './src/services',
'@test': './src/test',
'@assets': './src/assets',
},
},
],
Expand Down
68 changes: 60 additions & 8 deletions ios/NubbleApp.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
13B07FBC1A68108700A75B9A /* AppDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB01A68108700A75B9A /* AppDelegate.mm */; };
13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; };
13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; };
35D912C8BCB7E65D275F767E /* ExpoModulesProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90EC125F1EB7E75A4273035B /* ExpoModulesProvider.swift */; };
4C2A7BBE2CE0824265F6234D /* ExpoModulesProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49F34AF33B506C9204B658B2 /* ExpoModulesProvider.swift */; };
7699B88040F8A987B510C191 /* libPods-NubbleApp-NubbleAppTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 19F6CBCC0A4E27FBF8BF4A61 /* libPods-NubbleApp-NubbleAppTests.a */; };
81AB9BB82411601600AC10FF /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */; };
C2D69F372A108FE40057DBEA /* Panchang-Light.otf in Resources */ = {isa = PBXBuildFile; fileRef = C2D69F362A108FE40057DBEA /* Panchang-Light.otf */; };
Expand Down Expand Up @@ -49,11 +51,13 @@
13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = NubbleApp/main.m; sourceTree = "<group>"; };
19F6CBCC0A4E27FBF8BF4A61 /* libPods-NubbleApp-NubbleAppTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-NubbleApp-NubbleAppTests.a"; sourceTree = BUILT_PRODUCTS_DIR; };
3B4392A12AC88292D35C810B /* Pods-NubbleApp.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-NubbleApp.debug.xcconfig"; path = "Target Support Files/Pods-NubbleApp/Pods-NubbleApp.debug.xcconfig"; sourceTree = "<group>"; };
49F34AF33B506C9204B658B2 /* ExpoModulesProvider.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ExpoModulesProvider.swift; path = "Pods/Target Support Files/Pods-NubbleApp/ExpoModulesProvider.swift"; sourceTree = "<group>"; };
5709B34CF0A7D63546082F79 /* Pods-NubbleApp.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-NubbleApp.release.xcconfig"; path = "Target Support Files/Pods-NubbleApp/Pods-NubbleApp.release.xcconfig"; sourceTree = "<group>"; };
5B7EB9410499542E8C5724F5 /* Pods-NubbleApp-NubbleAppTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-NubbleApp-NubbleAppTests.debug.xcconfig"; path = "Target Support Files/Pods-NubbleApp-NubbleAppTests/Pods-NubbleApp-NubbleAppTests.debug.xcconfig"; sourceTree = "<group>"; };
5DCACB8F33CDC322A6C60F78 /* libPods-NubbleApp.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-NubbleApp.a"; sourceTree = BUILT_PRODUCTS_DIR; };
81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = LaunchScreen.storyboard; path = NubbleApp/LaunchScreen.storyboard; sourceTree = "<group>"; };
89C6BE57DB24E9ADA2F236DE /* Pods-NubbleApp-NubbleAppTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-NubbleApp-NubbleAppTests.release.xcconfig"; path = "Target Support Files/Pods-NubbleApp-NubbleAppTests/Pods-NubbleApp-NubbleAppTests.release.xcconfig"; sourceTree = "<group>"; };
90EC125F1EB7E75A4273035B /* ExpoModulesProvider.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ExpoModulesProvider.swift; path = "Pods/Target Support Files/Pods-NubbleApp-NubbleAppTests/ExpoModulesProvider.swift"; sourceTree = "<group>"; };
C2D69F362A108FE40057DBEA /* Panchang-Light.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "Panchang-Light.otf"; sourceTree = "<group>"; };
C2D69F382A10925C0057DBEA /* Satoshi-Black.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "Satoshi-Black.otf"; sourceTree = "<group>"; };
C2D69F392A10925C0057DBEA /* Satoshi-Medium.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "Satoshi-Medium.otf"; sourceTree = "<group>"; };
Expand Down Expand Up @@ -119,6 +123,15 @@
name = NubbleApp;
sourceTree = "<group>";
};
1D796DFB646FD31FD6D1D98C /* ExpoModulesProviders */ = {
isa = PBXGroup;
children = (
42D2E45AA4A70B9204A27B89 /* NubbleApp */,
84894476A3578FF9FDC04E8D /* NubbleAppTests */,
);
name = ExpoModulesProviders;
sourceTree = "<group>";
};
2D16E6871FA4F8E400B85C8A /* Frameworks */ = {
isa = PBXGroup;
children = (
Expand All @@ -129,6 +142,14 @@
name = Frameworks;
sourceTree = "<group>";
};
42D2E45AA4A70B9204A27B89 /* NubbleApp */ = {
isa = PBXGroup;
children = (
49F34AF33B506C9204B658B2 /* ExpoModulesProvider.swift */,
);
name = NubbleApp;
sourceTree = "<group>";
};
832341AE1AAA6A7D00B99B32 /* Libraries */ = {
isa = PBXGroup;
children = (
Expand All @@ -145,6 +166,7 @@
83CBBA001A601CBA00E9B192 /* Products */,
2D16E6871FA4F8E400B85C8A /* Frameworks */,
BBD78D7AC51CEA395F1C20DB /* Pods */,
1D796DFB646FD31FD6D1D98C /* ExpoModulesProviders */,
);
indentWidth = 2;
sourceTree = "<group>";
Expand All @@ -160,6 +182,14 @@
name = Products;
sourceTree = "<group>";
};
84894476A3578FF9FDC04E8D /* NubbleAppTests */ = {
isa = PBXGroup;
children = (
90EC125F1EB7E75A4273035B /* ExpoModulesProvider.swift */,
);
name = NubbleAppTests;
sourceTree = "<group>";
};
BBD78D7AC51CEA395F1C20DB /* Pods */ = {
isa = PBXGroup;
children = (
Expand Down Expand Up @@ -457,6 +487,7 @@
buildActionMask = 2147483647;
files = (
00E356F31AD99517003FC87E /* NubbleAppTests.m in Sources */,
35D912C8BCB7E65D275F767E /* ExpoModulesProvider.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand All @@ -466,6 +497,7 @@
files = (
13B07FBC1A68108700A75B9A /* AppDelegate.mm in Sources */,
13B07FC11A68108700A75B9A /* main.m in Sources */,
4C2A7BBE2CE0824265F6234D /* ExpoModulesProvider.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand All @@ -485,12 +517,15 @@
baseConfigurationReference = 5B7EB9410499542E8C5724F5 /* Pods-NubbleApp-NubbleAppTests.debug.xcconfig */;
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
DEVELOPMENT_TEAM = J29497Z9T9;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
INFOPLIST_FILE = NubbleAppTests/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 12.4;
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
Expand All @@ -501,8 +536,10 @@
"-lc++",
"$(inherited)",
);
PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)";
OTHER_SWIFT_FLAGS = "$(inherited) -D EXPO_CONFIGURATION_DEBUG";
PRODUCT_BUNDLE_IDENTIFIER = com.coffstack.nubble;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/NubbleApp.app/NubbleApp";
};
name = Debug;
Expand All @@ -512,9 +549,12 @@
baseConfigurationReference = 89C6BE57DB24E9ADA2F236DE /* Pods-NubbleApp-NubbleAppTests.release.xcconfig */;
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
COPY_PHASE_STRIP = NO;
DEVELOPMENT_TEAM = J29497Z9T9;
INFOPLIST_FILE = NubbleAppTests/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 12.4;
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
Expand All @@ -525,8 +565,10 @@
"-lc++",
"$(inherited)",
);
PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)";
OTHER_SWIFT_FLAGS = "$(inherited) -D EXPO_CONFIGURATION_RELEASE";
PRODUCT_BUNDLE_IDENTIFIER = com.coffstack.nubble;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/NubbleApp.app/NubbleApp";
};
name = Release;
Expand All @@ -537,7 +579,10 @@
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_TEAM = J29497Z9T9;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = NubbleApp/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
Expand All @@ -550,8 +595,10 @@
"-ObjC",
"-lc++",
);
PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)";
OTHER_SWIFT_FLAGS = "$(inherited) -D EXPO_CONFIGURATION_DEBUG";
PRODUCT_BUNDLE_IDENTIFIER = com.coffstack.nubble;
PRODUCT_NAME = NubbleApp;
PROVISIONING_PROFILE_SPECIFIER = "";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0;
VERSIONING_SYSTEM = "apple-generic";
Expand All @@ -564,7 +611,10 @@
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_TEAM = J29497Z9T9;
INFOPLIST_FILE = NubbleApp/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
Expand All @@ -576,8 +626,10 @@
"-ObjC",
"-lc++",
);
PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)";
OTHER_SWIFT_FLAGS = "$(inherited) -D EXPO_CONFIGURATION_RELEASE";
PRODUCT_BUNDLE_IDENTIFIER = com.coffstack.nubble;
PRODUCT_NAME = NubbleApp;
PROVISIONING_PROFILE_SPECIFIER = "";
SWIFT_VERSION = 5.0;
VERSIONING_SYSTEM = "apple-generic";
};
Expand Down Expand Up @@ -632,7 +684,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 12.4;
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
LD_RUNPATH_SEARCH_PATHS = (
/usr/lib/swift,
"$(inherited)",
Expand Down Expand Up @@ -697,7 +749,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 12.4;
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
LD_RUNPATH_SEARCH_PATHS = (
/usr/lib/swift,
"$(inherited)",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>
3 changes: 2 additions & 1 deletion ios/NubbleApp/AppDelegate.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#import <RCTAppDelegate.h>
#import <Expo/Expo.h>
#import <UIKit/UIKit.h>

@interface AppDelegate : RCTAppDelegate
@interface AppDelegate : EXAppDelegateWrapper

@end
34 changes: 18 additions & 16 deletions ios/NubbleApp/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,6 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>UIAppFonts</key>
<array>
<string>Panchang-Light.otf</string>

<string>Satoshi-Black.otf</string>
<string>Satoshi-BlackItalic.otf</string>
<string>Satoshi-Bold.otf</string>
<string>Satoshi-BoldItalic.otf</string>
<string>Satoshi-Italic.otf</string>
<string>Satoshi-Light.otf</string>
<string>Satoshi-LightItalic.otf</string>
<string>Satoshi-Medium.otf</string>
<string>Satoshi-MediumItalic.otf</string>
<string>Satoshi-Regular.otf</string>

</array>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleDisplayName</key>
Expand Down Expand Up @@ -53,6 +37,24 @@
</dict>
<key>NSLocationWhenInUseUsageDescription</key>
<string></string>
<key>NSPhotoLibraryUsageDescription</key>
<string>Para publicar novos posts</string>
<key>NSCameraUsageDescription</key>
<string>$(PRODUCT_NAME) precisa de acesso a camera para publicar novos posts.</string>
<key>UIAppFonts</key>
<array>
<string>Panchang-Light.otf</string>
<string>Satoshi-Black.otf</string>
<string>Satoshi-BlackItalic.otf</string>
<string>Satoshi-Bold.otf</string>
<string>Satoshi-BoldItalic.otf</string>
<string>Satoshi-Italic.otf</string>
<string>Satoshi-Light.otf</string>
<string>Satoshi-LightItalic.otf</string>
<string>Satoshi-Medium.otf</string>
<string>Satoshi-MediumItalic.otf</string>
<string>Satoshi-Regular.otf</string>
</array>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UIRequiredDeviceCapabilities</key>
Expand Down
Loading

0 comments on commit b5d46c0

Please sign in to comment.