반응형

Objective-C 개발시 ARC 혹은 MRC를 선택하여 개발을 한다. ARC는 Objective-C Class에만 해당되어 만약 Core Foundation과 같이 C/C++ 계열의 API는 Type Casting을 해줘야 ARC를 사용할 수 있다. (일명 Toll-Free Bridging) 오늘 소개할 내용은 *.m 파일에 ARC or Non-ARC Compile Flag를 사용하는 방법이며, 위에 얘기한 것처럼 Type Casting 없이 개별 파일에 Compile Flag만 변경해서도 사용할 수 있는 방법이다. 

우선 프로젝트 폴더의 상단 프로젝트명을 선택해서 나오는 Target에서  Build Phases중 Compile Sources를 열어보면 Compile될 *m파일 리스트가 보이며 Compile Flag 변경을 원하는 파일을 더블클릭하면 변경가능하다.

 

ARC 변경

-fobjc-arc

 

Non-ARC변경

-fno-obj-arc

반응형

'개발 > iOS' 카테고리의 다른 글

Universal Link (2/4) - 네이티브 링크 수신  (0) 2021.03.16
Universal Link (1/4) - 네이티브 환경설정  (0) 2021.03.16
String to CGFloat  (0) 2021.01.06
SceneDelegate 포인터 구하기  (0) 2021.01.05
앱 호출 (URL scheme)  (0) 2021.01.05
블로그 이미지

SKY STORY

,

String to CGFloat

개발/iOS 2021. 1. 6. 09:45
반응형
let sHeight = "100.0"
guard let num = NumberFormatter().number(from: sHeight) else { return 100.0 }
let fHeight = CGFloat(truncating: num)
print("\(fHeight)")
반응형

'개발 > iOS' 카테고리의 다른 글

Universal Link (1/4) - 네이티브 환경설정  (0) 2021.03.16
ARC or Non-ARC Compile Flag 설정  (0) 2021.02.05
SceneDelegate 포인터 구하기  (0) 2021.01.05
앱 호출 (URL scheme)  (0) 2021.01.05
URL query 파싱 및 json string 변환  (0) 2020.12.17
블로그 이미지

SKY STORY

,
반응형

방법 1

// Swift
let sd = self.view.window.windowScene.delegate

// Objective-C
SceneDelegate *sd = self.view.window.windowScene.delegate;

 

방법 2

Swift :

//
// UIResponder+Scene.swift
//

import UIKit

@available(iOS 13.0, *)
extension UIResponder {
    @objc var scene: UIScene? {
        return nil
    }
}

@available(iOS 13.0, *)
extension UIScene {
    @objc override var scene: UIScene? {
        return self
    }
}

@available(iOS 13.0, *)
extension UIView {
    @objc override var scene: UIScene? {
        if let window = self.window {
            return window.windowScene
        } else {
            return self.next?.scene
        }
    }
}

@available(iOS 13.0, *)
extension UIViewController {
    @objc override var scene: UIScene? {
        // Try walking the responder chain
        var res = self.next?.scene
        if (res == nil) {
            // That didn't work. Try asking my parent view controller
            res = self.parent?.scene
        }
        if (res == nil) {
            // That didn't work. Try asking my presenting view controller 
            res = self.presentingViewController?.scene
        }

        return res
    }
}

 

Objective-C :

//
// UIResponder+Scene.h
//

#import <UIKit/UIKit.h>

NS_ASSUME_NONNULL_BEGIN

@interface UIResponder (Scene)

@property (nonatomic, readonly, nullable) UIScene *scene API_AVAILABLE(ios(13.0));

@end

NS_ASSUME_NONNULL_END





// 
// UIResponder+Scene.m
//

#import "ViewController+Scene.h"

@implementation UIResponder (Scene)

- (UIScene *)scene {
    return nil;
}

@end

@implementation UIScene (Scene)

- (UIScene *)scene {
    return self;
}

@end

@implementation UIView (Scene)

- (UIScene *)scene {
    if (self.window) {
        return self.window.windowScene;
    } else {
        return self.nextResponder.scene;
    }
}

@end

@implementation UIViewController (Scene)

