728x90
반응형

 

Android Studio 버전이 올라가면 Gradle 버전도 올라가고 다른 Library도 버전이 올라가게 됩니다.

 

아래와 같이 AndroidX 같은 오류가 발생하기도 합니다.

Manifest merger failed : Attribute application@appComponentFactory value=(android.support.v4.app.CoreComponentFactory) from [com.android.support:support-compat:28.0.0] AndroidManifest.xml:22:18-91
	is also present at [androidx.core:core:1.0.0] AndroidManifest.xml:22:18-86 value=(androidx.core.app.CoreComponentFactory).
	Suggestion: add 'tools:replace="android:appComponentFactory"' to <application> element at AndroidManifest.xml:14:5-68:19 to override.

 

 

 

 

 

특정 Library는 AndroidX를 사용하는데 그걸 사용하는 프로젝트가 androidx를 사용한다는 처리가 되지 않았기 때문인데요.

 

gradle.properties 에서 아래와 같이 2줄을 추가해주면 오류를 해결할 수 있습니다.

android.useAndroidX=true
android.enableJetifier=true

 

 

 

 

 

AndroidX에 관련된 내용입니다.

 

https://developer.android.com/jetpack/androidx

 

AndroidX 개요  |  Android 개발자  |  Android Developers

AndroidX는 Android 팀이 Jetpack 내에서 라이브러리를 개발, 테스트, 패키징, 버전 관리, 출시하는 데 사용하는 오픈소스 프로젝트입니다. AndroidX는 기존 Android 지원 라이브러리를 크게 개선하여 만들어졌습니다. AndroidX는 지원 라이브러리와 마찬가지로 Android OS와 별도로 배송되며 Android 버전 전체에서 이전 버전과의 호환성을 제공합니다. AndroidX는 동일한 기능과 새로운 라이브러리를 제공하여 지원 라

developer.android.com

 

728x90
반응형
728x90
반응형

Android 9.0이상 버전이 출시되었는데도 Google은 아직 라이브러리를 수정하지 않았습니다.

 

한창 이슈였던 부분이었는데 문서화도 하지 않고 그냥 오류만 발생했습니다.

 

Apache http는 android 6.0 부터 삭제가 되었지만 이를 준수하지 않아 큰 문제를 만들기도 하였습니다.

 

아직도 구버전의 google map 을 사용하거나 이슈를 직감하지 못했던 분들에게 도움이 되고자 해결방법을 알아보겠습니다.

2019-12-23 10:56:02.355 20618-20812/xxx.xxx.xxx E/AndroidRuntime: FATAL EXCEPTION: Thread-17
    Process: xxx.xxx.xxx, PID: 20618
    java.lang.NoClassDefFoundError: Failed resolution of: Lorg/apache/http/ProtocolVersion;
        at br.b(:com.google.android.gms.dynamite_mapsdynamite@19831065@19.8.31 (100400-0):2)
        at bq.a(:com.google.android.gms.dynamite_mapsdynamite@19831065@19.8.31 (100400-0):3)
        at bs.a(:com.google.android.gms.dynamite_mapsdynamite@19831065@19.8.31 (100400-0):20)
        at com.google.maps.api.android.lib6.drd.ak.a(:com.google.android.gms.dynamite_mapsdynamite@19831065@19.8.31 (100400-0):6)
        at aw.a(:com.google.android.gms.dynamite_mapsdynamite@19831065@19.8.31 (100400-0):13)
        at aw.run(:com.google.android.gms.dynamite_mapsdynamite@19831065@19.8.31 (100400-0):49)
     Caused by: java.lang.ClassNotFoundException: Didn't find class "org.apache.http.ProtocolVersion" on path: DexPathList[[zip file "/data/user_de/0/com.google.android.gms/app_chimera/m/00000043/MapsDynamite.apk"],nativeLibraryDirectories=[/data/user_de/0/com.google.android.gms/app_chimera/m/00000043/MapsDynamite.apk!/lib/arm64-v8a, /system/lib64, /system/vendor/lib64]]
        at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:134)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:379)
        at w.loadClass(:com.google.android.gms.dynamite_dynamiteloader@19831065@19.8.31 (100400-0):16)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:312)
        at br.b(:com.google.android.gms.dynamite_mapsdynamite@19831065@19.8.31 (100400-0):2) 
        at bq.a(:com.google.android.gms.dynamite_mapsdynamite@19831065@19.8.31 (100400-0):3) 
        at bs.a(:com.google.android.gms.dynamite_mapsdynamite@19831065@19.8.31 (100400-0):20) 
        at com.google.maps.api.android.lib6.drd.ak.a(:com.google.android.gms.dynamite_mapsdynamite@19831065@19.8.31 (100400-0):6) 
        at aw.a(:com.google.android.gms.dynamite_mapsdynamite@19831065@19.8.31 (100400-0):13) 
        at aw.run(:com.google.android.gms.dynamite_mapsdynamite@19831065@19.8.31 (100400-0):49) 

 

 

 

 

