আইফোন ডেটা ব্যবহার ট্র্যাকিং / পর্যবেক্ষণ


136

আমি এই বিষয়ে অনুসন্ধান করেছি কিন্তু খুব কম বিশদ খুঁজে পেয়েছি যা সহায়ক ছিল। এই বিবরণ দিয়ে আমি নিম্নলিখিত হিসাবে কিছু কোড রান্না করার চেষ্টা করেছি।

দ্রষ্টব্য: অনুগ্রহ করে এই পোস্টে ভাগ করা বিশদটি কেবলমাত্র বিষয় দ্বারা নয়, এটি ডুপ্লিকেট হিসাবে চিহ্নিত করার আগে অন্যান্য পোস্টগুলির সাথে তুলনা করুন।

- (NSArray *)getDataCountersForType:(int)type {
    BOOL success;
    struct ifaddrs *addrs = nil;
    const struct ifaddrs *cursor = nil;
    const struct sockaddr_dl *dlAddr = nil;
    const struct if_data *networkStatisc = nil; 

    int dataSent = 0;
    int dataReceived = 0;

    success = getifaddrs(&addrs) == 0;
    if (success) {
        cursor = addrs;
        while (cursor != NULL) {
            if (cursor->ifa_addr->sa_family == AF_LINK) {
                dlAddr = (const struct sockaddr_dl *) cursor->ifa_addr;
                networkStatisc = (const struct if_data *) cursor->ifa_data;

                if (type == WiFi) {
                    dataSent += networkStatisc->ifi_opackets;
                    dataReceived += networkStatisc->ifi_ipackets;   
                }
                else if (type == WWAN) {
                    dataSent += networkStatisc->ifi_obytes;
                    dataReceived += networkStatisc->ifi_ibytes; 
                }
            }
            cursor = cursor->ifa_next;
        }
        freeifaddrs(addrs);
    }       
    return [NSArray arrayWithObjects:[NSNumber numberWithInt:dataSent], [NSNumber numberWithInt:dataReceived], nil];    
}

এই কোডটি একটি আইফোন ডিভাইসের ইন্টারনেট ব্যবহারের তথ্য সংগ্রহ করে (এবং কেবল আমার অ্যাপ্লিকেশন নয়)।

এখন, আমি যদি ওয়াইফাই বা 3 জি এর মাধ্যমে ইন্টারনেট ব্যবহার করি তবে আমি কেবলমাত্র ifi_obytes(প্রেরিত) এবং ifi_ibytes(প্রাপ্ত) ডেটা (বাইট) পাই তবে আমার মনে হয় ifi_opacketsএবং আমার ওয়াইফাই ব্যবহার করা উচিত ifi_ipackets

এছাড়াও যোগ করার জন্য যে যদি আমি একটি ওয়াইফাই নেটওয়ার্কে সংযুক্ত, কিন্তু ইন্টারনেট ব্যবহার করছি না, আমার এখনও মান যুক্ত হয়ে চেয়েছিলেন ifi_obytesএবং ifi_ibytes

আমি বাস্তবায়ন বা বুঝতে ভুল হতে পারে। আমাকে সাহায্য করার জন্য কেউ প্রয়োজন।


সম্পাদনা করুন: পরিবর্তে AF_LINKআমি চেষ্টা করেছি AF_INET( sockaddr_inপরিবর্তে sockaddr_dl)। এটি অ্যাপ্লিকেশনটিকে ক্র্যাশ করে।

উত্তর:


175

জিনিস যে pdp_ip0সকল ইন্টারফেস এক pdpXXXহয় WWANবিভিন্ন ফাংশন, ভয়েসমেল, সাধারণ নেটওয়ার্কিং ইন্টারফেস নিবেদিত ইন্টারফেসগুলি।

আমি অ্যাপল ফোরামে পড়েছি যে: ওএস নেটওয়ার্ক পরিসংখ্যান প্রক্রিয়া-অনুসারে প্রক্রিয়া ভিত্তিতে রাখে না। যেমন, এই সমস্যার সঠিক কোনও সমাধান নেই। তবে আপনি প্রতিটি নেটওয়ার্ক ইন্টারফেসের জন্য নেটওয়ার্ক পরিসংখ্যান পেতে পারেন।