- (UIScene *)scene {
    UIScene *res = self.nextResponder.scene;
    if (!res) {
        res = self.parentViewController.scene;
    }
    if (!res) {
        res = self.presentingViewController.scene;
    }

    return res;
}

@end

 

원문 : 
stackoverflow.com/questions/56588843/uiapplication-shared-delegate-equivalent-for-scenedelegate-xcode11

 

반응형

'개발 > iOS' 카테고리의 다른 글

ARC or Non-ARC Compile Flag 설정  (0) 2021.02.05
String to CGFloat  (0) 2021.01.06
앱 호출 (URL scheme)  (0) 2021.01.05
URL query 파싱 및 json string 변환  (0) 2020.12.17
디버깅 차단 처리 (Anti Debug)  (0) 2020.12.15
블로그 이미지

SKY STORY

,
반응형

스마트폰 BTC 채굴앱

https://get.cryptobrowser.site/34473645

 

Earn coins while browsing the web

Earn bitcoins while watching videos, chatting, or playing online. It has never been so easy to increase your income! Tell your friends about CryptoTab Browser, invite them to join, and earn more together. Grow your network—get more profit!

get.cryptobrowser.site

 

앱에서 앱으로 호출

Info.plist 설정 후 OpenURL함수를 통해 호출한다.

 

Info.plist 설정

  • 호출하는 쪽 URL Scheme 설정 (샘플앱 명 : sendApp)

 

  • 호출받는 쪽 URL Scheme 설정 (샘플앱 명 : receiveApp)

 

※ Xcode 11부터 SceneDelegate가 기본 iOS 앱 프로젝트 템플릿으로 자동으로 추가되면서 AppDelegate의 openURL 함수가 호출 되지 않으므로 SceneDelegate의 openURLContexts 함수에서 처리해야 한다.

// SceneDelegate.swift
func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) {
    if let url = URLContexts.first?.url {
        print("url = \(url)")
    }
}
// SceneDelegate.m
- (void)scene:(UIScene *)scene openURLContexts:(NSSet *)URLContexts {
    UIOpenURLContext *context = URLContexts.anyObject;
    NSURL *url = context.URL;
    NSLog(@"url = %@",url);
}
// Swift 앱 호출 샘플코드
if UIApplication.shared.canOpenURL(url) {
    if #available(iOS 10.0, *) {
        UIApplication.shared.open(url, options: [:], completionHandler: { (success) in

        })
    } else {
        UIApplication.shared.openURL(url)
    }
}
        
// Objective-C 앱 호출 샘플코드
if (YES == [[UIApplication sharedApplication] canOpenURL:url]) {
    if (@available(iOS 10.0, *)) {
        [[UIApplication sharedApplication] openURL:url options:@{} completionHandler:^(BOOL success) {}];
    } else {
        [[UIApplication sharedApplication] openURL:url];
    }
    return;
}

 

 

모바일 웹에서 앱 호출

  • 웹 브라우저(사파리,크롬 등)을 통한 웹사이트에서 앱 호출
window.location = "receiveApp://";

 

  • 웹뷰(WKWebView)를 통한 웹사이트에서 앱 호출

      ※ 주의 : 이 경우 해당 URL scheme이 호출될 때 직접 코드로 호출 해 주어야 한다. 

func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
    guard let url = navigationAction.request.url else {
        decisionHandler(.cancel)
        return
    }
    
    if (url.absoluteString.hasPrefix("receiveApp://")) {
        if UIApplication.shared.canOpenURL(url) {
            if #available(iOS 10.0, *) {
                UIApplication.shared.open(url, options: [:], completionHandler: { (success) in
                    
                })
            } else {
                UIApplication.shared.openURL(url)
            }
        }
        decisionHandler(.cancel)
        return
    }
    
    ... 중간생략 ...
}

 

스마트폰 BTC 채굴앱

https://get.cryptobrowser.site/34473645

 

Earn coins while browsing the web

Earn bitcoins while watching videos, chatting, or playing online. It has never been so easy to increase your income! Tell your friends about CryptoTab Browser, invite them to join, and earn more together. Grow your network—get more profit!

get.cryptobrowser.site

 

2021/01/06 - [iOS/Swift] - String to CGFloat