1. AndroidManifest.xml 에 uses-library 추가

기존 google maps library 를 그대로 사용하는 방법입니다.

 

AndroidManifest.xml파일에서 application 수준에 uses-library 를 추가 해주면 됩니다.

<application>
	...
    
	<uses-library
            android:name="org.apache.http.legacy"
            android:required="false" />
            
</application>

 

 

 

2. Google maps 라이브러리 업데이트

다른 방법으로는 수정된 google maps library 를 사용하면 됩니다.

com.google.android.gms:play-services-maps:16.x.x

 

 

 

 

이제 다시 build를 하면 정삭적으로 실행이 됩니다.

 

728x90
반응형
728x90
반응형

 

Android Studio 가 업데이트 됨에 따라 Gradle 버전도 올라가고, 최소 TargetSdkVersion 도 자연스럽게 올라갑니다.

 

회사 내부에서만 사용하는 앱은 HTTPS 가 아닌 HTTP로만 통신을 하고 있습니다.

 

즉 SSL인증서 적용을 하지 않은건데 targetSdkVersion 28 이상에서는 HTTP 사용을 보안정책에 의해 허용하지 않고 있습니다.

 

Android Build를 진행한다면 아래와 같은 오류가 발생하면서 통신이 거부 됩니다.

java.net.UnknownServiceException: CLEARTEXT communication to 0.0.0.0 not permitted by network security policy

 

 

 

 

 

그래도 내부 프로젝트만 사용한다면 인증서가 필요없으니 강제로 보안정책을 허용 해주도록 하겠습니다.

 

app -> manifests -> AndroidManifest.xml 을 open 합니다.

 

android 수준에서 usesCleartextTraffic 이라는 속성을 true로 해주면 보안정책을 허용해주게 됩니다.

<application
	...
    android:usesCleartextTraffic="true">
    
    ...
    
</application>

 

 

 

 

 

저장을 하고 다시 build를 해봅시다.

 

정상적으로 통신이 되는것을 확인하셨다면 끝난겁니다.

 

한줄의 추가로 SSL인증서를 무시했지만 내부에서만 사용하는 서비스에만 사용을 권해 드립니다.

 

728x90
반응형
728x90
반응형

형상관리를 하지만 IOS를 개발할때 파일의 충돌이 잘 발생합니다.

 

git ignore 설정을 하지 않는다면 다른 팀원과 소스 관리가 거의 불가능할 것입니다.

 

그럼에도 불구하고 Cocoapod 관련해서 오류가 발생한다면 재설치를 진행해야 정상 Build 가 됩니다.

 

 

 

 

터미널로 프로젝트 경로에 진입합니다.

 

Podfile. xcworkspace, Pods 폴더를 삭제하고 pod을 재설치 합니다.

sudo rm Podfile.lock 
sudo rm -r [프로젝트명].xcworkspace 
sudo rm -r Pods 
pod install

 

 

 

 

Proejct Clean 이나 Build 를 해서 되지 않는다면 위와 같은 방법으로 진행하시는걸 추천드립니다.

 

728x90
반응형
728x90
반응형

 

iOS 13 버전이 되면서 다크모드가 새롭게 추가되었습니다.

 

하지만 개발자에게는 앱 유지보수를 해야하는데 정보를 몰라서 곤경에 처하곤 합니다.

 

간단하게 다크모드 옵션을 해제하는 방법을 알아보겠습니다.

 

 

Info.plist

Xcode에서 info.plist 에서 아래와 같이 값을 추가 합니다.

 

 

 

Source Code는 아래와 같습니다.

<key>UIUserInterfaceStyle</key>
<string>Light</string>

 

 

 

 

AppDelegate

overrideUserInterfaceStyle앱의 window변수 에 대해 설정할 수 있습니다 .

 

프로젝트 생성 방법에 따라 AppDelegate파일 또는 SceneDelegate에 있을 수 있습니다.