সাধারণভাবে en0আপনার Wi-Fiইন্টারফেস এবং pdp_ip0আপনার WWANইন্টারফেস হয়।

নির্দিষ্ট তারিখ-কাল থেকে তথ্য ওয়াইফাই / সেলুলার নেটওয়ার্ক ডেটা পাওয়ার কোনও ভাল উপায় নেই!

পূর্ববর্তী ডিভাইস রিবুট থেকে ডেটা পরিসংখ্যান ( ifa_data->ifi_obytesএবং ifa_data->ifi_ibytes) সঞ্চিত হয়।

কেন জানি না, তবে কেবল ifi_opacketsএবং ifi_ipacketsএর জন্য প্রদর্শিত হয় lo0(আমি মনে করি এটির মূল ইন্টারফেস)।

হ্যাঁ. তারপরে ডিভাইসটি সংযুক্ত হয়ে গেছে WiFiএবং ইন্টারনেটের if_iobytesমানগুলি ব্যবহার করে না এখনও আসে কারণ এই পদ্ধতিটি কেবল ইন্টারনেট নয়, নেটওয়ার্ক বাইট এক্সচেঞ্জ সরবরাহ করে।

#include <net/if.h>
#include <ifaddrs.h>

static NSString *const DataCounterKeyWWANSent = @"WWANSent";
static NSString *const DataCounterKeyWWANReceived = @"WWANReceived";
static NSString *const DataCounterKeyWiFiSent = @"WiFiSent";
static NSString *const DataCounterKeyWiFiReceived = @"WiFiReceived";

NSDictionary *DataCounters()
{
    struct ifaddrs *addrs;
    const struct ifaddrs *cursor;

    u_int32_t WiFiSent = 0;
    u_int32_t WiFiReceived = 0;
    u_int32_t WWANSent = 0;
    u_int32_t WWANReceived = 0;

    if (getifaddrs(&addrs) == 0)
    {
        cursor = addrs;
        while (cursor != NULL)
        {
            if (cursor->ifa_addr->sa_family == AF_LINK)
            {
#ifdef DEBUG
                const struct if_data *ifa_data = (struct if_data *)cursor->ifa_data;
                if (ifa_data != NULL)
                {
                    NSLog(@"Interface name %s: sent %tu received %tu",cursor->ifa_name,ifa_data->ifi_obytes,ifa_data->ifi_ibytes);
                }
#endif

                // name of interfaces:
                // en0 is WiFi
                // pdp_ip0 is WWAN
                NSString *name = @(cursor->ifa_name);
                if ([name hasPrefix:@"en"])
                {
                    const struct if_data *ifa_data = (struct if_data *)cursor->ifa_data;
                    if (ifa_data != NULL)
                    {
                        WiFiSent += ifa_data->ifi_obytes;
                        WiFiReceived += ifa_data->ifi_ibytes;
                    }
                }

                if ([name hasPrefix:@"pdp_ip"])
                {
                    const struct if_data *ifa_data = (struct if_data *)cursor->ifa_data;
                    if (ifa_data != NULL)
                    {
                        WWANSent += ifa_data->ifi_obytes;
                        WWANReceived += ifa_data->ifi_ibytes;
                    }
                }
            }

            cursor = cursor->ifa_next;
        }

        freeifaddrs(addrs);
    }

    return @{DataCounterKeyWiFiSent : @(WiFiSent),
             DataCounterKeyWiFiReceived : @(WiFiReceived),
             DataCounterKeyWWANSent : @(WWANSent),
             DataCounterKeyWWANReceived : @(WWANReceived)};
}

উন্নত অনুলিপি / পেস্ট সমর্থন!


1
অনেক ধন্যবাদ. এই কোডটি বিস্ময়করভাবে কাজ করেছিল। এছাড়াও স্টাফ ব্যাখ্যা করার জন্য ধন্যবাদ।
সাহিল খান্না