2021/01/05 - [iOS/Tips] - SceneDelegate 포인터 구하기

2021/01/05 - [iOS/Tips] - 앱 호출 (URL scheme)

2020/12/24 - [개발노트] - 라이선스 종류

2020/12/24 - [OS/Mac OS X] - MacBook을 AP로 설정하는 방법

2020/12/18 - [Arduino] - Bit Rate, Baud Rate

2020/12/18 - [Arduino] - RS232 Serial 통신 불량체크

2020/12/17 - [프로그래밍/Java] - Java HotSpot(TM) 64-Bit Server VM warning: Sharing is only supported for boot loader classes because bootstrap classpath has been appended

2020/12/17 - [OS/Mac OS X] - OpenSSL을 이용한 Key 정보 Text 변환

2020/12/17 - [프로그래밍/Java] - RSA 암복호화

2020/12/17 - [iOS/Tips] - URL query 파싱 및 json string 변환

2020/12/16 - [개발노트] - Code 128 Barcode의 Check Digit 계산방법

2020/12/15 - [iOS/Tips] - 디버깅 차단 처리 (Anti Debug)

2020/12/14 - [iOS/Tips] - bundle id 알아내기

2020/12/12 - [AI/Algorithm] - 2D 충돌처리

반응형

'개발 > iOS' 카테고리의 다른 글

String to CGFloat  (0) 2021.01.06
SceneDelegate 포인터 구하기  (0) 2021.01.05
URL query 파싱 및 json string 변환  (0) 2020.12.17
디버깅 차단 처리 (Anti Debug)  (0) 2020.12.15
bundle id 알아내기  (0) 2020.12.14
블로그 이미지

SKY STORY

,
반응형
// 사용 방법
let url = URL(string:"https://www.test.com/myconmand?param1=ASDF&param2=1234")!
let qParams = url.queryParams().toJsonString()
let param2 = url.valueOf("param2")

print(
    """
    scheme      = \(url.scheme ?? "")
    host        = \(url.host ?? "")
    path        = \(url.path)
    query       = \(url.query ?? "")
    qParams     = \(qParams)
    param2      = \(param2 ?? "")
    """
)

// 결과 
scheme      = https
host        = www.test.com
path        = /myconmand
query       = param1=ASDF&param2=1234
qParams     = {"param1":"ASDF","param2":"1234"}
param2      = 1234
extension URL {
    
    func queryParams() -> [String:Any] {
        let queryItems = URLComponents(url: self, resolvingAgainstBaseURL: false)?.queryItems
        let queryTuples: [(String, Any)] = queryItems?.compactMap{
            guard let value = $0.value else { return nil }
            return ($0.name, value)
        } ?? []
        return Dictionary(uniqueKeysWithValues: queryTuples)
    }
    
    func valueOf(_ queryParamaterName: String) -> String? {
        guard let url = URLComponents(string: self.absoluteString) else { return nil }
        return url.queryItems?.first(where: { $0.name == queryParamaterName })?.value
    }
    
}
extension Dictionary {

    func toJsonData() -> Data {
        var jsonData: Data?
        do {
            jsonData = try JSONSerialization.data(withJSONObject: self, options: .init(rawValue: 0))
        } catch {
            print(error)
        }
        return jsonData!
    }

    func toJsonDataPrettyPrinted() -> Data {
        var jsonData: Data?
        do {
            jsonData = try JSONSerialization.data(withJSONObject: self, options: JSONSerialization.WritingOptions.prettyPrinted)
        } catch {
            print(error)
        }
        return jsonData!
    }
    
    func toJsonString() -> String {
        return toJsonData().toString()
    }
    
    func toPrettyPrintedJsonString() -> String {
        return toJsonDataPrettyPrinted().toString()
    }
    
}
extension Data {
    func hexString() -> String {
        return map { String(format: "%02hhx", $0) }.joined()
    }
    
    func toString() -> String {
        return String(data: self, encoding: String.Encoding.utf8)!
    }
}

 

2020/12/16 - [개발노트] - Code 128 Barcode의 Check Digit 계산방법

2020/12/15 - [iOS/Tips] - 디버깅 차단 처리 (Anti Debug)

2020/12/14 - [iOS/Tips] - bundle id 알아내기

