Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

initial commit

  • Loading branch information...
commit 8fcf67645bc10a386cd127bfd18908fb0702f010 0 parents
@pegli authored
Showing with 1,967 additions and 0 deletions.
  1. +2 −0  .gitignore
  2. +8 −0 mobile/android/.classpath
  3. +5 −0 mobile/android/.gitignore
  4. +17 −0 mobile/android/.project
  5. +7 −0 mobile/android/.settings/org.eclipse.jdt.apt.core.prefs
  6. +3 −0  mobile/android/.settings/org.eclipse.jdt.core.prefs
  7. +1 −0  mobile/android/LICENSE
  8. +6 −0 mobile/android/assets/README
  9. +3 −0  mobile/android/build.properties
  10. +10 −0 mobile/android/build.xml
  11. BIN  mobile/android/dist/keychain.jar
  12. +39 −0 mobile/android/documentation/index.md
  13. +66 −0 mobile/android/example/app.js
  14. +1 −0  mobile/android/hooks/README
  15. +35 −0 mobile/android/hooks/add.py
  16. +19 −0 mobile/android/hooks/install.py
  17. +34 −0 mobile/android/hooks/remove.py
  18. +18 −0 mobile/android/hooks/uninstall.py
  19. +17 −0 mobile/android/manifest
  20. +3 −0  mobile/android/platform/README
  21. +75 −0 mobile/android/src/com/obscure/keychain/KeychainItemProxy.java
  22. +53 −0 mobile/android/src/com/obscure/keychain/KeychainModule.java
  23. +11 −0 mobile/android/timodule.xml
  24. +4 −0 mobile/ios/.gitignore
  25. +2 −0  mobile/ios/Classes/.gitignore
  26. +13 −0 mobile/ios/Classes/ComObscureKeychainModule.h
  27. +105 −0 mobile/ios/Classes/ComObscureKeychainModule.m
  28. +9 −0 mobile/ios/Classes/ComObscureKeychainModuleAssets.h
  29. +15 −0 mobile/ios/Classes/ComObscureKeychainModuleAssets.m
  30. +74 −0 mobile/ios/Classes/KeychainItemWrapper.h
  31. +319 −0 mobile/ios/Classes/KeychainItemWrapper.m
  32. +19 −0 mobile/ios/Classes/KeychainItemWrapperProxy.h
  33. +65 −0 mobile/ios/Classes/KeychainItemWrapperProxy.m
  34. +4 −0 mobile/ios/ComObscureKeychain_Prefix.pch
  35. +62 −0 mobile/ios/LICENSE
  36. 0  mobile/ios/README
  37. +6 −0 mobile/ios/assets/README
  38. +196 −0 mobile/ios/build.py
  39. +39 −0 mobile/ios/documentation/index.md
  40. +66 −0 mobile/ios/example/app.js
  41. +1 −0  mobile/ios/hooks/README
  42. +35 −0 mobile/ios/hooks/add.py
  43. +19 −0 mobile/ios/hooks/install.py
  44. +34 −0 mobile/ios/hooks/remove.py
  45. +18 −0 mobile/ios/hooks/uninstall.py
  46. +349 −0 mobile/ios/keychain.xcodeproj/project.pbxproj
  47. +7 −0 mobile/ios/keychain.xcodeproj/project.xcworkspace/contents.xcworkspacedata
  48. +13 −0 mobile/ios/manifest
  49. +27 −0 mobile/ios/module.xcconfig
  50. +3 −0  mobile/ios/platform/README
  51. +11 −0 mobile/ios/timodule.xml
  52. +19 −0 mobile/ios/titanium.xcconfig