if #available(iOS 13.0, *) {
    window?.overrideUserInterfaceStyle = .light
}

 

 

 

UIViewController

UIViewController를 개별적으로 선택 해제하려면 아래와 같이 viewDidLoad 메서드안에 작성할 수 있습니다.

override func viewDidLoad() {
    super.viewDidLoad()
    // overrideUserInterfaceStyle is available with iOS 13
    if #available(iOS 13.0, *) {
        // Always adopt a light interface style.
        overrideUserInterfaceStyle = .light
    }
}
728x90
반응형

'프로그래밍 > iOS' 카테고리의 다른 글

[Swift5] Base64 Encode Url Safe  (0) 2020.01.14
[XCode] Cocoapod Build Error  (0) 2019.12.20
Swift 4 UIAlertController  (0) 2019.03.05
Swift 4 TableView Section  (0) 2019.03.04
Swift 4 UIRefreshControl  (0) 2019.03.04
728x90
반응형

 

Xcode에서 Gitlab을 연결하여 사용하는 방법을 알아보겠습니다.

 

Xcode 프로그램을 실행한 뒤 상단 메뉴 Xcode를 클릭한 뒤 Preferences... 메뉴를 클릭합니다.

 

 

 

아래와 같은 팝업이 보여지게 되고, Accounts 라는 탭으로 진입합니다.

 

현재는 연결되어있는 Source Control 정보가 없다보니 Apple IDs 정보면 보여지고 있습니다.

 

Source Control 연결을 위해 + 버튼을 클릭합니다.

 

 

새로 열린 화면에서 아래로 스크롤을 하다보면 GitLab.com 이라는 목록이 보여집니다.

 

Continue 버튼을 클릭합니다.

 

GitLab을 선택하였기 때문에 GitLab 계정을 입력하는 화면이 보여지게 됩니다.

 

Account 란은 GitLab에서 로그인하는 계정을 입력합니다.

 

Token은 GitLab에서 생성한 AccessToken 을 입력하면 됩니다.

 

정보를 입력한 후 Sign In 버튼을 클릭합니다.

정상적으로 로그인이 되었다면 아래와 같이 Apple IDs 아래로 Source Control Accounts 부분이 활성화 되어 등록된 정보가 보여지게됩니다.

 

 

 

728x90
반응형

'프로그래밍 > Tools' 카테고리의 다른 글

[STS] SpringToolSuite SVN 프로젝트 연결  (2) 2019.07.15
[STS] SpringToolSuite SVN 설치  (0) 2019.07.13
[Mac OS X] Docker 설치  (0) 2019.04.26
Atom Editor 설치  (0) 2019.03.29
728x90
반응형

 

Git 원격 저장소에 강제로 Push 를 진행할 때 나오는 에러입니다.

 

잘못된 파일이 있어 commit 을 되돌리려고 했는데 위의 에러가 발생해서 난감했습니다.

 

해당 에러는 Push 하려는 Branch 가 Protected 설정이 기본으로 되어있어서 발생하는 오류가 대부분입니다.

 

다른 오류로는 Branch 에 대해 Permission 을 주는 경우도 있습니다.

 

 

 

 

GitLab 에서 처리하는 방법을 알아보겠습니다.

 

원격 저장소에서 설정 -> 저장소 메뉴를 클릭합니다.

 

 

 

여러개의 목록이 나오는데 Protected Branches 항목을 Expend 하면 아래와 같이 보여지게 됩니다.

 

master branch 가 등록되어있는게 보여지는데 Unprotect 를 클릭하게 되면 해당 branch 는 보호 해제가 됩니다.

 

 

 

Unprotect 를 클릭해서 보호 해제를 하면 아래와 같은 화면이 보여지게 됩니다.

 

 

 

보호된 branch 가 없다는걸 확인 후 다시 강제 push 를 진행하면 정상 처리되는것을 확인 할 수 있습니다.

728x90
반응형

'프로그래밍 > Git' 카테고리의 다른 글

[GitHub] 비공개 프로젝트 contributions 설정  (0) 2021.06.22
728x90
반응형

 

JPA 를 사용하다보면 정말로 갈아 엎고 싶다는 생각이 많이 드네요.

 

연관관계가 복잡해지다 보면 간단하게 사용할 수 있는 JPA 가 꼭 필요한지 생각이 들곤 합니다.

 

그래서 조금 복잡한 쿼리를 진행하기 위해 MyBatis 를 적용해 보겠습니다.

 

 

 

 