2020/12/12 - [AI/Algorithm] - 2D 충돌처리

2020/12/11 - [iOS/Swift] - UIViewController 스위칭

2020/12/11 - [개발노트] - PlantUML 설치 (Mac OS X)

2020/12/11 - [개발노트] - 특수문자 발음

2020/12/10 - [iOS/Objective-C] - 웹뷰에서 javascript 함수 동기식 호출

2020/12/10 - [iOS/Tips] - Fat Static Library 빌드 (2/2)

2020/12/10 - [iOS/Tips] - Fat Static Library 빌드 (1/2)

2020/12/10 - [iOS/Tips] - Custom UserAgent 설정

2020/12/10 - [iOS/Tips] - CocoaPods 설치 및 제거

2020/12/10 - [iOS/Tips] - Clang diagnostic 경고 무시하기

2020/12/10 - [개발노트] - Bluetooth UUID

2020/12/08 - [개발노트] - 모바일 앱 메모리덤프 이슈 해결방법 

반응형

'개발 > iOS' 카테고리의 다른 글

SceneDelegate 포인터 구하기  (0) 2021.01.05
앱 호출 (URL scheme)  (0) 2021.01.05
디버깅 차단 처리 (Anti Debug)  (0) 2020.12.15
bundle id 알아내기  (0) 2020.12.14
UIViewController 스위칭  (0) 2020.12.11
블로그 이미지

SKY STORY

,
반응형

스마트폰 BTC 채굴앱

https://get.cryptobrowser.site/34473645

 

Earn coins while browsing the web

Earn bitcoins while watching videos, chatting, or playing online. It has never been so easy to increase your income! Tell your friends about CryptoTab Browser, invite them to join, and earn more together. Grow your network—get more profit!

get.cryptobrowser.site

 

앱 실행 시 디버깅 정보 접근 차단 처리

아래 클래스는 Objective-C, C 언어로 작성되었고

Swift 프로젝트에 사용되었습니다.

Release 빌드시에만 적용되도록 처리하였습니다. 

//
//  AntiDebug.h
//
//  Created by netcanis on 2020/05/22.
//  Copyright © 2020 netcanis. All rights reserved.
//

#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

@interface AntiDebug : NSObject

+ (BOOL)run;

@end

NS_ASSUME_NONNULL_END

 

//
//  AntiDebug.m
//
//  Created by netcanis on 2020/05/22.
//  Copyright © 2020 netcanis. All rights reserved.
//

#import "AntiDebug.h"
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>


////////////////////////////////////////////////////////////////////////
// 배포시 자동으로 안티디버깅 활성화 - 0:디버깅 연결, 1:디버깅 차단
#ifdef DEBUG
#define ANTI_DEBUG      (0) // 개발시 - 디버깅
#else
#define ANTI_DEBUG      (1) // 배포시 - 디버깅 차단
#endif//DEBUG
////////////////////////////////////////////////////////////////////////


//
// Anti Debug 처리
//

#if ANTI_DEBUG

// For debugger_ptrace.
// Ref: https://www.theiphonewiki.com/wiki/Bugging_Debuggers
#import <dlfcn.h>
#import <sys/types.h>

// For debugger_sysctl
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/sysctl.h>
#include <stdlib.h>

// For ioctl
#include <termios.h>
#include <sys/ioctl.h>

// For task_get_exception_ports
#include <mach/task.h>
#include <mach/mach_init.h>

// For kdebug_signpost
#import <sys/kdebug_signpost.h>

typedef int (*ptrace_ptr_t)(int _request, pid_t _pid, caddr_t _addr, int _data);

#if !defined(PT_DENY_ATTACH)
#define PT_DENY_ATTACH 31
#endif  // !defined(PT_DENY_ATTACH)

/*!
 @brief This is the basic ptrace functionality.
 @link http://www.coredump.gr/articles/ios-anti-debugging-protections-part-1/
 */
void debugger_ptrace()
{
    void* handle = dlopen(0, RTLD_GLOBAL | RTLD_NOW);
    ptrace_ptr_t ptrace_ptr = dlsym(handle, "ptrace");
    ptrace_ptr(PT_DENY_ATTACH, 0, 0, 0);
    dlclose(handle);
}