20
আপনাকে এই লাইব্রেরিগুলি আমদানি করতে হবে: # অন্তর্ভুক্ত <আরপা / ইনট.h> # অন্তর্ভুক্ত <নেট / if.h> # অন্তর্ভুক্ত <ifaddrs.h> # অন্তর্ভুক্ত <নেট / if_dl.h>
ব্যবহারকারী982705

9
এই কোড দিয়ে আইওএস অ্যাপ্লিকেশন প্রতি ডেটা ট্র্যাফিক ট্র্যাক করা সম্ভব?
fvisticot

2
@ ম্যাট: আমি যদি সমাধানটি এন্টারপ্রাইজ ক্লায়েন্টদের জন্য তৈরি করে থাকি এবং অ্যাপস্টোরে স্থাপন না করি তবে।
সাহিল খান্না

4
প্রতি অ্যাপ্লিকেশন ডেটা কীভাবে পাবেন? দয়া করে কোডটি শেয়ার করুন :)
বব ডি গ্রাফ

16

এটি বুঝতে গুরুত্বপূর্ণ যে এই কাউন্টারগুলি ডিভাইসের শেষ বুট হওয়ার পরে সরবরাহ করা হয়েছে।

সুতরাং, তাদের ফলপ্রসু ব্যবহার নিশ্চিত করতে জন্য, আপনাকে ডিভাইস এর আপটাইম প্রতি নমুনা সংসর্গে উচিত (আপনি ব্যবহার করতে পারেন mach_absolute_time()- দেখুন এই আরও তথ্যের জন্য)

একবার আপনার কাছে কাউন্টারের নমুনা + আপটাইম থাকলে আপনার ডেটা ব্যবহারের ক্ষেত্রে আরও ভাল হিউরিস্টিকস থাকতে পারে ...


mach_absolve_Time আপটাইম নয়। সিপিইউ সক্রিয় হওয়ার সময় এটি প্রায়। ডিভাইসটি যখন ঘুমায় তখন ম্যাক_অবসিউল_টাইম বেশিরভাগ গণনা বন্ধ করে দেয়।
বব হোয়াইটম্যান

13

গৃহীত উত্তরের সাথে যুক্ত করার জন্য, এটি বুঝতে গুরুত্বপূর্ণ যে ইন্টারফেসের দ্বারা প্রদর্শিত পরিমাণের পরিমাণ ওভারফ্লো হয়ে যায় এবং 0প্রতিটি পরে পুনরায় আরম্ভ হয় 4 GB, বিশেষত যদি আপনি দুটি কোডিংয়ের মধ্যে পার্থক্য গণনা করতে এই কোডটি ব্যবহার করছেন। এটি কারণ ifi_obytesএবং ifi_ibytesহয় uint_32এবং তাদের সর্বাধিক মান 4294967295

এছাড়াও, আমি unsigned intপ্রেরিত এবং প্রাপ্ত ডেটাযুক্ত ভেরিয়েবলগুলির জন্য গুলি ব্যবহার করার পরামর্শ দিচ্ছি । নিয়মিত intএসগুলিতে স্বাক্ষরযুক্ত স্বাক্ষরের পূর্ণসংখ্যার অর্ধেকতম মান থাকে, সুতরাং যুক্ত করার সময় ifi_obytesএটি একটি ওভারফ্লো হতে পারে।

unsigned int sent = 0;
sent += networkStatisc->ifi_obytes;

4

গৃহীত উত্তরের দ্রুততম সংস্করণ। আমি কোডটি ছোট ইউনিটগুলিতেও ভাঙ্গি।

struct DataUsageInfo {
    var wifiReceived: UInt32 = 0
    var wifiSent: UInt32 = 0
    var wirelessWanDataReceived: UInt32 = 0
    var wirelessWanDataSent: UInt32 = 0

    mutating func updateInfoByAdding(info: DataUsageInfo) {
        wifiSent += info.wifiSent
        wifiReceived += info.wifiReceived
        wirelessWanDataSent += info.wirelessWanDataSent
        wirelessWanDataReceived += info.wirelessWanDataReceived
    }
}

class DataUsage {

    private static let wwanInterfacePrefix = "pdp_ip"
    private static let wifiInterfacePrefix = "en"