build.gradle 에서 MyBatis 의존성을 추가 합니다.

 

버전은 조금씩 다를 수 있습니다.

dependencies {
    // MyBatis
    implementation 'org.mybatis.spring.boot:mybatis-spring-boot-starter:2.1.0'
    
}

 

 

 

 

application.yml 파일에서 datasource 설정을 해줍니다.

 

DB를 사용하신다면 무조건 해줘야 하는 부분입니다.

  # ===============================
  # = DATA SOURCE (MARIADB)
  # ===============================
  datasource:
    # 기본 DB
    url: jdbc:mariadb://gigas.synology.me:3306/xxx
    username: xxx
    password: xxx

 

 

 

 

기존에 DAO로 사용하던 부분입니다.

 

Interface에서 메서드를 생성한 후 Mapper를 호출해서 사용하던 방식은 아닙니다.

 

XML이 아닌 java코드로 간단하게 코드를 작성할 수 있습니다.

 

@Mapper 어노테이션으로 Mapper등록을 합니다.

 

@Select 어노테이션처럼 CRUD 를 선언해서 사용할 수 있습니다.

@Mapper
public interface UserMapper {

    /**
     * userNo 로 User 조회
     * @param userNo
     * @return
     */
    @Select("SELECT * FROM user WHERE user_no = #{user_no}")
    User getUser(@Param("user_no") Long userNo);
}

 

 

 

 

테스트 코드로 데이터를 찍어서 잘 돌아가는지 확인할 수 있습니다.

@RunWith(SpringRunner.class)
@SpringBootTest
public class PersistenceTests {


    @Autowired
    private UserMapper userMapper;
    
    @Test
    public void USER_MAPPER_TEST() {

        User user = userMapper.getUser(1L);

        System.err.println(user.toString());
    }
    
}

 

 

 

 

XML 을 사용하시는 분들은 application.yml 에 mybatis 속성을 추가 하여야 합니다.

 

type-aliases-package 는 result 도메인 패키지 경로를 작성합니다.

 

mapper-locations 는 mapper 파일 경로인데 resources 경로안에 mapper 폴더를 만들어 주겠습니다.

# ===============================
# = MYBATIS CONFIG
# ===============================
mybatis:
  type-aliases-package: com.xxx.xxxx
  mapper-locations: mapper/**/*.xml

 

 

 

UserMapper.xml 을 만들어 아래와 같이 select 문을 추가했습니다.

 

여기서 나오는 id 가 Mapper가 UserMapper 메서드와 매핑이 되어집니다.

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTO Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="com.xxx.xxx.persistence.UserMapper">
    <!-- userNo로 User조회 -->
    <select id="findByUserNo" parameterType="Integer" resultType="UserVO">
        SELECT *
            FROM user
            WHERE user_no = #{userNo}
    </select>
</mapper>

 

 

 

 

@Select 어노테이션을 사용하지 않고 아래와 같이 사용합니다.

 

테스트는 동일합니다.

@Mapper
public interface UserMapper {

    /**
     * userNo 로 User 조회
     * @param userNo
     * @return
     */
    UserVO findByUserNo(Long userNo);
}

 

 

 

 

정말 간단하게 설정부분도 필요없이 의존성을 추가하고 Mapper 를 만들어 보았습니다.

 

복잡한 코드는 XML로 따로 분리를 해서 사용하는게 좋고 간단한 쿼리는 어노테이션으로 진행하는걸 추천드립니다.

 

 

 

728x90
반응형

'프로그래밍 > Spring' 카테고리의 다른 글

[Lombok] Mac OS X Lombok Install  (2) 2019.07.18
[Lombok] Windows OS Lombok Install  (0) 2019.07.17
[STS] SpringToolSuite SVN 연결  (0) 2019.07.14
[Spring] Session Time Out Check  (2) 2019.05.31
[Spring] Thymeleaf Fragment Layout  (0) 2019.05.24
728x90
반응형

 

Layout에 이미지나 텍스트를 넣었지만 너무 내용물이 많아 화면에 넘어가는걸 처리하기 위해서 ScrollView Component 를 사용합니다.

 

거의 긴 내용이 필요한 화면에서는 필수라고 할 수 있죠.

 

일반적으로는 내용이 길어도 화면에 들어가면 상단부터 보여지게 됩니다.

 

 

 

 

하지만 ScrollView안에 RecyclerView를 넣었을때가 문제 입니다.

 