/*!
 @brief This function uses sysctl to check for attached debuggers.
 @link https://developer.apple.com/library/mac/qa/qa1361/_index.html
 @link http://www.coredump.gr/articles/ios-anti-debugging-protections-part-2/
 */
static bool debugger_sysctl(void)
// Returns true if the current process is being debugged (either
// running under the debugger or has a debugger attached post facto).
{
    int mib[4];
    struct kinfo_proc info;
    size_t info_size = sizeof(info);
    
    // Initialize the flags so that, if sysctl fails for some bizarre
    // reason, we get a predictable result.
    
    info.kp_proc.p_flag = 0;
    
    // Initialize mib, which tells sysctl the info we want, in this case
    // we're looking for information about a specific process ID.
    
    mib[0] = CTL_KERN;
    mib[1] = KERN_PROC;
    mib[2] = KERN_PROC_PID;
    mib[3] = getpid();
    
    // Call sysctl.
    
    if (sysctl(mib, 4, &info, &info_size, NULL, 0) == -1)
    {
        perror("perror sysctl");
        exit(-1);
    }
    
    // We're being debugged if the P_TRACED flag is set.
    
    return ((info.kp_proc.p_flag & P_TRACED) != 0);
}

static bool antiDebug(void)
{
//    // Determine if iOS device is 32- or 64-bit
//    if (sizeof(void*) == 4) {
//        NSLog(@"32-bit App");
//    } else if (sizeof(void*) == 8) {
//        NSLog(@"64-bit App");
//    }
    
    
    // If enabled the program should exit with code 055 in GDB
    // Program exited with code 055.
    debugger_ptrace();
    NSLog(@"Bypassed ptrace()");
    
    // If enabled the program should exit with code 0377 in GDB
    // Program exited with code 0377.
    if (debugger_sysctl())
    {
        //return -1;
        return NO;
    } else {
        NSLog(@"Bypassed sysctl()");
    }
    
    // Another way of calling ptrace.
    // Ref: https://www.theiphonewiki.com/wiki/Kernel_Syscalls
    #if __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_10_0
    // 'syscall' is deprecated: first deprecated in iOS 10.0 - syscall(2) is unsupported;
    // please switch to a supported interface.
    // For SYS_kdebug_trace use kdebug_signpost().
    syscall(26, 31, 0, 0);
    NSLog(@"Bypassed syscall()");
    #endif
    
    // Ref: https://reverse.put.as/wp-content/uploads/2012/07/Secuinside-2012-Presentation.pdf
    struct ios_execp_info
    {
        exception_mask_t masks[EXC_TYPES_COUNT];
        mach_port_t ports[EXC_TYPES_COUNT];
        exception_behavior_t behaviors[EXC_TYPES_COUNT];
        thread_state_flavor_t flavors[EXC_TYPES_COUNT];
        mach_msg_type_number_t count;
    };
    struct ios_execp_info *info = malloc(sizeof(struct ios_execp_info));
    kern_return_t kr = task_get_exception_ports(mach_task_self(), EXC_MASK_ALL, info->masks, &info->count, info->ports, info->behaviors, info->flavors);
    NSLog(@"Routine task_get_exception_ports : %d", kr);
    
    for (int i = 0; i < info->count; i++)
    {
        if (info->ports[i] !=0 || info->flavors[i] == THREAD_STATE_NONE)
        {
            NSLog(@"Being debugged... task_get_exception_ports");
        } else {
            NSLog(@"task_get_exception_ports bypassed");
        }
    }
    
    // Another way of figuring out if LLDB is attached.
    if (isatty(1)) {
        NSLog(@"Being Debugged isatty");
    } else {
        NSLog(@"isatty() bypassed");
    }
    
    // Yet another way of figuring out if LLDB is attached.
    if (!ioctl(1, TIOCGWINSZ)) {
        NSLog(@"Being Debugged ioctl");
    } else {
        NSLog(@"ioctl bypassed");
    }
    
    // Everything above relies on libraries. It is easy enough to hook these libraries and return the required
    // result to bypass those checks. So here it is implemented in ARM assembly. Not very fun to bypass these.
#ifdef __arm__
    asm volatile (
                  "mov r0, #31\n"
                  "mov r1, #0\n"
                  "mov r2, #0\n"
                  "mov r12, #26\n"
                  "svc #80\n"
                  );
    NSLog(@"Bypassed syscall() ASM");
#endif
#ifdef __arm64__
    asm volatile (
                  "mov x0, #26\n"
                  "mov x1, #31\n"
                  "mov x2, #0\n"
                  "mov x3, #0\n"
                  "mov x16, #0\n"
                  "svc #128\n"
                  );
    NSLog(@"Bypassed syscall() ASM64");
#endif
    
    return YES;
}
#endif//ANTI_DEBUG