2  .gitignore
@@ -0,0 +1,2 @@
+.svn
+.DS_Store
8 mobile/android/.classpath
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="src" path="build/.apt_generated"/>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+ <classpathentry kind="lib" path="/opt/android-sdk/platforms/android-7/android.jar"/> <classpathentry kind="lib" path="/opt/android-sdk/add-ons/addon_google_apis_google_inc_7/libs/maps.jar"/> <classpathentry kind="lib" path="/Library/Application Support/Titanium/mobilesdk/osx/1.7.1/android/titanium.jar"/> <classpathentry kind="lib" path="/Library/Application Support/Titanium/mobilesdk/osx/1.7.1/android/js.jar"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
5 mobile/android/.gitignore
@@ -0,0 +1,5 @@
+tmp
+bin
+build
+*.zip
+.apt_generated
17 mobile/android/.project
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>titanium-keychain</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
7 mobile/android/.settings/org.eclipse.jdt.apt.core.prefs
@@ -0,0 +1,7 @@
+#Thu Sep 02 15:18:34 CDT 2010
+eclipse.preferences.version=1
+org.eclipse.jdt.apt.aptEnabled=true
+org.eclipse.jdt.apt.genSrcDir=.apt_generated
+org.eclipse.jdt.apt.reconcileEnabled=true
+
+org.eclipse.jdt.apt.processorOptions/kroll.jsonFile=keychain.json
3  mobile/android/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,3 @@
+#Thu Sep 02 15:18:34 CDT 2010
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.processAnnotations=enabled
1  mobile/android/LICENSE
@@ -0,0 +1 @@
+TODO: place your license here and we'll include it in the module distribution
6 mobile/android/assets/README
@@ -0,0 +1,6 @@
+Place your assets like PNG files in this directory and they will be packaged with your module.
+
+If you create a file named com.obscure.keychain.js in this directory, it will be
+compiled and used as your module. This allows you to run pure Javascript
+modules that are pre-compiled.
+
3  mobile/android/build.properties
@@ -0,0 +1,3 @@
+titanium.platform=/Library/Application Support/Titanium/mobilesdk/osx/1.7.1/android
+android.platform=/opt/android-sdk/platforms/android-7
+google.apis=/opt/android-sdk/add-ons/addon_google_apis_google_inc_7
10 mobile/android/build.xml
@@ -0,0 +1,10 @@
+<project name="keychain" default="dist">
+ <description>
+ Ant build script for Titanium Android module keychain
+ </description>
+
+ <property name="ti.module.root" location="${basedir}"/>
+ <property file="build.properties" />
+
+ <import file="${titanium.platform}/../module/android/build.xml"/>
+</project>
BIN  mobile/android/dist/keychain.jar
Binary file not shown
39 mobile/android/documentation/index.md
@@ -0,0 +1,39 @@
+# keychain Module
+
+## Description
+
+TODO: Enter your module description here
+
+## Accessing the keychain Module
+
+To access this module from JavaScript, you would do the following:
+
+ var keychain = require("com.obscure.keychain");
+
+The keychain variable is a reference to the Module object.
+
+## Reference
+
+TODO: If your module has an API, you should document
+the reference here.
+
+### ___PROJECTNAMEASIDENTIFIER__.function
+
+TODO: This is an example of a module function.
+
+### ___PROJECTNAMEASIDENTIFIER__.property
+
+TODO: This is an example of a module property.
+
+## Usage
+
+TODO: Enter your usage example here
+
+## Author
+
+TODO: Enter your author name, email and other contact
+details you want to share here.
+
+## License
+
+TODO: Enter your license/legal information here.
66 mobile/android/example/app.js
@@ -0,0 +1,66 @@
+// This is a test harness for your module
+// You should do something interesting in this harness
+// to test out the module and to provide instructions
+// to users on how to use it by example.
+
+
+// open a single window
+var window = Ti.UI.createWindow({
+ backgroundColor:'white',
+});
+var label = Ti.UI.createLabel({
+ top: 20,
+ height: 30,
+ left: 10,
+ right: 10,
+ text: 'keychain test',
+});
+window.add(label);
+
+var button1 = Ti.UI.createButton({
+ title: 'set account',
+ top: 60,
+ height: 30,
+ width: 100,
+});
+button1.addEventListener('click', function() {
+ keychainItem.account = 'pegli';
+ Ti.API.info("new account = "+keychainItem.account);
+ label.text = "new account = "+keychainItem.account;
+});
+window.add(button1);
+
+var button2 = Ti.UI.createButton({
+ title: 'set password',
+ top: 100,
+ height: 30,
+ width: 100,
+});
+button2.addEventListener('click', function() {
+ keychainItem.valueData = 'supersecret';
+ Ti.API.info("new password = "+keychainItem.valueData);
+ label.text = "new password = "+keychainItem.valueData;
+});
+window.add(button2);
+
+var button3 = Ti.UI.createButton({
+ title: 'reset keychain item',
+ top: 140,
+ height: 30,
+ width: 100,
+});
+button3.addEventListener('click', function() {
+ keychainItem.reset();
+ Ti.API.info("reset item, account = "+keychainItem.account);
+ label.text = "reset item, account = "+keychainItem.account;
+});
+window.add(button3);
+
+window.open();
+
+// TODO: write your module tests here
+var keychain = require('com.obscure.keychain');
+Ti.API.info("module is => " + keychain);
+
+var keychainItem = keychain.createKeychainItem('mylogin');
+Ti.API.info("account = " + keychainItem.account + "; password = " + keychainItem.valueData);
1  mobile/android/hooks/README
@@ -0,0 +1 @@
+These files are not yet supported as of 1.4.0 but will be in a near future release.
35 mobile/android/hooks/add.py
@@ -0,0 +1,35 @@
+#!/usr/bin/env python
+#
+# This is the module project add hook that will be
+# called when your module is added to a project
+#
+import os, sys
+
+def dequote(s):
+ if s[0:1] == '"':
+ return s[1:-1]
+ return s
+
+def main(args,argc):
+ # You will get the following command line arguments
+ # in the following order:
+ #
+ # project_dir = the full path to the project root directory
+ # project_type = the type of project (desktop, mobile, ipad)
+ # project_name = the name of the project
+ #
+ project_dir = dequote(os.path.expanduser(args[1]))
+ project_type = dequote(args[2])
+ project_name = dequote(args[3])
+
+ # TODO: write your add hook here (optional)
+
+
+ # exit
+ sys.exit(0)
+
+
+
+if __name__ == '__main__':
+ main(sys.argv,len(sys.argv))
+
19 mobile/android/hooks/install.py
@@ -0,0 +1,19 @@
+#!/usr/bin/env python
+#
+# This is the module install hook that will be
+# called when your module is first installed
+#
+import os, sys
+
+def main(args,argc):
+
+ # TODO: write your install hook here (optional)
+
+ # exit
+ sys.exit(0)
+
+
+
+if __name__ == '__main__':
+ main(sys.argv,len(sys.argv))
+
34 mobile/android/hooks/remove.py
@@ -0,0 +1,34 @@
+#!/usr/bin/env python
+#
+# This is the module project remove hook that will be
+# called when your module is remove from a project
+#
+import os, sys
+
+def dequote(s):
+ if s[0:1] == '"':
+ return s[1:-1]
+ return s
+
+def main(args,argc):
+ # You will get the following command line arguments
+ # in the following order:
+ #
+ # project_dir = the full path to the project root directory
+ # project_type = the type of project (desktop, mobile, ipad)
+ # project_name = the name of the project
+ #
+ project_dir = dequote(os.path.expanduser(args[1]))
+ project_type = dequote(args[2])
+ project_name = dequote(args[3])
+
+ # TODO: write your remove hook here (optional)
+
+ # exit
+ sys.exit(0)
+
+
+
+if __name__ == '__main__':
+ main(sys.argv,len(sys.argv))
+
18 mobile/android/hooks/uninstall.py
@@ -0,0 +1,18 @@
+#!/usr/bin/env python
+#
+# This is the module uninstall hook that will be
+# called when your module is uninstalled
+#
+import os, sys
+
+def main(args,argc):
+
+ # TODO: write your uninstall hook here (optional)
+
+ # exit
+ sys.exit(0)
+
+
+if __name__ == '__main__':
+ main(sys.argv,len(sys.argv))
+
17 mobile/android/manifest
@@ -0,0 +1,17 @@
+#
+# this is your module manifest and used by Titanium
+# during compilation, packaging, distribution, etc.
+#
+version: 1.0
+description: Keychain access module for iPhone
+author: Paul Mietz Egli
+license: Apache 2.0
+copyright: Copyright (c) 2011 Paul Mietz Egli
+
+
+# these should not be edited
+name: keychain
+moduleid: com.obscure.keychain
+guid: eb0a9be8-02b5-43a2-a115-a220b293d202
+platform: android
+minsdk: 1.7.1
3  mobile/android/platform/README
@@ -0,0 +1,3 @@
+You can place platform-specific files here in sub-folders named "android" and/or "iphone", just as you can with normal Titanium Mobile SDK projects. Any folders and files you place here will be merged with the platform-specific files in a Titanium Mobile project that uses this module.
+
+When a Titanium Mobile project that uses this module is built, the files from this platform/ folder will be treated the same as files (if any) from the Titanium Mobile project's platform/ folder.
75 mobile/android/src/com/obscure/keychain/KeychainItemProxy.java
@@ -0,0 +1,75 @@
+package com.obscure.keychain;
+
+import org.appcelerator.kroll.KrollModule;
+import org.appcelerator.kroll.KrollProxy;
+import org.appcelerator.kroll.annotations.Kroll;
+import org.appcelerator.titanium.TiContext;
+import org.appcelerator.titanium.util.TiConfig;
+
+import android.content.ContextWrapper;
+import android.content.SharedPreferences;
+
+// This proxy can be created by calling Keychain.createExample({message: "hello world"})
+@Kroll.proxy(creatableInModule = KeychainModule.class)
+public class KeychainItemProxy extends KrollProxy {
+ // Standard Debugging variables
+ private static final String LCAT = "KeychainItemProxy";
+ private static final boolean DBG = TiConfig.LOGD;
+
+ private static final String ACCOUNT_KEY = "keychain.account";
+ private static final String VALUE_DATA_KEY = "keychain.valueData";
+
+ private SharedPreferences sharedPrefs;
+ private ContextWrapper androidContext;
+
+ // Constructor
+ public KeychainItemProxy(TiContext tiContext) {
+ super(tiContext);
+ androidContext = context.getAndroidContext();
+ }
+
+ @Override
+ public void handleCreationArgs(KrollModule createdInModule, Object[] args) {
+ super.handleCreationArgs(createdInModule, args);
+ if (args != null && args.length > 0) {
+ String name = String.format("keychain.%s", (String) args[0]);
+ sharedPrefs = androidContext.getSharedPreferences(name, 0);
+ }
+ }
+
+ @Kroll.getProperty
+ @Kroll.method
+ public String getAccount() {
+ return sharedPrefs.getString(ACCOUNT_KEY, null);
+ }
+
+ @Kroll.setProperty
+ @Kroll.method
+ public void setAccount(String value) {
+ SharedPreferences.Editor editor = sharedPrefs.edit();
+ editor.putString(ACCOUNT_KEY, value);
+ editor.commit();
+ }
+
+ @Kroll.getProperty
+ @Kroll.method
+ public String getValueData() {
+ return sharedPrefs.getString(VALUE_DATA_KEY, null);
+ }
+
+ @Kroll.setProperty
+ @Kroll.method
+ public void setValueData(String value) {
+ SharedPreferences.Editor editor = sharedPrefs.edit();
+ editor.putString(VALUE_DATA_KEY, value);
+ editor.commit();
+ }
+
+ @Kroll.method
+ public void reset() {
+ SharedPreferences.Editor editor = sharedPrefs.edit();
+ editor.remove(ACCOUNT_KEY);
+ editor.remove(VALUE_DATA_KEY);
+ editor.commit();
+ }
+}
53 mobile/android/src/com/obscure/keychain/KeychainModule.java
@@ -0,0 +1,53 @@
+/**
+ * This file was auto-generated by the Titanium Module SDK helper for Android
+ * Appcelerator Titanium Mobile
+ * Copyright (c) 2009-2010 by Appcelerator, Inc. All Rights Reserved.
+ * Licensed under the terms of the Apache Public License
+ * Please see the LICENSE included with this distribution for details.
+ *
+ */
+package com.obscure.keychain;
+
+import org.appcelerator.kroll.KrollModule;
+import org.appcelerator.kroll.annotations.Kroll;
+
+import org.appcelerator.titanium.TiContext;
+import org.appcelerator.titanium.util.Log;
+import org.appcelerator.titanium.util.TiConfig;
+
+@Kroll.module(name="Keychain", id="com.obscure.keychain")
+public class KeychainModule extends KrollModule
+{
+
+ // Standard Debugging variables
+ private static final String LCAT = "KeychainModule";
+ private static final boolean DBG = TiConfig.LOGD;
+
+ // You can define constants with @Kroll.constant, for example:
+ // @Kroll.constant public static final String EXTERNAL_NAME = value;
+
+ public KeychainModule(TiContext tiContext) {
+ super(tiContext);
+ }
+
+ // Methods
+ @Kroll.method
+ public String example() {
+ Log.d(LCAT, "example called");
+ return "hello world";
+ }
+
+ // Properties
+ @Kroll.getProperty
+ public String getExampleProp() {
+ Log.d(LCAT, "get example property");
+ return "hello world";
+ }
+
+
+ @Kroll.setProperty
+ public void setExampleProp(String value) {
+ Log.d(LCAT, "set example property: " + value);
+ }
+
+}
11 mobile/android/timodule.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ti:module xmlns:ti="http://ti.appcelerator.org" xmlns:android="http://schemas.android.com/apk/res/android">
+ <!--
+ Similar to tiapp.xml, but contains module/platform specific
+ configuration in <iphone> and <android> sections
+ -->
+ <iphone>
+ </iphone>
+ <android xmlns:android="http://schemas.android.com/apk/res/android">
+ </android>
+</ti:module>
4 mobile/ios/.gitignore
@@ -0,0 +1,4 @@
+tmp
+bin
+build
+*.zip
2  mobile/ios/Classes/.gitignore
@@ -0,0 +1,2 @@
+ComObscureKeychain.h
+ComObscureKeychain.m
13 mobile/ios/Classes/ComObscureKeychainModule.h
@@ -0,0 +1,13 @@
+/**
+ * Your Copyright Here
+ *
+ * Appcelerator Titanium is Copyright (c) 2009-2010 by Appcelerator, Inc.
+ * and licensed under the Apache Public License (version 2)
+ */
+#import "TiModule.h"
+
+@interface ComObscureKeychainModule : TiModule
+{
+}
+
+@end
105 mobile/ios/Classes/ComObscureKeychainModule.m
@@ -0,0 +1,105 @@
+/**
+ * Your Copyright Here
+ *
+ * Appcelerator Titanium is Copyright (c) 2009-2010 by Appcelerator, Inc.
+ * and licensed under the Apache Public License (version 2)
+ */
+#import <CoreFoundation/CoreFoundation.h>
+#import <Security/Security.h>
+#import "ComObscureKeychainModule.h"
+#import "KeychainItemWrapperProxy.h"
+#import "TiBase.h"
+#import "TiHost.h"
+#import "TiUtils.h"
+
+@implementation ComObscureKeychainModule
+
+#pragma mark Internal
+
+// this is generated for your module, please do not change it
+-(id)moduleGUID
+{
+ return @"acf8434d-5290-4b73-8f39-e4cd7349860a";
+}
+
+// this is generated for your module, please do not change it
+-(NSString*)moduleId
+{
+ return @"com.obscure.keychain";
+}
+
+#pragma mark Lifecycle
+
+-(void)startup
+{
+ // this method is called when the module is first loaded
+ // you *must* call the superclass
+ [super startup];
+
+ NSLog(@"[INFO] %@ loaded",self);
+}
+
+-(void)shutdown:(id)sender
+{
+ // this method is called when the module is being unloaded
+ // typically this is during shutdown. make sure you don't do too
+ // much processing here or the app will be quit forceably
+
+ // you *must* call the superclass
+ [super shutdown:sender];
+}
+
+#pragma mark Cleanup
+
+-(void)dealloc
+{
+ // release any resources that have been retained by the module
+ [super dealloc];
+}
+
+#pragma mark Internal Memory Management
+
+-(void)didReceiveMemoryWarning:(NSNotification*)notification
+{
+ // optionally release any resources that can be dynamically
+ // reloaded once memory is available - such as caches
+ [super didReceiveMemoryWarning:notification];
+}
+
+#pragma mark Listener Notifications
+
+-(void)_listenerAdded:(NSString *)type count:(int)count
+{
+ if (count == 1 && [type isEqualToString:@"my_event"])
+ {
+ // the first (of potentially many) listener is being added
+ // for event named 'my_event'
+ }
+}
+
+-(void)_listenerRemoved:(NSString *)type count:(int)count
+{
+ if (count == 0 && [type isEqualToString:@"my_event"])
+ {
+ // the last listener called for event named 'my_event' has
+ // been removed, we can optionally clean up any resources
+ // since no body is listening at this point for that event
+ }
+}
+
+#pragma Public APIs
+
+- (id)createKeychainItem:(id)args {
+ NSArray * arr = (NSArray *)args;
+ if (!arr || [arr count] < 1) return nil;
+
+ NSString * identifier = [TiUtils stringValue:[arr objectAtIndex:0]];
+ NSString * accessGroup = nil;
+ if ([arr count] > 1) {
+ accessGroup = [TiUtils stringValue:[arr objectAtIndex:1]];
+ }
+
+ return [[[KeychainItemWrapperProxy alloc] initWithIdentifier:identifier accessGroup:accessGroup] autorelease];
+}
+
+@end
9 mobile/ios/Classes/ComObscureKeychainModuleAssets.h
@@ -0,0 +1,9 @@
+/**
+ * This is a generated file. Do not edit or your changes will be lost
+ */
+
+@interface ComObscureKeychainModuleAssets : NSObject
+{
+}
+- (NSData*) moduleAsset;
+@end
15 mobile/ios/Classes/ComObscureKeychainModuleAssets.m
@@ -0,0 +1,15 @@
+/**
+ * This is a generated file. Do not edit or your changes will be lost
+ */
+#import "ComObscureKeychainModuleAssets.h"
+
+extern NSData * dataWithHexString (NSString * hexString);
+
+@implementation ComObscureKeychainModuleAssets
+
+- (NSData*) moduleAsset
+{
+ return nil;
+}
+
+@end
74 mobile/ios/Classes/KeychainItemWrapper.h
@@ -0,0 +1,74 @@
+/*
+ File: KeychainItemWrapper.h
+ Abstract:
+ Objective-C wrapper for accessing a single keychain item.
+
+ Version: 1.2
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
+ Inc. ("Apple") in consideration of your agreement to the following
+ terms, and your use, installation, modification or redistribution of
+ this Apple software constitutes acceptance of these terms. If you do
+ not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and
+ subject to these terms, Apple grants you a personal, non-exclusive
+ license, under Apple's copyrights in this original Apple software (the
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple
+ Software, with or without modifications, in source and/or binary forms;
+ provided that if you redistribute the Apple Software in its entirety and
+ without modifications, you must retain this notice and the following
+ text and disclaimers in all such redistributions of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may
+ be used to endorse or promote products derived from the Apple Software
+ without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or
+ implied, are granted by Apple herein, including but not limited to any
+ patent rights that may be infringed by your derivative works or by other
+ works in which the Apple Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ Copyright (C) 2010 Apple Inc. All Rights Reserved.
+
+*/
+
+#import <UIKit/UIKit.h>
+
+/*
+ The KeychainItemWrapper class is an abstraction layer for the iPhone Keychain communication. It is merely a
+ simple wrapper to provide a distinct barrier between all the idiosyncracies involved with the Keychain
+ CF/NS container objects.
+*/
+@interface KeychainItemWrapper : NSObject
+{
+ NSMutableDictionary *keychainItemData; // The actual keychain item data backing store.
+ NSMutableDictionary *genericPasswordQuery; // A placeholder for the generic keychain item query used to locate the item.
+}
+
+@property (nonatomic, retain) NSMutableDictionary *keychainItemData;
+@property (nonatomic, retain) NSMutableDictionary *genericPasswordQuery;
+
+// Designated initializer.
+- (id)initWithIdentifier: (NSString *)identifier accessGroup:(NSString *) accessGroup;
+- (void)setObject:(id)inObject forKey:(id)key;
+- (id)objectForKey:(id)key;
+
+// Initializes and resets the default generic keychain item data.
+- (void)resetKeychainItem;
+
+@end
319 mobile/ios/Classes/KeychainItemWrapper.m
@@ -0,0 +1,319 @@
+/*
+ File: KeychainItemWrapper.m
+ Abstract:
+ Objective-C wrapper for accessing a single keychain item.
+
+ Version: 1.2
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
+ Inc. ("Apple") in consideration of your agreement to the following
+ terms, and your use, installation, modification or redistribution of
+ this Apple software constitutes acceptance of these terms. If you do
+ not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and
+ subject to these terms, Apple grants you a personal, non-exclusive
+ license, under Apple's copyrights in this original Apple software (the
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple
+ Software, with or without modifications, in source and/or binary forms;
+ provided that if you redistribute the Apple Software in its entirety and
+ without modifications, you must retain this notice and the following
+ text and disclaimers in all such redistributions of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may
+ be used to endorse or promote products derived from the Apple Software
+ without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or
+ implied, are granted by Apple herein, including but not limited to any
+ patent rights that may be infringed by your derivative works or by other
+ works in which the Apple Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ Copyright (C) 2010 Apple Inc. All Rights Reserved.
+
+*/
+
+#import "KeychainItemWrapper.h"
+#import <Security/Security.h>
+
+/*
+
+These are the default constants and their respective types,
+available for the kSecClassGenericPassword Keychain Item class:
+
+kSecAttrAccessGroup - CFStringRef
+kSecAttrCreationDate - CFDateRef
+kSecAttrModificationDate - CFDateRef
+kSecAttrDescription - CFStringRef
+kSecAttrComment - CFStringRef
+kSecAttrCreator - CFNumberRef
+kSecAttrType - CFNumberRef
+kSecAttrLabel - CFStringRef
+kSecAttrIsInvisible - CFBooleanRef
+kSecAttrIsNegative - CFBooleanRef
+kSecAttrAccount - CFStringRef
+kSecAttrService - CFStringRef
+kSecAttrGeneric - CFDataRef
+
+See the header file Security/SecItem.h for more details.
+
+*/
+
+@interface KeychainItemWrapper (PrivateMethods)
+/*
+The decision behind the following two methods (secItemFormatToDictionary and dictionaryToSecItemFormat) was
+to encapsulate the transition between what the detail view controller was expecting (NSString *) and what the
+Keychain API expects as a validly constructed container class.
+*/
+- (NSMutableDictionary *)secItemFormatToDictionary:(NSDictionary *)dictionaryToConvert;
+- (NSMutableDictionary *)dictionaryToSecItemFormat:(NSDictionary *)dictionaryToConvert;
+
+// Updates the item in the keychain, or adds it if it doesn't exist.
+- (void)writeToKeychain;
+
+@end
+
+@implementation KeychainItemWrapper
+
+@synthesize keychainItemData, genericPasswordQuery;
+
+- (id)initWithIdentifier: (NSString *)identifier accessGroup:(NSString *) accessGroup;
+{
+ if (self = [super init])
+ {
+ // Begin Keychain search setup. The genericPasswordQuery leverages the special user
+ // defined attribute kSecAttrGeneric to distinguish itself between other generic Keychain
+ // items which may be included by the same application.
+ genericPasswordQuery = [[NSMutableDictionary alloc] init];
+
+ [genericPasswordQuery setObject:(id)kSecClassGenericPassword forKey:(id)kSecClass];
+ [genericPasswordQuery setObject:identifier forKey:(id)kSecAttrGeneric];
+
+ // The keychain access group attribute determines if this item can be shared
+ // amongst multiple apps whose code signing entitlements contain the same keychain access group.
+ if (accessGroup != nil)
+ {
+#if TARGET_IPHONE_SIMULATOR
+ // Ignore the access group if running on the iPhone simulator.
+ //
+ // Apps that are built for the simulator aren't signed, so there's no keychain access group
+ // for the simulator to check. This means that all apps can see all keychain items when run
+ // on the simulator.
+ //
+ // If a SecItem contains an access group attribute, SecItemAdd and SecItemUpdate on the
+ // simulator will return -25243 (errSecNoAccessForItem).
+#else
+ [genericPasswordQuery setObject:accessGroup forKey:(id)kSecAttrAccessGroup];
+#endif
+ }
+
+ // Use the proper search constants, return only the attributes of the first match.
+ [genericPasswordQuery setObject:(id)kSecMatchLimitOne forKey:(id)kSecMatchLimit];
+ [genericPasswordQuery setObject:(id)kCFBooleanTrue forKey:(id)kSecReturnAttributes];
+
+ NSDictionary *tempQuery = [NSDictionary dictionaryWithDictionary:genericPasswordQuery];
+
+ NSMutableDictionary *outDictionary = nil;
+
+ if (! SecItemCopyMatching((CFDictionaryRef)tempQuery, (CFTypeRef *)&outDictionary) == noErr)
+ {
+ // Stick these default values into keychain item if nothing found.
+ [self resetKeychainItem];
+
+ // Add the generic attribute and the keychain access group.
+ [keychainItemData setObject:identifier forKey:(id)kSecAttrGeneric];
+ if (accessGroup != nil)
+ {
+#if TARGET_IPHONE_SIMULATOR
+ // Ignore the access group if running on the iPhone simulator.
+ //
+ // Apps that are built for the simulator aren't signed, so there's no keychain access group
+ // for the simulator to check. This means that all apps can see all keychain items when run
+ // on the simulator.
+ //
+ // If a SecItem contains an access group attribute, SecItemAdd and SecItemUpdate on the
+ // simulator will return -25243 (errSecNoAccessForItem).
+#else
+ [keychainItemData setObject:accessGroup forKey:(id)kSecAttrAccessGroup];
+#endif
+ }
+ }
+ else
+ {
+ // load the saved data from Keychain.
+ self.keychainItemData = [self secItemFormatToDictionary:outDictionary];
+ }
+
+ [outDictionary release];
+ }
+
+ return self;
+}
+
+- (void)dealloc
+{
+ [keychainItemData release];
+ [genericPasswordQuery release];
+
+ [super dealloc];
+}
+
+- (void)setObject:(id)inObject forKey:(id)key
+{
+ if (inObject == nil) return;
+ id currentObject = [keychainItemData objectForKey:key];
+ if (![currentObject isEqual:inObject])
+ {
+ [keychainItemData setObject:inObject forKey:key];
+ [self writeToKeychain];
+ }
+}
+
+- (id)objectForKey:(id)key
+{
+ return [keychainItemData objectForKey:key];
+}
+
+- (void)resetKeychainItem
+{
+ OSStatus junk = noErr;
+ if (!keychainItemData)
+ {
+ self.keychainItemData = [[NSMutableDictionary alloc] init];
+ }
+ else if (keychainItemData)
+ {
+ NSMutableDictionary *tempDictionary = [self dictionaryToSecItemFormat:keychainItemData];
+ junk = SecItemDelete((CFDictionaryRef)tempDictionary);
+ NSAssert( junk == noErr || junk == errSecItemNotFound, @"Problem deleting current dictionary." );
+ }
+
+ // Default attributes for keychain item.
+ [keychainItemData setObject:@"" forKey:(id)kSecAttrAccount];
+ [keychainItemData setObject:@"" forKey:(id)kSecAttrLabel];
+ [keychainItemData setObject:@"" forKey:(id)kSecAttrDescription];
+
+ // Default data for keychain item.
+ [keychainItemData setObject:@"" forKey:(id)kSecValueData];
+}
+
+- (NSMutableDictionary *)dictionaryToSecItemFormat:(NSDictionary *)dictionaryToConvert
+{
+ // The assumption is that this method will be called with a properly populated dictionary
+ // containing all the right key/value pairs for a SecItem.
+
+ // Create a dictionary to return populated with the attributes and data.
+ NSMutableDictionary *returnDictionary = [NSMutableDictionary dictionaryWithDictionary:dictionaryToConvert];
+
+ // Add the Generic Password keychain item class attribute.
+ [returnDictionary setObject:(id)kSecClassGenericPassword forKey:(id)kSecClass];
+
+ // Convert the NSString to NSData to meet the requirements for the value type kSecValueData.
+ // This is where to store sensitive data that should be encrypted.
+ NSString *passwordString = [dictionaryToConvert objectForKey:(id)kSecValueData];
+ [returnDictionary setObject:[passwordString dataUsingEncoding:NSUTF8StringEncoding] forKey:(id)kSecValueData];
+
+ return returnDictionary;
+}
+
+- (NSMutableDictionary *)secItemFormatToDictionary:(NSDictionary *)dictionaryToConvert
+{
+ // The assumption is that this method will be called with a properly populated dictionary
+ // containing all the right key/value pairs for the UI element.
+
+ // Create a dictionary to return populated with the attributes and data.
+ NSMutableDictionary *returnDictionary = [NSMutableDictionary dictionaryWithDictionary:dictionaryToConvert];
+
+ // Add the proper search key and class attribute.
+ [returnDictionary setObject:(id)kCFBooleanTrue forKey:(id)kSecReturnData];
+ [returnDictionary setObject:(id)kSecClassGenericPassword forKey:(id)kSecClass];
+
+ // Acquire the password data from the attributes.
+ NSData *passwordData = NULL;
+ if (SecItemCopyMatching((CFDictionaryRef)returnDictionary, (CFTypeRef *)&passwordData) == noErr)
+ {
+ // Remove the search, class, and identifier key/value, we don't need them anymore.
+ [returnDictionary removeObjectForKey:(id)kSecReturnData];
+
+ // Add the password to the dictionary, converting from NSData to NSString.
+ NSString *password = [[[NSString alloc] initWithBytes:[passwordData bytes] length:[passwordData length]
+ encoding:NSUTF8StringEncoding] autorelease];
+ [returnDictionary setObject:password forKey:(id)kSecValueData];
+ }
+ else
+ {
+ // Don't do anything if nothing is found.
+ NSAssert(NO, @"Serious error, no matching item found in the keychain.\n");
+ }
+
+ [passwordData release];
+
+ return returnDictionary;
+}
+
+- (void)writeToKeychain
+{
+ NSDictionary *attributes = NULL;
+ NSMutableDictionary *updateItem = NULL;
+ OSStatus result;
+
+ if (SecItemCopyMatching((CFDictionaryRef)genericPasswordQuery, (CFTypeRef *)&attributes) == noErr)
+ {
+ // First we need the attributes from the Keychain.
+ updateItem = [NSMutableDictionary dictionaryWithDictionary:attributes];
+ // Second we need to add the appropriate search key/values.
+ [updateItem setObject:[genericPasswordQuery objectForKey:(id)kSecClass] forKey:(id)kSecClass];
+
+ // Lastly, we need to set up the updated attribute list being careful to remove the class.
+ NSMutableDictionary *tempCheck = [self dictionaryToSecItemFormat:keychainItemData];
+ [tempCheck removeObjectForKey:(id)kSecClass];
+
+#if TARGET_IPHONE_SIMULATOR
+ // Remove the access group if running on the iPhone simulator.
+ //
+ // Apps that are built for the simulator aren't signed, so there's no keychain access group
+ // for the simulator to check. This means that all apps can see all keychain items when run
+ // on the simulator.
+ //
+ // If a SecItem contains an access group attribute, SecItemAdd and SecItemUpdate on the
+ // simulator will return -25243 (errSecNoAccessForItem).
+ //
+ // The access group attribute will be included in items returned by SecItemCopyMatching,
+ // which is why we need to remove it before updating the item.
+ [tempCheck removeObjectForKey:(id)kSecAttrAccessGroup];
+#endif
+
+ // An implicit assumption is that you can only update a single item at a time.
+
+ result = SecItemUpdate((CFDictionaryRef)updateItem, (CFDictionaryRef)tempCheck);
+ if (result != noErr) {
+ NSLog(@"error updating keychain item: %ld", result);
+ NSLog(@"updateItem: %@", [updateItem description]);
+ }
+ }
+ else
+ {
+ // No previous item found; add the new one.
+ result = SecItemAdd((CFDictionaryRef)[self dictionaryToSecItemFormat:keychainItemData], NULL);
+ if (result != noErr) {
+ NSLog(@"error creating keychain item: %ld", result);
+ NSLog(@"keychainItemData: %@", [keychainItemData description]);
+ }
+ }
+}
+
+@end
19 mobile/ios/Classes/KeychainItemWrapperProxy.h
@@ -0,0 +1,19 @@
+//
+// KeychainItemWrapperProxy.h
+// keychain
+//
+// Created by Paul Mietz Egli on 7/20/11.
+// Copyright 2011 __MyCompanyName__. All rights reserved.
+//
+
+#import "TiProxy.h"
+#import "KeychainItemWrapper.h"
+
+@interface KeychainItemWrapperProxy : TiProxy {
+ @private
+ KeychainItemWrapper * keychainItem;
+}
+@property (nonatomic, retain) NSString * account;
+@property (nonatomic, retain) NSString * valueData;
+- (id)initWithIdentifier:(NSString *)identifier accessGroup:(NSString *)accessGroup;
+@end
65 mobile/ios/Classes/KeychainItemWrapperProxy.m
@@ -0,0 +1,65 @@
+//
+// KeychainItemWrapperProxy.m
+// keychain
+//
+// Created by Paul Mietz Egli on 7/20/11.
+// Copyright 2011 __MyCompanyName__. All rights reserved.
+//
+
+#import "KeychainItemWrapperProxy.h"
+
+@implementation KeychainItemWrapperProxy
+
+- (id)initWithIdentifier:(NSString *)identifier accessGroup:(NSString *)accessGroup
+{
+ self = [super init];
+ if (self) {
+ keychainItem = [[KeychainItemWrapper alloc] initWithIdentifier:identifier accessGroup:accessGroup];
+ }
+
+ return self;
+}
+
+-(void) dealloc {
+ [keychainItem release];
+ [super dealloc];
+}
+
+- (NSString *)account {
+ return [keychainItem objectForKey:(id)kSecAttrAccount];
+}
+
+- (void)setAccount:(NSString *)value {
+ [keychainItem setObject:value forKey:(id)kSecAttrAccount];
+}
+
+- (NSString *)valueData {
+ return [keychainItem objectForKey:(id)kSecValueData];
+}
+
+- (void)setValueData:(NSString *)value {
+ [keychainItem setObject:value forKey:(id)kSecValueData];
+}
+
+- (NSString *)description {
+ return [keychainItem objectForKey:(id)kSecAttrDescription];
+}
+
+- (void)setDescription:(NSString *)value {
+ [keychainItem setObject:value forKey:(id)kSecAttrDescription];
+}
+
+- (NSString *)comment {
+ return [keychainItem objectForKey:(id)kSecAttrComment];
+}
+
+- (void)setComment:(NSString *)value {
+ [keychainItem setObject:value forKey:(id)kSecAttrComment];
+}
+
+
+- (void)reset:(id)args {
+ [keychainItem resetKeychainItem];
+}
+
+@end
4 mobile/ios/ComObscureKeychain_Prefix.pch
@@ -0,0 +1,4 @@
+
+#ifdef __OBJC__
+ #import <Foundation/Foundation.h>
+#endif
62 mobile/ios/LICENSE
@@ -0,0 +1,62 @@
+Copyright 2011 Paul Mietz Egli
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+------------
+
+File: KeychainItemWrapper.h and KeychainItemWrapper.m
+Abstract:
+Objective-C wrapper for accessing a single keychain item.
+
+ Version: 1.2
+
+Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
+Inc. ("Apple") in consideration of your agreement to the following
+terms, and your use, installation, modification or redistribution of
+this Apple software constitutes acceptance of these terms. If you do
+not agree with these terms, please do not use, install, modify or
+redistribute this Apple software.
+
+In consideration of your agreement to abide by the following terms, and
+subject to these terms, Apple grants you a personal, non-exclusive
+license, under Apple's copyrights in this original Apple software (the
+"Apple Software"), to use, reproduce, modify and redistribute the Apple
+Software, with or without modifications, in source and/or binary forms;
+provided that if you redistribute the Apple Software in its entirety and
+without modifications, you must retain this notice and the following
+text and disclaimers in all such redistributions of the Apple Software.
+Neither the name, trademarks, service marks or logos of Apple Inc. may
+be used to endorse or promote products derived from the Apple Software
+without specific prior written permission from Apple. Except as
+expressly stated in this notice, no other rights or licenses, express or
+implied, are granted by Apple herein, including but not limited to any
+patent rights that may be infringed by your derivative works or by other
+works in which the Apple Software may be incorporated.
+
+The Apple Software is provided by Apple on an "AS IS" basis. APPLE
+MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+
+Copyright (C) 2010 Apple Inc. All Rights Reserved.
+
0  mobile/ios/README
No changes.
6 mobile/ios/assets/README
@@ -0,0 +1,6 @@
+Place your assets like PNG files in this directory and they will be packaged with your module.
+
+If you create a file named com.obscure.keychain.js in this directory, it will be
+compiled and used as your module. This allows you to run pure Javascript
+modules that are pre-compiled.
+
196 mobile/ios/build.py
@@ -0,0 +1,196 @@
+#!/usr/bin/env python
+#
+# Appcelerator Titanium Module Packager
+#
+#
+import os, sys, glob, string
+import zipfile
+from datetime import date
+
+cwd = os.path.abspath(os.path.dirname(sys._getframe(0).f_code.co_filename))
+os.chdir(cwd)
+required_module_keys = ['name','version','moduleid','description','copyright','license','copyright','platform','minsdk']
+module_defaults = {
+ 'description':'My module',
+ 'author': 'Your Name',
+ 'license' : 'Specify your license',
+ 'copyright' : 'Copyright (c) %s by Your Company' % str(date.today().year),
+}
+module_license_default = "TODO: place your license here and we'll include it in the module distribution"
+
+def replace_vars(config,token):
+ idx = token.find('$(')
+ while idx != -1:
+ idx2 = token.find(')',idx+2)
+ if idx2 == -1: break
+ key = token[idx+2:idx2]
+ if not config.has_key(key): break
+ token = token.replace('$(%s)' % key, config[key])
+ idx = token.find('$(')
+ return token
+
+
+def read_ti_xcconfig():
+ contents = open(os.path.join(cwd,'titanium.xcconfig')).read()
+ config = {}
+ for line in contents.splitlines(False):
+ line = line.strip()
+ if line[0:2]=='//': continue
+ idx = line.find('=')
+ if idx > 0:
+ key = line[0:idx].strip()
+ value = line[idx+1:].strip()
+ config[key] = replace_vars(config,value)
+ return config
+
+def generate_doc(config):
+ docdir = os.path.join(cwd,'documentation')
+ if not os.path.exists(docdir):
+ print "Couldn't find documentation file at: %s" % docdir
+ return None
+ sdk = config['TITANIUM_SDK']
+ support_dir = os.path.join(sdk,'module','support')
+ sys.path.append(support_dir)
+ import markdown
+ documentation = []
+ for file in os.listdir(docdir):
+ if os.path.isdir(file) == False:
+ md = open(os.path.join(docdir,file)).read()
+ html = markdown.markdown(md)
+ documentation.append({file:html});
+ return documentation
+
+def compile_js(manifest,config):
+ js_file = os.path.join(cwd,'assets','com.obscure.keychain.js')
+ if not os.path.exists(js_file): return
+
+ sdk = config['TITANIUM_SDK']
+ iphone_dir = os.path.join(sdk,'iphone')
+ sys.path.insert(0,iphone_dir)
+ from compiler import Compiler
+
+ path = os.path.basename(js_file)
+ metadata = Compiler.make_function_from_file(path,js_file)
+ method = metadata['method']
+ eq = path.replace('.','_')
+ method = ' return %s;' % method
+
+ f = os.path.join(cwd,'Classes','ComObscureKeychainModuleAssets.m')
+ c = open(f).read()
+ idx = c.find('return ')
+ before = c[0:idx]
+ after = """
+}
+
+@end
+ """
+ newc = before + method + after
+
+ if newc!=c:
+ x = open(f,'w')
+ x.write(newc)
+ x.close()
+
+def die(msg):
+ print msg
+ sys.exit(1)
+
+def warn(msg):
+ print "[WARN] %s" % msg
+
+def validate_license():
+ c = open(os.path.join(cwd,'LICENSE')).read()
+ if c.find(module_license_default)!=1:
+ warn('please update the LICENSE file with your license text before distributing')
+
+def validate_manifest():
+ path = os.path.join(cwd,'manifest')
+ f = open(path)
+ if not os.path.exists(path): die("missing %s" % path)
+ manifest = {}
+ for line in f.readlines():
+ line = line.strip()
+ if line[0:1]=='#': continue
+ if line.find(':') < 0: continue
+ key,value = line.split(':')
+ manifest[key.strip()]=value.strip()
+ for key in required_module_keys:
+ if not manifest.has_key(key): die("missing required manifest key '%s'" % key)
+ if module_defaults.has_key(key):
+ defvalue = module_defaults[key]
+ curvalue = manifest[key]
+ if curvalue==defvalue: warn("please update the manifest key: '%s' to a non-default value" % key)
+ return manifest,path
+
+ignoreFiles = ['.DS_Store','.gitignore','libTitanium.a','titanium.jar','README','com.obscure.keychain.js']
+ignoreDirs = ['.DS_Store','.svn','.git','CVSROOT']
+
+def zip_dir(zf,dir,basepath,ignore=[]):
+ for root, dirs, files in os.walk(dir):
+ for name in ignoreDirs:
+ if name in dirs:
+ dirs.remove(name) # don't visit ignored directories
+ for file in files:
+ if file in ignoreFiles: continue
+ e = os.path.splitext(file)
+ if len(e)==2 and e[1]=='.pyc':continue
+ from_ = os.path.join(root, file)
+ to_ = from_.replace(dir, basepath, 1)
+ zf.write(from_, to_)
+
+def glob_libfiles():
+ files = []
+ for libfile in glob.glob('build/**/*.a'):
+ if libfile.find('Release-')!=-1:
+ files.append(libfile)
+ return files
+
+def build_module(manifest,config):
+ rc = os.system("xcodebuild -sdk iphoneos -configuration Release")
+ if rc != 0:
+ die("xcodebuild failed")
+ rc = os.system("xcodebuild -sdk iphonesimulator -configuration Release")
+ if rc != 0:
+ die("xcodebuild failed")
+ # build the merged library using lipo
+ moduleid = manifest['moduleid']
+ libpaths = ''
+ for libfile in glob_libfiles():
+ libpaths+='%s ' % libfile
+
+ os.system("lipo %s -create -output build/lib%s.a" %(libpaths,moduleid))
+
+def package_module(manifest,mf,config):
+ name = manifest['name'].lower()
+ moduleid = manifest['moduleid'].lower()
+ version = manifest['version']
+ modulezip = '%s-iphone-%s.zip' % (moduleid,version)
+ if os.path.exists(modulezip): os.remove(modulezip)
+ zf = zipfile.ZipFile(modulezip, 'w', zipfile.ZIP_DEFLATED)
+ modulepath = 'modules/iphone/%s/%s' % (moduleid,version)
+ zf.write(mf,'%s/manifest' % modulepath)
+ libname = 'lib%s.a' % moduleid
+ zf.write('build/%s' % libname, '%s/%s' % (modulepath,libname))
+ docs = generate_doc(config)
+ if docs!=None:
+ for doc in docs:
+ for file, html in doc.iteritems():
+ filename = string.replace(file,'.md','.html')
+ zf.writestr('%s/documentation/%s'%(modulepath,filename),html)
+ for dn in ('assets','example','platform'):
+ if os.path.exists(dn):
+ zip_dir(zf,dn,'%s/%s' % (modulepath,dn),['README'])
+ zf.write('LICENSE','%s/LICENSE' % modulepath)
+ zf.write('module.xcconfig','%s/module.xcconfig' % modulepath)
+ zf.close()
+
+
+if __name__ == '__main__':
+ manifest,mf = validate_manifest()
+ validate_license()
+ config = read_ti_xcconfig()
+ compile_js(manifest,config)
+ build_module(manifest,config)
+ package_module(manifest,mf,config)
+ sys.exit(0)
+
39 mobile/ios/documentation/index.md
@@ -0,0 +1,39 @@
+# keychain Module
+
+## Description
+
+TODO: Enter your module description here
+
+## Accessing the keychain Module
+
+To access this module from JavaScript, you would do the following:
+
+ var keychain = require("com.obscure.keychain");
+
+The keychain variable is a reference to the Module object.
+
+## Reference
+
+TODO: If your module has an API, you should document
+the reference here.
+
+### ___PROJECTNAMEASIDENTIFIER__.function
+
+TODO: This is an example of a module function.
+
+### ___PROJECTNAMEASIDENTIFIER__.property
+
+TODO: This is an example of a module property.
+
+## Usage
+
+TODO: Enter your usage example here
+
+## Author
+
+TODO: Enter your author name, email and other contact
+details you want to share here.
+
+## License
+
+TODO: Enter your license/legal information here.
66 mobile/ios/example/app.js
@@ -0,0 +1,66 @@
+// This is a test harness for your module
+// You should do something interesting in this harness
+// to test out the module and to provide instructions
+// to users on how to use it by example.
+
+
+// open a single window
+var window = Ti.UI.createWindow({
+ backgroundColor:'white',
+});
+var label = Ti.UI.createLabel({
+ top: 20,
+ height: 30,
+ left: 10,
+ right: 10,
+ text: 'keychain test',
+});
+window.add(label);
+
+var button1 = Ti.UI.createButton({
+ title: 'set account',
+ top: 60,
+ height: 30,
+ width: 100,
+});
+button1.addEventListener('click', function() {
+ keychainItem.account = 'pegli';
+ Ti.API.info("new account = "+keychainItem.account);
+ label.text = "new account = "+keychainItem.account;
+});
+window.add(button1);
+
+var button2 = Ti.UI.createButton({
+ title: 'set password',
+ top: 100,
+ height: 30,
+ width: 100,
+});
+button2.addEventListener('click', function() {
+ keychainItem.valueData = 'supersecret';
+ Ti.API.info("new password = "+keychainItem.valueData);
+ label.text = "new password = "+keychainItem.valueData;
+});
+window.add(button2);
+
+var button3 = Ti.UI.createButton({
+ title: 'reset keychain item',
+ top: 140,
+ height: 30,
+ width: 100,
+});
+button3.addEventListener('click', function() {
+ keychainItem.reset();
+ Ti.API.info("reset item, account = "+keychainItem.account);
+ label.text = "reset item, account = "+keychainItem.account;
+});
+window.add(button3);
+
+window.open();
+
+// TODO: write your module tests here
+var keychain = require('com.obscure.keychain');
+Ti.API.info("module is => " + keychain);
+
+var keychainItem = keychain.createKeychainItem('mylogin');
+Ti.API.info("account = " + keychainItem.account + "; password = " + keychainItem.valueData);
1  mobile/ios/hooks/README
@@ -0,0 +1 @@
+These files are not yet supported as of 1.4.0 but will be in a near future release.
35 mobile/ios/hooks/add.py
@@ -0,0 +1,35 @@
+#!/usr/bin/env python
+#
+# This is the module project add hook that will be
+# called when your module is added to a project
+#
+import os, sys
+
+def dequote(s):
+ if s[0:1] == '"':
+ return s[1:-1]
+ return s
+
+def main(args,argc):
+ # You will get the following command line arguments
+ # in the following order:
+ #
+ # project_dir = the full path to the project root directory
+ # project_type = the type of project (desktop, mobile, ipad)
+ # project_name = the name of the project
+ #
+ project_dir = dequote(os.path.expanduser(args[1]))
+ project_type = dequote(args[2])
+ project_name = dequote(args[3])
+
+ # TODO: write your add hook here (optional)
+
+
+ # exit
+ sys.exit(0)
+
+
+
+if __name__ == '__main__':
+ main(sys.argv,len(sys.argv))
+
19 mobile/ios/hooks/install.py
@@ -0,0 +1,19 @@
+#!/usr/bin/env python
+#
+# This is the module install hook that will be
+# called when your module is first installed
+#
+import os, sys
+
+def main(args,argc):
+
+ # TODO: write your install hook here (optional)
+
+ # exit
+ sys.exit(0)
+
+
+
+if __name__ == '__main__':
+ main(sys.argv,len(sys.argv))
+
34 mobile/ios/hooks/remove.py
@@ -0,0 +1,34 @@
+#!/usr/bin/env python
+#
+# This is the module project remove hook that will be
+# called when your module is remove from a project
+#
+import os, sys
+
+def dequote(s):
+ if s[0:1] == '"':
+ return s[1:-1]
+ return s
+
+def main(args,argc):
+ # You will get the following command line arguments
+ # in the following order:
+ #
+ # project_dir = the full path to the project root directory
+ # project_type = the type of project (desktop, mobile, ipad)
+ # project_name = the name of the project
+ #
+ project_dir = dequote(os.path.expanduser(args[1]))
+ project_type = dequote(args[2])
+ project_name = dequote(args[3])
+
+ # TODO: write your remove hook here (optional)
+
+ # exit
+ sys.exit(0)
+
+
+
+if __name__ == '__main__':
+ main(sys.argv,len(sys.argv))
+
18 mobile/ios/hooks/uninstall.py
@@ -0,0 +1,18 @@
+#!/usr/bin/env python
+#
+# This is the module uninstall hook that will be
+# called when your module is uninstalled
+#
+import os, sys
+
+def main(args,argc):
+
+ # TODO: write your uninstall hook here (optional)
+
+ # exit
+ sys.exit(0)
+
+
+if __name__ == '__main__':
+ main(sys.argv,len(sys.argv))
+
349 mobile/ios/keychain.xcodeproj/project.pbxproj
@@ -0,0 +1,349 @@
+// !$*UTF8*$!
+{
+ archiveVersion = 1;
+ classes = {
+ };
+ objectVersion = 46;
+ objects = {
+
+/* Begin PBXAggregateTarget section */
+ 24416B8111C4CA220047AFDD /* Build & Test */ = {
+ isa = PBXAggregateTarget;
+ buildConfigurationList = 24416B8A11C4CA520047AFDD /* Build configuration list for PBXAggregateTarget "Build & Test" */;
+ buildPhases = (
+ 24416B8011C4CA220047AFDD /* ShellScript */,
+ );
+ dependencies = (
+ 24416B8511C4CA280047AFDD /* PBXTargetDependency */,
+ );
+ name = "Build & Test";
+ productName = "Build & test";
+ };
+/* End PBXAggregateTarget section */
+
+/* Begin PBXBuildFile section */
+ 24DD6CF91134B3F500162E58 /* ComObscureKeychainModule.h in Headers */ = {isa = PBXBuildFile; fileRef = 24DD6CF71134B3F500162E58 /* ComObscureKeychainModule.h */; };
+ 24DD6CFA1134B3F500162E58 /* ComObscureKeychainModule.m in Sources */ = {isa = PBXBuildFile; fileRef = 24DD6CF81134B3F500162E58 /* ComObscureKeychainModule.m */; };
+ 24DE9E1111C5FE74003F90F6 /* ComObscureKeychainModuleAssets.h in Headers */ = {isa = PBXBuildFile; fileRef = 24DE9E0F11C5FE74003F90F6 /* ComObscureKeychainModuleAssets.h */; };
+ 24DE9E1211C5FE74003F90F6 /* ComObscureKeychainModuleAssets.m in Sources */ = {isa = PBXBuildFile; fileRef = 24DE9E1011C5FE74003F90F6 /* ComObscureKeychainModuleAssets.m */; };
+ AA747D9F0F9514B9006C5449 /* ComObscureKeychain_Prefix.pch in Headers */ = {isa = PBXBuildFile; fileRef = AA747D9E0F9514B9006C5449 /* ComObscureKeychain_Prefix.pch */; };
+ AACBBE4A0F95108600F1A2B1 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AACBBE490F95108600F1A2B1 /* Foundation.framework */; };
+ DA20405F13D734510036A9B5 /* KeychainItemWrapper.h in Headers */ = {isa = PBXBuildFile; fileRef = DA20405B13D734510036A9B5 /* KeychainItemWrapper.h */; };
+ DA20406013D734510036A9B5 /* KeychainItemWrapper.m in Sources */ = {isa = PBXBuildFile; fileRef = DA20405C13D734510036A9B5 /* KeychainItemWrapper.m */; };
+ DA20406113D734510036A9B5 /* KeychainItemWrapperProxy.h in Headers */ = {isa = PBXBuildFile; fileRef = DA20405D13D734510036A9B5 /* KeychainItemWrapperProxy.h */; };
+ DA20406213D734510036A9B5 /* KeychainItemWrapperProxy.m in Sources */ = {isa = PBXBuildFile; fileRef = DA20405E13D734510036A9B5 /* KeychainItemWrapperProxy.m */; };
+ DA20406913D738B50036A9B5 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DA20406813D738B50036A9B5 /* Security.framework */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXContainerItemProxy section */
+ 24416B8411C4CA280047AFDD /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 0867D690FE84028FC02AAC07 /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = D2AAC07D0554694100DB518D;
+ remoteInfo = keychain;
+ };
+/* End PBXContainerItemProxy section */
+
+/* Begin PBXFileReference section */
+ 24DD6CF71134B3F500162E58 /* ComObscureKeychainModule.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ComObscureKeychainModule.h; path = Classes/ComObscureKeychainModule.h; sourceTree = "<group>"; };
+ 24DD6CF81134B3F500162E58 /* ComObscureKeychainModule.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ComObscureKeychainModule.m; path = Classes/ComObscureKeychainModule.m; sourceTree = "<group>"; };
+ 24DD6D1B1134B66800162E58 /* titanium.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = titanium.xcconfig; sourceTree = "<group>"; };
+ 24DE9E0F11C5FE74003F90F6 /* ComObscureKeychainModuleAssets.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ComObscureKeychainModuleAssets.h; path = Classes/ComObscureKeychainModuleAssets.h; sourceTree = "<group>"; };
+ 24DE9E1011C5FE74003F90F6 /* ComObscureKeychainModuleAssets.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ComObscureKeychainModuleAssets.m; path = Classes/ComObscureKeychainModuleAssets.m; sourceTree = "<group>"; };
+ AA747D9E0F9514B9006C5449 /* ComObscureKeychain_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ComObscureKeychain_Prefix.pch; sourceTree = SOURCE_ROOT; };
+ AACBBE490F95108600F1A2B1 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
+ D2AAC07E0554694100DB518D /* libComObscureKeychain.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libComObscureKeychain.a; sourceTree = BUILT_PRODUCTS_DIR; };
+ DA20405B13D734510036A9B5 /* KeychainItemWrapper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = KeychainItemWrapper.h; path = Classes/KeychainItemWrapper.h; sourceTree = "<group>"; };
+ DA20405C13D734510036A9B5 /* KeychainItemWrapper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = KeychainItemWrapper.m; path = Classes/KeychainItemWrapper.m; sourceTree = "<group>"; };
+ DA20405D13D734510036A9B5 /* KeychainItemWrapperProxy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = KeychainItemWrapperProxy.h; path = Classes/KeychainItemWrapperProxy.h; sourceTree = "<group>"; };
+ DA20405E13D734510036A9B5 /* KeychainItemWrapperProxy.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = KeychainItemWrapperProxy.m; path = Classes/KeychainItemWrapperProxy.m; sourceTree = "<group>"; };
+ DA20406813D738B50036A9B5 /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = System/Library/Frameworks/Security.framework; sourceTree = SDKROOT; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+ D2AAC07C0554694100DB518D /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ DA20406913D738B50036A9B5 /* Security.framework in Frameworks */,
+ AACBBE4A0F95108600F1A2B1 /* Foundation.framework in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+ 034768DFFF38A50411DB9C8B /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ D2AAC07E0554694100DB518D /* libComObscureKeychain.a */,
+ );
+ name = Products;
+ sourceTree = "<group>";
+ };
+ 0867D691FE84028FC02AAC07 /* keychain */ = {
+ isa = PBXGroup;
+ children = (
+ 08FB77AEFE84172EC02AAC07 /* Classes */,
+ 32C88DFF0371C24200C91783 /* Other Sources */,
+ 0867D69AFE84028FC02AAC07 /* Frameworks */,
+ 034768DFFF38A50411DB9C8B /* Products */,
+ );
+ name = keychain;
+ sourceTree = "<group>";
+ };
+ 0867D69AFE84028FC02AAC07 /* Frameworks */ = {
+ isa = PBXGroup;
+ children = (
+ DA20406813D738B50036A9B5 /* Security.framework */,
+ AACBBE490F95108600F1A2B1 /* Foundation.framework */,
+ );
+ name = Frameworks;
+ sourceTree = "<group>";
+ };
+ 08FB77AEFE84172EC02AAC07 /* Classes */ = {
+ isa = PBXGroup;
+ children = (
+ DA20405B13D734510036A9B5 /* KeychainItemWrapper.h */,
+ DA20405C13D734510036A9B5 /* KeychainItemWrapper.m */,
+ DA20405D13D734510036A9B5 /* KeychainItemWrapperProxy.h */,
+ DA20405E13D734510036A9B5 /* KeychainItemWrapperProxy.m */,
+ 24DE9E0F11C5FE74003F90F6 /* ComObscureKeychainModuleAssets.h */,
+ 24DE9E1011C5FE74003F90F6 /* ComObscureKeychainModuleAssets.m */,
+ 24DD6CF71134B3F500162E58 /* ComObscureKeychainModule.h */,
+ 24DD6CF81134B3F500162E58 /* ComObscureKeychainModule.m */,
+ );
+ name = Classes;
+ sourceTree = "<group>";
+ };
+ 32C88DFF0371C24200C91783 /* Other Sources */ = {
+ isa = PBXGroup;
+ children = (
+ AA747D9E0F9514B9006C5449 /* ComObscureKeychain_Prefix.pch */,
+ 24DD6D1B1134B66800162E58 /* titanium.xcconfig */,
+ );
+ name = "Other Sources";
+ sourceTree = "<group>";
+ };
+/* End PBXGroup section */
+
+/* Begin PBXHeadersBuildPhase section */
+ D2AAC07A0554694100DB518D /* Headers */ = {
+ isa = PBXHeadersBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ AA747D9F0F9514B9006C5449 /* ComObscureKeychain_Prefix.pch in Headers */,
+ 24DD6CF91134B3F500162E58 /* ComObscureKeychainModule.h in Headers */,
+ 24DE9E1111C5FE74003F90F6 /* ComObscureKeychainModuleAssets.h in Headers */,
+ DA20405F13D734510036A9B5 /* KeychainItemWrapper.h in Headers */,
+ DA20406113D734510036A9B5 /* KeychainItemWrapperProxy.h in Headers */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXHeadersBuildPhase section */
+
+/* Begin PBXNativeTarget section */
+ D2AAC07D0554694100DB518D /* keychain */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 1DEB921E08733DC00010E9CD /* Build configuration list for PBXNativeTarget "keychain" */;
+ buildPhases = (
+ D2AAC07A0554694100DB518D /* Headers */,
+ D2AAC07B0554694100DB518D /* Sources */,
+ D2AAC07C0554694100DB518D /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = keychain;
+ productName = keychain;
+ productReference = D2AAC07E0554694100DB518D /* libComObscureKeychain.a */;
+ productType = "com.apple.product-type.library.static";
+ };
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+ 0867D690FE84028FC02AAC07 /* Project object */ = {
+ isa = PBXProject;
+ attributes = {
+ LastUpgradeCheck = 0420;
+ };
+ buildConfigurationList = 1DEB922208733DC00010E9CD /* Build configuration list for PBXProject "keychain" */;
+ compatibilityVersion = "Xcode 3.2";
+ developmentRegion = English;
+ hasScannedForEncodings = 1;
+ knownRegions = (
+ English,
+ Japanese,
+ French,
+ German,
+ );
+ mainGroup = 0867D691FE84028FC02AAC07 /* keychain */;
+ productRefGroup = 034768DFFF38A50411DB9C8B /* Products */;
+ projectDirPath = "";
+ projectRoot = "";
+ targets = (
+ D2AAC07D0554694100DB518D /* keychain */,
+ 24416B8111C4CA220047AFDD /* Build & Test */,
+ );
+ };
+/* End PBXProject section */
+
+/* Begin PBXShellScriptBuildPhase section */
+ 24416B8011C4CA220047AFDD /* ShellScript */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ );
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "# shell script goes here\n\npython \"${TITANIUM_SDK}/titanium.py\" run --dir=\"${PROJECT_DIR}\"\nexit $?\n";
+ };
+/* End PBXShellScriptBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+ D2AAC07B0554694100DB518D /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 24DD6CFA1134B3F500162E58 /* ComObscureKeychainModule.m in Sources */,
+ 24DE9E1211C5FE74003F90F6 /* ComObscureKeychainModuleAssets.m in Sources */,
+ DA20406013D734510036A9B5 /* KeychainItemWrapper.m in Sources */,
+ DA20406213D734510036A9B5 /* KeychainItemWrapperProxy.m in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXSourcesBuildPhase section */
+
+/* Begin PBXTargetDependency section */
+ 24416B8511C4CA280047AFDD /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = D2AAC07D0554694100DB518D /* keychain */;
+ targetProxy = 24416B8411C4CA280047AFDD /* PBXContainerItemProxy */;
+ };
+/* End PBXTargetDependency section */
+
+/* Begin XCBuildConfiguration section */
+ 1DEB921F08733DC00010E9CD /* Debug */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 24DD6D1B1134B66800162E58 /* titanium.xcconfig */;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ ARCHS = "$(ARCHS_STANDARD_32_BIT)";
+ COPY_PHASE_STRIP = NO;
+ DSTROOT = /tmp/ComObscureKeychain.dst;
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_MODEL_TUNING = G5;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PRECOMPILE_PREFIX_HEADER = YES;
+ GCC_PREFIX_HEADER = ComObscureKeychain_Prefix.pch;
+ INSTALL_PATH = /usr/local/lib;
+ PRODUCT_NAME = ComObscureKeychain;
+ };
+ name = Debug;
+ };
+ 1DEB922008733DC00010E9CD /* Release */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 24DD6D1B1134B66800162E58 /* titanium.xcconfig */;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ ARCHS = "$(ARCHS_STANDARD_32_BIT)";
+ DSTROOT = /tmp/ComObscureKeychain.dst;
+ GCC_MODEL_TUNING = G5;
+ GCC_PRECOMPILE_PREFIX_HEADER = YES;
+ GCC_PREFIX_HEADER = ComObscureKeychain_Prefix.pch;
+ INSTALL_PATH = /usr/local/lib;
+ PRODUCT_NAME = ComObscureKeychain;
+ };
+ name = Release;
+ };
+ 1DEB922308733DC00010E9CD /* Debug */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 24DD6D1B1134B66800162E58 /* titanium.xcconfig */;
+ buildSettings = {
+ ARCHS = "$(ARCHS_STANDARD_32_BIT)";
+ GCC_C_LANGUAGE_STANDARD = c99;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ IPHONEOS_DEPLOYMENT_TARGET = 3.2;
+ OTHER_LDFLAGS = "";
+ SDKROOT = iphoneos;
+ };
+ name = Debug;
+ };
+ 1DEB922408733DC00010E9CD /* Release */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 24DD6D1B1134B66800162E58 /* titanium.xcconfig */;
+ buildSettings = {
+ ARCHS = "$(ARCHS_STANDARD_32_BIT)";
+ GCC_C_LANGUAGE_STANDARD = c99;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ IPHONEOS_DEPLOYMENT_TARGET = 3.2;
+ OTHER_LDFLAGS = "";
+ SDKROOT = iphoneos;
+ };
+ name = Release;
+ };
+ 24416B8211C4CA220047AFDD /* Debug */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 24DD6D1B1134B66800162E58 /* titanium.xcconfig */;
+ buildSettings = {
+ COPY_PHASE_STRIP = NO;
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ PRODUCT_NAME = "Build & test";
+ };
+ name = Debug;
+ };
+ 24416B8311C4CA220047AFDD /* Release */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 24DD6D1B1134B66800162E58 /* titanium.xcconfig */;
+ buildSettings = {
+ COPY_PHASE_STRIP = YES;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ PRODUCT_NAME = "Build & test";
+ ZERO_LINK = NO;
+ };
+ name = Release;
+ };
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+ 1DEB921E08733DC00010E9CD /* Build configuration list for PBXNativeTarget "keychain" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 1DEB921F08733DC00010E9CD /* Debug */,
+ 1DEB922008733DC00010E9CD /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ 1DEB922208733DC00010E9CD /* Build configuration list for PBXProject "keychain" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 1DEB922308733DC00010E9CD /* Debug */,
+ 1DEB922408733DC00010E9CD /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ 24416B8A11C4CA520047AFDD /* Build configuration list for PBXAggregateTarget "Build & Test" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 24416B8211C4CA220047AFDD /* Debug */,
+ 24416B8311C4CA220047AFDD /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+/* End XCConfigurationList section */
+ };
+ rootObject = 0867D690FE84028FC02AAC07 /* Project object */;
+}
7 mobile/ios/keychain.xcodeproj/project.xcworkspace/contents.xcworkspacedata
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Workspace
+ version = "1.0">
+ <FileRef
+ location = "self:keychain.xcodeproj">
+ </FileRef>
+</Workspace>
13 mobile/ios/manifest
@@ -0,0 +1,13 @@
+version: 1.0
+description: Keychain access module for iPhone
+author: Paul Mietz Egli
+license: Apache 2.0
+copyright: Copyright (c) 2011 Paul Mietz Egli
+
+
+# these should not be edited
+name: keychain
+moduleid: com.obscure.keychain
+guid: acf8434d-5290-4b73-8f39-e4cd7349860a
+platform: iphone
+minsdk: 1.7.1
27 mobile/ios/module.xcconfig
@@ -0,0 +1,27 @@
+//
+// PLACE ANY BUILD DEFINITIONS IN THIS FILE AND THEY WILL BE
+// PICKED UP DURING THE APP BUILD FOR YOUR MODULE
+//
+// see the following webpage for instructions on the settings
+// for this file:
+// http://developer.apple.com/mac/library/documentation/DeveloperTools/Conceptual/XcodeBuildSystem/400-Build_Configurations/build_configs.html
+//
+
+//
+// How to add a Framework (example)
+//
+OTHER_LDFLAGS=$(inherited) -framework Security
+//
+// Adding a framework for a specific version(s) of iPhone:
+//
+// OTHER_LDFLAGS[sdk=iphoneos4*]=$(inherited) -framework Foo
+// OTHER_LDFLAGS[sdk=iphonesimulator4*]=$(inherited) -framework Foo
+//
+//
+// How to add a compiler define:
+//
+// OTHER_CFLAGS=$(inherited) -DFOO=1
+//
+//
+// IMPORTANT NOTE: always use $(inherited) in your overrides
+//
3  mobile/ios/platform/README
@@ -0,0 +1,3 @@
+You can place platform-specific files here in sub-folders named "android" and/or "iphone", just as you can with normal Titanium Mobile SDK projects. Any folders and files you place here will be merged with the platform-specific files in a Titanium Mobile project that uses this module.
+
+When a Titanium Mobile project that uses this module is built, the files from this platform/ folder will be treated the same as files (if any) from the Titanium Mobile project's platform/ folder.
11 mobile/ios/timodule.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ti:module xmlns:ti="http://ti.appcelerator.org" xmlns:android="http://schemas.android.com/apk/res/android">
+ <!--
+ Similar to tiapp.xml, but contains module/platform specific
+ configuration in <iphone> and <android> sections
+ -->
+ <iphone>
+ </iphone>
+ <android xmlns:android="http://schemas.android.com/apk/res/android">
+ </android>
+</ti:module>
19 mobile/ios/titanium.xcconfig
@@ -0,0 +1,19 @@
+//
+//
+// CHANGE THESE VALUES TO REFLECT THE VERSION (AND LOCATION IF DIFFERENT)
+// OF YOUR TITANIUM SDK YOU'RE BUILDING FOR
+//
+//
+TITANIUM_SDK_VERSION = 1.7.2
+
+
+//
+// THESE SHOULD BE OK GENERALLY AS-IS
+//
+TITANIUM_SDK = $(HOME)/Library/Application Support/Titanium/mobilesdk/osx/$(TITANIUM_SDK_VERSION)
+TITANIUM_BASE_SDK = "$(TITANIUM_SDK)/iphone/include"
+TITANIUM_BASE_SDK2 = "$(TITANIUM_SDK)/iphone/include/TiCore"
+HEADER_SEARCH_PATHS= $(TITANIUM_BASE_SDK) $(TITANIUM_BASE_SDK2)
+
+
+
Please sign in to comment.
Something went wrong with that request. Please try again.