Skip to content

Commit d15bd36

Browse files
committed
iPhone changes working
1 parent 6d1ea42 commit d15bd36

File tree

7 files changed

+206
-84
lines changed

7 files changed

+206
-84
lines changed

App.tsx

+118-36
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,10 @@ import {
66
StyleSheet,
77
TouchableOpacity,
88
Platform,
9+
Alert,
910
} from 'react-native';
1011
import { Dropdown } from 'react-native-element-dropdown';
12+
import NfcManager, { NfcTech, Ndef } from 'react-native-nfc-manager';
1113

1214
const OpenSpool = () => {
1315
const [color, setColor] = useState('pink');
@@ -16,13 +18,13 @@ const OpenSpool = () => {
1618
const [maxTemp, setMaxTemp] = useState('210');
1719

1820
const colors = [
19-
{ label: 'Pink', value: 'pink', hex: '#ea338d' },
20-
{ label: 'Black', value: 'black', hex: '#000000' },
21-
{ label: 'White', value: 'white', hex: '#FFFFFF' },
22-
{ label: 'Yellow', value: 'yellow', hex: '#FFEB3B' },
23-
{ label: 'Red', value: 'red', hex: '#F44336' },
24-
{ label: 'Blue', value: 'blue', hex: '#2196F3' },
25-
{ label: 'Green', value: 'green', hex: '#4CAF50' },
21+
{ label: 'Pink', value: 'pink', hex: 'ea338d' },
22+
{ label: 'Black', value: 'black', hex: '000000' },
23+
{ label: 'White', value: 'white', hex: 'ffffff' },
24+
{ label: 'Yellow', value: 'yellow', hex: 'FFEB3B' },
25+
{ label: 'Red', value: 'red', hex: 'f95d73' },
26+
{ label: 'Blue', value: 'blue', hex: '2196F3' },
27+
{ label: 'Green', value: 'green', hex: '4CAF50' },
2628
];
2729

2830
const types = [
@@ -33,28 +35,103 @@ const OpenSpool = () => {
3335
{ label: 'Nylon', value: 'nylon' },
3436
];
3537

36-
const temperatures = Array.from({ length: 11 }, (_, i) => ({
38+
const temperatures = Array.from({ length: 20 }, (_, i) => ({
3739
label: `${180 + i * 5}°C`,
38-
value: (180 + i * 5).toString()
40+
value: (180 + i * 5).toString(),
3941
}));
4042

41-
const handleReadTag = () => {
42-
console.log('Reading NFC tag...');
43-
};
44-
45-
const handleWriteTag = () => {
46-
console.log('Writing to NFC tag...');
47-
};
48-
49-
const renderColorItem = (item) => {
43+
const renderColorItem = (item: any) => {
5044
return (
5145
<View style={styles.colorItem}>
52-
<View style={[styles.colorSwatch, { backgroundColor: item.hex }]} />
46+
<View style={[styles.colorSwatch, { backgroundColor: `#${item.hex}` }]} />
5347
<Text style={styles.colorLabel}>{item.label}</Text>
5448
</View>
5549
);
5650
};
5751

52+
const verifyAndSetMinTemp = (temp: string) => {
53+
if (Number(temp) >= Number(maxTemp)) {
54+
Alert.alert('Min temperature must be less than max temperature');
55+
}
56+
setMinTemp(temp);
57+
};
58+
59+
const verifyAndSetMaxTemp = (temp: string) => {
60+
if (Number(temp) <= Number(minTemp)) {
61+
Alert.alert('Max temperature must be greater than min temperature');
62+
}
63+
setMaxTemp(temp);
64+
};
65+
66+
async function readNdef() {
67+
try {
68+
// register for the NFC tag with NDEF in it
69+
await NfcManager.requestTechnology(NfcTech.Ndef);
70+
71+
// Extract NDEF message (if present)
72+
const tag = await NfcManager.getTag();
73+
74+
// Extract NDEF message (if present)
75+
if (tag?.ndefMessage) {
76+
const rawValue = tag.ndefMessage.map(record =>
77+
String.fromCharCode(...record.payload)
78+
);
79+
80+
let jsonValue = JSON.parse(rawValue.toString());
81+
var nfcColor = colors.find(c => c.hex.toLowerCase() === jsonValue.color_hex.toLowerCase());
82+
var nfcType = types.find(t => t.value.toLowerCase() === jsonValue.type.toLowerCase());
83+
84+
setColor(nfcColor?.value ?? 'blue');
85+
setType(nfcType?.value ?? 'pla');
86+
setMinTemp(jsonValue.min_temp.toString());
87+
setMaxTemp(jsonValue.max_temp.toString());
88+
} else {
89+
Alert.alert('No NDEF message found on the tag.');
90+
}
91+
} catch (ex) {
92+
console.warn('Oops!', ex);
93+
} finally {
94+
// stop the nfc scanning
95+
NfcManager.cancelTechnologyRequest();
96+
}
97+
}
98+
99+
const writeNdef = async () => {
100+
101+
if (Number(minTemp) >= Number(maxTemp)) {
102+
Alert.alert('Min temperature must be less than max temperature');
103+
return;
104+
}
105+
106+
try {
107+
await NfcManager.requestTechnology(NfcTech.Ndef);
108+
109+
const jsonData = {
110+
version: '1.0',
111+
protocol: 'openspool',
112+
color_hex: colors.find(c => c.value === color)?.hex,
113+
type: type,
114+
min_temp: Number(minTemp),
115+
max_temp: Number(maxTemp),
116+
brand: 'Generic',
117+
};
118+
const jsonStr = JSON.stringify(jsonData);
119+
const ndefRecords = Ndef.record(Ndef.TNF_MIME_MEDIA, 'application/json', '1', jsonStr);
120+
121+
//requires an array, but makes it a single once it's passed in
122+
const bytes = await Ndef.encodeMessage([ndefRecords]);
123+
124+
if (bytes) {
125+
await NfcManager.ndefHandler
126+
.writeNdefMessage(bytes);
127+
}
128+
} catch (error) {
129+
console.error('Error writing JSON:', error);
130+
} finally {
131+
NfcManager.cancelTechnologyRequest();
132+
}
133+
};
134+
58135

59136
return (
60137
<SafeAreaView style={styles.container}>
@@ -63,7 +140,7 @@ const OpenSpool = () => {
63140

64141
<View style={styles.circleContainer}>
65142
<View style={[styles.circle, {
66-
backgroundColor: colors.find(c => c.value === color)?.hex || color
143+
backgroundColor: `#${colors.find(c => c.value === color)?.hex}` || color,
67144
}]} />
68145
</View>
69146

@@ -80,8 +157,8 @@ const OpenSpool = () => {
80157
value={color}
81158
onChange={item => setColor(item.value)}
82159
renderItem={renderColorItem}
83-
placeholderStyle={{ color: '#999' }}
84-
selectedTextStyle={{ color: '#ffffff' }}
160+
placeholderStyle={styles.placeHolder}
161+
selectedTextStyle={styles.selected}
85162
/>
86163
</View>
87164

@@ -96,8 +173,8 @@ const OpenSpool = () => {
96173
placeholder="Select type"
97174
value={type}
98175
onChange={item => setType(item.value)}
99-
placeholderStyle={{ color: '#999' }}
100-
selectedTextStyle={{ color: '#ffffff' }}
176+
placeholderStyle={styles.placeHolder}
177+
selectedTextStyle={styles.selected}
101178
/>
102179
</View>
103180

@@ -112,9 +189,9 @@ const OpenSpool = () => {
112189
valueField="value"
113190
placeholder="Min temp"
114191
value={minTemp}
115-
onChange={item => setMinTemp(item.value)}
116-
placeholderStyle={{ color: '#999' }}
117-
selectedTextStyle={{ color: '#ffffff' }}
192+
onChange={item => verifyAndSetMinTemp(item.value)}
193+
placeholderStyle={styles.placeHolder}
194+
selectedTextStyle={styles.selected}
118195
/>
119196
</View>
120197

@@ -128,9 +205,9 @@ const OpenSpool = () => {
128205
valueField="value"
129206
placeholder="Max temp"
130207
value={maxTemp}
131-
onChange={item => setMaxTemp(item.value)}
132-
placeholderStyle={{ color: '#999' }}
133-
selectedTextStyle={{ color: '#ffffff' }}
208+
onChange={item => verifyAndSetMaxTemp(item.value)}
209+
placeholderStyle={styles.placeHolder}
210+
selectedTextStyle={styles.selected}
134211
/>
135212
</View>
136213
</View>
@@ -139,13 +216,13 @@ const OpenSpool = () => {
139216
<View style={styles.buttonContainer}>
140217
<TouchableOpacity
141218
style={styles.button}
142-
onPress={handleReadTag}
219+
onPress={readNdef}
143220
>
144221
<Text style={styles.buttonText}>Read Tag</Text>
145222
</TouchableOpacity>
146223
<TouchableOpacity
147224
style={styles.button}
148-
onPress={handleWriteTag}
225+
onPress={writeNdef}
149226
>
150227
<Text style={styles.buttonText}>Write Tag</Text>
151228
</TouchableOpacity>
@@ -200,9 +277,9 @@ const styles = StyleSheet.create({
200277
color: '#999', // Lighter grey for navigation icons
201278
},
202279
circle: {
203-
width: 140,
204-
height: 140,
205-
borderRadius: 70, // Exactly half of width/height
280+
width: 180,
281+
height: 180,
282+
borderRadius: 90, // Exactly half of width/height
206283
alignContent: 'center',
207284
backgroundColor: 'black',
208285
overflow: 'hidden', // This helps with some rendering artifacts[5]
@@ -278,7 +355,6 @@ const styles = StyleSheet.create({
278355
},
279356
colorLabel: {
280357
fontSize: 16,
281-
color: '#ffffff', // White text for color labels
282358

283359
},
284360
colorSwatch: {
@@ -289,6 +365,12 @@ const styles = StyleSheet.create({
289365
borderWidth: 1,
290366
borderColor: 'transparent',
291367
},
368+
placeHolder: {
369+
color: '#999',
370+
},
371+
selected: {
372+
color: '#ffffff',
373+
},
292374
});
293375

294376
export default OpenSpool;

ios/OpenSpool.xcodeproj/project.pbxproj

+8-4
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
13B07FB81A68108700A75B9A /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = PrivacyInfo.xcprivacy; path = OpenSpool/PrivacyInfo.xcprivacy; sourceTree = "<group>"; };
4848
19F6CBCC0A4E27FBF8BF4A61 /* libPods-OpenSpool-OpenSpoolTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-OpenSpool-OpenSpoolTests.a"; sourceTree = BUILT_PRODUCTS_DIR; };
4949
3B4392A12AC88292D35C810B /* Pods-OpenSpool.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-OpenSpool.debug.xcconfig"; path = "Target Support Files/Pods-OpenSpool/Pods-OpenSpool.debug.xcconfig"; sourceTree = "<group>"; };
50+
4EC4FD2B2D3422530080FAB2 /* OpenSpool.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; name = OpenSpool.entitlements; path = OpenSpool/OpenSpool.entitlements; sourceTree = "<group>"; };
5051
5709B34CF0A7D63546082F79 /* Pods-OpenSpool.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-OpenSpool.release.xcconfig"; path = "Target Support Files/Pods-OpenSpool/Pods-OpenSpool.release.xcconfig"; sourceTree = "<group>"; };
5152
591C4798DBAB41DEA723F844 /* Orbitron-Black.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "Orbitron-Black.ttf"; path = "../assets/fonts/Orbitron-Black.ttf"; sourceTree = "<group>"; };
5253
5B7EB9410499542E8C5724F5 /* Pods-OpenSpool-OpenSpoolTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-OpenSpool-OpenSpoolTests.debug.xcconfig"; path = "Target Support Files/Pods-OpenSpool-OpenSpoolTests/Pods-OpenSpool-OpenSpoolTests.debug.xcconfig"; sourceTree = "<group>"; };
@@ -100,6 +101,7 @@
100101
13B07FAE1A68108700A75B9A /* OpenSpool */ = {
101102
isa = PBXGroup;
102103
children = (
104+
4EC4FD2B2D3422530080FAB2 /* OpenSpool.entitlements */,
103105
13B07FAF1A68108700A75B9A /* AppDelegate.h */,
104106
13B07FB01A68108700A75B9A /* AppDelegate.mm */,
105107
13B07FB51A68108700A75B9A /* Images.xcassets */,
@@ -502,8 +504,9 @@
502504
buildSettings = {
503505
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
504506
CLANG_ENABLE_MODULES = YES;
507+
CODE_SIGN_ENTITLEMENTS = OpenSpool/OpenSpool.entitlements;
505508
CURRENT_PROJECT_VERSION = 1;
506-
DEVELOPMENT_TEAM = MDV7B53NY3;
509+
DEVELOPMENT_TEAM = Z68JT2P8SR;
507510
ENABLE_BITCODE = NO;
508511
INFOPLIST_FILE = OpenSpool/Info.plist;
509512
IPHONEOS_DEPLOYMENT_TARGET = 15.1;
@@ -531,8 +534,9 @@
531534
buildSettings = {
532535
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
533536
CLANG_ENABLE_MODULES = YES;
537+
CODE_SIGN_ENTITLEMENTS = OpenSpool/OpenSpool.entitlements;
534538
CURRENT_PROJECT_VERSION = 1;
535-
DEVELOPMENT_TEAM = MDV7B53NY3;
539+
DEVELOPMENT_TEAM = Z68JT2P8SR;
536540
INFOPLIST_FILE = OpenSpool/Info.plist;
537541
IPHONEOS_DEPLOYMENT_TARGET = 15.1;
538542
LD_RUNPATH_SEARCH_PATHS = (
@@ -586,7 +590,7 @@
586590
COPY_PHASE_STRIP = NO;
587591
ENABLE_STRICT_OBJC_MSGSEND = YES;
588592
ENABLE_TESTABILITY = YES;
589-
ENABLE_USER_SCRIPT_SANDBOXING = YES;
593+
ENABLE_USER_SCRIPT_SANDBOXING = NO;
590594
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = "";
591595
GCC_C_LANGUAGE_STANDARD = gnu99;
592596
GCC_DYNAMIC_NO_PIC = NO;
@@ -665,7 +669,7 @@
665669
COPY_PHASE_STRIP = YES;
666670
ENABLE_NS_ASSERTIONS = NO;
667671
ENABLE_STRICT_OBJC_MSGSEND = YES;
668-
ENABLE_USER_SCRIPT_SANDBOXING = YES;
672+
ENABLE_USER_SCRIPT_SANDBOXING = NO;
669673
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = "";
670674
GCC_C_LANGUAGE_STANDARD = gnu99;
671675
GCC_NO_COMMON_BLOCKS = YES;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3+
<plist version="1.0">
4+
<dict/>
5+
</plist>

ios/OpenSpool/Info.plist

+18
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,24 @@
2020
<string>6.0</string>
2121
<key>CFBundleName</key>
2222
<string>$(PRODUCT_NAME)</string>
23+
<key>NFCReaderUsageDescription</key>
24+
<string>We need to use NFC</string>
25+
<key>com.apple.developer.nfc.readersession.iso7816.select-identifiers</key>
26+
<array>
27+
<string>D2760000850100</string>
28+
<string>D2760000850101</string>
29+
</array>
30+
<key>com.apple.developer.nfc.readersession.felica.systemcodes</key>
31+
<array>
32+
<string>8005</string>
33+
<string>8008</string>
34+
<string>0003</string>
35+
<string>fe00</string>
36+
<string>90b7</string>
37+
<string>927a</string>
38+
<string>12FC</string>
39+
<string>86a7</string>
40+
</array>
2341
<key>CFBundlePackageType</key>
2442
<string>APPL</string>
2543
<key>CFBundleShortVersionString</key>

ios/OpenSpool/OpenSpool.entitlements

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3+
<plist version="1.0">
4+
<dict>
5+
<key>com.apple.developer.nfc.readersession.formats</key>
6+
<array>
7+
<string>TAG</string>
8+
</array>
9+
</dict>
10+
</plist>

0 commit comments

Comments
 (0)