    class func getDataUsage() -> DataUsageInfo {
        var interfaceAddresses: UnsafeMutablePointer<ifaddrs> = nil
        var dataUsageInfo = DataUsageInfo()

        guard getifaddrs(&interfaceAddresses) == 0 else { return dataUsageInfo }

        var pointer = interfaceAddresses
        while pointer != nil {
            guard let info = getDataUsageInfo(from: pointer) else {
                pointer = pointer.memory.ifa_next
                continue
            }
            dataUsageInfo.updateInfoByAdding(info)
            pointer = pointer.memory.ifa_next
        }

        freeifaddrs(interfaceAddresses)

        return dataUsageInfo
    }

    private class func getDataUsageInfo(from infoPointer: UnsafeMutablePointer<ifaddrs>) -> DataUsageInfo? {
        let pointer = infoPointer

        let name: String! = String.fromCString(infoPointer.memory.ifa_name)

        let addr = pointer.memory.ifa_addr.memory
        guard addr.sa_family == UInt8(AF_LINK) else { return nil }

        return dataUsageInfo(from: pointer, name: name)
    }

    private class func dataUsageInfo(from pointer: UnsafeMutablePointer<ifaddrs>, name: String) -> DataUsageInfo {
        var networkData: UnsafeMutablePointer<if_data> = nil
        var dataUsageInfo = DataUsageInfo()

        if name.hasPrefix(wifiInterfacePrefix) {
            networkData = unsafeBitCast(pointer.memory.ifa_data, UnsafeMutablePointer<if_data>.self)
            dataUsageInfo.wifiSent += networkData.memory.ifi_obytes
            dataUsageInfo.wifiReceived += networkData.memory.ifi_ibytes
        } else if name.hasPrefix(wwanInterfacePrefix) {
            networkData = unsafeBitCast(pointer.memory.ifa_data, UnsafeMutablePointer<if_data>.self)
            dataUsageInfo.wirelessWanDataSent += networkData.memory.ifi_obytes
            dataUsageInfo.wirelessWanDataReceived += networkData.memory.ifi_ibytes
        }

        return dataUsageInfo
    }
}

4

আমি উত্স কোডের উপরে সুইফট 3 সংস্করণে স্থির করেছি

struct DataUsageInfo {
    var wifiReceived: UInt32 = 0
    var wifiSent: UInt32 = 0
    var wirelessWanDataReceived: UInt32 = 0
    var wirelessWanDataSent: UInt32 = 0

    mutating func updateInfoByAdding(_ info: DataUsageInfo) {
        wifiSent += info.wifiSent
        wifiReceived += info.wifiReceived
        wirelessWanDataSent += info.wirelessWanDataSent
        wirelessWanDataReceived += info.wirelessWanDataReceived
    }
}


class DataUsage {

    private static let wwanInterfacePrefix = "pdp_ip"
    private static let wifiInterfacePrefix = "en"

    class func getDataUsage() -> DataUsageInfo {
        var ifaddr: UnsafeMutablePointer<ifaddrs>?
        var dataUsageInfo = DataUsageInfo()

        guard getifaddrs(&ifaddr) == 0 else { return dataUsageInfo }
        while let addr = ifaddr {
            guard let info = getDataUsageInfo(from: addr) else {
                ifaddr = addr.pointee.ifa_next
                continue
            }
            dataUsageInfo.updateInfoByAdding(info)
            ifaddr = addr.pointee.ifa_next
        }

        freeifaddrs(ifaddr)

        return dataUsageInfo
    }

    private class func getDataUsageInfo(from infoPointer: UnsafeMutablePointer<ifaddrs>) -> DataUsageInfo? {
        let pointer = infoPointer
        let name: String! = String(cString: pointer.pointee.ifa_name)
        let addr = pointer.pointee.ifa_addr.pointee
        guard addr.sa_family == UInt8(AF_LINK) else { return nil }

        return dataUsageInfo(from: pointer, name: name)
    }

    private class func dataUsageInfo(from pointer: UnsafeMutablePointer<ifaddrs>, name: String) -> DataUsageInfo {
        var networkData: UnsafeMutablePointer<if_data>?
        var dataUsageInfo = DataUsageInfo()