@implementation AntiDebug

+ (BOOL)run {
#if ANTI_DEBUG
    return antiDebug();
#endif
    return YES;
}

@end

 

//
//  XXX-Bridging-Header.h
//
//  Created by netcanis on 2019/11/25.
//  Copyright © 2019 netcanis. All rights reserved.
//

#ifndef XXX_Bridging_Header_h
#define XXX_Bridging_Header_h

#import "AntiDebug.h"

#endif /* XXX_Bridging_Header_h */

 

//
//  AppDelegate.swift
//
//  Created by netcanis on 2019/11/25.
//  Copyright © 2019 netcanis. All rights reserved.
//

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        // Override point for customization after application launch.

        guard AntiDebug.run() else {
            return false
        }
        
		... 생략 ...
    
        return true
    }

 

스마트폰 BTC 채굴앱

https://get.cryptobrowser.site/34473645

 

Earn coins while browsing the web

Earn bitcoins while watching videos, chatting, or playing online. It has never been so easy to increase your income! Tell your friends about CryptoTab Browser, invite them to join, and earn more together. Grow your network—get more profit!

get.cryptobrowser.site

 

2020/12/14 - [iOS/Tips] - bundle id 알아내기

2020/12/12 - [AI/Algorithm] - 2D 충돌처리

2020/12/11 - [iOS/Swift] - UIViewController 스위칭

2020/12/11 - [개발노트] - PlantUML 설치 (Mac OS X)

2020/12/11 - [개발노트] - 특수문자 발음

2020/12/10 - [iOS/Objective-C] - 웹뷰에서 javascript 함수 동기식 호출

2020/12/10 - [iOS/Tips] - Fat Static Library 빌드 (2/2)

2020/12/10 - [iOS/Tips] - Fat Static Library 빌드 (1/2)

2020/12/10 - [iOS/Tips] - Custom UserAgent 설정

2020/12/10 - [iOS/Tips] - CocoaPods 설치 및 제거

2020/12/10 - [iOS/Tips] - Clang diagnostic 경고 무시하기

2020/12/10 - [개발노트] - Bluetooth UUID

2020/12/08 - [개발노트] - 모바일 앱 메모리덤프 이슈 해결방법

2020/12/08 - [프로그래밍/Java Script] - Android, iOS 앱 설치여부 체크 및 스토어 이동

2020/08/21 - [Android/Tips] - aab파일 apk파일로 변환

2020/08/11 - [iOS/Swift] - WKWebView 화면 출력 완료 이벤트

2020/08/06 - [iOS/Tips] - 개발관련 폴더 경로

2020/07/19 - [Android/Tips] - 안드로이드 원격 디버깅 방법

반응형

'개발 > iOS' 카테고리의 다른 글

앱 호출 (URL scheme)  (0) 2021.01.05
URL query 파싱 및 json string 변환  (0) 2020.12.17
bundle id 알아내기  (0) 2020.12.14
UIViewController 스위칭  (0) 2020.12.11
웹뷰에서 javascript 함수 동기식 호출  (0) 2020.12.10
블로그 이미지

SKY STORY

,

bundle id 알아내기

개발/iOS 2020. 12. 14. 15:15
반응형

스마트폰 BTC 채굴앱
https://get.cryptobrowser.site/34473645

 

Earn coins while browsing the web

Earn bitcoins while watching videos, chatting, or playing online. It has never been so easy to increase your income! Tell your friends about CryptoTab Browser, invite them to join, and earn more together. Grow your network—get more profit!

get.cryptobrowser.site


