Projects/청하-청년을 위한 커뮤니티 서비스

[청하] 20. Android 강제 업데이트 검사 기능 구현

Lpromotion 2024. 10. 15. 20:06

“Android 강제 업데이트 검사 기능”은 사용자들이 최신 버전의 앱을 사용하도록 유도하기 위한 기능이다.

버그 수정이나 새로운 기능이 추가되면 이것을 이용할 수 있는 버전을 사용하는 것이 좋기 때문에, 업데이트를 유도하는 기능을 추가했다.

간단한 작동 방식을 설명하자면

  1. 데이터베이스에 앱 깅제 업데이트 버전 정보를 저장한다.
  2. 사용자가 앱을 실행하면 사용자의 앱 버전과 데이터베이스에 저장된 강제 업데이트 버전을 비교한다.
  3. 사용자의 앱 버전이 데이터베이스의 버전보다 낮으면 강제 업데이트를 요구한다.

 

1. 프로젝트 구조

src/main/java/com/example/withpeace/
│
├── domain/                 # 도메인 모델 (엔티티)
│   └── AppVersion.java     # 앱 버전 엔티티
│
├── repository/                    # 데이터 접근 계층
│   └── AppVersionRepository.java  # 앱 버전 레포지토리
│
│
├── controller/             # 컨트롤러 계층
│   └── App.java            # 앱 관련 API 엔드포인트
│
└── service/                # 비즈니스 로직 계층
    └── AppService.java     # 앱 관련 비즈니스 로직

 

2. 도메인 모델 구현

AppVersion

@Entity
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@DynamicUpdate
@Table(name = "appversions")
public class AppVersion {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id", nullable = false, updatable = false, unique = true)
    private Long id;

    @Column(name = "android_force_update_version", nullable = false)
    private int androidForceUpdateVersion; // 강제 업데이트가 필요한 최소 버전

    @Builder
    public AppVersion(int androidForceUpdateVersion) {
        this.androidForceUpdateVersion = androidForceUpdateVersion;
    }

    // 강제 업데이트 버전 설정 메서드
    public void setAndroidForceUpdateVersion(int androidForceUpdateVersion) {
        this.androidForceUpdateVersion = androidForceUpdateVersion;
    }
}

AppVersion 엔티티는 안드로이드 앱의 강제 업데이트 버전 정보를 저장한다.

`androidForceUpdateVersion` 는 강제 업데이트가 필요한 최소 버전을 의미한다. 사용자의 현재 앱 버전이 이 버전보다 낮으면 업데이트를 유도한다.

 

3. 레포지토리 구현

AppVersionRepository

@Repository
public interface AppVersionRepository extends JpaRepository<AppVersion, Long> {

    AppVersion findFirstByOrderByIdAsc();
}

`findFirstByOrderByIdAsc` 는 데이터베이스에서 상위 1개(ID가 가장 작은) AppVersion을 조회한다. 최신 강제 업데이트 버전 정보를 가지고 오기 위함이다.

 

4. 컨트롤러 구현

@RestController
@RequiredArgsConstructor
@RequestMapping("api/v1/app")
public class AppController {

    private final AppService appService;

    // 안드로이드 강제 업데이트 검사
    @GetMapping("/check/android")
    public ResponseDto<?> checkAndroidForceUpdate(@RequestParam int currentVersion) {
        // 현재 버전과 강제 업데이트 버전을 비교하여 업데이트 필요 여부 반환
        boolean forceUpdate = appService.checkAndroidForceUpdate(currentVersion);
        return ResponseDto.ok(forceUpdate);
    }
}

`currentVersion`(사용자의 현재 앱 버전)을 쿼리 파라미터로 받아 강제 업데이트가 필요한지 여부를 반환한다.

 

5. 서비스 구현

@Service
@RequiredArgsConstructor
public class AppService {

    private final UserRepository userRepository;
    private final AppVersionRepository appVersionRepository;

    private int androidForceUpdateVersion;

    @PostConstruct
    public void initVersion() {
        AppVersion appVersion = appVersionRepository.findFirstByOrderByIdAsc();
        if (appVersion != null) {
            // 데이터베이스에서 강제 업데이트 버전 정보를 가져옴
            androidForceUpdateVersion = appVersion.getAndroidForceUpdateVersion();
        } else {
            // 데이터베이스에 버전 정보가 없는 경우, 초기값으로 1을 설정
            AppVersion newAppVersion = appVersionRepository.save(AppVersion.builder().build());
            newAppVersion.setAndroidForceUpdateVersion(1);
            appVersionRepository.save(newAppVersion);
            androidForceUpdateVersion = 1;
        }
    }

    public boolean checkAndroidForceUpdate(int currentVersion) {
        return currentVersion < androidForceUpdateVersion;
    }

}

 

5.1. initVersion 메서드

`@PostConstruct` 로 인해 애플리케이션 시작 시 실행되어 데이터베이스에서 강제 업데이트 버전 정보를 가져온다.

데이터베이스에 버전 정보가 없으면 초기값으로 1을 설정한다.

버전 정보는 `androidForceUpdateVersion` 클래스 변수에 저장한다.

 

@PostConstruct와 androidForceUpdateVersion 클래스 변수 사용 이유

initVersion 메서드에 `@PostConstruct` 어노테이션을 사용하고 `androidForceUpdateVersion` 을 클래스 변수로 선언한 이유는

  • 매 요청마다 데이터베이스를 조회하지 않고, 애플리케이션 시작 시 한 번만 조회하여 메모리에 저장하여 성능을 최적화하기 위함이다.
  • “ADMIN”인 사용자만 이 정보를 변경할 수 있기 때문에 자주 변경되지 않는다는 점을 생각해 클래스 변수로 선언했다.

 

5.2. checkAndroidForceUpdate 메서드

사용자의 현재 앱 버전과 강제 업데이트 버전을 비교하고, 현재 버전이 더 낮으면 true를 반환하여 업데이트가 필요함을 알린다.

 

6. API 응답 예시

요청 URL

[POST] http://cheongha.site/api/v1/app/check/android?currentVersion=8

 

Response Body

{
  "data": true, // true: 업데이트 필요 O, false: 업데이트 필요 X
  "error": null
}
반응형