        if name.hasPrefix(wifiInterfacePrefix) {
            networkData = unsafeBitCast(pointer.pointee.ifa_data, to: UnsafeMutablePointer<if_data>.self)
            if let data = networkData {
                dataUsageInfo.wifiSent += data.pointee.ifi_obytes
                dataUsageInfo.wifiReceived += data.pointee.ifi_ibytes
            }

        } else if name.hasPrefix(wwanInterfacePrefix) {
            networkData = unsafeBitCast(pointer.pointee.ifa_data, to: UnsafeMutablePointer<if_data>.self)
            if let data = networkData {
                dataUsageInfo.wirelessWanDataSent += data.pointee.ifi_obytes
                dataUsageInfo.wirelessWanDataReceived += data.pointee.ifi_ibytes
            }
        }

        return dataUsageInfo
    }
}

4

পূর্ববর্তী সংস্করণগুলির উপর ভিত্তি করে একটি নতুন সংস্করণ, তবে সুইফট 4 এবং এক্সকোড 9 এর জন্য অভিযোজিত

struct DataUsageInfo {
    var wifiReceived: UInt32 = 0
    var wifiSent: UInt32 = 0
    var wirelessWanDataReceived: UInt32 = 0
    var wirelessWanDataSent: UInt32 = 0

    mutating func updateInfoByAdding(info: DataUsageInfo) {
        wifiSent += info.wifiSent
        wifiReceived += info.wifiReceived
        wirelessWanDataSent += info.wirelessWanDataSent
        wirelessWanDataReceived += info.wirelessWanDataReceived
    }
}

class DataUsage {

    private static let wwanInterfacePrefix = "pdp_ip"
    private static let wifiInterfacePrefix = "en"

    class func getDataUsage() -> DataUsageInfo {
        var interfaceAddresses: UnsafeMutablePointer<ifaddrs>? = nil

        var dataUsageInfo = DataUsageInfo()

        guard getifaddrs(&interfaceAddresses) == 0 else { return dataUsageInfo }

        var pointer = interfaceAddresses
        while pointer != nil {
            guard let info = getDataUsageInfo(from: pointer!) else {
                pointer = pointer!.pointee.ifa_next
                continue
            }
            dataUsageInfo.updateInfoByAdding(info: info)
            pointer = pointer!.pointee.ifa_next
        }

        freeifaddrs(interfaceAddresses)

        return dataUsageInfo
    }

    private class func getDataUsageInfo(from infoPointer: UnsafeMutablePointer<ifaddrs>) -> DataUsageInfo? {
        let pointer = infoPointer

        let name: String! = String(cString: infoPointer.pointee.ifa_name)
        let addr = pointer.pointee.ifa_addr.pointee
        guard addr.sa_family == UInt8(AF_LINK) else { return nil }

        return dataUsageInfo(from: pointer, name: name)
    }

    private class func dataUsageInfo(from pointer: UnsafeMutablePointer<ifaddrs>, name: String) -> DataUsageInfo {
        var networkData: UnsafeMutablePointer<if_data>? = nil
        var dataUsageInfo = DataUsageInfo()

        if name.hasPrefix(wifiInterfacePrefix) {
            networkData = unsafeBitCast(pointer.pointee.ifa_data, to: UnsafeMutablePointer<if_data>.self)
            dataUsageInfo.wifiSent += networkData?.pointee.ifi_obytes ?? 0
            dataUsageInfo.wifiReceived += networkData?.pointee.ifi_ibytes ?? 0
        } else if name.hasPrefix(wwanInterfacePrefix) {
            networkData = unsafeBitCast(pointer.pointee.ifa_data, to: UnsafeMutablePointer<if_data>.self)
            dataUsageInfo.wirelessWanDataSent += networkData?.pointee.ifi_obytes ?? 0
            dataUsageInfo.wirelessWanDataReceived += networkData?.pointee.ifi_ibytes ?? 0
        }

        return dataUsageInfo
    }
}

এটি প্রতিটি অ্যাপ্লিকেশন বা এটি ব্যবহার করা আসল অ্যাপের জন্য দেখায়?
মাকসিম নাইয়াজভ