iOS기기에 설치된 앱의 bundle id를 알아내는 방법을 알아보자.
직접 개발중이라면 당연히 알 수 있지만 앱스토어에서 설치한 앱의 번들아이디를 얻으려면 어떻게 할까.
물론 탈옥되지 않은 폰으로 말이다.

ipa 파일의 번들아이디를 구할 경우 :

- ipa확장자를 zip으로 변경한 뒤 압축을 푼다.
- 디렉토리 내에 XXX.app파일을 선택하고 우클릭하여 'Show Package Contents' 선택

- 폴더 내 'Info.plist'파일을 열어 원하는 정보를 취득한다.
- bundle id에 대한 키는 'CFBundleURLName'이다.

앱스토어에서 설치한 앱의 경우 :

- Console.app 실행

- 기기를 연결하고 앱을 실행한다.
- 좌측 Devices 목록에서 디바이스 선택
- 우측 상단 검색으로 '(bundle)'라고 입력

- 설치된 앱들의 bundle id중 찾고자 한 앱을 찾는다.


스마트폰 BTC 채굴앱
https://get.cryptobrowser.site/34473645

 

Earn coins while browsing the web

Earn bitcoins while watching videos, chatting, or playing online. It has never been so easy to increase your income! Tell your friends about CryptoTab Browser, invite them to join, and earn more together. Grow your network—get more profit!

get.cryptobrowser.site


2020/12/12 - [AI/Algorithm] - 2D 충돌처리
2020/12/11 - [iOS/Swift] - UIViewController 스위칭
2020/12/11 - [개발노트] - PlantUML 설치 (Mac OS X)
2020/12/11 - [개발노트] - 특수문자 발음
2020/12/10 - [iOS/Objective-C] - 웹뷰에서 javascript 함수 동기식 호출
2020/12/10 - [iOS/Tips] - Fat Static Library 빌드 (2/2)
2020/12/10 - [iOS/Tips] - Fat Static Library 빌드 (1/2)
2020/12/10 - [iOS/Tips] - Custom UserAgent 설정

반응형

'개발 > iOS' 카테고리의 다른 글

URL query 파싱 및 json string 변환  (0) 2020.12.17
디버깅 차단 처리 (Anti Debug)  (0) 2020.12.15
UIViewController 스위칭  (0) 2020.12.11
웹뷰에서 javascript 함수 동기식 호출  (0) 2020.12.10
Fat Static Library 빌드 (2/2)  (0) 2020.12.10
블로그 이미지

SKY STORY

,
반응형

손쉬운 업데이트를 위해 대부분의 회사에서 하이브리드 앱으로 개발을 합니다.

이 과정에 특정 서비스의 경우 웹뷰를 따로 구성해야하는 상황이 발생합니다.

예를들어, AViewController, BViewController와 같이 UIViewController를 상속받는 ViewController를 따로 생성하여 웹뷰를 구성하게 됩니다. 이러한 구성에 따로 생성된 뷰컨트럴러간 스위칭이 필요한 경우가 발생합니다.

+ UINavigationController

   - AViewController

   - BViewController

   - CViewController

위와 같은 경우 마지막에 추가된 CViewController가 화면에 출력됩니다.

UINavigationController의 뷰컨트럴러 배열의 순서를 변경하면 원하는 뷰컨트럴러를 최상단으로 올릴 수 있습니다.

다음은 해당 기능을 구현한 클래스입니다.

extension UINavigationController {
	// 주어진 UIViewController를 제거합니다.
    func removeVC(_ kindClass: AnyClass) {
        self.viewControllers = self.viewControllers.filter {!$0.isKind(of:kindClass)}
    }
    
    // 주어진 UIViewController가 존재하는지 체크
    func containsVC(_ kindClass: AnyClass) -> Bool {
        return self.viewControllers.contains(where: {$0.isKind(of:kindClass)})
    }
    
    // 주어진 UIViewController를 최상위에 출력되도록 합니다.
    func setTopVC(_ kindClass: AnyClass) -> UIViewController? {
        var stack: [UIViewController] = self.viewControllers
        var index: Int = 0
        for vc in stack {
            if vc.isKind(of: kindClass) {
                stack.remove(at: index)
                stack.append(vc)
                self.viewControllers = stack
                return vc
            }
            index += 1
        }
        return nil
    }
    