화면에 들어가면 ScrollView가 로드 된 후 RecyclerView가 로드 되기 때문에 RecyclerView가 로드된 부분에서 보여지게 됩니다.

 

의외로 이런 화면 구성이 간혹 기획되곤 합니다..

 

ScrollView 안에 RecyclerView가 있어도 상단에 보여지도록 처리를 해보겠습니다.

 

ScrollView Component 를 id 로 scrollView라고 정의 해보겠습니다.

android:id="@+id/scrollView"

 

 

 

ScrollView 자동스크롤

ScrollView.FOCUS_DOWN 은 하단으로 위치 하게 되는 옵션이고, ScrollView.FOCUS_UP 은 상단으로 위치 하게 되는 옵션입니다.

 

이외에도 여러가지 옵션이 있지만 여기서 다루지는 않겠습니다.

 

Kotlin 사용

scrollView.post {
	scrollView.fullScroll.ScrollView.FOCUS_UP)
}

 

Java로 사용

ScrollView scrollView = (ScrollView) findViewById(R.id.scrollView);
scrollView.post(new Runnable() {
	@Override
    public void run() {
    	scrollView.funnScroll(ScrollView.FOCUS_UP);	
    }
});

 

 

 

로드가 된 후 맨 상단으로 가고 싶을 땐 Thread 처리하지 않는다면 옵션이 적용되지 않습니다.

 

특정 Component Click 이벤트가 발생하면 스크롤이 되도록 처리 해도 됩니다.

 

다양하게 사용할 수 있으니 많은 응용을 해보세요.

 

728x90
반응형
728x90
반응형

 

이전글에서는 Windows OS 에서 Lombok 설치하는 방법을 알아보았습니다.

 

이번글에서는 Mac OS X 에서 Lombok 을 설치해보도록 하겠습니다.

 

https://gigas-blog.tistory.com/150

 

 

 

Lombok Download

아래의 URI로 이동하여 Lombok.jar 파일을 다운로드 합니다.

 

https://projectlombok.org/download

 

Download

 

projectlombok.org

 

 

Version은 계속 업데이트가 되고있습니다.

 

Download 1.18.8 Test 를 클릭해 다운로드 합니다.

 

 

 

Download 가 완료되면 아래와 같이 Jar 파일이 보이게 됩니다.

 

 

 

 

lombok.jar 실행합니다.

마우스 우클릭 -> 열기로 실행이 안된다면 터미널을 실행해서 진행해야 합니다.

 

터미널에서 파일명에 맞게 경로와 이름을 넣어 명령어를 실행합니다.

java -jar lombok-1.18.8.jar

 

 

명령어를 잘 입력하셨다면 아래와 같이 설치화면이 보여지게 됩니다.

 

자동으로 STS나 Eclipse 가 보여지지 않고 있기 때문에 Specify location... 버튼을 클릭해서 파일을 선택해줘야 합니다.

 

Specify location... 버튼을 클릭합니다.

 

 

탐색 화면이 나오는데 Applications -> Contents -> Eclipse 의 경로에 들어갑니다.

 

SpringToolSuite4.ini 라는 파일이 있는데 이 파일을 선택하고 Open 버튼을 클릭합니다.

 

잘 선택이 되었기 때문에 목록에 STS 가 보여지게 됩니다.

 

Install/Update 버튼을 클릭하여 설치를 진행하겠습니다.

 

아래와 같은 설치가 성공이 되었다면 Quit Installer 버튼을 클릭해 종료합니다.

 

 

설치가 잘 되었는지 확인합니다.

 

SpringToolSuite4.ini 파일을 열어보면 

 

-javaagent:/Applications/SpringTollSuite4.app/Contents/Eclipse/lombok.jar 옵션이 추가된것을 확인할 수 있습니다.

 

Mac OS X 역시 약간의 설치 과정이 필요하지만 개발을 더 쉽고 간편하게 진행할 수 있습니다.

 

Mac OS X 에서도 Lombok 을 쉽게 사용해보세요.

 

728x90
반응형

'프로그래밍 > Spring' 카테고리의 다른 글

[Spring] Spring Boot 2 MyBatis 설정  (2) 2019.09.03
[Lombok] Windows OS Lombok Install  (0) 2019.07.17
[STS] SpringToolSuite SVN 연결  (0) 2019.07.14
[Spring] Session Time Out Check  (2) 2019.05.31
[Spring] Thymeleaf Fragment Layout  (0) 2019.05.24

+ Recent posts