এটি বিশ্বব্যাপী ব্যবহার ... এটি অ্যাপ্লিকেশন দ্বারা পৃথক নয়।
dede.exe

এবং মানটি শেষ রিবুট থেকে। বিগত / চলতি মাসের জন্য কোনও উপায় নেই?
স্লাভচো

@Slavcho। এই পোস্টের তারিখ পর্যন্ত এটি সম্ভব ছিল না। আমি আইওএস 12 এর পরে এখনও এটি নিয়ে একটি নতুন গবেষণা করিনি। আমি আপনাকে পুনরুদ্ধার করার জন্য কোনও জায়গায় আইআর জমা করার পরামর্শ দিচ্ছি।
dede.exe

0

আবার একই উত্তরের জন্য দুঃখিত।

তবে আমি দেখতে পেয়েছি যে ইউআইএনটি 32 যথেষ্ট নয়, সুতরাং এটি খুব বড় হয়ে গেলে ক্রাশ হয়।

আমি সবেমাত্র UInt32 এ UInt64 এ পরিবর্তন করেছি এবং এটি দুর্দান্ত কাজ করে।

struct DataUsageInfo {
    var wifiReceived: UInt64 = 0
    var wifiSent: UInt64 = 0
    var wirelessWanDataReceived: UInt64 = 0
    var wirelessWanDataSent: UInt64 = 0

    mutating func updateInfoByAdding(info: DataUsageInfo) {
        wifiSent += info.wifiSent
        wifiReceived += info.wifiReceived
        wirelessWanDataSent += info.wirelessWanDataSent
        wirelessWanDataReceived += info.wirelessWanDataReceived
    }
}

class DataUsage {

    private static let wwanInterfacePrefix = "pdp_ip"
    private static let wifiInterfacePrefix = "en"

    class func getDataUsage() -> DataUsageInfo {
        var interfaceAddresses: UnsafeMutablePointer<ifaddrs>? = nil

        var dataUsageInfo = DataUsageInfo()

        guard getifaddrs(&interfaceAddresses) == 0 else { return dataUsageInfo }

        var pointer = interfaceAddresses
        while pointer != nil {
            guard let info = getDataUsageInfo(from: pointer!) else {
                pointer = pointer!.pointee.ifa_next
                continue
            }
            dataUsageInfo.updateInfoByAdding(info: info)
            pointer = pointer!.pointee.ifa_next
        }

        freeifaddrs(interfaceAddresses)

        return dataUsageInfo
    }

    private class func getDataUsageInfo(from infoPointer: UnsafeMutablePointer<ifaddrs>) -> DataUsageInfo? {
        let pointer = infoPointer

        let name: String! = String(cString: infoPointer.pointee.ifa_name)
        let addr = pointer.pointee.ifa_addr.pointee
        guard addr.sa_family == UInt8(AF_LINK) else { return nil }

        return dataUsageInfo(from: pointer, name: name)
    }

    private class func dataUsageInfo(from pointer: UnsafeMutablePointer<ifaddrs>, name: String) -> DataUsageInfo {
        var networkData: UnsafeMutablePointer<if_data>? = nil
        var dataUsageInfo = DataUsageInfo()

        if name.hasPrefix(wifiInterfacePrefix) {
            networkData = unsafeBitCast(pointer.pointee.ifa_data, to: UnsafeMutablePointer<if_data>.self)
            dataUsageInfo.wifiSent += UInt64(networkData?.pointee.ifi_obytes ?? 0)
            dataUsageInfo.wifiReceived += UInt64(networkData?.pointee.ifi_ibytes ?? 0)
        } else if name.hasPrefix(wwanInterfacePrefix) {
            networkData = unsafeBitCast(pointer.pointee.ifa_data, to: UnsafeMutablePointer<if_data>.self)
            dataUsageInfo.wirelessWanDataSent += UInt64(networkData?.pointee.ifi_obytes ?? 0)
            dataUsageInfo.wirelessWanDataReceived += UInt64(networkData?.pointee.ifi_ibytes ?? 0)
        }

        return dataUsageInfo
    }
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.