{"id":12072,"date":"2026-02-20T12:34:33","date_gmt":"2026-02-20T03:34:33","guid":{"rendered":"https:\/\/www.moonmile.net\/blog\/?p=12072"},"modified":"2026-02-20T12:35:27","modified_gmt":"2026-02-20T03:35:27","slug":"iphoneios-%e3%81%a7-ibeacon-%e3%81%a8-en-api-%e7%99%ba%e4%bf%a1%e6%a9%9f%e3%82%92%e4%bd%9c%e3%82%8b","status":"publish","type":"post","link":"http:\/\/www.moonmile.net\/blog\/archives\/12072","title":{"rendered":"iPhone(iOS) \u3067 iBeacon \u3068 EN API \u767a\u4fe1\u6a5f\u3092\u4f5c\u308b"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">\u63a5\u89e6\u78ba\u8a8d\u30a2\u30d7\u30ea\u3067\u306f Android\/iOS \u306e\u76f8\u4e92\u3067 BLE \u901a\u4fe1\u3092\u884c\u3046\u305f\u3081\u306b\u3001iOS \u3067\u306e\u767a\u4fe1\u6a5f\u306e\u30c1\u30a7\u30c3\u30af\u3082\u3057\u3066\u304a\u304d\u307e\u3059\u3002<br>iOS \u306e\u5834\u5408\u306f\u300116 bit Service UUID \u5f62\u5f0f\u3068 Manufacturer Data \u5f62\u5f0f\u3067\u306f\u767a\u4fe1\u3067\u304d\u307e\u305b\u3093\u3002\u304c\u3001&#8221;\u767a\u4fe1\u3067\u304d\u306a\u3044\u3053\u3068&#8221; \u3092\u78ba\u8a8d\u3059\u308b\u305f\u3081\u306b\u3001\u3042\u3048\u3066\u4e21\u65b9\u306e\u5b9f\u88c5\u3082\u3057\u3066\u3042\u308a\u307e\u3059\u3002\u5b9f\u969b\u306b iOS\/Android \u306e\u53d7\u4fe1\u6a5f\u3067\u53d7\u4fe1\u304c\u3067\u304d\u306a\u3044\u3053\u3068\u3092\u78ba\u8a8d\u3057\u3066\u304f\u3060\u3055\u3044\u3002<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">iOS \u306e\u5834\u5408\u3001BLE \u306e\u767a\u4fe1\u30bf\u30a4\u30df\u30f3\u30b0\u3092\u5236\u5fa1\u3059\u308b\u3053\u3068\u306f\u3067\u304d\u307e\u305b\u3093\u3002\u53d7\u4fe1\u6a5f\u306e\u69d8\u5b50\u3092\u898b\u308b\u3068\u3001\u304b\u306a\u308a\u306e\u983b\u5ea6\u3067\u53d7\u4fe1\u3059\u308b\u306e\u3067\u3001Android \u306e Low Latency \u3068\u540c\u7b49\u306e\u767a\u4fe1\u30bf\u30a4\u30df\u30f3\u30b0\u3067\u767a\u4fe1\u3057\u3066\u3044\u308b\u3088\u3046\u3067\u3059\u3002\u3053\u308c\u306f\u3001\u5225\u9014 M5Stack \u3067\u53d7\u4fe1\u6a5f\u3092\u4f5c\u3063\u3066\u8a08\u6e2c\u3057\u3066\u3044\u304d\u305f\u3044\u3068\u601d\u3044\u307e\u3059\u3002<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>SwiftUI \u3067\u4f5c\u308b<\/strong><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u3053\u308c\u3082 SwiftUI \u3067\u4f5c\u308a\u307e\u3059\u3002\u6700\u7d42\u7684\u306b\u306f Flutter \u3068\u304b React Native \u3067\u3082\u3088\u3044\u6c17\u304c\u3059\u308b\u306e\u3067\u3059\u304c\u3001BLE \u307e\u308f\u308a\u306e\u5236\u5fa1\u304c\u3001Android \u3068 iOS \u3067\u304b\u306a\u308a\u7570\u306a\u308b\u306e\u3067\u30cd\u30a4\u30c6\u30a3\u30d6\u306e\u307e\u307e\u3067\u4f5c\u3063\u3066\u3042\u308a\u307e\u3059\u3002<\/p>\n\n\n\n<pre class=\"wp-block-syntaxhighlighter-code\">struct ContentView: View {\n    var body: some View {\n        TabView {\n            BeaconTabView()\n                .tabItem {\n                    Label(\"Beacon\", systemImage: \"antenna.radiowaves.left.and.right\")\n                }\n\n            FolkBearsTabView()\n                .tabItem {\n                    Label(\"FolkBears\", systemImage: \"bear\")\n                }\n\n            ENTabView()\n                .tabItem {\n                    Label(\"EN API\", systemImage: \"wave.3.right\")\n                }\n\n            MfDTabView()\n                .tabItem {\n                    Label(\"MfD\", systemImage: \"shippingbox\")\n                }\n        }\n    }\n}\n\nstruct BeaconTabView: View {\n    @StateObject private var transmitter = BeaconTransmitter()\n    @State private var majorHex: String = \"\"\n    @State private var minorHex: String = \"\"\n\n    var body: some View {\n        NavigationView {\n            Form {\n                Section {\n                    HStack {\n                        Text(\"Bluetooth\")\n                        Spacer()\n                        Text(transmitter.bluetoothState)\n                            .foregroundStyle(.secondary)\n                    }\n                    HStack {\n                        Text(\"\u9001\u4fe1\u72b6\u614b\")\n                        Spacer()\n                        Text(transmitter.transmissionStatus)\n                            .foregroundStyle(transmitter.isTransmitting ? .green : .secondary)\n                    }\n                } header: {\n                    Text(\"\u30b9\u30c6\u30fc\u30bf\u30b9\")\n                }\n\n                Section {\n                    TextField(\"Major (4 hex)\", text: $majorHex)\n                        .textInputAutocapitalization(.none)\n                        .autocorrectionDisabled(true)\n                        .font(.system(.body, design: .monospaced))\n                        .onSubmit(applyMajorMinor)\n\n                    TextField(\"Minor (4 hex)\", text: $minorHex)\n                        .textInputAutocapitalization(.none)\n                        .autocorrectionDisabled(true)\n                        .font(.system(.body, design: .monospaced))\n                        .onSubmit(applyMajorMinor)\n                } header: {\n                    Text(\"Major \/ Minor (hex)\")\n                }\n\n                Section {\n                    Toggle(\"raw iBeacon manufacturer \u3092\u4f7f\u3046\", isOn: $transmitter.useRawIBeaconAdvertising)\n                } header: {\n                    Text(\"\u30aa\u30d7\u30b7\u30e7\u30f3\")\n                }\n\n                Section {\n                    HStack {\n                        Button {\n                            transmitter.startTransmitting()\n                        } label: {\n                            Label(\"\u767a\u4fe1\u958b\u59cb\", systemImage: \"play.fill\")\n                        }\n                        .disabled(transmitter.isTransmitting || transmitter.bluetoothState != \"Powered On\")\n\n                        Button {\n                            transmitter.stopTransmitting()\n                        } label: {\n                            Label(\"\u505c\u6b62\", systemImage: \"stop.fill\")\n                        }\n                        .disabled(!transmitter.isTransmitting)\n                    }\n                } header: {\n                    Text(\"\u64cd\u4f5c\")\n                }\n            }\n            .navigationTitle(\"Beacon\")\n            .onAppear(perform: syncFieldsFromModel)\n        }\n    }\n\n    private func syncFieldsFromModel() {\n        let newMajor = UInt16.random(in: 0...UInt16.max)\n        let newMinor = UInt16.random(in: 0...UInt16.max)\n        transmitter.major = newMajor\n        transmitter.minor = newMinor\n        majorHex = String(format: \"%04X\", newMajor)\n        minorHex = String(format: \"%04X\", newMinor)\n    }\n\n    private func applyMajorMinor() {\n        let cleanedMajor = majorHex.trimmingCharacters(in: .whitespacesAndNewlines)\n            .replacingOccurrences(of: \"0x\", with: \"\")\n            .uppercased()\n        if let value = UInt16(cleanedMajor, radix: 16) {\n            transmitter.major = value\n            majorHex = String(format: \"%04X\", value)\n        }\n\n        let cleanedMinor = minorHex.trimmingCharacters(in: .whitespacesAndNewlines)\n            .replacingOccurrences(of: \"0x\", with: \"\")\n            .uppercased()\n        if let value = UInt16(cleanedMinor, radix: 16) {\n            transmitter.minor = value\n            minorHex = String(format: \"%04X\", value)\n        }\n    }\n}\n<\/pre>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>iBeacon \u5f62\u5f0f\u3067\u767a\u4fe1\u3059\u308b<\/strong><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">iBeacon \u3092\u767a\u4fe1\u3059\u308b\u3068\u304d\u306f CBPeripheralManager, CLBeaconRegion, CBPeripheralManagerDelegate \u3092\u4f7f\u3044\u307e\u3059\u3002iBeacon \u81ea\u4f53\u306f\u3001Manufacturer Data \u3068\u540c\u3058\u306a\u306e\u3067\u3001\u5b9f\u306f startAdvertisingRawIBeacon \u95a2\u6570\u306e\u3088\u3046\u306b\u3001Manufacturer Data \u3092\u624b\u4f5c\u308a\u3057\u3066 startAdvertising \u3059\u308b\u3053\u3068\u3082\u53ef\u80fd\u306a\u306e\u3067\u3059\u304c\u3001\u5b9f\u306f\u3067\u304d\u307e\u305b\u3093\u3002iOS \u3067\u306f\u3001\u81ea\u7531\u306a\u30c7\u30fc\u30bf\u3092\u9001\u4fe1\u3059\u308b\u3053\u3068\u304c\u3067\u304d\u306a\u304f\u3066\u3001\u30a2\u30c9\u30d0\u30bf\u30a4\u30ba\u306f iBeacon \u5f62\u5f0f\u306e\u307f\u306b\u9650\u3089\u308c\u3066\u3044\u307e\u3059\u3002<\/p>\n\n\n\n<pre class=\"wp-block-syntaxhighlighter-code\">class BeaconTransmitter: NSObject, ObservableObject {\n    private var peripheralManager: CBPeripheralManager?\n    private var beaconRegion: CLBeaconRegion?\n    \/\/ \u5b9f\u9a13\u7528: raw iBeacon manufacturer data \u3092\u4f7f\u3063\u3066\u5e83\u544a\u3059\u308b\u304b\u3069\u3046\u304b\n    @Published var useRawIBeaconAdvertising = false\n    \/\/ \u4fdd\u6301\u3057\u3066\u304a\u304f\u30a2\u30c9\u30d0\u30bf\u30a4\u30ba\u30c7\u30fc\u30bf\uff08\u30c7\u30d0\u30c3\u30b0\u7528\uff09\n    private var lastAdvertisementData: [String: Any]?\n\n    @Published var isTransmitting = false\n    @Published var transmissionStatus = \"\u505c\u6b62\u4e2d\"\n    @Published var bluetoothState = \"Unknown\"\n    @Published var major: UInt16 = 0\n    @Published var minor: UInt16 = 0\n\n    \/\/ \u30c7\u30d5\u30a9\u30eb\u30c8\u306eiBeacon\u8a2d\u5b9a\n    private let defaultUUID = UUID(uuidString: \"90FA7ABE-FAB6-485E-B700-1A17804CAA13\")!\n    private let defaultIdentifier = \"FolkBearsBeacon\"\n\n    override init() {\n        super.init()\n        setupPeripheralManager()\n    }\n\n    private func setupPeripheralManager() {\n        peripheralManager = CBPeripheralManager(delegate: self, queue: nil)\n    }\n\n    func startTransmitting() {\n        guard let peripheralManager = peripheralManager,\n              peripheralManager.state == .poweredOn,\n              !isTransmitting else {\n            print(\"Bluetooth \u304c\u5229\u7528\u3067\u304d\u306a\u3044\u304b\u3001\u65e2\u306b\u767a\u4fe1\u4e2d\u3067\u3059\")\n            return\n        }\n\n        let major = CLBeaconMajorValue(major)\n        let minor = CLBeaconMinorValue(minor)\n\n        \/\/ \u30d3\u30fc\u30b3\u30f3\u30ea\u30fc\u30b8\u30e7\u30f3\u3092\u4f5c\u6210\n        beaconRegion = CLBeaconRegion(\n            uuid: defaultUUID,\n            major: major,\n            minor: minor,\n            identifier: defaultIdentifier\n        )\n\n        guard let region = beaconRegion else { return }\n\n        \/\/ \u30a2\u30c9\u30d0\u30bf\u30a4\u30ba\u30e1\u30f3\u30c8\u30c7\u30fc\u30bf\u3092\u751f\u6210\n        if useRawIBeaconAdvertising {\n            \/\/ raw manufacturer data \u3092\u4f5c\u6210\u3057\u3066 startAdvertising \u3059\u308b\n            startAdvertisingRawIBeacon(uuid: defaultUUID, major: UInt16(major), minor: UInt16(minor), txPower: -59)\n        } else {\n            \/\/ measuredPower\u3092\u660e\u793a\u7684\u306b\u8a2d\u5b9a\uff08-59dBm\u304c\u4e00\u822c\u7684\uff09\n            let peripheralData = region.peripheralData(withMeasuredPower: -59 as NSNumber)\n            \/\/ \u4fdd\u6301\u3057\u3066\u304a\u304f\uff08\u30c7\u30d0\u30c3\u30b0\uff09\n            if let adv = peripheralData as? [String: Any] {\n                lastAdvertisementData = adv\n            }\n            \/\/ \u30a2\u30c9\u30d0\u30bf\u30a4\u30ba\u958b\u59cb\n            peripheralManager.startAdvertising(peripheralData as? [String: Any])\n        }\n\n        isTransmitting = true\n        transmissionStatus = \"\u767a\u4fe1\u4e2d...\"\n        let majorHex = String(format: \"%04X\", major)\n        let minorHex = String(format: \"%04X\", minor)\n        print(\"\ud83d\udce1 iBeacon \u767a\u4fe1\u958b\u59cb\")\n        print(\"   UUID: \\(defaultUUID)\")\n        print(\"   Major: \\(majorHex)\")\n        print(\"   Minor: \\(minorHex)\")\n        print(\"   Measured Power: -59dBm\")\n\n        \/\/ \u30c7\u30d0\u30c3\u30b0\u7528\uff1a\u30a2\u30c9\u30d0\u30bf\u30a4\u30ba\u30e1\u30f3\u30c8\u30c7\u30fc\u30bf\u3092\u8868\u793a\n        if useRawIBeaconAdvertising {\n            if let adv = lastAdvertisementData {\n                print(\"   Advertisement Data (raw manufacturer used): \\(adv)\")\n            } else {\n                print(\"   Advertisement Data: (raw manufacturer advertising active)\")\n            }\n        } else if let advData = lastAdvertisementData {\n            print(\"   Advertisement Data: \\(advData)\")\n        }\n    }\n\n    \/\/ MARK: - Raw iBeacon (manufacturer data) \u5e83\u544a\uff08\u5b9f\u9a13\u7528\uff09\n    \/\/\/ iBeacon \u306e manufacturer data \u3092\u624b\u4f5c\u308a\u3057\u3066\u5e83\u544a\u3092\u884c\u3046\uff08\u5b9f\u9a13\u7528\uff09\n    private func startAdvertisingRawIBeacon(uuid: UUID, major: UInt16, minor: UInt16, txPower: Int8 = -59) {\n        \/\/ iBeacon \u30d5\u30a9\u30fc\u30de\u30c3\u30c8: Apple company id (0x004C little-endian), 0x02, 0x15, UUID(16), major(2), minor(2), tx(1)\n        var data = Data()\n        \/\/ Apple company ID (0x004C) little-endian\n        data.append(0x4C)\n        data.append(0x00)\n        \/\/ iBeacon type and length\n        data.append(0x02)\n        data.append(0x15)\n\n        \/\/ UUID bytes (big-endian order as raw bytes of UUID)\n        withUnsafeBytes(of: uuid.uuid) { (bytes: UnsafeRawBufferPointer) in\n            data.append(contentsOf: bytes)\n        }\n\n        \/\/ major (big endian)\n        data.append(UInt8((major >> 8) &amp; 0xFF))\n        data.append(UInt8(major &amp; 0xFF))\n        \/\/ minor (big endian)\n        data.append(UInt8((minor >> 8) &amp; 0xFF))\n        data.append(UInt8(minor &amp; 0xFF))\n        \/\/ tx power\n        data.append(UInt8(bitPattern: txPower))\n\n        let adv: [String: Any] = [CBAdvertisementDataManufacturerDataKey: data]\n        \/\/ \u30c7\u30d0\u30c3\u30b0\u7528\u306b\u4fdd\u6301\u3068\u8868\u793a\n        lastAdvertisementData = adv\n        print(\"\ud83d\udce1 iBeacon (raw) \u767a\u4fe1\u30c7\u30fc\u30bf\u751f\u6210: manufacturerData length=\\(data.count)\")\n\n        peripheralManager?.startAdvertising(adv)\n    }\n\n    func stopTransmitting() {\n        guard let peripheralManager = peripheralManager,\n              isTransmitting else { return }\n\n        peripheralManager.stopAdvertising()\n\n        isTransmitting = false\n        transmissionStatus = \"\u505c\u6b62\u4e2d\"\n        print(\"iBeacon \u767a\u4fe1\u505c\u6b62\")\n    }\n\n    func updateBeaconParameters(major: CLBeaconMajorValue? = nil, minor: CLBeaconMinorValue? = nil) {\n        if let major = major { self.major = major }\n        if let minor = minor { self.minor = minor }\n\n        let newMajor = CLBeaconMajorValue(self.major)\n        let newMinor = CLBeaconMinorValue(self.minor)\n\n        if isTransmitting {\n            stopTransmitting()\n            DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {\n                self.startTransmitting()\n            }\n        }\n        print(\"\u30d3\u30fc\u30b3\u30f3\u30d1\u30e9\u30e1\u30fc\u30bf\u66f4\u65b0 - Major: \\(newMajor), Minor: \\(newMinor)\")\n    }\n}\nextension BeaconTransmitter: CBPeripheralManagerDelegate {\n    func peripheralManagerDidUpdateState(_ peripheral: CBPeripheralManager) {\n        DispatchQueue.main.async {\n            switch peripheral.state {\n            case .poweredOn:\n                self.bluetoothState = \"Powered On\"\n                print(\"Bluetooth \u304c\u6709\u52b9\u306b\u306a\u308a\u307e\u3057\u305f\")\n            case .poweredOff:\n                self.bluetoothState = \"Powered Off\"\n                self.stopTransmitting()\n                print(\"Bluetooth \u304c\u7121\u52b9\u3067\u3059\")\n            case .resetting:\n                self.bluetoothState = \"Resetting\"\n                print(\"Bluetooth \u30ea\u30bb\u30c3\u30c8\u4e2d\")\n            case .unauthorized:\n                self.bluetoothState = \"Unauthorized\"\n                print(\"Bluetooth \u4f7f\u7528\u6a29\u9650\u304c\u3042\u308a\u307e\u305b\u3093\")\n            case .unsupported:\n                self.bluetoothState = \"Unsupported\"\n                print(\"Bluetooth \u304c\u30b5\u30dd\u30fc\u30c8\u3055\u308c\u3066\u3044\u307e\u305b\u3093\")\n            case .unknown:\n                self.bluetoothState = \"Unknown\"\n                print(\"Bluetooth \u72b6\u614b\u4e0d\u660e\")\n            @unknown default:\n                self.bluetoothState = \"Unknown\"\n                break\n            }\n        }\n    }\n\n    func peripheralManagerDidStartAdvertising(_ peripheral: CBPeripheralManager, error: Error?) {\n        DispatchQueue.main.async {\n            if let error = error {\n                print(\"\u274c \u30a2\u30c9\u30d0\u30bf\u30a4\u30ba\u958b\u59cb\u30a8\u30e9\u30fc: \\(error.localizedDescription)\")\n                self.transmissionStatus = \"\u30a8\u30e9\u30fc: \\(error.localizedDescription)\"\n                self.isTransmitting = false\n            } else {\n                print(\"\u2705 \u30a2\u30c9\u30d0\u30bf\u30a4\u30ba\u958b\u59cb\u6210\u529f\")\n                print(\"   \u72b6\u614b: Advertising\")\n                print(\"   \u78ba\u8a8d: Android\u5074\u3067\u30b9\u30ad\u30e3\u30f3\u3092\u958b\u59cb\u3057\u3066\u304f\u3060\u3055\u3044\")\n                self.transmissionStatus = \"\u767a\u4fe1\u4e2d\"\n            }\n        }\n    }\n\n    func peripheralManagerIsReady(toUpdateSubscribers peripheral: CBPeripheralManager) {\n        print(\"\ud83d\udd04 PeripheralManager\u306e\u6e96\u5099\u5b8c\u4e86\")\n    }\n}\n<\/pre>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>\u30c7\u30d0\u30a4\u30b9\u540d\u306e\u767a\u898b\u30a2\u30c9\u30d0\u30bf\u30a4\u30ba<\/strong><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">GattAdvertise \u3067\u3001Device Name \u3092\u30a2\u30c9\u30d0\u30bf\u30a4\u30ba\u3059\u308b\u30d1\u30bf\u30fc\u30f3\u3082\u4f5c\u3063\u3066\u3044\u307e\u3059\u3002\u3053\u308c\u306f GATT \u63a5\u7d9a\u306e\u524d\u306b\u767a\u4fe1\u3055\u308c\u308b\u30a2\u30c9\u30d0\u30bf\u30a4\u30ba\u3067\u3059\u3002<br>\u30c7\u30d0\u30a4\u30b9\u540d\u3060\u3051\u3092\u9001\u4fe1\uff08\u5b9f\u306f\u30c7\u30d0\u30a4\u30b9\u540d\u81ea\u4f53\u306f\u3044\u3089\u306a\u3044\u306e\u3067\u3059\u304c\uff09\u3059\u308b\u3060\u3051\u306a\u306e\u3067\u3001CBPeripheralManager \u3068 CBPeripheralManagerDelegate \u3060\u3051\u3067\u5341\u5206\u3067\u3059\u3002\u30a2\u30c9\u30d0\u30bf\u30a4\u30ba\u30c7\u30fc\u30bf advertisementData \u3067\u306f\u3001CBAdvertisementDataServiceUUIDsKey \u3068 CBAdvertisementDataLocalNameKey \u306e\u307f\u304c\u6709\u52b9\u306b\u306a\u308a\u307e\u3059\u3002\u4ed6\u306e\u30ad\u30fc\u3092\u8a2d\u5b9a\u3057\u3066\u3082\u7121\u8996\u3055\u308c\u307e\u3059\u3002<\/p>\n\n\n\n<pre class=\"wp-block-syntaxhighlighter-code\">class GattAdvertise: NSObject, ObservableObject {\n    private var peripheralManager: CBPeripheralManager?\n    private var customService: CBMutableService?\n    \n    @Published var isAdvertising = false\n    @Published var advertisingStatus = \"\u505c\u6b62\u4e2d\"\n    @Published var bluetoothState = \"Unknown\"\n    @Published var connectedCentrals: [CBCentral] = []\n    \n    \/\/ \u30ab\u30b9\u30bf\u30e0\u30b5\u30fc\u30d3\u30b9\u3068\u30ad\u30e3\u30e9\u30af\u30bf\u30ea\u30b9\u30c6\u30a3\u30c3\u30af\u306eUUID\n    private let serviceUUID = CBUUID(string: \"90FA7ABE-FAB6-485E-B700-1A17804CAA13\")\n    private let characteristicUUID = CBUUID(string: \"90FA7ABE-FAB6-485E-B700-1A17804CAA14\")\n    private let deviceName = \"FolkBears-GATT\"\n    \n    private var customCharacteristic: CBMutableCharacteristic?\n    private var characteristicValue = \"Hello GATT World!\"\n    \n    override init() {\n        super.init()\n        setupPeripheralManager()\n    }\n    \n    private func setupPeripheralManager() {\n        peripheralManager = CBPeripheralManager(delegate: self, queue: nil)\n    }\n    \n    func startAdvertising() {\n        guard let peripheralManager = peripheralManager,\n              peripheralManager.state == .poweredOn,\n              !isAdvertising else {\n            print(\"Bluetooth \u304c\u5229\u7528\u3067\u304d\u306a\u3044\u304b\u3001\u65e2\u306b\u30a2\u30c9\u30d0\u30bf\u30a4\u30ba\u4e2d\u3067\u3059\")\n            return\n        }\n        \n        let advertisementData: [String: Any] = [\n            CBAdvertisementDataServiceUUIDsKey: [serviceUUID],\n            CBAdvertisementDataLocalNameKey: deviceName\n        ]\n        \n        peripheralManager.startAdvertising(advertisementData)\n        \n        isAdvertising = true\n        advertisingStatus = \"\u30a2\u30c9\u30d0\u30bf\u30a4\u30ba\u4e2d...\"\n        print(\"GATT \u30a2\u30c9\u30d0\u30bf\u30a4\u30ba\u958b\u59cb - \u30b5\u30fc\u30d3\u30b9: \\(serviceUUID)\")\n    }\n    \n    func stopAdvertising() {\n        guard let peripheralManager = peripheralManager,\n              isAdvertising else { return }\n        \n        peripheralManager.stopAdvertising()\n        peripheralManager.removeAllServices()\n        \n        isAdvertising = false\n        advertisingStatus = \"\u505c\u6b62\u4e2d\"\n        connectedCentrals.removeAll()\n        print(\"GATT \u30a2\u30c9\u30d0\u30bf\u30a4\u30ba\u505c\u6b62\")\n    }\n    \n    func getConnectionSummary() -> String {\n        return \"\"\"\n        \u30a2\u30c9\u30d0\u30bf\u30a4\u30ba\u72b6\u614b: \\(advertisingStatus)\n        \u63a5\u7d9a\u4e2d\u30c7\u30d0\u30a4\u30b9\u6570: \\(connectedCentrals.count)\u500b\n        \u30b5\u30fc\u30d3\u30b9UUID: \\(serviceUUID)\n        \u30c7\u30d0\u30a4\u30b9\u540d: \\(deviceName)\n        \"\"\"\n    }\n}\n\n\/\/ MARK: - CBPeripheralManagerDelegate\nextension GattAdvertise: CBPeripheralManagerDelegate {\n    func peripheralManagerDidUpdateState(_ peripheral: CBPeripheralManager) {\n        DispatchQueue.main.async {\n            switch peripheral.state {\n            case .poweredOn:\n                self.bluetoothState = \"Powered On\"\n                print(\"Bluetooth \u304c\u6709\u52b9\u306b\u306a\u308a\u307e\u3057\u305f\")\n            case .poweredOff:\n                self.bluetoothState = \"Powered Off\"\n                self.stopAdvertising()\n                print(\"Bluetooth \u304c\u7121\u52b9\u3067\u3059\")\n            case .resetting:\n                self.bluetoothState = \"Resetting\"\n                print(\"Bluetooth \u30ea\u30bb\u30c3\u30c8\u4e2d\")\n            case .unauthorized:\n                self.bluetoothState = \"Unauthorized\"\n                print(\"Bluetooth \u4f7f\u7528\u6a29\u9650\u304c\u3042\u308a\u307e\u305b\u3093\")\n            case .unsupported:\n                self.bluetoothState = \"Unsupported\"\n                print(\"Bluetooth \u304c\u30b5\u30dd\u30fc\u30c8\u3055\u308c\u3066\u3044\u307e\u305b\u3093\")\n            case .unknown:\n                self.bluetoothState = \"Unknown\"\n                print(\"Bluetooth \u72b6\u614b\u4e0d\u660e\")\n            @unknown default:\n                self.bluetoothState = \"Unknown\"\n                break\n            }\n        }\n    }\n    \n    func peripheralManagerDidStartAdvertising(_ peripheral: CBPeripheralManager, error: Error?) {\n        DispatchQueue.main.async {\n            if let error = error {\n                print(\"\u30a2\u30c9\u30d0\u30bf\u30a4\u30ba\u958b\u59cb\u30a8\u30e9\u30fc: \\(error.localizedDescription)\")\n                self.advertisingStatus = \"\u30a8\u30e9\u30fc\"\n                self.isAdvertising = false\n            } else {\n                print(\"\u30a2\u30c9\u30d0\u30bf\u30a4\u30ba\u958b\u59cb\u6210\u529f\")\n                self.advertisingStatus = \"\u30a2\u30c9\u30d0\u30bf\u30a4\u30ba\u4e2d\"\n            }\n        }\n    }\n}\n<\/pre>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>16 bit Service UUID \u5f62\u5f0f\u306e\u767a\u4fe1<\/strong><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">EN API \u5f62\u5f0f\u306e\u767a\u4fe1\u306f\u300116 bit Service UUID \u3092\u6307\u5b9a\u3057\u3066\u767a\u4fe1\u3059\u308b\u30d1\u30bf\u30fc\u30f3\u3067\u3059\u304c\u3001iOS \u3067\u306f\u9001\u4fe1\u3067\u304d\u307e\u305b\u3093\u3002\u9001\u4fe1\u306f\u3067\u304d\u306a\u3044\u306e\u3067\u3059\u304c\u3001\u78ba\u8a8d\u306e\u305f\u3081\u306b\u30b3\u30fc\u30c9\u306f\u4f5c\u3063\u3066\u3042\u308a\u307e\u3059\u3002Android \u306e\u53d7\u4fe1\u6a5f\u3067\u53d7\u4fe1\u3067\u304d\u306a\u3044\u3053\u3068\u3092\u78ba\u8a8d\u3057\u3066\u304f\u3060\u3055\u3044\u3002<br>\u305f\u307e\u306b\u3001Android\/iOS \u306e\u53d7\u4fe1\u6a5f\u306b\u5230\u9054\u3059\u308b\u3053\u3068\u304c\u3042\u308a\uff08\u3053\u306e\u3068\u304d\u306e\u30a2\u30c9\u30d0\u30bf\u30a4\u30ba\u30c7\u30fc\u30bf\u306f\u30e9\u30f3\u30c0\u30e0\u5024\u306b\u306a\u3063\u3066\u3044\u307e\u3059\uff09\u3001\u5fae\u5999\u306a\u611f\u3058\u304c\u3059\u308b\u306e\u3067\u3059\u304c\u3001\u4f7f\u3048\u306a\u3044\u306e\u306f\u78ba\u304b\u3067\u3059\u3002<\/p>\n\n\n\n<pre class=\"wp-block-syntaxhighlighter-code\">class ENSimTransmitter: NSObject, ObservableObject {\n\tprivate var peripheralManager: CBPeripheralManager?\n\tprivate let serviceUUID = CBUUID(string: \"FD6F\") \/\/ Exposure Notification 16-bit UUID\n    private let altServiceUUID = CBUUID(string: \"FF00\") \/\/ Alternative UUID for testing\n\n\t@Published var isTransmitting = false\n\t@Published var transmissionStatus = \"\u505c\u6b62\u4e2d\"\n\t@Published var bluetoothState = \"Unknown\"\n\t@Published var localName = \"ENSim\"\n    @Published var useAltService: Bool = false\n\t@Published var rpi: Data = ENSimTransmitter.generateRandomRpi()\n\n\toverride init() {\n\t\tsuper.init()\n\t\tsetupPeripheralManager()\n\t}\n\n\tprivate func setupPeripheralManager() {\n\t\tperipheralManager = CBPeripheralManager(delegate: self, queue: nil)\n\t}\n\n\tfunc startTransmitting() {\n\t\tguard let manager = peripheralManager else {\n\t\t\tprint(\"PeripheralManager \u304c\u521d\u671f\u5316\u3055\u308c\u3066\u3044\u307e\u305b\u3093\")\n\t\t\treturn\n\t\t}\n\n\t\tguard manager.state == .poweredOn else {\n\t\t\tprint(\"Bluetooth \u304c\u5229\u7528\u3067\u304d\u307e\u305b\u3093 (state: \\(manager.state.rawValue))\")\n\t\t\treturn\n\t\t}\n\n\t\tguard !isTransmitting else {\n\t\t\tprint(\"\u65e2\u306b\u30a2\u30c9\u30d0\u30bf\u30a4\u30ba\u4e2d\u3067\u3059\")\n\t\t\treturn\n\t\t}\n\n        let selectedService = useAltService ? altServiceUUID : serviceUUID\n        let serviceData: [CBUUID: Data] = [selectedService: rpi]\n\n\t\tlet advertisementData: [String: Any] = [\n\t\t\tCBAdvertisementDataServiceUUIDsKey: [selectedService],\n\t\t\tCBAdvertisementDataLocalNameKey: localName,\n\t\t\t\/\/ CBAdvertisementDataServiceDataKey: serviceData\n\t\t]\n\n\t\tmanager.startAdvertising(advertisementData)\n\n\t\tisTransmitting = true\n\t\ttransmissionStatus = \"\u767a\u4fe1\u4e2d...\"\n\n\t\tprint(\"\ud83d\udce1 EN \u30b7\u30df\u30e5\u30ec\u30fc\u30b7\u30e7\u30f3\u767a\u4fe1\u958b\u59cb\")\n\t\tprint(\"   Service UUID (16-bit): \\(useAltService ? altServiceUUID.uuidString : serviceUUID.uuidString)\")\n\t\tprint(\"   Local Name: \\(localName)\")\n\t\tprint(\"   RPI (hex): \\(rpi.map { String(format: \"%02X\", $0) }.joined())\")\n\t}\n\n\tfunc stopTransmitting() {\n\t\tguard let manager = peripheralManager, isTransmitting else { return }\n\n\t\tmanager.stopAdvertising()\n\t\tisTransmitting = false\n\t\ttransmissionStatus = \"\u505c\u6b62\u4e2d\"\n\n\t\tprint(\"EN \u30b7\u30df\u30e5\u30ec\u30fc\u30b7\u30e7\u30f3\u767a\u4fe1\u505c\u6b62\")\n\t}\n\n\tprivate static func generateRandomRpi() -> Data {\n\t\t\n\t\t\/\/ let bytes = (0..&lt;16).map { _ in UInt8.random(in: 0...255) }\n\n\t\t\/\/ \u30e9\u30f3\u30c0\u30e0\u306a uuid \u3092\u751f\u6210\u3057\u3066 RPI \u3068\u3057\u3066\u4f7f\u7528\uff08\u30c7\u30d0\u30c3\u30b0\u7528\uff09\n\t\t\/\/ \u9001\u4fe1\u306f\u6210\u529f\u3059\u308b\u304c\u3001Service Data \u306e\u5185\u5bb9\u306f\u30e9\u30f3\u30c0\u30e0\u5024\u306b\u306a\u3063\u3066\u3057\u307e\u3046\u306e\u3067\u3001\n\t\t\/\/ \u5b9f\u8cea\u5229\u7528\u304c\u3067\u304d\u306a\u3044\u3002\n\t\tlet uuid = UUID()\n\t\tlet uuidBytes = withUnsafeBytes(of: uuid.uuid) { Array($0) }\n\t\tlet bytes = Array(uuidBytes.prefix(16))\n\t\treturn Data(bytes)\n\t}\n}\n<\/pre>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Manufacturer Data \u5f62\u5f0f\u306e\u767a\u4fe1<\/strong><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u81ea\u7531\u306a\u5f62\u5f0f\u3067\u30c7\u30fc\u30bf\u3092\u30d6\u30ed\u30fc\u30c9\u30ad\u30e3\u30b9\u30c8\u3059\u308b\u5834\u5408\u306f\u3001Manufacturer Data \u5f62\u5f0f\u3067\u767a\u4fe1\u3059\u308b\u306e\u304c\u4e00\u756a\u3044\u3044\u306e\u3067\u3059\u304c\u3001\u3053\u308c\u3082 iOS \u3067\u306f\u4f7f\u3048\u307e\u305b\u3093\u3002\u3053\u308c\u3082\u3001\u4f7f\u3048\u306a\u3044\u3053\u3068\u3092\u78ba\u8a8d\u3059\u308b\u305f\u3081\u306b\u30b3\u30fc\u30c9\u3092\u4f5c\u3063\u3066\u3042\u308a\u307e\u3059\u3002<br>\u5148\u306b\u66f8\u3044\u305f\u901a\u308a\u3001startAdvertisingRawIBeacon \u95a2\u6570\u3092\u4f5c\u3063\u3066\u3082\u30c7\u30fc\u30bf\u306f\u9001\u4fe1\u3067\u304d\u307e\u305b\u3093\u3002<\/p>\n\n\n\n<pre class=\"wp-block-syntaxhighlighter-code\">\/\/\/ Advertises custom manufacturer data (often consumed as scan response data on the scanner side).\n\/\/\/ \u30d5\u30a9\u30fc\u30de\u30c3\u30c8: [0]=0x02 (type), [1]=0x10 (length=16), [2..17]=TempId(16byte)\n\nclass ManufacturerDataTransmitter: NSObject, ObservableObject {\n\tprivate var peripheralManager: CBPeripheralManager?\n\n\t@Published var isTransmitting = false\n\t@Published var transmissionStatus = \"\u505c\u6b62\u4e2d\"\n\t@Published var bluetoothState = \"Unknown\"\n\t@Published var localName: String = \"MFG\"\n\n\t\/\/\/ 16-bit company identifier (Little Endian in the payload). Default: 0xFFFF for testing.\n\t@Published var companyId: UInt16 = 0xFFFF\n    let beacon_type = 0x02\n    let beacon_length = 0x10\n\n\t\/\/\/ Arbitrary manufacturer payload. Default 16 zero bytes for easy overriding.\n\t@Published var tempIdBytes: Data = Data(repeating: 0x00, count: 16)\n\n\t\/\/\/ Last advertisement dictionary for debugging.\n\tprivate(set) var lastAdvertisementData: [String: Any]? = nil\n\n\toverride init() {\n\t\tsuper.init()\n\t\tsetupPeripheralManager()\n\t}\n\n\tprivate func setupPeripheralManager() {\n\t\tperipheralManager = CBPeripheralManager(delegate: self, queue: nil)\n\t}\n\n\t\/\/\/ Start advertising manufacturer data. Uses CBAdvertisementDataManufacturerDataKey which may appear in scan response on the scanner side depending on size and platform rules.\n\tfunc startTransmitting() {\n\t\tguard let manager = peripheralManager else {\n\t\t\tprint(\"PeripheralManager \u304c\u521d\u671f\u5316\u3055\u308c\u3066\u3044\u307e\u305b\u3093\")\n\t\t\treturn\n\t\t}\n\n\t\tguard manager.state == .poweredOn else {\n\t\t\tprint(\"Bluetooth \u304c\u5229\u7528\u3067\u304d\u307e\u305b\u3093 (state: \\(manager.state.rawValue))\")\n\t\t\treturn\n\t\t}\n\n\t\tguard !isTransmitting else {\n\t\t\tprint(\"\u65e2\u306b\u30a2\u30c9\u30d0\u30bf\u30a4\u30ba\u4e2d\u3067\u3059\")\n\t\t\treturn\n\t\t}\n\n\t\t\/\/ Build manufacturer data: company ID (little endian) + payload.\n\t\tvar mfgData = Data()\n\t\tmfgData.append(UInt8(companyId &amp; 0xFF))\n\t\tmfgData.append(UInt8((companyId >> 8) &amp; 0xFF))\n        mfgData.append(UInt8(beacon_type))\n\t\tmfgData.append(UInt8(beacon_length))\n        mfgData.append(tempIdBytes)\n\t\tlet advertisementData: [String: Any] = [\n\t\t\tCBAdvertisementDataManufacturerDataKey: mfgData,\n\t\t\tCBAdvertisementDataLocalNameKey: localName\n\t\t]\n\n\t\tlastAdvertisementData = advertisementData\n\t\tmanager.startAdvertising(advertisementData)\n\n\t\tisTransmitting = true\n\t\ttransmissionStatus = \"\u767a\u4fe1\u4e2d...\"\n\n\t\tprint(\"\ud83d\udce1 Manufacturer \u767a\u4fe1\u958b\u59cb\")\n\t\tprint(String(format: \"   Company ID: 0x%04X (LE)\", companyId))\n\t\tprint(\"   tempIdBytes (hex): \\(tempIdBytes.map { String(format: \"%02X\", $0) }.joined())\")\n\t\tprint(\"   Local Name: \\(localName)\")\n\t}\n\n\tfunc stopTransmitting() {\n\t\tguard let manager = peripheralManager, isTransmitting else { return }\n\n\t\tmanager.stopAdvertising()\n\t\tisTransmitting = false\n\t\ttransmissionStatus = \"\u505c\u6b62\u4e2d\"\n\n\t\tprint(\"Manufacturer \u767a\u4fe1\u505c\u6b62\")\n\t}\n}\n<\/pre>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>\u5b9f\u884c<\/strong><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u5de6\u304b\u3089<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Android \u3067\u53d7\u4fe1<\/li>\n\n\n\n<li>iPhone \u3067\u53d7\u4fe1<\/li>\n\n\n\n<li>iPhone \u3067\u767a\u4fe1<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">\u3068\u3044\u3046\u72b6\u614b\u3067\u3059\u3002iBeacon \u306e UUID \u306f\u540c\u3058\u306a\u306e\u3067\u3001major \u3068 minor \u3067\u5224\u65ad\u3092\u3057\u307e\u3059\u3002<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">iBeacon \u53d7\u767a\u4fe1\u306e\u69d8\u5b50<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><a href=\"https:\/\/www.moonmile.net\/blog\/wp-content\/uploads\/2026\/02\/image-49.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"768\" src=\"https:\/\/www.moonmile.net\/blog\/wp-content\/uploads\/2026\/02\/image-49.png\" alt=\"\" class=\"wp-image-12073\" srcset=\"http:\/\/www.moonmile.net\/blog\/wp-content\/uploads\/2026\/02\/image-49.png 1024w, http:\/\/www.moonmile.net\/blog\/wp-content\/uploads\/2026\/02\/image-49-300x225.png 300w, http:\/\/www.moonmile.net\/blog\/wp-content\/uploads\/2026\/02\/image-49-768x576.png 768w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">\u53d7\u4fe1\u56de\u6570\u306f5\u5206\u4ee5\u5185\u306b\u53d7\u4fe1\u3057\u305f\u30d3\u30fc\u30b3\u30f3\u306e\u56de\u6570\u3092\u6570\u3048\u3066\u3044\u308b\u306e\u3067\u30015\u5206\u7a0b\u5ea6\u653e\u7f6e\u3057\u3066\u304a\u304f\u30681\u5206\u3042\u305f\u308a\u306e\u53d7\u4fe1\u983b\u5ea6\u304c\u8a08\u7b97\u3067\u304d\u307e\u3059\u3002\u5b9f\u969b\u306f\u3001\u5e73\u5747\u7b49\u3092\u8003\u3048\u306a\u3044\u3068\u3044\u3051\u306a\u3044\u306e\u3067\u3001\u3082\u3046\u5c11\u3057\u7d71\u8a08\u30c7\u30fc\u30bf\u3068\u3057\u3066\u4fdd\u5b58\u3067\u304d\u308b\u3088\u3046\u306b\u3057\u306a\u3044\u3068\u3044\u3051\u306a\u3044\u306e\u3067\u3059\u304c\u3002<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">iOS \u306e\u53d7\u4fe1\u6a5f\u3067\u306f1\u79d2\u306b1\u56de\u7a0b\u5ea6\u3001Android\u306e\u53d7\u4fe1\u6a5f\u3067\u306f1\u79d2\u306b5\u56de\u7a0b\u5ea6\u53d7\u4fe1\u3057\u3066\u3044\u307e\u3059\u3002\u305f\u3076\u3093\u3001iOS \u53d7\u4fe1\u6a5f\u306e\u307b\u3046\u3067\u9593\u5f15\u3044\u3066\u3044\u308b\u3068\u601d\u3046\u306e\u3067\u3059\u304c\u3001\u3053\u306e\u3042\u305f\u308a\u306f\u5f8c\u306b\u691c\u8a3c\u3057\u307e\u3059\u3002<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Android : 5\u5206\u3067 1210 \u56de = 1\u79d2\u3042\u305f\u308a 4.03 \u56de<\/li>\n\n\n\n<li>iOS : 5\u5206\u3067 300 \u56de = 1\u79d2\u3042\u305f\u308a 1 \u56de<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">5\u5206\u5f8c<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><a href=\"https:\/\/www.moonmile.net\/blog\/wp-content\/uploads\/2026\/02\/image-50.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"768\" src=\"https:\/\/www.moonmile.net\/blog\/wp-content\/uploads\/2026\/02\/image-50.png\" alt=\"\" class=\"wp-image-12074\" srcset=\"http:\/\/www.moonmile.net\/blog\/wp-content\/uploads\/2026\/02\/image-50.png 1024w, http:\/\/www.moonmile.net\/blog\/wp-content\/uploads\/2026\/02\/image-50-300x225.png 300w, http:\/\/www.moonmile.net\/blog\/wp-content\/uploads\/2026\/02\/image-50-768x576.png 768w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>\u53c2\u8003\u30b3\u30fc\u30c9<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">folkbears-transmitter-ios <a href=\"https:\/\/github.com\/FolkBearsGroup\/ble-tools\/tree\/master\/folkbears-transmitter-ios\">https:\/\/github.com\/FolkBearsGroup\/ble-tools\/tree\/master\/folkbears-transmitter-ios<\/a><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u63a5\u89e6\u78ba\u8a8d\u30a2\u30d7\u30ea\u3067\u306f Android\/iOS \u306e\u76f8\u4e92\u3067 BLE \u901a\u4fe1\u3092\u884c\u3046\u305f\u3081\u306b\u3001iOS \u3067\u306e\u767a\u4fe1\u6a5f\u306e\u30c1\u30a7\u30c3\u30af\u3082\u3057\u3066\u304a\u304d\u307e\u3059\u3002iOS \u306e\u5834\u5408\u306f\u300116 bit Service UUID \u5f62\u5f0f\u3068 Manufacturer Da &hellip; <a href=\"http:\/\/www.moonmile.net\/blog\/archives\/12072\">\u7d9a\u304d\u3092\u8aad\u3080 <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_feature_clip_id":0,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_post_was_ever_published":false},"categories":[3,110],"tags":[],"class_list":["post-12072","post","type-post","status-publish","format-standard","hentry","category-dev","category-folkbears"],"jetpack_sharing_enabled":true,"jetpack_featured_media_url":"","_links":{"self":[{"href":"http:\/\/www.moonmile.net\/blog\/wp-json\/wp\/v2\/posts\/12072","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/www.moonmile.net\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.moonmile.net\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.moonmile.net\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"http:\/\/www.moonmile.net\/blog\/wp-json\/wp\/v2\/comments?post=12072"}],"version-history":[{"count":2,"href":"http:\/\/www.moonmile.net\/blog\/wp-json\/wp\/v2\/posts\/12072\/revisions"}],"predecessor-version":[{"id":12076,"href":"http:\/\/www.moonmile.net\/blog\/wp-json\/wp\/v2\/posts\/12072\/revisions\/12076"}],"wp:attachment":[{"href":"http:\/\/www.moonmile.net\/blog\/wp-json\/wp\/v2\/media?parent=12072"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.moonmile.net\/blog\/wp-json\/wp\/v2\/categories?post=12072"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.moonmile.net\/blog\/wp-json\/wp\/v2\/tags?post=12072"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}