    // 주어진 UIViewController를 존재하는 경우 최상위에 출력되도록 합니다.
    func activateVC(_ kindClass: AnyClass) {
        if containsVC(kindClass) {
            _ = setTopVC(kindClass)
        }
    }
}

extension UIViewController {
	// 옵져버 추가
    func addObserver(_ aSelector: Selector) {
        NotificationCenter.default.addObserver(self,
                                               selector: aSelector,
                                               name: NSNotification.Name(self.theClassName),
                                               object: nil)
    }
	
    // 옵져버 삭제
    func removeObserver() {
        NotificationCenter.default.removeObserver(self)
    }
    
    // 타깃 뷰컨트럴러로 데이터 전달 
    func post(_ targetClassName: String, _ userInfo: [AnyHashable : Any], _ delay: Double = 0.0) {
        let delayTime: Double = (delay < 0) ? 1.0 : delay
        Timer.scheduledTimer(withTimeInterval: delayTime, repeats: false, block: {_ in
            NotificationCenter.default.post(name: NSNotification.Name(targetClassName),
            object: nil,
            userInfo: userInfo)
        })
    }
}



//
// BViewController
// 

override func viewDidLoad() {
    super.viewDidLoad()
    addObserver(#selector(onCommand))
    ... 중간 생략 ...
}
        
deinit {
    removeObserver()
}

... 중간 생략 ...

@objc func onCommand(notification: Notification) {
    guard notification.name.rawValue == self.theClassName else { return }
    guard let userInfo = notification.userInfo else { return }
    
    let name = userInfo["name"] as? String ?? ""
    if name == "이벤트이름" {
        let paramString = userInfo["data"] as! String
        self.sendScript(name: "이벤트이름", result: paramString)
    }
    else {
        //self.userMethod = name
        //self.userInfo = userInfo["data"] as! Dictionary <String, Any>
    }
}

    

//
// 사용 방법
// : 아래 내용은 CViewController에서 BViewController로 이벤트 데이터를 전달 및 화면 스위칭한다.
//

// BViewController에 이벤트 데이터 정보 전달
post("BViewController", ["name" : "이벤트이름", "data" : "전달할 데이터 정보"])

// 0.5초 딜레이 주어 웹뷰 로딩 시간을 주었다.
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
	self.navigationController?.activateVC(BViewController.self)
}

 

2020/12/11 - [iOS/Swift] - UIViewController 스위칭

2020/12/11 - [개발노트] - PlantUML 설치 (Mac OS X)

2020/12/11 - [분류 전체보기] - Tones And I - Dance Monkey

2020/12/11 - [lyrics] - Beyonce - Halo

2020/12/11 - [개발노트] - 특수문자 발음

2020/12/10 - [iOS/Objective-C] - 웹뷰에서 javascript 함수 동기식 호출

2020/12/10 - [iOS/Tips] - Fat Static Library 빌드 (2/2)

2020/12/10 - [iOS/Tips] - Fat Static Library 빌드 (1/2)

2020/12/10 - [iOS/Tips] - Custom UserAgent 설정

2020/12/10 - [iOS/Tips] - CocoaPods 설치 및 제거

2020/12/10 - [iOS/Tips] - Clang diagnostic 경고 무시하기

2020/12/10 - [개발노트] - Bluetooth UUID

2020/12/08 - [개발노트] - 모바일 앱 메모리덤프 이슈 해결방법

2020/12/08 - [프로그래밍/Java Script] - Android, iOS 앱 설치여부 체크 및 스토어 이동

2020/08/21 - [Android/Tips] - aab파일 apk파일로 변환

반응형

'개발 > iOS' 카테고리의 다른 글

디버깅 차단 처리 (Anti Debug)  (0) 2020.12.15
bundle id 알아내기  (0) 2020.12.14
웹뷰에서 javascript 함수 동기식 호출  (0) 2020.12.10
Fat Static Library 빌드 (2/2)  (0) 2020.12.10
Fat Static Library 빌드 (1/2)  (1) 2020.12.10
블로그 이미지

SKY STORY

,